diff options
Diffstat (limited to 'mesonbuild/compilers')
-rw-r--r-- | mesonbuild/compilers/c.py | 3 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 186 | ||||
-rw-r--r-- | mesonbuild/compilers/cpp.py | 6 | ||||
-rw-r--r-- | mesonbuild/compilers/cs.py | 7 | ||||
-rw-r--r-- | mesonbuild/compilers/cuda.py | 6 | ||||
-rw-r--r-- | mesonbuild/compilers/d.py | 3 | ||||
-rw-r--r-- | mesonbuild/compilers/fortran.py | 6 | ||||
-rw-r--r-- | mesonbuild/compilers/java.py | 4 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/visualstudio.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/objc.py | 7 | ||||
-rw-r--r-- | mesonbuild/compilers/objcpp.py | 7 | ||||
-rw-r--r-- | mesonbuild/compilers/rust.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/swift.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/vala.py | 4 |
14 files changed, 123 insertions, 122 deletions
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py index 6a91b8e..aa48f7a 100644 --- a/mesonbuild/compilers/c.py +++ b/mesonbuild/compilers/c.py @@ -48,10 +48,11 @@ class CCompiler(CLikeCompiler, Compiler): except KeyError: raise MesonException('Unknown function attribute "{}"'.format(name)) + language = 'c' + def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool, info: 'MachineInfo', exe_wrapper: typing.Optional[str] = None, **kwargs): # If a child ObjC or CPP class has already set it, don't set it ourselves - self.language = 'c' Compiler.__init__(self, exelist, version, for_machine, info, **kwargs) CLikeCompiler.__init__(self, is_cross, exe_wrapper) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index eedd4cf..20b339b 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -681,6 +681,7 @@ class Compiler: internal_libs = () LINKER_PREFIX = None # type: typing.Union[None, str, typing.List[str]] + INVOKES_LINKER = True def __init__(self, exelist, version, for_machine: MachineChoice, info: 'MachineInfo', linker: typing.Optional['DynamicLinker'] = None, **kwargs): @@ -731,8 +732,9 @@ class Compiler: def get_language(self) -> str: return self.language - def get_display_language(self) -> str: - return self.language.capitalize() + @classmethod + def get_display_language(cls) -> str: + return cls.language.capitalize() def get_default_suffix(self) -> str: return self.default_suffix @@ -794,106 +796,11 @@ class Compiler: """ return [] - def use_preproc_flags(self) -> bool: - """ - Whether the compiler (or processes it spawns) cares about CPPFLAGS - """ - return self.get_language() in {'c', 'cpp', 'objc', 'objcpp'} - - def use_ldflags(self) -> bool: - """ - Whether the compiler (or processes it spawns) cares about LDFLAGS - """ - return self.get_language() in languages_using_ldflags - def get_linker_args_from_envvars(self) -> typing.List[str]: return self.linker.get_args_from_envvars() - def get_args_from_envvars(self) -> typing.Tuple[typing.List[str], typing.List[str]]: - """ - Returns a tuple of (compile_flags, link_flags) for the specified language - from the inherited environment - """ - def log_var(var, val: typing.Optional[str]): - if val: - mlog.log('Appending {} from environment: {!r}'.format(var, val)) - else: - mlog.debug('No {} in the environment, not changing global flags.'.format(var)) - - lang = self.get_language() - compiler_is_linker = self.linker is not None and self.linker.invoked_by_compiler() - - if lang not in cflags_mapping: - return [], [] - - compile_flags = [] # type: typing.List[str] - link_flags = [] # type: typing.List[str] - - env_compile_flags = os.environ.get(cflags_mapping[lang]) - log_var(cflags_mapping[lang], env_compile_flags) - if env_compile_flags is not None: - compile_flags += split_args(env_compile_flags) - - # Link flags (same for all languages) - if self.use_ldflags(): - env_link_flags = self.get_linker_args_from_envvars() - else: - env_link_flags = [] - log_var('LDFLAGS', env_link_flags) - link_flags += env_link_flags - if compiler_is_linker: - # When the compiler is used as a wrapper around the linker (such as - # with GCC and Clang), the compile flags can be needed while linking - # too. This is also what Autotools does. However, we don't want to do - # this when the linker is stand-alone such as with MSVC C/C++, etc. - link_flags = compile_flags + link_flags - - # Pre-processor flags for certain languages - if self.use_preproc_flags(): - env_preproc_flags = os.environ.get('CPPFLAGS') - log_var('CPPFLAGS', env_preproc_flags) - if env_preproc_flags is not None: - compile_flags += split_args(env_preproc_flags) - - return compile_flags, link_flags - - def get_options(self): - opts = {} # build afresh every time - description = 'Extra arguments passed to the {}'.format(self.get_display_language()) - opts.update({ - self.language + '_args': coredata.UserArrayOption( - description + ' compiler', - [], split_args=True, user_input=True, allow_dups=True), - self.language + '_link_args': coredata.UserArrayOption( - description + ' linker', - [], split_args=True, user_input=True, allow_dups=True), - }) - - return opts - - def get_and_default_options(self, properties: Properties): - """ - Take default values from env variables and/or config files. - """ - opts = self.get_options() - - if properties.fallback: - # Get from env vars. - compile_args, link_args = self.get_args_from_envvars() - else: - compile_args = [] - link_args = [] - - for k, o in opts.items(): - if k in properties: - # Get from configuration files. - o.set_value(properties[k]) - elif k == self.language + '_args': - o.set_value(compile_args) - elif k == self.language + '_link_args': - o.set_value(link_args) - - return opts + def get_options(self) -> typing.Dict[str, coredata.UserOption]: + return {} def get_option_compile_args(self, options): return [] @@ -1219,3 +1126,84 @@ def get_largefile_args(compiler): # transitionary features and must be enabled by programs that use # those features explicitly. return [] + + +def get_args_from_envvars(lang: str, use_linker_args: bool) -> typing.Tuple[typing.List[str], typing.List[str]]: + """ + Returns a tuple of (compile_flags, link_flags) for the specified language + from the inherited environment + """ + def log_var(var, val: typing.Optional[str]): + if val: + mlog.log('Appending {} from environment: {!r}'.format(var, val)) + else: + mlog.debug('No {} in the environment, not changing global flags.'.format(var)) + + if lang not in cflags_mapping: + return [], [] + + compile_flags = [] # type: typing.List[str] + link_flags = [] # type: typing.List[str] + + env_compile_flags = os.environ.get(cflags_mapping[lang]) + log_var(cflags_mapping[lang], env_compile_flags) + if env_compile_flags is not None: + compile_flags += split_args(env_compile_flags) + + # Link flags (same for all languages) + if lang in languages_using_ldflags: + # This is duplicated between the linkers, but I'm not sure how else + # to handle this + env_link_flags = split_args(os.environ.get('LDFLAGS', '')) + else: + env_link_flags = [] + log_var('LDFLAGS', env_link_flags) + link_flags += env_link_flags + if use_linker_args: + # When the compiler is used as a wrapper around the linker (such as + # with GCC and Clang), the compile flags can be needed while linking + # too. This is also what Autotools does. However, we don't want to do + # this when the linker is stand-alone such as with MSVC C/C++, etc. + link_flags = compile_flags + link_flags + + # Pre-processor flags for certain languages + if lang in {'c', 'cpp', 'objc', 'objcpp'}: + env_preproc_flags = os.environ.get('CPPFLAGS') + log_var('CPPFLAGS', env_preproc_flags) + if env_preproc_flags is not None: + compile_flags += split_args(env_preproc_flags) + + return compile_flags, link_flags + + +def get_global_options(lang: str, comp: typing.Type[Compiler], + properties: Properties) -> typing.Dict[str, coredata.UserOption]: + """Retreive options that apply to all compilers for a given language.""" + description = 'Extra arguments passed to the {}'.format(lang) + opts = { + lang + '_args': coredata.UserArrayOption( + description + ' compiler', + [], split_args=True, user_input=True, allow_dups=True), + lang + '_link_args': coredata.UserArrayOption( + description + ' linker', + [], split_args=True, user_input=True, allow_dups=True), + } + + if properties.fallback: + # Get from env vars. + # XXX: True here is a hack + compile_args, link_args = get_args_from_envvars(lang, comp.INVOKES_LINKER) + else: + compile_args = [] + link_args = [] + + for k, o in opts.items(): + if k in properties: + # Get from configuration files. + o.set_value(properties[k]) + elif k == lang + '_args': + o.set_value(compile_args) + elif k == lang + '_link_args': + o.set_value(link_args) + + return opts diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py index 9e9e78e..f8ded00 100644 --- a/mesonbuild/compilers/cpp.py +++ b/mesonbuild/compilers/cpp.py @@ -59,14 +59,16 @@ class CPPCompiler(CLikeCompiler, Compiler): except KeyError: raise MesonException('Unknown function attribute "{}"'.format(name)) + language = 'cpp' + def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool, info: 'MachineInfo', exe_wrap: typing.Optional[str] = None, **kwargs): # If a child ObjCPP class has already set it, don't set it ourselves - self.language = 'cpp' Compiler.__init__(self, exelist, version, for_machine, info, **kwargs) CLikeCompiler.__init__(self, is_cross, exe_wrap) - def get_display_language(self): + @staticmethod + def get_display_language(): return 'C++' def get_no_stdinc_args(self): diff --git a/mesonbuild/compilers/cs.py b/mesonbuild/compilers/cs.py index 137acc1..d064e7c 100644 --- a/mesonbuild/compilers/cs.py +++ b/mesonbuild/compilers/cs.py @@ -33,15 +33,18 @@ cs_optimization_args = {'0': [], class CsCompiler(BasicLinkerIsCompilerMixin, Compiler): + + language = 'cs' + def __init__(self, exelist, version, for_machine: MachineChoice, info: 'MachineInfo', comp_id, runner=None): - self.language = 'cs' super().__init__(exelist, version, for_machine, info) self.id = comp_id self.is_cross = False self.runner = runner - def get_display_language(self): + @classmethod + def get_display_language(cls): return 'C sharp' def get_always_args(self): diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py index 91dde0c..385e4cf 100644 --- a/mesonbuild/compilers/cuda.py +++ b/mesonbuild/compilers/cuda.py @@ -30,13 +30,12 @@ if typing.TYPE_CHECKING: class CudaCompiler(Compiler): LINKER_PREFIX = '-Xlinker=' + language = 'cuda' _universal_flags = {'compiler': ['-I', '-D', '-U', '-E'], 'linker': ['-l', '-L']} def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper, host_compiler, info: 'MachineInfo', **kwargs): - if not hasattr(self, 'language'): - self.language = 'cuda' super().__init__(exelist, version, for_machine, info, **kwargs) self.is_cross = is_cross self.exe_wrapper = exe_wrapper @@ -62,9 +61,6 @@ class CudaCompiler(Compiler): def get_always_args(self): return [] - def get_display_language(self): - return 'Cuda' - def get_no_stdinc_args(self): return [] diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py index e84a18f..15770a5 100644 --- a/mesonbuild/compilers/d.py +++ b/mesonbuild/compilers/d.py @@ -412,9 +412,10 @@ class DCompiler(Compiler): 'mtd': ['-mscrtlib=libcmtd'], } + language = 'd' + def __init__(self, exelist, version, for_machine: MachineChoice, info: 'MachineInfo', arch, is_cross, exe_wrapper, **kwargs): - self.language = 'd' super().__init__(exelist, version, for_machine, info, **kwargs) self.id = 'unknown' self.arch = arch diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py index f66ff38..4aff72e 100644 --- a/mesonbuild/compilers/fortran.py +++ b/mesonbuild/compilers/fortran.py @@ -41,16 +41,14 @@ if TYPE_CHECKING: class FortranCompiler(CLikeCompiler, Compiler): + language = 'fortran' + def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): - self.language = 'fortran' Compiler.__init__(self, exelist, version, for_machine, info, **kwargs) CLikeCompiler.__init__(self, is_cross, exe_wrapper) self.id = 'unknown' - def get_display_language(self): - return 'Fortran' - def has_function(self, funcname, prefix, env, *, extra_args=None, dependencies=None): raise MesonException('Fortran does not have "has_function" capability.\n' 'It is better to test if a Fortran capability is working like:\n\n' diff --git a/mesonbuild/compilers/java.py b/mesonbuild/compilers/java.py index cc195ff..bb62fb2 100644 --- a/mesonbuild/compilers/java.py +++ b/mesonbuild/compilers/java.py @@ -25,9 +25,11 @@ if typing.TYPE_CHECKING: from ..envconfig import MachineInfo class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler): + + language = 'java' + def __init__(self, exelist, version, for_machine: MachineChoice, info: 'MachineInfo'): - self.language = 'java' super().__init__(exelist, version, for_machine, info) self.id = 'unknown' self.is_cross = False diff --git a/mesonbuild/compilers/mixins/visualstudio.py b/mesonbuild/compilers/mixins/visualstudio.py index 4798bdc..8e18144 100644 --- a/mesonbuild/compilers/mixins/visualstudio.py +++ b/mesonbuild/compilers/mixins/visualstudio.py @@ -111,6 +111,8 @@ class VisualStudioLikeCompiler(metaclass=abc.ABCMeta): '3': ['/W4'], } # type: typing.Dict[str, typing.List[str]] + INVOKES_LINKER = False + def __init__(self, target: str): self.base_options = ['b_pch', 'b_ndebug', 'b_vscrt'] # FIXME add lto, pgo and the like self.target = target diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py index f69c57c..a4aa5dc 100644 --- a/mesonbuild/compilers/objc.py +++ b/mesonbuild/compilers/objc.py @@ -27,14 +27,17 @@ if typing.TYPE_CHECKING: class ObjCCompiler(CLikeCompiler, Compiler): + + language = 'objc' + def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool, info: 'MachineInfo', exe_wrap: typing.Optional[str], **kwargs): - self.language = 'objc' Compiler.__init__(self, exelist, version, for_machine, info, **kwargs) CLikeCompiler.__init__(self, is_cross, exe_wrap) - def get_display_language(self): + @staticmethod + def get_display_language(): return 'Objective-C' def sanity_check(self, work_dir, environment): diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py index 76cda7b..b42cef6 100644 --- a/mesonbuild/compilers/objcpp.py +++ b/mesonbuild/compilers/objcpp.py @@ -26,14 +26,17 @@ if typing.TYPE_CHECKING: from ..envconfig import MachineInfo class ObjCPPCompiler(CLikeCompiler, Compiler): + + language = 'objcpp' + def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool, info: 'MachineInfo', exe_wrap: typing.Optional[str], **kwargs): - self.language = 'objcpp' Compiler.__init__(self, exelist, version, for_machine, info, **kwargs) CLikeCompiler.__init__(self, is_cross, exe_wrap) - def get_display_language(self): + @staticmethod + def get_display_language(): return 'Objective-C++' def sanity_check(self, work_dir, environment): diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py index 405afea..613414d 100644 --- a/mesonbuild/compilers/rust.py +++ b/mesonbuild/compilers/rust.py @@ -33,10 +33,10 @@ rust_optimization_args = {'0': [], class RustCompiler(Compiler): # rustc doesn't invoke the compiler itself, it doesn't need a LINKER_PREFIX + language = 'rust' def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs): - self.language = 'rust' super().__init__(exelist, version, for_machine, info, **kwargs) self.exe_wrapper = exe_wrapper self.id = 'rustc' diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py index c5d3885..0909d20 100644 --- a/mesonbuild/compilers/swift.py +++ b/mesonbuild/compilers/swift.py @@ -33,10 +33,10 @@ swift_optimization_args = {'0': [], class SwiftCompiler(Compiler): LINKER_PREFIX = ['-Xlinker'] + language = 'swift' def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, info: 'MachineInfo', **kwargs): - self.language = 'swift' super().__init__(exelist, version, for_machine, info, **kwargs) self.version = version self.id = 'llvm' diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py index 528a56d..3f4e5fa 100644 --- a/mesonbuild/compilers/vala.py +++ b/mesonbuild/compilers/vala.py @@ -24,9 +24,11 @@ if typing.TYPE_CHECKING: from ..envconfig import MachineInfo class ValaCompiler(Compiler): + + language = 'vala' + def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, info: 'MachineInfo'): - self.language = 'vala' super().__init__(exelist, version, for_machine, info) self.version = version self.is_cross = is_cross |