Allow secondary generators when building with CMake. (#9324)

CMake supports the notion of secondary generators which provide extra
information to (e.g.) IDEs over and above that normally provided by
the primary generator. Spack only supports the 'Unix Makefiles' and
'Ninja' primary generators but was not parsing out the primary
generator when a secondary generator was also included (e.g. for
a generator attribute like 'Codeblocks - Ninja'). This adds a regex
for extracting the primary generator for validation.

Since the secondary generator is irrelevant to a Spack build, it is
passed on to CMake without further validation.
This commit is contained in:
Chris Green 2019-02-12 12:39:19 -06:00 committed by Peter Scheibel
parent f9c27f52bd
commit 05f565356f
2 changed files with 50 additions and 4 deletions

View file

@ -7,6 +7,7 @@
import inspect import inspect
import os import os
import platform import platform
import re
import spack.build_environment import spack.build_environment
from llnl.util.filesystem import working_dir from llnl.util.filesystem import working_dir
@ -14,6 +15,19 @@
from spack.directives import depends_on, variant from spack.directives import depends_on, variant
from spack.package import PackageBase, InstallError, run_after 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): class CMakePackage(PackageBase):
"""Specialized class for packages built using CMake """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: [<secondary-generator> - ]<primary_generator>. 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 of a CMake package
phases = ['cmake', 'build', 'install'] phases = ['cmake', 'build', 'install']
@ -108,11 +133,13 @@ def _std_args(pkg):
generator = 'Unix Makefiles' generator = 'Unix Makefiles'
# Make sure a valid generator was chosen # Make sure a valid generator was chosen
valid_generators = ['Unix Makefiles', 'Ninja'] valid_primary_generators = ['Unix Makefiles', 'Ninja']
if generator not in valid_generators: primary_generator = _extract_primary_generator(generator)
if primary_generator not in valid_primary_generators:
msg = "Invalid CMake generator: '{0}'\n".format(generator) msg = "Invalid CMake generator: '{0}'\n".format(generator)
msg += "CMakePackage currently supports the following " 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) raise InstallError(msg)
try: try:
@ -124,9 +151,11 @@ def _std_args(pkg):
'-G', generator, '-G', generator,
'-DCMAKE_INSTALL_PREFIX:PATH={0}'.format(pkg.prefix), '-DCMAKE_INSTALL_PREFIX:PATH={0}'.format(pkg.prefix),
'-DCMAKE_BUILD_TYPE:STRING={0}'.format(build_type), '-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]: if platform.mac_ver()[0]:
args.extend([ args.extend([
'-DCMAKE_FIND_FRAMEWORK:STRING=LAST', '-DCMAKE_FIND_FRAMEWORK:STRING=LAST',

View file

@ -115,6 +115,23 @@ def test_cmake_std_args(config, mock_packages):
assert get_std_cmake_args(pkg) 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') @pytest.mark.usefixtures('config', 'mock_packages')
class TestAutotoolsPackage(object): class TestAutotoolsPackage(object):