diff options
author | Harmen Stoppels <me@harmenstoppels.nl> | 2024-01-24 10:14:13 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-24 10:14:13 +0100 |
commit | 28b7f72b9615796bf467503d0bcdc357f5be65a5 (patch) | |
tree | 38480500aaac7183bfb8b1e49d7b04584048f83f /lib | |
parent | 61421b3a67941f5c91239360b4d7d3ee5c3428df (diff) | |
download | spack-28b7f72b9615796bf467503d0bcdc357f5be65a5.tar.gz spack-28b7f72b9615796bf467503d0bcdc357f5be65a5.tar.bz2 spack-28b7f72b9615796bf467503d0bcdc357f5be65a5.tar.xz spack-28b7f72b9615796bf467503d0bcdc357f5be65a5.zip |
set_packge_py_globals: only set pure build related globals on the root in build context (#42215)
Previously `std_args` was called on non-roots in a build context, which is redundant, and also leads to issues when `std_args` expects build deps of the `pkg` to be installed.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/build_environment.py | 69 | ||||
-rw-r--r-- | lib/spack/spack/build_systems/meson.py | 4 | ||||
-rw-r--r-- | lib/spack/spack/test/build_environment.py | 34 |
3 files changed, 66 insertions, 41 deletions
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py index 1ef3c658dc..68369cbe05 100644 --- a/lib/spack/spack/build_environment.py +++ b/lib/spack/spack/build_environment.py @@ -555,58 +555,55 @@ def set_package_py_globals(pkg, context: Context = Context.BUILD): """ module = ModuleChangePropagator(pkg) - m = module - if context == Context.BUILD: - jobs = determine_number_of_jobs(parallel=pkg.parallel) - m.make_jobs = jobs - - # TODO: make these build deps that can be installed if not found. - m.make = MakeExecutable("make", jobs) - m.gmake = MakeExecutable("gmake", jobs) - m.ninja = MakeExecutable("ninja", jobs, supports_jobserver=False) - # TODO: johnwparent: add package or builder support to define these build tools - # for now there is no entrypoint for builders to define these on their - # own - if sys.platform == "win32": - m.nmake = Executable("nmake") - m.msbuild = Executable("msbuild") - # analog to configure for win32 - m.cscript = Executable("cscript") - - # Find the configure script in the archive path - # Don't use which for this; we want to find it in the current dir. - m.configure = Executable("./configure") - - # Standard CMake arguments - m.std_cmake_args = spack.build_systems.cmake.CMakeBuilder.std_args(pkg) - m.std_meson_args = spack.build_systems.meson.MesonBuilder.std_args(pkg) - m.std_pip_args = spack.build_systems.python.PythonPipBuilder.std_args(pkg) + module.std_cmake_args = spack.build_systems.cmake.CMakeBuilder.std_args(pkg) + module.std_meson_args = spack.build_systems.meson.MesonBuilder.std_args(pkg) + module.std_pip_args = spack.build_systems.python.PythonPipBuilder.std_args(pkg) + + jobs = determine_number_of_jobs(parallel=pkg.parallel) + module.make_jobs = jobs + + # TODO: make these build deps that can be installed if not found. + module.make = MakeExecutable("make", jobs) + module.gmake = MakeExecutable("gmake", jobs) + module.ninja = MakeExecutable("ninja", jobs, supports_jobserver=False) + # TODO: johnwparent: add package or builder support to define these build tools + # for now there is no entrypoint for builders to define these on their + # own + if sys.platform == "win32": + module.nmake = Executable("nmake") + module.msbuild = Executable("msbuild") + # analog to configure for win32 + module.cscript = Executable("cscript") + + # Find the configure script in the archive path + # Don't use which for this; we want to find it in the current dir. + module.configure = Executable("./configure") # Put spack compiler paths in module scope. (Some packages use it # in setup_run_environment etc, so don't put it context == build) link_dir = spack.paths.build_env_path - m.spack_cc = os.path.join(link_dir, pkg.compiler.link_paths["cc"]) - m.spack_cxx = os.path.join(link_dir, pkg.compiler.link_paths["cxx"]) - m.spack_f77 = os.path.join(link_dir, pkg.compiler.link_paths["f77"]) - m.spack_fc = os.path.join(link_dir, pkg.compiler.link_paths["fc"]) + module.spack_cc = os.path.join(link_dir, pkg.compiler.link_paths["cc"]) + module.spack_cxx = os.path.join(link_dir, pkg.compiler.link_paths["cxx"]) + module.spack_f77 = os.path.join(link_dir, pkg.compiler.link_paths["f77"]) + module.spack_fc = os.path.join(link_dir, pkg.compiler.link_paths["fc"]) # Useful directories within the prefix are encapsulated in # a Prefix object. - m.prefix = pkg.prefix + module.prefix = pkg.prefix # Platform-specific library suffix. - m.dso_suffix = dso_suffix + module.dso_suffix = dso_suffix def static_to_shared_library(static_lib, shared_lib=None, **kwargs): - compiler_path = kwargs.get("compiler", m.spack_cc) + compiler_path = kwargs.get("compiler", module.spack_cc) compiler = Executable(compiler_path) return _static_to_shared_library( pkg.spec.architecture, compiler, static_lib, shared_lib, **kwargs ) - m.static_to_shared_library = static_to_shared_library + module.static_to_shared_library = static_to_shared_library module.propagate_changes_to_mro() @@ -975,8 +972,8 @@ class SetupContext: self.should_set_package_py_globals = ( self.should_setup_dependent_build_env | self.should_setup_run_env | UseMode.ROOT ) - # In a build context, the root and direct build deps need build-specific globals set. - self.needs_build_context = UseMode.ROOT | UseMode.BUILDTIME_DIRECT + # In a build context, the root needs build-specific globals set. + self.needs_build_context = UseMode.ROOT def set_all_package_py_globals(self): """Set the globals in modules of package.py files.""" diff --git a/lib/spack/spack/build_systems/meson.py b/lib/spack/spack/build_systems/meson.py index 860fa4cf1b..2c2bc0d1a0 100644 --- a/lib/spack/spack/build_systems/meson.py +++ b/lib/spack/spack/build_systems/meson.py @@ -149,7 +149,7 @@ class MesonBuilder(BaseBuilder): else: default_library = "shared" - args = [ + return [ "-Dprefix={0}".format(pkg.prefix), # If we do not specify libdir explicitly, Meson chooses something # like lib/x86_64-linux-gnu, which causes problems when trying to @@ -163,8 +163,6 @@ class MesonBuilder(BaseBuilder): "-Dwrap_mode=nodownload", ] - return args - @property def build_dirname(self): """Returns the directory name to use when building the package.""" diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py index fb9874daeb..1f2d9e904f 100644 --- a/lib/spack/spack/test/build_environment.py +++ b/lib/spack/spack/test/build_environment.py @@ -457,10 +457,10 @@ def test_parallel_false_is_not_propagating(default_mock_concretization): # b (parallel =True) s = default_mock_concretization("a foobar=bar") - spack.build_environment.set_package_py_globals(s.package) + spack.build_environment.set_package_py_globals(s.package, context=Context.BUILD) assert s["a"].package.module.make_jobs == 1 - spack.build_environment.set_package_py_globals(s["b"].package) + spack.build_environment.set_package_py_globals(s["b"].package, context=Context.BUILD) assert s["b"].package.module.make_jobs == spack.build_environment.determine_number_of_jobs( parallel=s["b"].package.parallel ) @@ -685,3 +685,33 @@ def test_clear_compiler_related_runtime_variables_of_build_deps(default_mock_con assert "FC" not in result assert "F77" not in result assert result["ANOTHER_VAR"] == "this-should-be-present" + + +@pytest.mark.parametrize("context", [Context.BUILD, Context.RUN]) +def test_build_system_globals_only_set_on_root_during_build(default_mock_concretization, context): + """Test whether when setting up a build environment, the build related globals are set only + in the top level spec. + + TODO: Since module instances are globals themselves, and Spack defines properties on them, they + persist across tests. In principle this is not terrible, cause the variables are mostly static. + But obviously it can lead to very hard to find bugs... We should get rid of those globals and + define them instead as a property on the package instance. + """ + root = spack.spec.Spec("mpileaks").concretized() + build_variables = ("std_cmake_args", "std_meson_args", "std_pip_args") + + # See todo above, we clear out any properties that may have been set by the previous test. + # Commenting this loop will make the test fail. I'm leaving it here as a reminder that those + # globals were always a bad idea, and we should pass them to the package instance. + for spec in root.traverse(): + for variable in build_variables: + spec.package.module.__dict__.pop(variable, None) + + spack.build_environment.SetupContext(root, context=context).set_all_package_py_globals() + + # Excpect the globals to be set at the root in a build context only. + should_be_set = lambda depth: context == Context.BUILD and depth == 0 + + for depth, spec in root.traverse(depth=True, root=True): + for variable in build_variables: + assert hasattr(spec.package.module, variable) == should_be_set(depth) |