diff --git a/lib/spack/docs/environments.rst b/lib/spack/docs/environments.rst index 48ff06d27e..963903ec64 100644 --- a/lib/spack/docs/environments.rst +++ b/lib/spack/docs/environments.rst @@ -416,6 +416,23 @@ that git clone if ``foo`` is in the environment. Further development on ``foo`` can be tested by reinstalling the environment, and eventually committed and pushed to the upstream git repo. +If the package being developed supports out-of-source builds then users can use the +``--build_directory`` flag to control the location and name of the build directory. +This is a shortcut to set the ``package_attributes:build_directory`` in the +``packages`` configuration (see :ref:`assigning-package-attributes`). +The supplied location will become the build-directory for that package in all future builds. + +.. warning:: + Potential pitfalls of setting the build directory + Spack does not check for out-of-source build compatibility with the packages and + so the onerous of making sure the package supports out-of-source builds is on + the user. + For example, most ``autotool`` and ``makefile`` packages do not support out-of-source builds + while all ``CMake`` packages do. + Understanding these nuances are on the software developers and we strongly encourage + developers to only redirect the build directory if they understand their package's + build-system. + ^^^^^^^ Loading ^^^^^^^ diff --git a/lib/spack/docs/packages_yaml.rst b/lib/spack/docs/packages_yaml.rst index bfd7f5ca2b..ab839500f8 100644 --- a/lib/spack/docs/packages_yaml.rst +++ b/lib/spack/docs/packages_yaml.rst @@ -647,6 +647,8 @@ manually placed files within the install prefix are owned by the assigned group. If no group is assigned, Spack will allow the OS default behavior to go as expected. +.. _assigning-package-attributes: + ---------------------------- Assigning Package Attributes ---------------------------- diff --git a/lib/spack/spack/cmd/develop.py b/lib/spack/spack/cmd/develop.py index 13a265af12..0c9db3274c 100644 --- a/lib/spack/spack/cmd/develop.py +++ b/lib/spack/spack/cmd/develop.py @@ -8,6 +8,7 @@ import llnl.util.tty as tty import spack.cmd +import spack.config import spack.spec import spack.util.path import spack.version @@ -21,6 +22,7 @@ def setup_parser(subparser): subparser.add_argument("-p", "--path", help="source location of package") + subparser.add_argument("-b", "--build-directory", help="build directory for the package") clone_group = subparser.add_mutually_exclusive_group() clone_group.add_argument( @@ -151,4 +153,11 @@ def develop(parser, args): env = spack.cmd.require_active_env(cmd_name="develop") tty.debug("Updating develop config for {0} transactionally".format(env.name)) with env.write_transaction(): + if args.build_directory is not None: + spack.config.add( + "packages:{}:package_attributes:build_directory:{}".format( + spec.name, args.build_directory + ), + env.scope_name, + ) _update_config(spec, path) diff --git a/lib/spack/spack/test/cmd/develop.py b/lib/spack/spack/test/cmd/develop.py index 73741ddbe7..7d01853fd4 100644 --- a/lib/spack/spack/test/cmd/develop.py +++ b/lib/spack/spack/test/cmd/develop.py @@ -9,6 +9,7 @@ import llnl.util.filesystem as fs +import spack.config import spack.environment as ev import spack.spec from spack.main import SpackCommand @@ -21,7 +22,7 @@ @pytest.mark.usefixtures("mutable_mock_env_path", "mock_packages", "mock_fetch", "mutable_config") class TestDevelop: - def check_develop(self, env, spec, path=None): + def check_develop(self, env, spec, path=None, build_dir=None): path = path or spec.name # check in memory representation @@ -41,6 +42,12 @@ def check_develop(self, env, spec, path=None): else: assert yaml_entry["path"] == path + if build_dir is not None: + scope = env.scope_name + assert build_dir == spack.config.get( + "packages:{}:package_attributes:build_directory".format(spec.name), scope + ) + def test_develop_no_path_no_clone(self): env("create", "test") with ev.read("test") as e: @@ -72,6 +79,12 @@ def test_develop_no_args(self): develop() self.check_develop(e, spack.spec.Spec("mpich@=1.0")) + def test_develop_build_directory(self): + env("create", "test") + with ev.read("test") as e: + develop("-b", "test_build_dir", "mpich@1.0") + self.check_develop(e, spack.spec.Spec("mpich@=1.0"), None, "test_build_dir") + def test_develop_twice(self): env("create", "test") with ev.read("test") as e: diff --git a/share/spack/spack-completion.bash b/share/spack/spack-completion.bash index ebcab9683e..b268afa76c 100755 --- a/share/spack/spack-completion.bash +++ b/share/spack/spack-completion.bash @@ -999,7 +999,7 @@ _spack_dev_build() { _spack_develop() { if $list_options then - SPACK_COMPREPLY="-h --help -p --path --no-clone --clone -f --force" + SPACK_COMPREPLY="-h --help -p --path -b --build-directory --no-clone --clone -f --force" else _all_packages fi diff --git a/share/spack/spack-completion.fish b/share/spack/spack-completion.fish index b2c0a89362..20f0ec837e 100755 --- a/share/spack/spack-completion.fish +++ b/share/spack/spack-completion.fish @@ -1405,12 +1405,14 @@ complete -c spack -n '__fish_spack_using_command dev-build' -l reuse-deps -f -a complete -c spack -n '__fish_spack_using_command dev-build' -l reuse-deps -d 'reuse installed dependencies only' # spack develop -set -g __fish_spack_optspecs_spack_develop h/help p/path= no-clone clone f/force= +set -g __fish_spack_optspecs_spack_develop h/help p/path= b/build-directory= no-clone clone f/force= complete -c spack -n '__fish_spack_using_command_pos_remainder 0 develop' -f -k -a '(__fish_spack_specs_or_id)' complete -c spack -n '__fish_spack_using_command develop' -s h -l help -f -a help complete -c spack -n '__fish_spack_using_command develop' -s h -l help -d 'show this help message and exit' complete -c spack -n '__fish_spack_using_command develop' -s p -l path -r -f -a path complete -c spack -n '__fish_spack_using_command develop' -s p -l path -r -d 'source location of package' +complete -c spack -n '__fish_spack_using_command develop' -s b -l build-directory -r -f -a build_directory +complete -c spack -n '__fish_spack_using_command develop' -s b -l build-directory -r -d 'build directory for the package' complete -c spack -n '__fish_spack_using_command develop' -l no-clone -f -a clone complete -c spack -n '__fish_spack_using_command develop' -l no-clone -d 'do not clone, the package already exists at the source path' complete -c spack -n '__fish_spack_using_command develop' -l clone -f -a clone