diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py index acdfa66ea2..5d70994bd4 100644 --- a/lib/spack/spack/build_systems/cmake.py +++ b/lib/spack/spack/build_systems/cmake.py @@ -7,6 +7,7 @@ import inspect import os import platform +import re import spack.build_environment from llnl.util.filesystem import working_dir @@ -14,6 +15,19 @@ from spack.directives import depends_on, variant from spack.package import PackageBase, InstallError, run_after +# Regex to extract the primary generator from the CMake generator +# string. +_primary_generator_extractor = re.compile(r'(?:.* - )?(.*)') + + +def _extract_primary_generator(generator): + """Use the compiled regex _primary_generator_extractor to extract the + primary generator from the generator string which may contain an + optional secondary generator. + """ + primary_generator = _primary_generator_extractor.match(generator).group(1) + return primary_generator + class CMakePackage(PackageBase): """Specialized class for packages built using CMake @@ -42,6 +56,17 @@ class CMakePackage(PackageBase): +-----------------------------------------------+--------------------+ + The generator used by CMake can be specified by providing the + generator attribute. Per + https://cmake.org/cmake/help/git-master/manual/cmake-generators.7.html, + the format is: [ - ]. The + full list of primary and secondary generators supported by CMake may + be found in the documentation for the version of CMake used; + however, at this time Spack supports only the primary generators + "Unix Makefiles" and "Ninja." Spack's CMake support is agnostic with + respect to primary generators. Spack will generate a runtime error + if the generator string does not follow the prescribed format, or if + the primary generator is not supported. """ #: Phases of a CMake package phases = ['cmake', 'build', 'install'] @@ -108,11 +133,13 @@ def _std_args(pkg): generator = 'Unix Makefiles' # Make sure a valid generator was chosen - valid_generators = ['Unix Makefiles', 'Ninja'] - if generator not in valid_generators: + valid_primary_generators = ['Unix Makefiles', 'Ninja'] + primary_generator = _extract_primary_generator(generator) + if primary_generator not in valid_primary_generators: msg = "Invalid CMake generator: '{0}'\n".format(generator) msg += "CMakePackage currently supports the following " - msg += "generators: '{0}'".format("', '".join(valid_generators)) + msg += "primary generators: '{0}'".\ + format("', '".join(valid_primary_generators)) raise InstallError(msg) try: @@ -124,9 +151,11 @@ def _std_args(pkg): '-G', generator, '-DCMAKE_INSTALL_PREFIX:PATH={0}'.format(pkg.prefix), '-DCMAKE_BUILD_TYPE:STRING={0}'.format(build_type), - '-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON' ] + if primary_generator == 'Unix Makefiles': + args.append('-DCMAKE_VERBOSE_MAKEFILE:BOOL=ON') + if platform.mac_ver()[0]: args.extend([ '-DCMAKE_FIND_FRAMEWORK:STRING=LAST', diff --git a/lib/spack/spack/test/build_systems.py b/lib/spack/spack/test/build_systems.py index 1932d1bbc2..fb9117bc0c 100644 --- a/lib/spack/spack/test/build_systems.py +++ b/lib/spack/spack/test/build_systems.py @@ -115,6 +115,23 @@ def test_cmake_std_args(config, mock_packages): assert get_std_cmake_args(pkg) +def test_cmake_bad_generator(config, mock_packages): + s = Spec('cmake-client') + s.concretize() + pkg = spack.repo.get(s) + pkg.generator = 'Yellow Sticky Notes' + with pytest.raises(spack.package.InstallError): + get_std_cmake_args(pkg) + + +def test_cmake_secondary_generator(config, mock_packages): + s = Spec('cmake-client') + s.concretize() + pkg = spack.repo.get(s) + pkg.generator = 'CodeBlocks - Unix Makefiles' + assert get_std_cmake_args(pkg) + + @pytest.mark.usefixtures('config', 'mock_packages') class TestAutotoolsPackage(object):