@ -14,12 +14,12 @@
import functools
import os . path
import typing
from . . import coredata
from . . import mlog
from . . mesonlib import MesonException , version_compare
from . c import CCompiler , VisualStudioCCompiler , ClangClCCompiler , IntelClCCompiler
from . compilers import (
gnu_winlibs ,
msvc_winlibs ,
@ -31,20 +31,27 @@ from .compilers import (
ArmCompiler ,
ArmclangCompiler ,
CcrxCompiler ,
Compiler ,
VisualStudioLikeCompiler ,
)
from . c_function_attributes import CXX_FUNC_ATTRIBUTES
from . c_function_attributes import CXX_FUNC_ATTRIBUTES , C_FUNC_ATTRIBUTES
from . clike import CLikeCompiler
class CPPCompiler ( CCompiler ) :
class CPPCompiler ( CLikeCompiler , Compiler ) :
@classmethod
def attribute_check_func ( cls , name ) :
return CXX_FUNC_ATTRIBUTES . get ( name , super ( ) . attribute_check_func ( name ) )
try :
return CXX_FUNC_ATTRIBUTES . get ( name , C_FUNC_ATTRIBUTES [ name ] )
except KeyError :
raise MesonException ( ' Unknown function attribute " {} " ' . format ( name ) )
def __init__ ( self , exelist , version , is_cross , exe_wrap , * * kwargs ) :
def __init__ ( self , exelist , version , is_cross : bool ,
exe_wrap : typing . Optional [ str ] = None , * * kwargs ) :
# If a child ObjCPP class has already set it, don't set it ourselves
if not hasattr ( self , ' language ' ) :
self . language = ' cpp '
CCompiler . __init__ ( self , exelist , version , is_cross , exe_wrap , * * kwargs )
self . language = ' cpp '
Compiler . __init__ ( self , exelist , version , * * kwargs )
CLike Compiler . __init__ ( self , is_cross , exe_wrap )
def get_display_language ( self ) :
return ' C++ '
@ -142,7 +149,11 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler):
def get_options ( self ) :
opts = CPPCompiler . get_options ( self )
opts . update ( { ' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' , ' C++ language standard to use ' ,
opts . update ( { ' cpp_eh ' : coredata . UserComboOption ( ' cpp_eh ' ,
' C++ exception handling type. ' ,
[ ' none ' , ' default ' ] ,
' default ' ) ,
' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' , ' C++ language standard to use ' ,
[ ' none ' , ' c++98 ' , ' c++03 ' , ' c++11 ' , ' c++14 ' , ' c++17 ' , ' c++1z ' , ' c++2a ' ,
' gnu++11 ' , ' gnu++14 ' , ' gnu++17 ' , ' gnu++1z ' , ' gnu++2a ' ] ,
' none ' ) } )
@ -153,6 +164,8 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler):
std = options [ ' cpp_std ' ]
if std . value != ' none ' :
args . append ( self . _find_best_cpp_std ( std . value ) )
if options [ ' cpp_eh ' ] . value == ' none ' :
args . append ( ' -fno-exceptions ' )
return args
def get_option_link_args ( self , options ) :
@ -174,7 +187,11 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
def get_options ( self ) :
opts = CPPCompiler . get_options ( self )
opts . update ( { ' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' , ' C++ language standard to use ' ,
opts . update ( { ' cpp_eh ' : coredata . UserComboOption ( ' cpp_eh ' ,
' C++ exception handling type. ' ,
[ ' none ' , ' default ' ] ,
' default ' ) ,
' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' , ' C++ language standard to use ' ,
[ ' none ' , ' c++98 ' , ' c++03 ' , ' c++11 ' , ' c++14 ' , ' c++17 ' ,
' gnu++98 ' , ' gnu++03 ' , ' gnu++11 ' , ' gnu++14 ' , ' gnu++17 ' ] ,
' none ' ) } )
@ -185,6 +202,8 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
std = options [ ' cpp_std ' ]
if std . value != ' none ' :
args . append ( ' -std= ' + std . value )
if options [ ' cpp_eh ' ] . value == ' none ' :
args . append ( ' -fno-exceptions ' )
return args
def get_option_link_args ( self , options ) :
@ -203,7 +222,11 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
def get_options ( self ) :
opts = CPPCompiler . get_options ( self )
opts . update ( { ' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' , ' C++ language standard to use ' ,
opts . update ( { ' cpp_eh ' : coredata . UserComboOption ( ' cpp_eh ' ,
' C++ exception handling type. ' ,
[ ' none ' , ' default ' ] ,
' default ' ) ,
' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' , ' C++ language standard to use ' ,
[ ' none ' , ' c++98 ' , ' c++03 ' , ' c++11 ' , ' c++14 ' , ' c++17 ' , ' c++1z ' , ' c++2a ' ,
' gnu++03 ' , ' gnu++11 ' , ' gnu++14 ' , ' gnu++17 ' , ' gnu++1z ' , ' gnu++2a ' ] ,
' none ' ) ,
@ -221,6 +244,8 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
std = options [ ' cpp_std ' ]
if std . value != ' none ' :
args . append ( self . _find_best_cpp_std ( std . value ) )
if options [ ' cpp_eh ' ] . value == ' none ' :
args . append ( ' -fno-exceptions ' )
if options [ ' cpp_debugstl ' ] . value :
args . append ( ' -D_GLIBCXX_DEBUG=1 ' )
return args
@ -251,7 +276,11 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler):
# It does not support c++/gnu++ 17 and 1z, but still does support 0x, 1y, and gnu++98.
def get_options ( self ) :
opts = CPPCompiler . get_options ( self )
opts . update ( { ' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' , ' C++ language standard to use ' ,
opts . update ( { ' cpp_eh ' : coredata . UserComboOption ( ' cpp_eh ' ,
' C++ exception handling type. ' ,
[ ' none ' , ' default ' ] ,
' default ' ) ,
' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' , ' C++ language standard to use ' ,
[ ' none ' , ' c++98 ' , ' c++03 ' , ' c++0x ' , ' c++11 ' , ' c++14 ' , ' c++1y ' ,
' gnu++98 ' , ' gnu++03 ' , ' gnu++0x ' , ' gnu++11 ' , ' gnu++14 ' , ' gnu++1y ' ] ,
' none ' ) ,
@ -297,7 +326,11 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler):
c_stds + = [ ' c++17 ' ]
if version_compare ( self . version , ' >=17.0.0 ' ) :
g_stds + = [ ' gnu++14 ' ]
opts . update ( { ' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' , ' C++ language standard to use ' ,
opts . update ( { ' cpp_eh ' : coredata . UserComboOption ( ' cpp_eh ' ,
' C++ exception handling type. ' ,
[ ' none ' , ' default ' ] ,
' default ' ) ,
' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' , ' C++ language standard to use ' ,
[ ' none ' ] + c_stds + g_stds ,
' none ' ) ,
' cpp_debugstl ' : coredata . UserBooleanOption ( ' cpp_debugstl ' ,
@ -314,6 +347,8 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler):
' gnu++03 ' : ' gnu++98 '
}
args . append ( ' -std= ' + remap_cpp03 . get ( std . value , std . value ) )
if options [ ' cpp_eh ' ] . value == ' none ' :
args . append ( ' -fno-exceptions ' )
if options [ ' cpp_debugstl ' ] . value :
args . append ( ' -D_GLIBCXX_DEBUG=1 ' )
return args
@ -322,29 +357,18 @@ class IntelCPPCompiler(IntelCompiler, CPPCompiler):
return [ ]
class VisualStudioCPPCompiler ( VisualStudioCCompiler , CPPCompiler ) :
def __init__ ( self , exelist , version , is_cross , exe_wrap , target ) :
CPPCompiler . __init__ ( self , exelist , version , is_cross , exe_wrap )
VisualStudioCCompiler . __init__ ( self , exelist , version , is_cross , exe_wrap , target )
self . base_options = [ ' b_pch ' , ' b_vscrt ' ] # FIXME add lto, pgo and the like
class VisualStudioLikeCPPCompilerMixin :
def get_options ( self ) :
cpp_stds = [ ' none ' , ' c++11 ' , ' vc++11 ' ]
if self . id == ' clang-cl ' :
cpp_stds . extend ( [ ' c++14 ' , ' vc++14 ' , ' c++17 ' , ' vc++17 ' , ' c++latest ' ] )
else :
# Visual Studio 2015 and later
if version_compare ( self . version , ' >=19 ' ) :
cpp_stds . extend ( [ ' c++14 ' , ' vc++14 ' , ' c++latest ' , ' vc++latest ' ] )
# Visual Studio 2017 and later
if version_compare ( self . version , ' >=19.11 ' ) :
cpp_stds . extend ( [ ' c++17 ' , ' vc++17 ' ] )
""" Mixin for C++ specific method overrides in MSVC-like compilers. """
opts = CPPCompiler . get_options ( self )
def get_option_link_args ( self , options ) :
return options [ ' cpp_winlibs ' ] . value [ : ]
def _get_options_impl ( self , opts , cpp_stds : typing . List [ str ] ) :
opts . update ( { ' cpp_eh ' : coredata . UserComboOption ( ' cpp_eh ' ,
' C++ exception handling type. ' ,
[ ' none ' , ' a ' , ' s ' , ' sc ' ] ,
' sc ' ) ,
[ ' none ' , ' a ' , ' s ' , ' sc ' , ' default ' ] ,
' default ' ) ,
' cpp_std ' : coredata . UserComboOption ( ' cpp_std ' ,
' C++ language standard to use ' ,
cpp_stds ,
@ -358,7 +382,9 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
args = [ ]
eh = options [ ' cpp_eh ' ]
if eh . value != ' none ' :
if eh . value == ' default ' :
args . append ( ' /EHsc ' )
elif eh . value != ' none ' :
args . append ( ' /EH ' + eh . value )
vc_version_map = {
@ -393,24 +419,38 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
return args
def get_option_link_args ( self , options ) :
return options [ ' cpp_winlibs ' ] . value [ : ]
def get_compiler_check_args ( self ) :
# Visual Studio C++ compiler doesn't support -fpermissive,
# so just use the plain C args.
return VisualStudioCCompiler . get_compiler_check_args ( self )
# XXX: this is a hack because so much GnuLike stuff is in the base CPPCompiler class.
return CLikeCompiler . get_compiler_check_args ( self )
class ClangClCPPCompiler ( VisualStudioCPPCompiler , ClangClCCompiler ) :
class VisualStudioCPPCompiler ( VisualStudioLikeCPPCompilerMixin , VisualStudioLikeCompiler , CPPCompiler ) :
def __init__ ( self , exelist , version , is_cross , exe_wrap , target ) :
VisualStudioCPPCompiler . __init__ ( self , exelist , version , is_cross , exe_wrap , target )
self . id = ' clang-cl '
CPPCompiler . __init__ ( self , exelist , version , is_cross , exe_wrap )
VisualStudioLikeCompiler . __init__ ( self , target )
self . base_options = [ ' b_pch ' , ' b_vscrt ' ] # FIXME add lto, pgo and the like
self . id = ' msvc '
def get_options ( self ) :
cpp_stds = [ ' none ' , ' c++11 ' , ' vc++11 ' ]
# Visual Studio 2015 and later
if version_compare ( self . version , ' >=19 ' ) :
cpp_stds . extend ( [ ' c++14 ' , ' vc++14 ' , ' c++latest ' , ' vc++latest ' ] )
# Visual Studio 2017 and later
if version_compare ( self . version , ' >=19.11 ' ) :
cpp_stds . extend ( [ ' c++17 ' , ' vc++17 ' ] )
return self . _get_options_impl ( super ( ) . get_options ( ) , cpp_stds )
class IntelClCPPCompiler ( VisualStudioCPPCompiler , IntelClCCompiler ) :
class ClangClCPPCompiler ( VisualStudioLikeCPPCompilerMixin , VisualStudioLikeCompiler , CPP Compiler) :
def __init__ ( self , exelist , version , is_cross , exe_wrap , target ) :
VisualStudioCPPCompiler . __init__ ( self , exelist , version , is_cross , exe_wrap , target )
self . id = ' intel '
CPPCompiler . __init__ ( self , exelist , version , is_cross , exe_wrap )
VisualStudioLikeCompiler . __init__ ( self , target )
self . id = ' clang-cl '
def get_options ( self ) :
cpp_stds = [ ' none ' , ' c++11 ' , ' vc++11 ' , ' c++14 ' , ' vc++14 ' , ' c++17 ' , ' vc++17 ' , ' c++latest ' ]
return self . _get_options_impl ( super ( ) . get_options ( ) , cpp_stds )
class ArmCPPCompiler ( ArmCompiler , CPPCompiler ) :