Refactor environment setup.
- Gave setup_environment and setup_dependent_environment more similar signatures. They now allows editing the Spack env and the runtime env for *this* package and dependents, respectively. - modify_module renamed to setup_dependent_python_module for symmetry with setup_dependent_environment and to avoid confusion with environment modules. - removed need for patching Package objects at runtime. - adjust packages to reflect these changes.
This commit is contained in:
		@@ -47,13 +47,6 @@ class Mpich(Package):
 | 
			
		||||
    provides('mpi@:3.0', when='@3:')
 | 
			
		||||
    provides('mpi@:1.3', when='@1:')
 | 
			
		||||
 | 
			
		||||
    def setup_environment(self, env):
 | 
			
		||||
        env.set_env('MPICH_CC', self.compiler.cc)
 | 
			
		||||
        env.set_env('MPICH_CXX', self.compiler.cxx)
 | 
			
		||||
        env.set_env('MPICH_F77', self.compiler.f77)
 | 
			
		||||
        env.set_env('MPICH_F90', self.compiler.fc)
 | 
			
		||||
        env.set_env('MPICH_FC', self.compiler.fc)
 | 
			
		||||
 | 
			
		||||
    def setup_dependent_environment(self, env, dependent_spec):
 | 
			
		||||
        env.set_env('MPICH_CC', spack_cc)
 | 
			
		||||
        env.set_env('MPICH_CXX', spack_cxx)
 | 
			
		||||
@@ -61,7 +54,7 @@ def setup_dependent_environment(self, env, dependent_spec):
 | 
			
		||||
        env.set_env('MPICH_F90', spack_f90)
 | 
			
		||||
        env.set_env('MPICH_FC', spack_fc)
 | 
			
		||||
 | 
			
		||||
    def modify_module(self, module, spec, dep_spec):
 | 
			
		||||
    def setup_dependent_python_module(self, module, spec, dep_spec):
 | 
			
		||||
        """For dependencies, make mpicc's use spack wrapper."""
 | 
			
		||||
        # FIXME : is this necessary ? Shouldn't this be part of a contract with MPI providers?
 | 
			
		||||
        module.mpicc = join_path(self.prefix.bin, 'mpicc')
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,7 @@ def install(self, spec, prefix):
 | 
			
		||||
            make()
 | 
			
		||||
            make("install")
 | 
			
		||||
 | 
			
		||||
    def modify_module(self, module, spec, dependent_spec):
 | 
			
		||||
    def setup_dependent_python_module(self, module, spec, dependent_spec):
 | 
			
		||||
        lib_dsuffix = '.dylib' if sys.platform == 'darwin' else '.so'
 | 
			
		||||
        lib_suffix = lib_dsuffix if '+shared' in spec['scalapack'] else '.a'
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -41,17 +41,13 @@ class Openmpi(Package):
 | 
			
		||||
    def url_for_version(self, version):
 | 
			
		||||
        return "http://www.open-mpi.org/software/ompi/v%s/downloads/openmpi-%s.tar.bz2" % (version.up_to(2), version)
 | 
			
		||||
 | 
			
		||||
    def setup_environment(self, env):
 | 
			
		||||
        env.set_env('OMPI_CC', self.compiler.cc)
 | 
			
		||||
        env.set_env('OMPI_CXX', self.compiler.cxx)
 | 
			
		||||
        env.set_env('OMPI_FC', self.compiler.fc)
 | 
			
		||||
        env.set_env('OMPI_F77', self.compiler.f77)
 | 
			
		||||
 | 
			
		||||
    def setup_dependent_environment(self, env, dependent_spec):
 | 
			
		||||
        env.set_env('OMPI_CC', spack_cc)
 | 
			
		||||
        env.set_env('OMPI_CXX', spack_cxx)
 | 
			
		||||
        env.set_env('OMPI_FC', spack_fc)
 | 
			
		||||
        env.set_env('OMPI_F77', spack_f77)
 | 
			
		||||
    def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
 | 
			
		||||
        spack_env.set_env('OMPI_CC', spack_cc)
 | 
			
		||||
        spack_env.set_env('OMPI_CXX', spack_cxx)
 | 
			
		||||
        spack_env.set_env('OMPI_FC', spack_fc)
 | 
			
		||||
        spack_env.set_env('OMPI_F77', spack_f77)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def install(self, spec, prefix):
 | 
			
		||||
        config_args = ["--prefix=%s" % prefix,
 | 
			
		||||
 
 | 
			
		||||
@@ -92,13 +92,21 @@ def python_include_dir(self):
 | 
			
		||||
    def site_packages_dir(self):
 | 
			
		||||
        return os.path.join(self.python_lib_dir, 'site-packages')
 | 
			
		||||
 | 
			
		||||
    def setup_dependent_environment(self, env, extension_spec):
 | 
			
		||||
        # Set PYTHONPATH to include site-packages dir for the extension and any other python extensions it depends on.
 | 
			
		||||
 | 
			
		||||
    def setup_dependent_environment(self, spack_env, run_env, extension_spec):
 | 
			
		||||
        # TODO: do this only for actual extensions.
 | 
			
		||||
 | 
			
		||||
        # Set PYTHONPATH to include site-packages dir for the
 | 
			
		||||
        # extension and any other python extensions it depends on.
 | 
			
		||||
        python_paths = []
 | 
			
		||||
        for d in extension_spec.traverse():
 | 
			
		||||
            if d.package.extends(self.spec):
 | 
			
		||||
                python_paths.append(os.path.join(d.prefix, self.site_packages_dir))
 | 
			
		||||
        env.set_env('PYTHONPATH', ':'.join(python_paths))
 | 
			
		||||
 | 
			
		||||
        pythonpath = ':'.join(python_paths)
 | 
			
		||||
        spack_env.set_env('PYTHONPATH', pythonpath)
 | 
			
		||||
        run_env.set_env('PYTHONPATH', pythonpath)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def modify_module(self, module, spec, ext_spec):
 | 
			
		||||
        """
 | 
			
		||||
@@ -114,31 +122,6 @@ def modify_module(self, module, spec, ext_spec):
 | 
			
		||||
        else:
 | 
			
		||||
            module.python = Executable(join_path(spec.prefix.bin, 'python'))
 | 
			
		||||
 | 
			
		||||
        # The code below patches the any python extension to have good defaults for `setup_dependent_environment` and
 | 
			
		||||
        # `setup_environment` only if the extension didn't override any of these functions explicitly.
 | 
			
		||||
        def _setup_env(self, env):
 | 
			
		||||
            site_packages = glob.glob(join_path(self.spec.prefix.lib, "python*/site-packages"))
 | 
			
		||||
            if site_packages:
 | 
			
		||||
                env.prepend_path('PYTHONPATH', site_packages[0])
 | 
			
		||||
 | 
			
		||||
        def _setup_denv(self, env, extension_spec):
 | 
			
		||||
            pass
 | 
			
		||||
 | 
			
		||||
        pkg_cls = type(ext_spec.package)  # Retrieve the type we may want to patch
 | 
			
		||||
        if 'python' in pkg_cls.extendees:
 | 
			
		||||
            # List of overrides we are interested in
 | 
			
		||||
            interesting_overrides = ['setup_environment', 'setup_dependent_environment']
 | 
			
		||||
            overrides_found = [
 | 
			
		||||
                (name, defining_cls) for name, _, defining_cls, _, in inspect.classify_class_attrs(pkg_cls)
 | 
			
		||||
                if
 | 
			
		||||
                name in interesting_overrides and  # The attribute has the right name
 | 
			
		||||
                issubclass(defining_cls, Package) and defining_cls is not Package  # and is an actual override
 | 
			
		||||
            ]
 | 
			
		||||
            if not overrides_found:
 | 
			
		||||
                # If no override were found go on patching
 | 
			
		||||
                pkg_cls.setup_environment = functools.wraps(Package.setup_environment)(_setup_env)
 | 
			
		||||
                pkg_cls.setup_dependent_environment = functools.wraps(Package.setup_dependent_environment)(_setup_denv)
 | 
			
		||||
 | 
			
		||||
        # Add variables for lib/pythonX.Y and lib/pythonX.Y/site-packages dirs.
 | 
			
		||||
        module.python_lib_dir     = os.path.join(ext_spec.prefix, self.python_lib_dir)
 | 
			
		||||
        module.python_include_dir = os.path.join(ext_spec.prefix, self.python_include_dir)
 | 
			
		||||
 
 | 
			
		||||
@@ -55,8 +55,14 @@ class Qt(Package):
 | 
			
		||||
    depends_on("mesa", when='@4:+mesa')
 | 
			
		||||
    depends_on("libxcb")
 | 
			
		||||
 | 
			
		||||
    def setup_environment(self, env):
 | 
			
		||||
        env.set_env['QTDIR'] = self.prefix
 | 
			
		||||
 | 
			
		||||
    def setup_environment(self, spack_env, env):
 | 
			
		||||
        env.set_env('QTDIR', self.prefix)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def setup_dependent_environment(self, spack_env, run_env, dspec):
 | 
			
		||||
        spack_env.set_env('QTDIR', self.prefix)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def patch(self):
 | 
			
		||||
        if self.spec.satisfies('@4'):
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Ruby(Package):
 | 
			
		||||
    """A dynamic, open source programming language with a focus on 
 | 
			
		||||
    """A dynamic, open source programming language with a focus on
 | 
			
		||||
    simplicity and productivity."""
 | 
			
		||||
 | 
			
		||||
    homepage = "https://www.ruby-lang.org/"
 | 
			
		||||
@@ -17,15 +17,17 @@ def install(self, spec, prefix):
 | 
			
		||||
        make()
 | 
			
		||||
        make("install")
 | 
			
		||||
 | 
			
		||||
    def setup_dependent_environment(self, env, extension_spec):
 | 
			
		||||
    def setup_dependent_environment(self, spack_env, run_env, extension_spec):
 | 
			
		||||
        # TODO: do this only for actual extensions.
 | 
			
		||||
        # Set GEM_PATH to include dependent gem directories
 | 
			
		||||
        ruby_paths = []
 | 
			
		||||
        for d in extension_spec.traverse():
 | 
			
		||||
            if d.package.extends(self.spec):
 | 
			
		||||
                ruby_paths.append(d.prefix)
 | 
			
		||||
        env.set_env('GEM_PATH', concatenate_paths(ruby_paths))
 | 
			
		||||
 | 
			
		||||
        spack_env.set_env('GEM_PATH', concatenate_paths(ruby_paths))
 | 
			
		||||
        # The actual installation path for this gem
 | 
			
		||||
        env.set_env('GEM_HOME', extension_spec.prefix)
 | 
			
		||||
        spack_env.set_env('GEM_HOME', extension_spec.prefix)
 | 
			
		||||
 | 
			
		||||
    def modify_module(self, module, spec, ext_spec):
 | 
			
		||||
        """Called before ruby modules' install() methods.  Sets GEM_HOME
 | 
			
		||||
@@ -38,5 +40,3 @@ def modify_module(self, module, spec, ext_spec):
 | 
			
		||||
        # Ruby extension builds have global ruby and gem functions
 | 
			
		||||
        module.ruby = Executable(join_path(spec.prefix.bin, 'ruby'))
 | 
			
		||||
        module.gem = Executable(join_path(spec.prefix.bin, 'gem'))
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user