diff options
-rw-r--r-- | lib/spack/spack/build_systems/cached_cmake.py | 249 | ||||
-rw-r--r-- | lib/spack/spack/pkgkit.py | 4 | ||||
-rw-r--r-- | var/spack/repos/builtin/packages/axom/package.py | 540 | ||||
-rw-r--r-- | var/spack/repos/builtin/packages/hdf5/package.py | 2 |
4 files changed, 357 insertions, 438 deletions
diff --git a/lib/spack/spack/build_systems/cached_cmake.py b/lib/spack/spack/build_systems/cached_cmake.py deleted file mode 100644 index 0704a4aa09..0000000000 --- a/lib/spack/spack/build_systems/cached_cmake.py +++ /dev/null @@ -1,249 +0,0 @@ -# Copyright 2013-2021 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 os - -from llnl.util.filesystem import install, mkdirp -import llnl.util.tty as tty - -from spack.build_systems.cmake import CMakePackage -from spack.package import run_after - - -def cmake_cache_path(name, value, comment=""): - """Generate a string for a cmake cache variable""" - return 'set({0} "{1}" CACHE PATH "{2}")\n'.format(name, value, comment) - - -def cmake_cache_string(name, value, comment=""): - """Generate a string for a cmake cache variable""" - return 'set({0} "{1}" CACHE STRING "{2}")\n'.format(name, value, comment) - - -def cmake_cache_option(name, boolean_value, comment=""): - """Generate a string for a cmake configuration option""" - - value = "ON" if boolean_value else "OFF" - return 'set({0} {1} CACHE BOOL "{2}")\n'.format(name, value, comment) - - -class CachedCMakePackage(CMakePackage): - """Specialized class for packages built using CMake initial cache. - - This feature of CMake allows packages to increase reproducibility, - especially between Spack- and manual builds. It also allows packages to - sidestep certain parsing bugs in extremely long ``cmake`` commands, and to - avoid system limits on the length of the command line.""" - - phases = ['initconfig', 'cmake', 'build', 'install'] - - @property - def cache_name(self): - return "{0}-{1}-{2}@{3}.cmake".format( - self.name, - self.spec.architecture, - self.spec.compiler.name, - self.spec.compiler.version, - ) - - @property - def cache_path(self): - return os.path.join(self.stage.source_path, self.cache_name) - - def flag_handler(self, name, flags): - if name in ('cflags', 'cxxflags', 'cppflags', 'fflags'): - return (None, None, None) # handled in the cmake cache - return (flags, None, None) - - def initconfig_compiler_entries(self): - # This will tell cmake to use the Spack compiler wrappers when run - # through Spack, but use the underlying compiler when run outside of - # Spack - spec = self.spec - - # Fortran compiler is optional - if "FC" in os.environ: - spack_fc_entry = cmake_cache_path( - "CMAKE_Fortran_COMPILER", os.environ['FC']) - system_fc_entry = cmake_cache_path( - "CMAKE_Fortran_COMPILER", self.compiler.fc) - else: - spack_fc_entry = "# No Fortran compiler defined in spec" - system_fc_entry = "# No Fortran compiler defined in spec" - - entries = [ - "#------------------{0}".format("-" * 60), - "# Compilers", - "#------------------{0}".format("-" * 60), - "# Compiler Spec: {0}".format(spec.compiler), - "#------------------{0}".format("-" * 60), - 'if(DEFINED ENV{SPACK_CC})\n', - ' ' + cmake_cache_path( - "CMAKE_C_COMPILER", os.environ['CC']), - ' ' + cmake_cache_path( - "CMAKE_CXX_COMPILER", os.environ['CXX']), - ' ' + spack_fc_entry, - 'else()\n', - ' ' + cmake_cache_path( - "CMAKE_C_COMPILER", self.compiler.cc), - ' ' + cmake_cache_path( - "CMAKE_CXX_COMPILER", self.compiler.cxx), - ' ' + system_fc_entry, - 'endif()\n' - ] - - # use global spack compiler flags - cppflags = ' '.join(spec.compiler_flags['cppflags']) - if cppflags: - # avoid always ending up with ' ' with no flags defined - cppflags += ' ' - cflags = cppflags + ' '.join(spec.compiler_flags['cflags']) - if cflags: - entries.append(cmake_cache_string("CMAKE_C_FLAGS", cflags)) - cxxflags = cppflags + ' '.join(spec.compiler_flags['cxxflags']) - if cxxflags: - entries.append(cmake_cache_string("CMAKE_CXX_FLAGS", cxxflags)) - fflags = ' '.join(spec.compiler_flags['fflags']) - if fflags: - entries.append(cmake_cache_string("CMAKE_Fortran_FLAGS", fflags)) - - # Override XL compiler family - familymsg = ("Override to proper compiler family for XL") - if "xlf" in (self.compiler.fc or ''): # noqa: F821 - entries.append(cmake_cache_string( - "CMAKE_Fortran_COMPILER_ID", "XL", - familymsg)) - if "xlc" in self.compiler.cc: # noqa: F821 - entries.append(cmake_cache_string( - "CMAKE_C_COMPILER_ID", "XL", - familymsg)) - if "xlC" in self.compiler.cxx: # noqa: F821 - entries.append(cmake_cache_string( - "CMAKE_CXX_COMPILER_ID", "XL", - familymsg)) - - return entries - - def initconfig_mpi_entries(self): - spec = self.spec - - if "+mpi" not in spec: - return [] - - entries = [ - "#------------------{0}".format("-" * 60), - "# MPI", - "#------------------{0}\n".format("-" * 60), - ] - - entries.append(cmake_cache_path("MPI_C_COMPILER", - spec['mpi'].mpicc)) - entries.append(cmake_cache_path("MPI_CXX_COMPILER", - spec['mpi'].mpicxx)) - entries.append(cmake_cache_path("MPI_Fortran_COMPILER", - spec['mpi'].mpifc)) - - # Check for slurm - using_slurm = False - slurm_checks = ['+slurm', - 'schedulers=slurm', - 'process_managers=slurm'] - if any(spec['mpi'].satisfies(variant) for variant in slurm_checks): - using_slurm = True - - # Determine MPIEXEC - if using_slurm: - if spec['mpi'].external: - # Heuristic until we have dependents on externals - mpiexec = '/usr/bin/srun' - else: - mpiexec = os.path.join(spec['slurm'].prefix.bin, 'srun') - else: - mpiexec = os.path.join(spec['mpi'].prefix.bin, 'mpirun') - if not os.path.exists(mpiexec): - mpiexec = os.path.join(spec['mpi'].prefix.bin, 'mpiexec') - - if not os.path.exists(mpiexec): - msg = "Unable to determine MPIEXEC, %s tests may fail" % self.name - entries.append("# {0}\n".format(msg)) - tty.warn(msg) - else: - # starting with cmake 3.10, FindMPI expects MPIEXEC_EXECUTABLE - # vs the older versions which expect MPIEXEC - if self.spec["cmake"].satisfies('@3.10:'): - entries.append(cmake_cache_path("MPIEXEC_EXECUTABLE", - mpiexec)) - else: - entries.append(cmake_cache_path("MPIEXEC", mpiexec)) - - # Determine MPIEXEC_NUMPROC_FLAG - if using_slurm: - entries.append(cmake_cache_string("MPIEXEC_NUMPROC_FLAG", "-n")) - else: - entries.append(cmake_cache_string("MPIEXEC_NUMPROC_FLAG", "-np")) - - return entries - - def initconfig_hardware_entries(self): - spec = self.spec - - entries = [ - "#------------------{0}".format("-" * 60), - "# Hardware", - "#------------------{0}\n".format("-" * 60), - ] - - if '+cuda' in spec: - entries.append("#------------------{0}".format("-" * 30)) - entries.append("# Cuda") - entries.append("#------------------{0}\n".format("-" * 30)) - - cudatoolkitdir = spec['cuda'].prefix - entries.append(cmake_cache_path("CUDA_TOOLKIT_ROOT_DIR", - cudatoolkitdir)) - cudacompiler = "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc" - entries.append(cmake_cache_path("CMAKE_CUDA_COMPILER", - cudacompiler)) - - if "+mpi" in spec: - entries.append(cmake_cache_path("CMAKE_CUDA_HOST_COMPILER", - "${MPI_CXX_COMPILER}")) - else: - entries.append(cmake_cache_path("CMAKE_CUDA_HOST_COMPILER", - "${CMAKE_CXX_COMPILER}")) - - return entries - - def std_initconfig_entries(self): - return [ - "#------------------{0}".format("-" * 60), - "# !!!! This is a generated file, edit at own risk !!!!", - "#------------------{0}".format("-" * 60), - "# CMake executable path: {0}".format( - self.spec['cmake'].command.path), - "#------------------{0}\n".format("-" * 60), - ] - - def initconfig(self, spec, prefix): - cache_entries = (self.std_initconfig_entries() + - self.initconfig_compiler_entries() + - self.initconfig_mpi_entries() + - self.initconfig_hardware_entries() + - self.initconfig_package_entries()) - - with open(self.cache_name, 'w') as f: - for entry in cache_entries: - f.write('%s\n' % entry) - f.write('\n') - - @property - def std_cmake_args(self): - args = super(CachedCMakePackage, self).std_cmake_args - args.extend(['-C', self.cache_path]) - return args - - @run_after('install') - def install_cmake_cache(self): - mkdirp(self.spec.prefix.share.cmake) - install(self.cache_path, self.spec.prefix.share.cmake) diff --git a/lib/spack/spack/pkgkit.py b/lib/spack/spack/pkgkit.py index bc44d0b7b2..133a581e20 100644 --- a/lib/spack/spack/pkgkit.py +++ b/lib/spack/spack/pkgkit.py @@ -19,10 +19,6 @@ from spack.build_systems.makefile import MakefilePackage from spack.build_systems.aspell_dict import AspellDictPackage from spack.build_systems.autotools import AutotoolsPackage from spack.build_systems.cmake import CMakePackage -from spack.build_systems.cached_cmake import ( - CachedCMakePackage, cmake_cache_option, cmake_cache_path, - cmake_cache_string -) from spack.build_systems.cuda import CudaPackage from spack.build_systems.oneapi import IntelOneApiPackage from spack.build_systems.oneapi import IntelOneApiLibraryPackage diff --git a/var/spack/repos/builtin/packages/axom/package.py b/var/spack/repos/builtin/packages/axom/package.py index a8609f2568..b15544ce68 100644 --- a/var/spack/repos/builtin/packages/axom/package.py +++ b/var/spack/repos/builtin/packages/axom/package.py @@ -9,6 +9,20 @@ import os import socket from os.path import join as pjoin +import llnl.util.tty as tty + + +def cmake_cache_entry(name, value, comment=""): + """Generate a string for a cmake cache variable""" + return 'set({0} "{1}" CACHE PATH "{2}")\n\n'.format(name, value, comment) + + +def cmake_cache_option(name, boolean_value, comment=""): + """Generate a string for a cmake configuration option""" + + value = "ON" if boolean_value else "OFF" + return 'set({0} {1} CACHE BOOL "{2}")\n\n'.format(name, value, comment) + def get_spec_path(spec, package_name, path_replacements={}, use_bin=False): """Extracts the prefix path for the given spack package @@ -28,7 +42,7 @@ def get_spec_path(spec, package_name, path_replacements={}, use_bin=False): return path -class Axom(CachedCMakePackage, CudaPackage): +class Axom(CMakePackage, CudaPackage): """Axom provides a robust, flexible software infrastructure for the development of multi-physics applications and computational tools.""" @@ -46,6 +60,7 @@ class Axom(CachedCMakePackage, CudaPackage): version('0.3.0', tag='v0.3.0', submodules=True) version('0.2.9', tag='v0.2.9', submodules=True) + phases = ["hostconfig", "cmake", "build", "install"] root_cmakelists_dir = 'src' # ----------------------------------------------------------------------- @@ -56,7 +71,7 @@ class Axom(CachedCMakePackage, CudaPackage): variant('debug', default=False, description='Build debug instead of optimized version') - variant('cpp14', default=True, description="Build with C++14 support") + variant('cpp14', default=True, description="Build with C++14 support") variant('fortran', default=True, description="Build with Fortran support") @@ -102,7 +117,7 @@ class Axom(CachedCMakePackage, CudaPackage): depends_on("umpire~openmp", when="+umpire~openmp") depends_on("umpire+openmp", when="+umpire+openmp") - depends_on("umpire+cuda", when="+umpire+cuda") + depends_on("umpire+cuda+deviceconst", when="+umpire+cuda") for sm_ in CudaPackage.cuda_arch_values: depends_on('raja cuda_arch={0}'.format(sm_), @@ -124,6 +139,12 @@ class Axom(CachedCMakePackage, CudaPackage): depends_on("py-shroud", when="+devtools") depends_on("llvm+clang@10.0.0", when="+devtools", type='build') + def flag_handler(self, name, flags): + if name in ('cflags', 'cxxflags', 'fflags'): + # the package manages these flags in another way + return (None, None, None) + return (flags, None, None) + def _get_sys_type(self, spec): sys_type = spec.architecture # if on llnl systems, we can use the SYS_TYPE @@ -131,159 +152,108 @@ class Axom(CachedCMakePackage, CudaPackage): sys_type = env["SYS_TYPE"] return sys_type - @property - def cache_name(self): + def _get_host_config_path(self, spec): hostname = socket.gethostname() if "SYS_TYPE" in env: # Are we on a LLNL system then strip node number hostname = hostname.rstrip('1234567890') - return "{0}-{1}-{2}@{3}.cmake".format( - hostname, - self._get_sys_type(self.spec), - self.spec.compiler.name, - self.spec.compiler.version - ) - - def initconfig_compiler_entries(self): - spec = self.spec - entries = super(Axom, self).initconfig_compiler_entries() - - if "+fortran" in spec or self.compiler.fc is not None: - entries.append(cmake_cache_option("ENABLE_FORTRAN", True)) + filename = "{0}-{1}-{2}.cmake".format(hostname, + self._get_sys_type(spec), + spec.compiler) + dest_dir = self.stage.source_path + fullpath = os.path.abspath(pjoin(dest_dir, filename)) + return fullpath + + def hostconfig(self, spec, prefix): + """ + This method creates a 'host-config' file that specifies + all of the options used to configure and build Axom. + """ + + c_compiler = env["SPACK_CC"] + cpp_compiler = env["SPACK_CXX"] + f_compiler = None + + # see if we should enable fortran support + if "SPACK_FC" in env.keys(): + # even if this is set, it may not exist + # do one more sanity check + if os.path.isfile(env["SPACK_FC"]): + f_compiler = env["SPACK_FC"] + + # cmake + if "+cmake" in spec: + cmake_exe = pjoin(spec['cmake'].prefix.bin, "cmake") else: - entries.append(cmake_cache_option("ENABLE_FORTRAN", False)) - - if ((self.compiler.fc is not None) - and ("gfortran" in self.compiler.fc) - and ("clang" in self.compiler.cxx)): + cmake_exe = which("cmake") + if cmake_exe is None: + # error could not find cmake! + crash() + cmake_exe = cmake_exe.command + cmake_exe = os.path.realpath(cmake_exe) + + host_config_path = self._get_host_config_path(spec) + cfg = open(host_config_path, "w") + cfg.write("#------------------{0}\n".format("-" * 60)) + cfg.write("# !!!! This is a generated file, edit at own risk !!!!\n") + cfg.write("#------------------{0}\n".format("-" * 60)) + cfg.write("# SYS_TYPE: {0}\n".format(self._get_sys_type(spec))) + cfg.write("# Compiler Spec: {0}\n".format(spec.compiler)) + cfg.write("#------------------{0}\n".format("-" * 60)) + # show path to cmake for reference and to be used by config-build.py + cfg.write("# CMake executable path: {0}\n".format(cmake_exe)) + cfg.write("#------------------{0}\n\n".format("-" * 60)) + + # compiler settings + cfg.write("#------------------{0}\n".format("-" * 60)) + cfg.write("# Compilers\n") + cfg.write("#------------------{0}\n\n".format("-" * 60)) + + cfg.write(cmake_cache_entry("CMAKE_C_COMPILER", c_compiler)) + cfg.write(cmake_cache_entry("CMAKE_CXX_COMPILER", cpp_compiler)) + + if "+fortran" in spec or f_compiler is not None: + cfg.write(cmake_cache_option("ENABLE_FORTRAN", True)) + cfg.write(cmake_cache_entry("CMAKE_Fortran_COMPILER", f_compiler)) + else: + cfg.write(cmake_cache_option("ENABLE_FORTRAN", False)) + + # use global spack compiler flags + cppflags = ' '.join(spec.compiler_flags['cppflags']) + if cppflags: + # avoid always ending up with ' ' with no flags defined + cppflags += ' ' + cflags = cppflags + ' '.join(spec.compiler_flags['cflags']) + if cflags: + cfg.write(cmake_cache_entry("CMAKE_C_FLAGS", cflags)) + cxxflags = cppflags + ' '.join(spec.compiler_flags['cxxflags']) + if cxxflags: + cfg.write(cmake_cache_entry("CMAKE_CXX_FLAGS", cxxflags)) + fflags = ' '.join(spec.compiler_flags['fflags']) + if fflags: + cfg.write(cmake_cache_entry("CMAKE_Fortran_FLAGS", fflags)) + + if ((f_compiler is not None) + and ("gfortran" in f_compiler) + and ("clang" in cpp_compiler)): libdir = pjoin(os.path.dirname( - os.path.dirname(self.compiler.cxx)), "lib") + os.path.dirname(cpp_compiler)), "lib") flags = "" for _libpath in [libdir, libdir + "64"]: if os.path.exists(_libpath): flags += " -Wl,-rpath,{0}".format(_libpath) description = ("Adds a missing libstdc++ rpath") if flags: - entries.append(cmake_cache_string("BLT_EXE_LINKER_FLAGS", flags, - description)) + cfg.write(cmake_cache_entry("BLT_EXE_LINKER_FLAGS", flags, + description)) if "+cpp14" in spec: - entries.append(cmake_cache_string("BLT_CXX_STD", "c++14", "")) - - return entries - - def initconfig_hardware_entries(self): - spec = self.spec - entries = super(Axom, self).initconfig_hardware_entries() - - if spec.satisfies('target=ppc64le:'): - if "+cuda" in spec: - entries.append(cmake_cache_option("ENABLE_CUDA", True)) - entries.append(cmake_cache_option("CUDA_SEPARABLE_COMPILATION", - True)) - - entries.append( - cmake_cache_option("AXOM_ENABLE_ANNOTATIONS", True)) - - # CUDA_FLAGS - cudaflags = "-restrict --expt-extended-lambda " - - if not spec.satisfies('cuda_arch=none'): - cuda_arch = spec.variants['cuda_arch'].value[0] - entries.append(cmake_cache_string( - "CMAKE_CUDA_ARCHITECTURES", - cuda_arch)) - cudaflags += '-arch sm_${CMAKE_CUDA_ARCHITECTURES} ' - else: - entries.append( - "# cuda_arch could not be determined\n\n") - - if "+cpp14" in spec: - cudaflags += " -std=c++14" - else: - cudaflags += " -std=c++11" - entries.append( - cmake_cache_string("CMAKE_CUDA_FLAGS", cudaflags)) - - entries.append( - "# nvcc does not like gtest's 'pthreads' flag\n") - entries.append( - cmake_cache_option("gtest_disable_pthreads", True)) - - entries.append("#------------------{0}".format("-" * 30)) - entries.append("# Hardware Specifics") - entries.append("#------------------{0}\n".format("-" * 30)) - - # OpenMP - entries.append(cmake_cache_option("ENABLE_OPENMP", - spec.satisfies('+openmp'))) - - # Enable death tests - entries.append(cmake_cache_option( - "ENABLE_GTEST_DEATH_TESTS", - not spec.satisfies('+cuda target=ppc64le:') - )) - - if spec.satisfies('target=ppc64le:'): - if (self.compiler.fc is not None) and ("xlf" in self.compiler.fc): - description = ("Converts C-style comments to Fortran style " - "in preprocessed files") - entries.append(cmake_cache_string( - "BLT_FORTRAN_FLAGS", - "-WF,-C! -qxlf2003=polymorphic", - description)) - # Grab lib directory for the current fortran compiler - libdir = pjoin(os.path.dirname( - os.path.dirname(self.compiler.fc)), - "lib") - description = ("Adds a missing rpath for libraries " - "associated with the fortran compiler") - linker_flags = "${BLT_EXE_LINKER_FLAGS} -Wl,-rpath," + libdir - entries.append(cmake_cache_string("BLT_EXE_LINKER_FLAGS", - linker_flags, description)) - if "+shared" in spec: - linker_flags = "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath," \ - + libdir - entries.append(cmake_cache_string( - "CMAKE_SHARED_LINKER_FLAGS", - linker_flags, description)) - - # Fix for working around CMake adding implicit link directories - # returned by the BlueOS compilers to link executables with - # non-system default stdlib - _gcc_prefix = "/usr/tce/packages/gcc/gcc-4.9.3/lib64" - if os.path.exists(_gcc_prefix): - _gcc_prefix2 = pjoin( - _gcc_prefix, - "gcc/powerpc64le-unknown-linux-gnu/4.9.3") - _link_dirs = "{0};{1}".format(_gcc_prefix, _gcc_prefix2) - entries.append(cmake_cache_string( - "BLT_CMAKE_IMPLICIT_LINK_DIRECTORIES_EXCLUDE", _link_dirs)) - - return entries - - def initconfig_mpi_entries(self): - spec = self.spec - entries = super(Axom, self).initconfig_mpi_entries() - - if "+mpi" in spec: - entries.append(cmake_cache_option("ENABLE_MPI", True)) - if spec['mpi'].name == 'spectrum-mpi': - entries.append(cmake_cache_string("BLT_MPI_COMMAND_APPEND", - "mpibind")) - else: - entries.append(cmake_cache_option("ENABLE_MPI", False)) - - return entries - - def initconfig_package_entries(self): - spec = self.spec - entries = [] + cfg.write(cmake_cache_entry("BLT_CXX_STD", "c++14", "")) # TPL locations - entries.append("#------------------{0}".format("-" * 60)) - entries.append("# TPLs") - entries.append("#------------------{0}\n".format("-" * 60)) + cfg.write("#------------------{0}\n".format("-" * 60)) + cfg.write("# TPLs\n") + cfg.write("#------------------{0}\n\n".format("-" * 60)) # Try to find the common prefix of the TPL directory, including the # compiler. If found, we will use this in the TPL paths @@ -294,28 +264,113 @@ class Axom(CachedCMakePackage, CudaPackage): if len(prefix_paths) == 2: tpl_root = os.path.realpath(pjoin(prefix_paths[0], compiler_str)) path_replacements[tpl_root] = "${TPL_ROOT}" - entries.append("# Root directory for generated TPLs\n") - entries.append(cmake_cache_path("TPL_ROOT", tpl_root)) + cfg.write("# Root directory for generated TPLs\n") + cfg.write(cmake_cache_entry("TPL_ROOT", tpl_root)) conduit_dir = get_spec_path(spec, "conduit", path_replacements) - entries.append(cmake_cache_path("CONDUIT_DIR", conduit_dir)) + cfg.write(cmake_cache_entry("CONDUIT_DIR", conduit_dir)) # optional tpls - for dep in ('mfem', 'hdf5', 'lua', 'scr', 'raja', 'umpire'): - if '+%s' % dep in spec: - dep_dir = get_spec_path(spec, dep, path_replacements) - entries.append(cmake_cache_path('%s_DIR' % dep.upper(), - dep_dir)) + + if "+mfem" in spec: + mfem_dir = get_spec_path(spec, "mfem", path_replacements) + cfg.write(cmake_cache_entry("MFEM_DIR", mfem_dir)) + else: + cfg.write("# MFEM not built\n\n") + + if "+hdf5" in spec: + hdf5_dir = get_spec_path(spec, "hdf5", path_replacements) + cfg.write(cmake_cache_entry("HDF5_DIR", hdf5_dir)) + else: + cfg.write("# HDF5 not built\n\n") + + if "+lua" in spec: + lua_dir = get_spec_path(spec, "lua", path_replacements) + cfg.write(cmake_cache_entry("LUA_DIR", lua_dir)) + else: + cfg.write("# Lua not built\n\n") + + if "+scr" in spec: + scr_dir = get_spec_path(spec, "scr", path_replacements) + cfg.write(cmake_cache_entry("SCR_DIR", scr_dir)) + else: + cfg.write("# SCR not built\n\n") + + if "+raja" in spec: + raja_dir = get_spec_path(spec, "raja", path_replacements) + cfg.write(cmake_cache_entry("RAJA_DIR", raja_dir)) + else: + cfg.write("# RAJA not built\n\n") + + if "+umpire" in spec: + umpire_dir = get_spec_path(spec, "umpire", path_replacements) + cfg.write(cmake_cache_entry("UMPIRE_DIR", umpire_dir)) + else: + cfg.write("# Umpire not built\n\n") + + cfg.write("#------------------{0}\n".format("-" * 60)) + cfg.write("# MPI\n") + cfg.write("#------------------{0}\n\n".format("-" * 60)) + + if "+mpi" in spec: + cfg.write(cmake_cache_option("ENABLE_MPI", True)) + cfg.write(cmake_cache_entry("MPI_C_COMPILER", spec['mpi'].mpicc)) + cfg.write(cmake_cache_entry("MPI_CXX_COMPILER", + spec['mpi'].mpicxx)) + if "+fortran" in spec or f_compiler is not None: + cfg.write(cmake_cache_entry("MPI_Fortran_COMPILER", + spec['mpi'].mpifc)) + + # Check for slurm + using_slurm = False + slurm_checks = ['+slurm', + 'schedulers=slurm', + 'process_managers=slurm'] + if any(spec['mpi'].satisfies(variant) for variant in slurm_checks): + using_slurm = True + + # Determine MPIEXEC + if using_slurm: + if spec['mpi'].external: + mpiexec = '/usr/bin/srun' + else: + mpiexec = os.path.join(spec['slurm'].prefix.bin, 'srun') + else: + mpiexec = os.path.join(spec['mpi'].prefix.bin, 'mpirun') + if not os.path.exists(mpiexec): + mpiexec = os.path.join(spec['mpi'].prefix.bin, 'mpiexec') + + if not os.path.exists(mpiexec): + msg = "Unable to determine MPIEXEC, Axom tests may fail" + cfg.write("# {0}\n\n".format(msg)) + tty.msg(msg) + else: + # starting with cmake 3.10, FindMPI expects MPIEXEC_EXECUTABLE + # vs the older versions which expect MPIEXEC + if self.spec["cmake"].satisfies('@3.10:'): + cfg.write(cmake_cache_entry("MPIEXEC_EXECUTABLE", mpiexec)) + else: + cfg.write(cmake_cache_entry("MPIEXEC", mpiexec)) + + # Determine MPIEXEC_NUMPROC_FLAG + if using_slurm: + cfg.write(cmake_cache_entry("MPIEXEC_NUMPROC_FLAG", "-n")) else: - entries.append('# %s not build\n' % dep.upper()) + cfg.write(cmake_cache_entry("MPIEXEC_NUMPROC_FLAG", "-np")) + + if spec['mpi'].name == 'spectrum-mpi': + cfg.write(cmake_cache_entry("BLT_MPI_COMMAND_APPEND", + "mpibind")) + else: + cfg.write(cmake_cache_option("ENABLE_MPI", False)) ################################## # Devtools ################################## - entries.append("#------------------{0}".format("-" * 60)) - entries.append("# Devtools") - entries.append("#------------------{0}\n".format("-" * 60)) + cfg.write("#------------------{0}\n".format("-" * 60)) + cfg.write("# Devtools\n") + cfg.write("#------------------{0}\n\n".format("-" * 60)) # Add common prefix to path replacement list if "+devtools" in spec: @@ -324,59 +379,176 @@ class Axom(CachedCMakePackage, CudaPackage): path2 = os.path.realpath(spec["doxygen"].prefix) devtools_root = os.path.commonprefix([path1, path2])[:-1] path_replacements[devtools_root] = "${DEVTOOLS_ROOT}" - entries.append( - "# Root directory for generated developer tools\n") - entries.append(cmake_cache_path("DEVTOOLS_ROOT", devtools_root)) - - # Only turn on clangformat support if devtools is on - clang_fmt_path = spec['llvm'].prefix.bin.join('clang-format') - entries.append(cmake_cache_path( - "CLANGFORMAT_EXECUTABLE", clang_fmt_path)) - else: - entries.append("# ClangFormat disabled due to disabled devtools\n") - entries.append(cmake_cache_option("ENABLE_CLANGFORMAT", False)) + cfg.write("# Root directory for generated developer tools\n") + cfg.write(cmake_cache_entry("DEVTOOLS_ROOT", devtools_root)) if "+python" in spec or "+devtools" in spec: python_path = os.path.realpath(spec['python'].command.path) for key in path_replacements: python_path = python_path.replace(key, path_replacements[key]) - entries.append(cmake_cache_path("PYTHON_EXECUTABLE", python_path)) - - enable_docs = "doxygen" in spec or "py-sphinx" in spec - entries.append(cmake_cache_option("ENABLE_DOCS", enable_docs)) - - if "py-sphinx" in spec: - python_bin_dir = get_spec_path(spec, "python", - path_replacements, - use_bin=True) - entries.append(cmake_cache_path("SPHINX_EXECUTABLE", + cfg.write(cmake_cache_entry("PYTHON_EXECUTABLE", python_path)) + + if "doxygen" in spec or "py-sphinx" in spec: + cfg.write(cmake_cache_option("ENABLE_DOCS", True)) + + if "doxygen" in spec: + doxygen_bin_dir = get_spec_path(spec, "doxygen", + path_replacements, + use_bin=True) + cfg.write(cmake_cache_entry("DOXYGEN_EXECUTABLE", + pjoin(doxygen_bin_dir, + "doxygen"))) + + if "py-sphinx" in spec: + python_bin_dir = get_spec_path(spec, "python", + path_replacements, + use_bin=True) + cfg.write(cmake_cache_entry("SPHINX_EXECUTABLE", pjoin(python_bin_dir, "sphinx-build"))) + else: + cfg.write(cmake_cache_option("ENABLE_DOCS", False)) if "py-shroud" in spec: shroud_bin_dir = get_spec_path(spec, "py-shroud", path_replacements, use_bin=True) - entries.append(cmake_cache_path("SHROUD_EXECUTABLE", - pjoin(shroud_bin_dir, "shroud"))) + cfg.write(cmake_cache_entry("SHROUD_EXECUTABLE", + pjoin(shroud_bin_dir, "shroud"))) + + if "cppcheck" in spec: + cppcheck_bin_dir = get_spec_path(spec, "cppcheck", + path_replacements, use_bin=True) + cfg.write(cmake_cache_entry("CPPCHECK_EXECUTABLE", + pjoin(cppcheck_bin_dir, "cppcheck"))) + + # Only turn on clangformat support if devtools is on + if "+devtools" in spec: + clang_fmt_path = spec['llvm'].prefix.bin.join('clang-format') + cfg.write(cmake_cache_entry("CLANGFORMAT_EXECUTABLE", + clang_fmt_path)) + else: + cfg.write("# ClangFormat disabled due to disabled devtools\n") + cfg.write(cmake_cache_option("ENABLE_CLANGFORMAT", False)) - for dep in ('uncrustify', 'cppcheck', 'doxygen'): - if dep in spec: - dep_bin_dir = get_spec_path(spec, dep, path_replacements, - use_bin=True) - entries.append(cmake_cache_path('%s_EXECUTABLE' % dep.upper(), - pjoin(dep_bin_dir, dep))) + ################################## + # Other machine specifics + ################################## - return entries + cfg.write("#------------------{0}\n".format("-" * 60)) + cfg.write("# Other machine specifics\n") + cfg.write("#------------------{0}\n\n".format("-" * 60)) + + # OpenMP + if "+openmp" in spec: + cfg.write(cmake_cache_option("ENABLE_OPENMP", True)) + else: + cfg.write(cmake_cache_option("ENABLE_OPENMP", False)) + + # Enable death tests + if spec.satisfies('target=ppc64le:') and "+cuda" in spec: + cfg.write(cmake_cache_option("ENABLE_GTEST_DEATH_TESTS", False)) + else: + cfg.write(cmake_cache_option("ENABLE_GTEST_DEATH_TESTS", True)) + + # Override XL compiler family + familymsg = ("Override to proper compiler family for XL") + if (f_compiler is not None) and ("xlf" in f_compiler): + cfg.write(cmake_cache_entry("CMAKE_Fortran_COMPILER_ID", "XL", + familymsg)) + if "xlc" in c_compiler: + cfg.write(cmake_cache_entry("CMAKE_C_COMPILER_ID", "XL", + familymsg)) + if "xlC" in cpp_compiler: + cfg.write(cmake_cache_entry("CMAKE_CXX_COMPILER_ID", "XL", + familymsg)) + + if spec.satisfies('target=ppc64le:'): + if (f_compiler is not None) and ("xlf" in f_compiler): + description = ("Converts C-style comments to Fortran style " + "in preprocessed files") + cfg.write(cmake_cache_entry("BLT_FORTRAN_FLAGS", + "-WF,-C! -qxlf2003=polymorphic", + description)) + # Grab lib directory for the current fortran compiler + libdir = os.path.join(os.path.dirname( + os.path.dirname(f_compiler)), "lib") + description = ("Adds a missing rpath for libraries " + "associated with the fortran compiler") + linker_flags = "${BLT_EXE_LINKER_FLAGS} -Wl,-rpath," + libdir + cfg.write(cmake_cache_entry("BLT_EXE_LINKER_FLAGS", + linker_flags, description)) + if "+shared" in spec: + linker_flags = "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-rpath," \ + + libdir + cfg.write(cmake_cache_entry("CMAKE_SHARED_LINKER_FLAGS", + linker_flags, description)) + + if "+cuda" in spec: + cfg.write("#------------------{0}\n".format("-" * 60)) + cfg.write("# Cuda\n") + cfg.write("#------------------{0}\n\n".format("-" * 60)) + + cfg.write(cmake_cache_option("ENABLE_CUDA", True)) + + cudatoolkitdir = spec['cuda'].prefix + cfg.write(cmake_cache_entry("CUDA_TOOLKIT_ROOT_DIR", + cudatoolkitdir)) + cudacompiler = "${CUDA_TOOLKIT_ROOT_DIR}/bin/nvcc" + cfg.write(cmake_cache_entry("CMAKE_CUDA_COMPILER", + cudacompiler)) + + cfg.write(cmake_cache_option("CUDA_SEPARABLE_COMPILATION", + True)) + + cfg.write(cmake_cache_option("AXOM_ENABLE_ANNOTATIONS", True)) + + # CUDA_FLAGS + cudaflags = "-restrict " + + if not spec.satisfies('cuda_arch=none'): + cuda_arch = spec.variants['cuda_arch'].value + axom_arch = 'sm_{0}'.format(cuda_arch[0]) + cfg.write(cmake_cache_entry("AXOM_CUDA_ARCH", axom_arch)) + cudaflags += "-arch ${AXOM_CUDA_ARCH} " + else: + cfg.write("# cuda_arch could not be determined\n\n") + + cudaflags += "-std=c++11 --expt-extended-lambda -G " + cfg.write(cmake_cache_entry("CMAKE_CUDA_FLAGS", cudaflags)) + + if "+mpi" in spec: + cfg.write(cmake_cache_entry("CMAKE_CUDA_HOST_COMPILER", + "${MPI_CXX_COMPILER}")) + else: + cfg.write(cmake_cache_entry("CMAKE_CUDA_HOST_COMPILER", + "${CMAKE_CXX_COMPILER}")) + + cfg.write("# nvcc does not like gtest's 'pthreads' flag\n") + cfg.write(cmake_cache_option("gtest_disable_pthreads", True)) + + cfg.write("\n") + cfg.close() + tty.info("Spack generated Axom host-config file: " + host_config_path) def cmake_args(self): + spec = self.spec + host_config_path = self._get_host_config_path(spec) + options = [] + options.extend(['-C', host_config_path]) if self.run_tests is False: options.append('-DENABLE_TESTS=OFF') else: options.append('-DENABLE_TESTS=ON') - options.append(self.define_from_variant( - 'BUILD_SHARED_LIBS', 'shared')) + if "+shared" in spec: + options.append('-DBUILD_SHARED_LIBS=ON') + else: + options.append('-DBUILD_SHARED_LIBS=OFF') return options + + @run_after('install') + def install_cmake_cache(self): + install(self._get_host_config_path(self.spec), prefix) diff --git a/var/spack/repos/builtin/packages/hdf5/package.py b/var/spack/repos/builtin/packages/hdf5/package.py index 01c1428766..8425242b53 100644 --- a/var/spack/repos/builtin/packages/hdf5/package.py +++ b/var/spack/repos/builtin/packages/hdf5/package.py @@ -245,7 +245,7 @@ class Hdf5(AutotoolsPackage): # sanity check in configure, so this doesn't merit a variant. extra_args = ['--enable-unsupported', '--enable-symbols=yes', - '--with-zlib=%s' % self.spec['zlib'].prefix] + '--with-zlib'] extra_args += self.enable_or_disable('threadsafe') extra_args += self.enable_or_disable('cxx') extra_args += self.enable_or_disable('hl') |