From 15c98fa57c0022df3c3788f19b3febd484d8ccd7 Mon Sep 17 00:00:00 2001 From: Chris Green Date: Fri, 8 Jun 2018 15:49:31 -0500 Subject: compiler flags: add cxx98 standard support (#7601) The following improvements are made to cxx standard support (e.g. compiler.cxxNN_flag functions) in compilers: * Add cxx98_flag property * Add support for throwing an exception when a flag is not supported (previously if a flag was not supported the application was terminated with tty.die) * The name of the flag associated with e.g. c++14 standard support changes for different compiler versions (e.g. c++1y vs c++14). This makes a few corrections on what flag to return for which version. * Added tests to confirm that versions report expected flags for various c++ standards (or raise an exception for versions that don't provide a given cxx standard) Note that if a given cxx standard is the default, the associated flag property will return ""; cxx98 is assumed to be the default standard so this is the behavior for the associated property in the base compiler class. Package changes: * Improvements to the boost spec to take advantage of the improved standard flag facility. * Update the clingo spec to catch the new exception rather than look for an empty flag to indicate non-support (which is not part of the compiler flag API) --- lib/spack/docs/packaging_guide.rst | 4 +- lib/spack/spack/compiler.py | 48 ++++-- lib/spack/spack/compilers/clang.py | 43 ++++-- lib/spack/spack/compilers/gcc.py | 35 ++++- lib/spack/spack/compilers/intel.py | 16 +- lib/spack/spack/compilers/xl.py | 10 +- lib/spack/spack/compilers/xl_r.py | 10 +- lib/spack/spack/test/compilers.py | 169 ++++++++++++++++++++- var/spack/repos/builtin/packages/boost/package.py | 41 ++++- var/spack/repos/builtin/packages/clingo/package.py | 4 +- 10 files changed, 328 insertions(+), 52 deletions(-) diff --git a/lib/spack/docs/packaging_guide.rst b/lib/spack/docs/packaging_guide.rst index ca21092f26..34be562c29 100644 --- a/lib/spack/docs/packaging_guide.rst +++ b/lib/spack/docs/packaging_guide.rst @@ -2654,8 +2654,8 @@ In rare circumstances such as compiling and running small unit tests, a package developer may need to know what are the appropriate compiler flags to enable features like ``OpenMP``, ``c++11``, ``c++14`` and alike. To that end the compiler classes in ``spack`` implement the -following **properties**: ``openmp_flag``, ``cxx11_flag``, -``cxx14_flag``, which can be accessed in a package by +following **properties**: ``openmp_flag``, ``cxx98_flag``, ``cxx11_flag``, +``cxx14_flag``, and ``cxx17_flag``, which can be accessed in a package by ``self.compiler.cxx11_flag`` and alike. Note that the implementation is such that if a given compiler version does not support this feature, an error will be produced. Therefore package developers can also use these diff --git a/lib/spack/spack/compiler.py b/lib/spack/spack/compiler.py index 6d9742150e..b219eee09d 100644 --- a/lib/spack/spack/compiler.py +++ b/lib/spack/spack/compiler.py @@ -178,40 +178,40 @@ class Compiler(object): @property def openmp_flag(self): # If it is not overridden, assume it is not supported and warn the user - tty.die( - "The compiler you have chosen does not currently support OpenMP.", - "If you think it should, please edit the compiler subclass and", - "submit a pull request or issue.") + raise UnsupportedCompilerFlag(self, "OpenMP", "openmp_flag") + + # This property should be overridden in the compiler subclass if + # C++98 is not the default standard for that compiler + @property + def cxx98_flag(self): + return "" # This property should be overridden in the compiler subclass if # C++11 is supported by that compiler @property def cxx11_flag(self): # If it is not overridden, assume it is not supported and warn the user - tty.die( - "The compiler you have chosen does not currently support C++11.", - "If you think it should, please edit the compiler subclass and", - "submit a pull request or issue.") + raise UnsupportedCompilerFlag(self, + "the C++11 standard", + "cxx11_flag") # This property should be overridden in the compiler subclass if # C++14 is supported by that compiler @property def cxx14_flag(self): # If it is not overridden, assume it is not supported and warn the user - tty.die( - "The compiler you have chosen does not currently support C++14.", - "If you think it should, please edit the compiler subclass and", - "submit a pull request or issue.") + raise UnsupportedCompilerFlag(self, + "the C++14 standard", + "cxx14_flag") # This property should be overridden in the compiler subclass if # C++17 is supported by that compiler @property def cxx17_flag(self): # If it is not overridden, assume it is not supported and warn the user - tty.die( - "The compiler you have chosen does not currently support C++17.", - "If you think it should, please edit the compiler subclass and", - "submit a pull request or issue.") + raise UnsupportedCompilerFlag(self, + "the C++17 standard", + "cxx17_flag") # # Compiler classes have methods for querying the version of @@ -339,3 +339,19 @@ class InvalidCompilerError(spack.error.SpackError): def __init__(self): super(InvalidCompilerError, self).__init__( "Compiler has no executables.") + + +class UnsupportedCompilerFlag(spack.error.SpackError): + + def __init__(self, compiler, feature, flag_name, ver_string=None): + super(UnsupportedCompilerFlag, self).__init__( + "{0} ({1}) does not support {2} (as compiler.{3})." + .format(compiler.name, + ver_string if ver_string else compiler.version, + feature, + flag_name), + "If you think it should, please edit the compiler.{0} subclass to" + .format(compiler.name) + + " implement the {0} property and submit a pull request or issue." + .format(flag_name) + ) diff --git a/lib/spack/spack/compilers/clang.py b/lib/spack/spack/compilers/clang.py index ce54e49c79..2aa958ab91 100644 --- a/lib/spack/spack/compilers/clang.py +++ b/lib/spack/spack/compilers/clang.py @@ -30,7 +30,7 @@ from shutil import copytree, ignore_patterns import llnl.util.tty as tty import spack.paths -from spack.compiler import Compiler, _version_cache +from spack.compiler import Compiler, _version_cache, UnsupportedCompilerFlag from spack.util.executable import Executable from spack.version import ver @@ -69,7 +69,10 @@ class Clang(Compiler): @property def openmp_flag(self): if self.is_apple: - tty.die("Clang from Apple does not support Openmp yet.") + raise UnsupportedCompilerFlag(self, + "OpenMP", + "openmp_flag", + "Xcode {0}".format(self.version)) else: return "-fopenmp" @@ -77,14 +80,20 @@ class Clang(Compiler): def cxx11_flag(self): if self.is_apple: # Adapted from CMake's AppleClang-CXX rules - # Spack's AppleClang detection only valid form Xcode >= 4.6 + # Spack's AppleClang detection only valid from Xcode >= 4.6 if self.version < ver('4.0.0'): - tty.die("Only Apple LLVM 4.0 and above support c++11") + raise UnsupportedCompilerFlag(self, + "the C++11 standard", + "cxx11_flag", + "Xcode < 4.0.0") else: return "-std=c++11" else: if self.version < ver('3.3'): - tty.die("Only Clang 3.3 and above support c++11.") + raise UnsupportedCompilerFlag(self, + "the C++11 standard", + "cxx11_flag", + "< 3.3") else: return "-std=c++11" @@ -93,14 +102,20 @@ class Clang(Compiler): if self.is_apple: # Adapted from CMake's rules for AppleClang if self.version < ver('5.1.0'): - tty.die("Only Apple LLVM 5.1 and above support c++14.") + raise UnsupportedCompilerFlag(self, + "the C++14 standard", + "cxx14_flag", + "Xcode < 5.1.0") elif self.version < ver('6.1.0'): return "-std=c++1y" else: return "-std=c++14" else: if self.version < ver('3.4'): - tty.die("Only Clang 3.4 and above support c++14.") + raise UnsupportedCompilerFlag(self, + "the C++14 standard", + "cxx14_flag", + "< 3.5") elif self.version < ver('3.5'): return "-std=c++1y" else: @@ -111,14 +126,22 @@ class Clang(Compiler): if self.is_apple: # Adapted from CMake's rules for AppleClang if self.version < ver('6.1.0'): - tty.die("Only Apple LLVM 6.1 and above support c++17.") + raise UnsupportedCompilerFlag(self, + "the C++17 standard", + "cxx17_flag", + "Xcode < 6.1.0") else: return "-std=c++1z" else: if self.version < ver('3.5'): - tty.die("Only Clang 3.5 and above support c++17.") - else: + raise UnsupportedCompilerFlag(self, + "the C++17 standard", + "cxx17_flag", + "< 5.0") + elif self.version < ver('5.0'): return "-std=c++1z" + else: + return "-std=c++17" @property def pic_flag(self): diff --git a/lib/spack/spack/compilers/gcc.py b/lib/spack/spack/compilers/gcc.py index e52dd5c047..489e87e544 100644 --- a/lib/spack/spack/compilers/gcc.py +++ b/lib/spack/spack/compilers/gcc.py @@ -22,10 +22,9 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## -import llnl.util.tty as tty - import spack.compilers.clang -from spack.compiler import Compiler, get_compiler_version +from spack.compiler import \ + Compiler, get_compiler_version, UnsupportedCompilerFlag from spack.version import ver @@ -60,10 +59,20 @@ class Gcc(Compiler): def openmp_flag(self): return "-fopenmp" + @property + def cxx98_flag(self): + if self.version < ver('6.0'): + return "" + else: + return "-std=c++98" + @property def cxx11_flag(self): if self.version < ver('4.3'): - tty.die("Only gcc 4.3 and above support c++11.") + raise UnsupportedCompilerFlag(self, + "the C++11 standard", + "cxx11_flag", + " < 4.3") elif self.version < ver('4.7'): return "-std=c++0x" else: @@ -72,18 +81,28 @@ class Gcc(Compiler): @property def cxx14_flag(self): if self.version < ver('4.8'): - tty.die("Only gcc 4.8 and above support c++14.") + raise UnsupportedCompilerFlag(self, + "the C++14 standard", + "cxx14_flag", + "< 4.8") elif self.version < ver('4.9'): return "-std=c++1y" - else: + elif self.version < ver('6.0'): return "-std=c++14" + else: + return "" @property def cxx17_flag(self): if self.version < ver('5.0'): - tty.die("Only gcc 5.0 and above support c++17.") - else: + raise UnsupportedCompilerFlag(self, + "the C++17 standard", + "cxx17_flag", + "< 5.0") + elif self.version < ver('6.0'): return "-std=c++1z" + else: + return "-std=c++17" @property def pic_flag(self): diff --git a/lib/spack/spack/compilers/intel.py b/lib/spack/spack/compilers/intel.py index 0c5ba3ab40..962120362e 100644 --- a/lib/spack/spack/compilers/intel.py +++ b/lib/spack/spack/compilers/intel.py @@ -22,9 +22,8 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## -import llnl.util.tty as tty - -from spack.compiler import Compiler, get_compiler_version +from spack.compiler import \ + Compiler, get_compiler_version, UnsupportedCompilerFlag from spack.version import ver @@ -60,7 +59,11 @@ class Intel(Compiler): @property def cxx11_flag(self): if self.version < ver('11.1'): - tty.die("Only intel 11.1 and above support c++11.") + raise UnsupportedCompilerFlag(self, + "the C++11 standard", + "cxx11_flag", + "< 11.1") + elif self.version < ver('13'): return "-std=c++0x" else: @@ -70,7 +73,10 @@ class Intel(Compiler): def cxx14_flag(self): # Adapted from CMake's Intel-CXX rules. if self.version < ver('15'): - tty.die("Only intel 15.0 and above support c++14.") + raise UnsupportedCompilerFlag(self, + "the C++14 standard", + "cxx14_flag", + "< 15") elif self.version < ver('15.0.2'): return "-std=c++1y" else: diff --git a/lib/spack/spack/compilers/xl.py b/lib/spack/spack/compilers/xl.py index 7b5bd3994b..4448efbb98 100644 --- a/lib/spack/spack/compilers/xl.py +++ b/lib/spack/spack/compilers/xl.py @@ -22,9 +22,8 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## -import llnl.util.tty as tty - -from spack.compiler import Compiler, get_compiler_version +from spack.compiler import \ + Compiler, get_compiler_version, UnsupportedCompilerFlag from spack.version import ver @@ -54,7 +53,10 @@ class Xl(Compiler): @property def cxx11_flag(self): if self.version < ver('13.1'): - tty.die("Only xlC 13.1 and above have some c++11 support.") + raise UnsupportedCompilerFlag(self, + "the C++11 standard", + "cxx11_flag", + "< 13.1") else: return "-qlanglvl=extended0x" diff --git a/lib/spack/spack/compilers/xl_r.py b/lib/spack/spack/compilers/xl_r.py index 774db363af..9aa12a03ce 100644 --- a/lib/spack/spack/compilers/xl_r.py +++ b/lib/spack/spack/compilers/xl_r.py @@ -23,9 +23,8 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## -import llnl.util.tty as tty - -from spack.compiler import Compiler, get_compiler_version +from spack.compiler import \ + Compiler, get_compiler_version, UnsupportedCompilerFlag from spack.version import ver @@ -55,7 +54,10 @@ class XlR(Compiler): @property def cxx11_flag(self): if self.version < ver('13.1'): - tty.die("Only xlC 13.1 and above have some c++11 support.") + raise UnsupportedCompilerFlag(self, + "the C++11 standard", + "cxx11_flag", + "< 13.1") else: return "-qlanglvl=extended0x" diff --git a/lib/spack/spack/test/compilers.py b/lib/spack/spack/test/compilers.py index 2c9d68f674..4e14641b63 100644 --- a/lib/spack/spack/test/compilers.py +++ b/lib/spack/spack/test/compilers.py @@ -22,11 +22,12 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## +from copy import copy from six import iteritems import spack.spec import spack.compilers as compilers -from spack.compiler import _get_versioned_tuple +from spack.compiler import _get_versioned_tuple, Compiler def test_get_compiler_duplicates(config): @@ -79,3 +80,169 @@ def test_compiler_flags_from_config_are_grouped(): compiler = compilers.compiler_from_config_entry(compiler_entry) assert any(x == '-foo-flag foo-val' for x in compiler.flags['cflags']) + + +# Test behavior of flags and UnsupportedCompilerFlag. + +# Utility function to test most flags. +default_compiler_entry = { + 'spec': 'clang@2.0.0-apple', + 'operating_system': 'foo-os', + 'paths': { + 'cc': 'cc-path', + 'cxx': 'cxx-path', + 'fc': None, + 'f77': None + }, + 'flags': {}, + 'modules': None +} + + +# Fake up a mock compiler where everything is defaulted. +class MockCompiler(Compiler): + def __init__(self): + super(MockCompiler, self).__init__( + "badcompiler@1.0.0", + default_compiler_entry['operating_system'], + None, + [default_compiler_entry['paths']['cc'], + default_compiler_entry['paths']['cxx'], + default_compiler_entry['paths']['fc'], + default_compiler_entry['paths']['f77']]) + + @property + def name(self): + return "mockcompiler" + + @property + def version(self): + return "1.0.0" + + +# Get the desired flag from the specified compiler spec. +def flag_value(flag, spec): + compiler = None + if spec is None: + compiler = MockCompiler() + else: + compiler_entry = copy(default_compiler_entry) + compiler_entry['spec'] = spec + # Disable faulty id()-based cache (issue #7647). + compilers._compiler_cache = {} + compiler = compilers.compiler_from_config_entry(compiler_entry) + + return getattr(compiler, flag) + + +# Utility function to verify that the expected exception is thrown for +# an unsupported flag. +def unsupported_flag_test(flag, spec=None): + caught_exception = None + try: + flag_value(flag, spec) + except spack.compiler.UnsupportedCompilerFlag: + caught_exception = True + + assert(caught_exception and "Expected exception not thrown.") + + +# Verify the expected flag value for the give compiler spec. +def supported_flag_test(flag, flag_value_ref, spec=None): + assert(flag_value(flag, spec) == flag_value_ref) + + +# Tests for UnsupportedCompilerFlag exceptions from default +# implementations of flags. +def test_default_flags(): + unsupported_flag_test("openmp_flag") + unsupported_flag_test("cxx11_flag") + unsupported_flag_test("cxx14_flag") + unsupported_flag_test("cxx17_flag") + supported_flag_test("cxx98_flag", "") + + +# Verify behavior of particular compiler definitions. +def test_clang_flags(): + # Common + supported_flag_test("pic_flag", "-fPIC", "gcc@4.0") + + # Apple Clang. + unsupported_flag_test("openmp_flag", "clang@2.0.0-apple") + unsupported_flag_test("cxx11_flag", "clang@2.0.0-apple") + supported_flag_test("cxx11_flag", "-std=c++11", "clang@4.0.0-apple") + unsupported_flag_test("cxx14_flag", "clang@5.0.0-apple") + supported_flag_test("cxx14_flag", "-std=c++1y", "clang@5.1.0-apple") + supported_flag_test("cxx14_flag", "-std=c++14", "clang@6.1.0-apple") + unsupported_flag_test("cxx17_flag", "clang@6.0.0-apple") + supported_flag_test("cxx17_flag", "-std=c++1z", "clang@6.1.0-apple") + + # non-Apple Clang. + supported_flag_test("openmp_flag", "-fopenmp", "clang@3.3") + unsupported_flag_test("cxx11_flag", "clang@3.2") + supported_flag_test("cxx11_flag", "-std=c++11", "clang@3.3") + unsupported_flag_test("cxx14_flag", "clang@3.3") + supported_flag_test("cxx14_flag", "-std=c++1y", "clang@3.4") + supported_flag_test("cxx14_flag", "-std=c++14", "clang@3.5") + unsupported_flag_test("cxx17_flag", "clang@3.4") + supported_flag_test("cxx17_flag", "-std=c++1z", "clang@3.5") + supported_flag_test("cxx17_flag", "-std=c++17", "clang@5.0") + + +def test_cce_flags(): + supported_flag_test("openmp_flag", "-h omp", "cce@1.0") + supported_flag_test("cxx11_flag", "-h std=c++11", "cce@1.0") + supported_flag_test("pic_flag", "-h PIC", "cce@1.0") + + +def test_gcc_flags(): + supported_flag_test("openmp_flag", "-fopenmp", "gcc@4.1") + supported_flag_test("cxx98_flag", "", "gcc@5.2") + supported_flag_test("cxx98_flag", "-std=c++98", "gcc@6.0") + unsupported_flag_test("cxx11_flag", "gcc@4.2") + supported_flag_test("cxx11_flag", "-std=c++0x", "gcc@4.3") + supported_flag_test("cxx11_flag", "-std=c++11", "gcc@4.7") + unsupported_flag_test("cxx14_flag", "gcc@4.7") + supported_flag_test("cxx14_flag", "-std=c++1y", "gcc@4.8") + supported_flag_test("cxx14_flag", "-std=c++14", "gcc@4.9") + supported_flag_test("cxx14_flag", "", "gcc@6.0") + unsupported_flag_test("cxx17_flag", "gcc@4.9") + supported_flag_test("pic_flag", "-fPIC", "gcc@4.0") + + +def test_intel_flags(): + supported_flag_test("openmp_flag", "-openmp", "intel@15.0") + supported_flag_test("openmp_flag", "-qopenmp", "intel@16.0") + unsupported_flag_test("cxx11_flag", "intel@11.0") + supported_flag_test("cxx11_flag", "-std=c++0x", "intel@12.0") + supported_flag_test("cxx11_flag", "-std=c++11", "intel@13") + unsupported_flag_test("cxx14_flag", "intel@14.0") + supported_flag_test("cxx14_flag", "-std=c++1y", "intel@15.0") + supported_flag_test("cxx14_flag", "-std=c++14", "intel@15.0.2") + supported_flag_test("pic_flag", "-fPIC", "intel@1.0") + + +def test_nag_flags(): + supported_flag_test("openmp_flag", "-openmp", "nag@1.0") + supported_flag_test("cxx11_flag", "-std=c++11", "nag@1.0") + supported_flag_test("pic_flag", "-PIC", "nag@1.0") + + +def test_pgi_flags(): + supported_flag_test("openmp_flag", "-mp", "pgi@1.0") + supported_flag_test("cxx11_flag", "-std=c++11", "pgi@1.0") + supported_flag_test("pic_flag", "-fpic", "pgi@1.0") + + +def test_xl_flags(): + supported_flag_test("openmp_flag", "-qsmp=omp", "xl@1.0") + unsupported_flag_test("cxx11_flag", "xl@13.0") + supported_flag_test("cxx11_flag", "-qlanglvl=extended0x", "xl@13.1") + supported_flag_test("pic_flag", "-qpic", "xl@1.0") + + +def test_xl_r_flags(): + supported_flag_test("openmp_flag", "-qsmp=omp", "xl_r@1.0") + unsupported_flag_test("cxx11_flag", "xl_r@13.0") + supported_flag_test("cxx11_flag", "-qlanglvl=extended0x", "xl_r@13.1") + supported_flag_test("pic_flag", "-qpic", "xl_r@1.0") diff --git a/var/spack/repos/builtin/packages/boost/package.py b/var/spack/repos/builtin/packages/boost/package.py index 5666df8baa..db72c06212 100644 --- a/var/spack/repos/builtin/packages/boost/package.py +++ b/var/spack/repos/builtin/packages/boost/package.py @@ -126,6 +126,11 @@ class Boost(Package): variant(lib, default=(lib not in default_noinstall_libs), description="Compile with {0} library".format(lib)) + variant('cxxstd', + default='default', + values=('default', '98', '11', '14', '17'), + multi=False, + description='Use the specified C++ standard when building.') variant('debug', default=False, description='Switch to the debug version of Boost') variant('shared', default=True, @@ -250,6 +255,26 @@ class Boost(Package): if '+python' in spec: f.write(self.bjam_python_line(spec)) + def cxxstd_to_flag(self, std): + flag = '' + if self.spec.variants['cxxstd'].value == '98': + flag = self.compiler.cxx98_flag + elif self.spec.variants['cxxstd'].value == '11': + flag = self.compiler.cxx11_flag + elif self.spec.variants['cxxstd'].value == '14': + flag = self.compiler.cxx14_flag + elif self.spec.variants['cxxstd'].value == '17': + flag = self.compiler.cxx17_flag + elif self.spec.variants['cxxstd'].value == 'default': + # Let the compiler do what it usually does. + pass + else: + # The user has selected a (new?) legal value that we've + # forgotten to deal with here. + tty.die("INTERNAL ERROR: cannot accommodate unexpected variant ", + "cxxstd={0}".format(spec.variants['cxxstd'].value)) + return flag + def determine_b2_options(self, spec, options): if '+debug' in spec: options.append('variant=debug') @@ -299,6 +324,17 @@ class Boost(Package): 'toolset=%s' % self.determine_toolset(spec) ]) + # Other C++ flags. + cxxflags = [] + + # Deal with C++ standard. + if spec.satisfies('@1.66:'): + options.append('cxxstd={0}'.format(spec.variants['cxxstd'].value)) + else: # Add to cxxflags for older Boost. + flag = self.cxxstd_to_flag(spec.variants['cxxstd'].value) + if flag: + cxxflags.append(flag) + # clang is not officially supported for pre-compiled headers # and at least in clang 3.9 still fails to build # http://www.boost.org/build/doc/html/bbv2/reference/precompiled_headers.html @@ -306,10 +342,13 @@ class Boost(Package): if spec.satisfies('%clang'): options.extend(['pch=off']) if '+clanglibcpp' in spec: + cxxflags.append('-stdlib=libc++') options.extend(['toolset=clang', - 'cxxflags="-stdlib=libc++"', 'linkflags="-stdlib=libc++"']) + if cxxflags: + options.append('cxxflags="{0}"'.format(' '.join(cxxflags))) + return threadingOpts def add_buildopt_symlinks(self, prefix): diff --git a/var/spack/repos/builtin/packages/clingo/package.py b/var/spack/repos/builtin/packages/clingo/package.py index cf45630e12..c014e14cf2 100644 --- a/var/spack/repos/builtin/packages/clingo/package.py +++ b/var/spack/repos/builtin/packages/clingo/package.py @@ -44,7 +44,9 @@ class Clingo(CMakePackage): depends_on('python') def cmake_args(self): - if not self.compiler.cxx14_flag: + try: + self.compiler.cxx14_flag + except UnsupportedCompilerFlag: InstallError('clingo requires a C++14-compliant C++ compiler') args = ['-DCLINGO_BUILD_WITH_PYTHON=ON', -- cgit v1.2.3-70-g09d2