Fix spack package inheritance for module variables (#10097)
* we weren't properly setting module variables for the root package in a DAG -- just for transitive dependencies.
This commit is contained in:
committed by
Todd Gamblin
parent
05f9c68c30
commit
d2d0ab06b7
@@ -370,10 +370,8 @@ def set_build_environment_variables(pkg, env, dirty):
|
|||||||
return env
|
return env
|
||||||
|
|
||||||
|
|
||||||
def set_module_variables_for_package(pkg, module):
|
def _set_variables_for_single_module(pkg, module):
|
||||||
"""Populate the module scope of install() with some useful functions.
|
"""Helper function to set module variables for single module."""
|
||||||
This makes things easier for package writers.
|
|
||||||
"""
|
|
||||||
# number of jobs spack will build with.
|
# number of jobs spack will build with.
|
||||||
jobs = spack.config.get('config:build_jobs') or multiprocessing.cpu_count()
|
jobs = spack.config.get('config:build_jobs') or multiprocessing.cpu_count()
|
||||||
if not pkg.parallel:
|
if not pkg.parallel:
|
||||||
@@ -444,6 +442,20 @@ def static_to_shared_library(static_lib, shared_lib=None, **kwargs):
|
|||||||
m.static_to_shared_library = static_to_shared_library
|
m.static_to_shared_library = static_to_shared_library
|
||||||
|
|
||||||
|
|
||||||
|
def set_module_variables_for_package(pkg):
|
||||||
|
"""Populate the module scope of install() with some useful functions.
|
||||||
|
This makes things easier for package writers.
|
||||||
|
"""
|
||||||
|
# If a user makes their own package repo, e.g.
|
||||||
|
# spack.pkg.mystuff.libelf.Libelf, and they inherit from an existing class
|
||||||
|
# like spack.pkg.original.libelf.Libelf, then set the module variables
|
||||||
|
# for both classes so the parent class can still use them if it gets
|
||||||
|
# called. parent_class_modules includes pkg.module.
|
||||||
|
modules = parent_class_modules(pkg.__class__)
|
||||||
|
for mod in modules:
|
||||||
|
_set_variables_for_single_module(pkg, mod)
|
||||||
|
|
||||||
|
|
||||||
def _static_to_shared_library(arch, compiler, static_lib, shared_lib=None,
|
def _static_to_shared_library(arch, compiler, static_lib, shared_lib=None,
|
||||||
**kwargs):
|
**kwargs):
|
||||||
"""
|
"""
|
||||||
@@ -591,6 +603,8 @@ def get_std_meson_args(pkg):
|
|||||||
def parent_class_modules(cls):
|
def parent_class_modules(cls):
|
||||||
"""
|
"""
|
||||||
Get list of superclass modules that descend from spack.package.PackageBase
|
Get list of superclass modules that descend from spack.package.PackageBase
|
||||||
|
|
||||||
|
Includes cls.__module__
|
||||||
"""
|
"""
|
||||||
if (not issubclass(cls, spack.package.PackageBase) or
|
if (not issubclass(cls, spack.package.PackageBase) or
|
||||||
issubclass(spack.package.PackageBase, cls)):
|
issubclass(spack.package.PackageBase, cls)):
|
||||||
@@ -634,23 +648,15 @@ def setup_package(pkg, dirty):
|
|||||||
spec = pkg.spec
|
spec = pkg.spec
|
||||||
for dspec in pkg.spec.traverse(order='post', root=False,
|
for dspec in pkg.spec.traverse(order='post', root=False,
|
||||||
deptype=('build', 'test')):
|
deptype=('build', 'test')):
|
||||||
# If a user makes their own package repo, e.g.
|
|
||||||
# spack.pkg.mystuff.libelf.Libelf, and they inherit from
|
|
||||||
# an existing class like spack.pkg.original.libelf.Libelf,
|
|
||||||
# then set the module variables for both classes so the
|
|
||||||
# parent class can still use them if it gets called.
|
|
||||||
spkg = dspec.package
|
spkg = dspec.package
|
||||||
modules = parent_class_modules(spkg.__class__)
|
set_module_variables_for_package(spkg)
|
||||||
for mod in modules:
|
|
||||||
set_module_variables_for_package(spkg, mod)
|
|
||||||
set_module_variables_for_package(spkg, spkg.module)
|
|
||||||
|
|
||||||
# Allow dependencies to modify the module
|
# Allow dependencies to modify the module
|
||||||
dpkg = dspec.package
|
dpkg = dspec.package
|
||||||
dpkg.setup_dependent_package(pkg.module, spec)
|
dpkg.setup_dependent_package(pkg.module, spec)
|
||||||
dpkg.setup_dependent_environment(spack_env, run_env, spec)
|
dpkg.setup_dependent_environment(spack_env, run_env, spec)
|
||||||
|
|
||||||
set_module_variables_for_package(pkg, pkg.module)
|
set_module_variables_for_package(pkg)
|
||||||
pkg.setup_environment(spack_env, run_env)
|
pkg.setup_environment(spack_env, run_env)
|
||||||
|
|
||||||
# Loading modules, in particular if they are meant to be used outside
|
# Loading modules, in particular if they are meant to be used outside
|
||||||
|
|||||||
@@ -515,22 +515,13 @@ def environment_modifications(self):
|
|||||||
# before asking for package-specific modifications
|
# before asking for package-specific modifications
|
||||||
for item in dependencies(self.spec, 'all'):
|
for item in dependencies(self.spec, 'all'):
|
||||||
package = self.spec[item.name].package
|
package = self.spec[item.name].package
|
||||||
modules = build_environment.parent_class_modules(package.__class__)
|
build_environment.set_module_variables_for_package(package)
|
||||||
for mod in modules:
|
|
||||||
build_environment.set_module_variables_for_package(
|
|
||||||
package, mod
|
|
||||||
)
|
|
||||||
build_environment.set_module_variables_for_package(
|
|
||||||
package, package.module
|
|
||||||
)
|
|
||||||
package.setup_dependent_package(
|
package.setup_dependent_package(
|
||||||
self.spec.package.module, self.spec
|
self.spec.package.module, self.spec
|
||||||
)
|
)
|
||||||
package.setup_dependent_environment(_, env, self.spec)
|
package.setup_dependent_environment(_, env, self.spec)
|
||||||
# Package specific modifications
|
# Package specific modifications
|
||||||
build_environment.set_module_variables_for_package(
|
build_environment.set_module_variables_for_package(self.spec.package)
|
||||||
self.spec.package, self.spec.package.module
|
|
||||||
)
|
|
||||||
self.spec.package.setup_environment(_, env)
|
self.spec.package.setup_environment(_, env)
|
||||||
|
|
||||||
# Modifications required from modules.yaml
|
# Modifications required from modules.yaml
|
||||||
|
|||||||
@@ -215,3 +215,18 @@ def _set_wrong_cc(x):
|
|||||||
paths = os.environ['PATH'].split(':')
|
paths = os.environ['PATH'].split(':')
|
||||||
|
|
||||||
assert paths.index(spack_path) < paths.index(module_path)
|
assert paths.index(spack_path) < paths.index(module_path)
|
||||||
|
|
||||||
|
|
||||||
|
def test_package_inheritance_module_setup(config, mock_packages):
|
||||||
|
s = spack.spec.Spec('multimodule-inheritance')
|
||||||
|
s.concretize()
|
||||||
|
pkg = s.package
|
||||||
|
|
||||||
|
spack.build_environment.setup_package(pkg, False)
|
||||||
|
|
||||||
|
os.environ['TEST_MODULE_VAR'] = 'failed'
|
||||||
|
|
||||||
|
assert pkg.use_module_variable() == 'test_module_variable'
|
||||||
|
assert os.environ['TEST_MODULE_VAR'] == 'test_module_variable'
|
||||||
|
|
||||||
|
os.environ.pop('TEST_MODULE_VAR')
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# Copyright 2013-2018 Lawrence Livermore National Security, LLC and other
|
||||||
|
# Spack Project Developers. See the top-level COPYRIGHT file for details.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
|
||||||
|
|
||||||
|
import spack.pkg.builtin.mock.simple_inheritance as si
|
||||||
|
|
||||||
|
|
||||||
|
class MultimoduleInheritance(si.BaseWithDirectives):
|
||||||
|
"""Simple package which inherits a method and several directives"""
|
||||||
|
|
||||||
|
homepage = "http://www.example.com"
|
||||||
|
url = "http://www.example.com/multimodule-1.0.tar.gz"
|
||||||
|
|
||||||
|
version('1.0', '0123456789abcdef0123456789abcdef')
|
||||||
|
|
||||||
|
depends_on('openblas', when='+openblas')
|
||||||
|
|
||||||
|
def install(self, spec, prefix):
|
||||||
|
pass
|
||||||
@@ -13,6 +13,12 @@ class BaseWithDirectives(Package):
|
|||||||
variant('openblas', description='Activates openblas', default=True)
|
variant('openblas', description='Activates openblas', default=True)
|
||||||
provides('service1')
|
provides('service1')
|
||||||
|
|
||||||
|
def use_module_variable(self):
|
||||||
|
"""Must be called in build environment. Allows us to test parent class
|
||||||
|
using module variables set up by build_environment."""
|
||||||
|
env['TEST_MODULE_VAR'] = 'test_module_variable'
|
||||||
|
return env['TEST_MODULE_VAR']
|
||||||
|
|
||||||
|
|
||||||
class SimpleInheritance(BaseWithDirectives):
|
class SimpleInheritance(BaseWithDirectives):
|
||||||
"""Simple package which acts as a build dependency"""
|
"""Simple package which acts as a build dependency"""
|
||||||
|
|||||||
Reference in New Issue
Block a user