aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/compilers')
-rw-r--r--mesonbuild/compilers/c.py3
-rw-r--r--mesonbuild/compilers/compilers.py186
-rw-r--r--mesonbuild/compilers/cpp.py6
-rw-r--r--mesonbuild/compilers/cs.py7
-rw-r--r--mesonbuild/compilers/cuda.py6
-rw-r--r--mesonbuild/compilers/d.py3
-rw-r--r--mesonbuild/compilers/fortran.py6
-rw-r--r--mesonbuild/compilers/java.py4
-rw-r--r--mesonbuild/compilers/mixins/visualstudio.py2
-rw-r--r--mesonbuild/compilers/objc.py7
-rw-r--r--mesonbuild/compilers/objcpp.py7
-rw-r--r--mesonbuild/compilers/rust.py2
-rw-r--r--mesonbuild/compilers/swift.py2
-rw-r--r--mesonbuild/compilers/vala.py4
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