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)
This commit is contained in:
		| @@ -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 | package developer may need to know what are the appropriate compiler | ||||||
| flags to enable features like ``OpenMP``, ``c++11``, ``c++14`` and | flags to enable features like ``OpenMP``, ``c++11``, ``c++14`` and | ||||||
| alike. To that end the compiler classes in ``spack`` implement the | alike. To that end the compiler classes in ``spack`` implement the | ||||||
| following **properties**: ``openmp_flag``, ``cxx11_flag``, | following **properties**: ``openmp_flag``, ``cxx98_flag``, ``cxx11_flag``, | ||||||
| ``cxx14_flag``, which can be accessed in a package by | ``cxx14_flag``, and ``cxx17_flag``, which can be accessed in a package by | ||||||
| ``self.compiler.cxx11_flag`` and alike. Note that the implementation is | ``self.compiler.cxx11_flag`` and alike. Note that the implementation is | ||||||
| such that if a given compiler version does not support this feature, an | such that if a given compiler version does not support this feature, an | ||||||
| error will be produced. Therefore package developers can also use these | error will be produced. Therefore package developers can also use these | ||||||
|   | |||||||
| @@ -178,40 +178,40 @@ def version(self): | |||||||
|     @property |     @property | ||||||
|     def openmp_flag(self): |     def openmp_flag(self): | ||||||
|         # If it is not overridden, assume it is not supported and warn the user |         # If it is not overridden, assume it is not supported and warn the user | ||||||
|         tty.die( |         raise UnsupportedCompilerFlag(self, "OpenMP", "openmp_flag") | ||||||
|             "The compiler you have chosen does not currently support OpenMP.", |  | ||||||
|             "If you think it should, please edit the compiler subclass and", |     # This property should be overridden in the compiler subclass if | ||||||
|             "submit a pull request or issue.") |     # 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 |     # This property should be overridden in the compiler subclass if | ||||||
|     # C++11 is supported by that compiler |     # C++11 is supported by that compiler | ||||||
|     @property |     @property | ||||||
|     def cxx11_flag(self): |     def cxx11_flag(self): | ||||||
|         # If it is not overridden, assume it is not supported and warn the user |         # If it is not overridden, assume it is not supported and warn the user | ||||||
|         tty.die( |         raise UnsupportedCompilerFlag(self, | ||||||
|             "The compiler you have chosen does not currently support C++11.", |                                       "the C++11 standard", | ||||||
|             "If you think it should, please edit the compiler subclass and", |                                       "cxx11_flag") | ||||||
|             "submit a pull request or issue.") |  | ||||||
|  |  | ||||||
|     # This property should be overridden in the compiler subclass if |     # This property should be overridden in the compiler subclass if | ||||||
|     # C++14 is supported by that compiler |     # C++14 is supported by that compiler | ||||||
|     @property |     @property | ||||||
|     def cxx14_flag(self): |     def cxx14_flag(self): | ||||||
|         # If it is not overridden, assume it is not supported and warn the user |         # If it is not overridden, assume it is not supported and warn the user | ||||||
|         tty.die( |         raise UnsupportedCompilerFlag(self, | ||||||
|             "The compiler you have chosen does not currently support C++14.", |                                       "the C++14 standard", | ||||||
|             "If you think it should, please edit the compiler subclass and", |                                       "cxx14_flag") | ||||||
|             "submit a pull request or issue.") |  | ||||||
|  |  | ||||||
|     # This property should be overridden in the compiler subclass if |     # This property should be overridden in the compiler subclass if | ||||||
|     # C++17 is supported by that compiler |     # C++17 is supported by that compiler | ||||||
|     @property |     @property | ||||||
|     def cxx17_flag(self): |     def cxx17_flag(self): | ||||||
|         # If it is not overridden, assume it is not supported and warn the user |         # If it is not overridden, assume it is not supported and warn the user | ||||||
|         tty.die( |         raise UnsupportedCompilerFlag(self, | ||||||
|             "The compiler you have chosen does not currently support C++17.", |                                       "the C++17 standard", | ||||||
|             "If you think it should, please edit the compiler subclass and", |                                       "cxx17_flag") | ||||||
|             "submit a pull request or issue.") |  | ||||||
|  |  | ||||||
|     # |     # | ||||||
|     # Compiler classes have methods for querying the version of |     # Compiler classes have methods for querying the version of | ||||||
| @@ -339,3 +339,19 @@ class InvalidCompilerError(spack.error.SpackError): | |||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         super(InvalidCompilerError, self).__init__( |         super(InvalidCompilerError, self).__init__( | ||||||
|             "Compiler has no executables.") |             "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) | ||||||
|  |         ) | ||||||
|   | |||||||
| @@ -30,7 +30,7 @@ | |||||||
| import llnl.util.tty as tty | import llnl.util.tty as tty | ||||||
|  |  | ||||||
| import spack.paths | 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.util.executable import Executable | ||||||
| from spack.version import ver | from spack.version import ver | ||||||
|  |  | ||||||
| @@ -69,7 +69,10 @@ def is_apple(self): | |||||||
|     @property |     @property | ||||||
|     def openmp_flag(self): |     def openmp_flag(self): | ||||||
|         if self.is_apple: |         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: |         else: | ||||||
|             return "-fopenmp" |             return "-fopenmp" | ||||||
|  |  | ||||||
| @@ -77,14 +80,20 @@ def openmp_flag(self): | |||||||
|     def cxx11_flag(self): |     def cxx11_flag(self): | ||||||
|         if self.is_apple: |         if self.is_apple: | ||||||
|             # Adapted from CMake's AppleClang-CXX rules |             # 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'): |             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: |             else: | ||||||
|                 return "-std=c++11" |                 return "-std=c++11" | ||||||
|         else: |         else: | ||||||
|             if self.version < ver('3.3'): |             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: |             else: | ||||||
|                 return "-std=c++11" |                 return "-std=c++11" | ||||||
|  |  | ||||||
| @@ -93,14 +102,20 @@ def cxx14_flag(self): | |||||||
|         if self.is_apple: |         if self.is_apple: | ||||||
|             # Adapted from CMake's rules for AppleClang |             # Adapted from CMake's rules for AppleClang | ||||||
|             if self.version < ver('5.1.0'): |             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'): |             elif self.version < ver('6.1.0'): | ||||||
|                 return "-std=c++1y" |                 return "-std=c++1y" | ||||||
|             else: |             else: | ||||||
|                 return "-std=c++14" |                 return "-std=c++14" | ||||||
|         else: |         else: | ||||||
|             if self.version < ver('3.4'): |             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'): |             elif self.version < ver('3.5'): | ||||||
|                 return "-std=c++1y" |                 return "-std=c++1y" | ||||||
|             else: |             else: | ||||||
| @@ -111,14 +126,22 @@ def cxx17_flag(self): | |||||||
|         if self.is_apple: |         if self.is_apple: | ||||||
|             # Adapted from CMake's rules for AppleClang |             # Adapted from CMake's rules for AppleClang | ||||||
|             if self.version < ver('6.1.0'): |             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: |             else: | ||||||
|                 return "-std=c++1z" |                 return "-std=c++1z" | ||||||
|         else: |         else: | ||||||
|             if self.version < ver('3.5'): |             if self.version < ver('3.5'): | ||||||
|                 tty.die("Only Clang 3.5 and above support c++17.") |                 raise UnsupportedCompilerFlag(self, | ||||||
|             else: |                                               "the C++17 standard", | ||||||
|  |                                               "cxx17_flag", | ||||||
|  |                                               "< 5.0") | ||||||
|  |             elif self.version < ver('5.0'): | ||||||
|                 return "-std=c++1z" |                 return "-std=c++1z" | ||||||
|  |             else: | ||||||
|  |                 return "-std=c++17" | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def pic_flag(self): |     def pic_flag(self): | ||||||
|   | |||||||
| @@ -22,10 +22,9 @@ | |||||||
| # License along with this program; if not, write to the Free Software | # License along with this program; if not, write to the Free Software | ||||||
| # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
| import llnl.util.tty as tty |  | ||||||
|  |  | ||||||
| import spack.compilers.clang | 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 | from spack.version import ver | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -60,10 +59,20 @@ class Gcc(Compiler): | |||||||
|     def openmp_flag(self): |     def openmp_flag(self): | ||||||
|         return "-fopenmp" |         return "-fopenmp" | ||||||
|  |  | ||||||
|  |     @property | ||||||
|  |     def cxx98_flag(self): | ||||||
|  |         if self.version < ver('6.0'): | ||||||
|  |             return "" | ||||||
|  |         else: | ||||||
|  |             return "-std=c++98" | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def cxx11_flag(self): |     def cxx11_flag(self): | ||||||
|         if self.version < ver('4.3'): |         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'): |         elif self.version < ver('4.7'): | ||||||
|             return "-std=c++0x" |             return "-std=c++0x" | ||||||
|         else: |         else: | ||||||
| @@ -72,18 +81,28 @@ def cxx11_flag(self): | |||||||
|     @property |     @property | ||||||
|     def cxx14_flag(self): |     def cxx14_flag(self): | ||||||
|         if self.version < ver('4.8'): |         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'): |         elif self.version < ver('4.9'): | ||||||
|             return "-std=c++1y" |             return "-std=c++1y" | ||||||
|         else: |         elif self.version < ver('6.0'): | ||||||
|             return "-std=c++14" |             return "-std=c++14" | ||||||
|  |         else: | ||||||
|  |             return "" | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def cxx17_flag(self): |     def cxx17_flag(self): | ||||||
|         if self.version < ver('5.0'): |         if self.version < ver('5.0'): | ||||||
|             tty.die("Only gcc 5.0 and above support c++17.") |             raise UnsupportedCompilerFlag(self, | ||||||
|         else: |                                           "the C++17 standard", | ||||||
|  |                                           "cxx17_flag", | ||||||
|  |                                           "< 5.0") | ||||||
|  |         elif self.version < ver('6.0'): | ||||||
|             return "-std=c++1z" |             return "-std=c++1z" | ||||||
|  |         else: | ||||||
|  |             return "-std=c++17" | ||||||
|  |  | ||||||
|     @property |     @property | ||||||
|     def pic_flag(self): |     def pic_flag(self): | ||||||
|   | |||||||
| @@ -22,9 +22,8 @@ | |||||||
| # License along with this program; if not, write to the Free Software | # License along with this program; if not, write to the Free Software | ||||||
| # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # 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, UnsupportedCompilerFlag | ||||||
| from spack.compiler import Compiler, get_compiler_version |  | ||||||
| from spack.version import ver | from spack.version import ver | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -60,7 +59,11 @@ def openmp_flag(self): | |||||||
|     @property |     @property | ||||||
|     def cxx11_flag(self): |     def cxx11_flag(self): | ||||||
|         if self.version < ver('11.1'): |         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'): |         elif self.version < ver('13'): | ||||||
|             return "-std=c++0x" |             return "-std=c++0x" | ||||||
|         else: |         else: | ||||||
| @@ -70,7 +73,10 @@ def cxx11_flag(self): | |||||||
|     def cxx14_flag(self): |     def cxx14_flag(self): | ||||||
|         # Adapted from CMake's Intel-CXX rules. |         # Adapted from CMake's Intel-CXX rules. | ||||||
|         if self.version < ver('15'): |         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'): |         elif self.version < ver('15.0.2'): | ||||||
|             return "-std=c++1y" |             return "-std=c++1y" | ||||||
|         else: |         else: | ||||||
|   | |||||||
| @@ -22,9 +22,8 @@ | |||||||
| # License along with this program; if not, write to the Free Software | # License along with this program; if not, write to the Free Software | ||||||
| # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # 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, UnsupportedCompilerFlag | ||||||
| from spack.compiler import Compiler, get_compiler_version |  | ||||||
| from spack.version import ver | from spack.version import ver | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -54,7 +53,10 @@ def openmp_flag(self): | |||||||
|     @property |     @property | ||||||
|     def cxx11_flag(self): |     def cxx11_flag(self): | ||||||
|         if self.version < ver('13.1'): |         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: |         else: | ||||||
|             return "-qlanglvl=extended0x" |             return "-qlanglvl=extended0x" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,9 +23,8 @@ | |||||||
| # License along with this program; if not, write to the Free Software | # License along with this program; if not, write to the Free Software | ||||||
| # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # 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, UnsupportedCompilerFlag | ||||||
| from spack.compiler import Compiler, get_compiler_version |  | ||||||
| from spack.version import ver | from spack.version import ver | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -55,7 +54,10 @@ def openmp_flag(self): | |||||||
|     @property |     @property | ||||||
|     def cxx11_flag(self): |     def cxx11_flag(self): | ||||||
|         if self.version < ver('13.1'): |         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: |         else: | ||||||
|             return "-qlanglvl=extended0x" |             return "-qlanglvl=extended0x" | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,11 +22,12 @@ | |||||||
| # License along with this program; if not, write to the Free Software | # License along with this program; if not, write to the Free Software | ||||||
| # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||||
| ############################################################################## | ############################################################################## | ||||||
|  | from copy import copy | ||||||
| from six import iteritems | from six import iteritems | ||||||
|  |  | ||||||
| import spack.spec | import spack.spec | ||||||
| import spack.compilers as compilers | 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): | 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) |     compiler = compilers.compiler_from_config_entry(compiler_entry) | ||||||
|     assert any(x == '-foo-flag foo-val' for x in compiler.flags['cflags']) |     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") | ||||||
|   | |||||||
| @@ -126,6 +126,11 @@ class Boost(Package): | |||||||
|         variant(lib, default=(lib not in default_noinstall_libs), |         variant(lib, default=(lib not in default_noinstall_libs), | ||||||
|                 description="Compile with {0} library".format(lib)) |                 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, |     variant('debug', default=False, | ||||||
|             description='Switch to the debug version of Boost') |             description='Switch to the debug version of Boost') | ||||||
|     variant('shared', default=True, |     variant('shared', default=True, | ||||||
| @@ -250,6 +255,26 @@ def determine_bootstrap_options(self, spec, withLibs, options): | |||||||
|             if '+python' in spec: |             if '+python' in spec: | ||||||
|                 f.write(self.bjam_python_line(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): |     def determine_b2_options(self, spec, options): | ||||||
|         if '+debug' in spec: |         if '+debug' in spec: | ||||||
|             options.append('variant=debug') |             options.append('variant=debug') | ||||||
| @@ -299,6 +324,17 @@ def determine_b2_options(self, spec, options): | |||||||
|                 'toolset=%s' % self.determine_toolset(spec) |                 '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 |         # clang is not officially supported for pre-compiled headers | ||||||
|         # and at least in clang 3.9 still fails to build |         # and at least in clang 3.9 still fails to build | ||||||
|         #   http://www.boost.org/build/doc/html/bbv2/reference/precompiled_headers.html |         #   http://www.boost.org/build/doc/html/bbv2/reference/precompiled_headers.html | ||||||
| @@ -306,10 +342,13 @@ def determine_b2_options(self, spec, options): | |||||||
|         if spec.satisfies('%clang'): |         if spec.satisfies('%clang'): | ||||||
|             options.extend(['pch=off']) |             options.extend(['pch=off']) | ||||||
|             if '+clanglibcpp' in spec: |             if '+clanglibcpp' in spec: | ||||||
|  |                 cxxflags.append('-stdlib=libc++') | ||||||
|                 options.extend(['toolset=clang', |                 options.extend(['toolset=clang', | ||||||
|                                 'cxxflags="-stdlib=libc++"', |  | ||||||
|                                 'linkflags="-stdlib=libc++"']) |                                 'linkflags="-stdlib=libc++"']) | ||||||
|  |  | ||||||
|  |         if cxxflags: | ||||||
|  |             options.append('cxxflags="{0}"'.format(' '.join(cxxflags))) | ||||||
|  |  | ||||||
|         return threadingOpts |         return threadingOpts | ||||||
|  |  | ||||||
|     def add_buildopt_symlinks(self, prefix): |     def add_buildopt_symlinks(self, prefix): | ||||||
|   | |||||||
| @@ -44,7 +44,9 @@ class Clingo(CMakePackage): | |||||||
|     depends_on('python') |     depends_on('python') | ||||||
|  |  | ||||||
|     def cmake_args(self): |     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') |             InstallError('clingo requires a C++14-compliant C++ compiler') | ||||||
|  |  | ||||||
|         args = ['-DCLINGO_BUILD_WITH_PYTHON=ON', |         args = ['-DCLINGO_BUILD_WITH_PYTHON=ON', | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Chris Green
					Chris Green