aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/compilers.py
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild/compilers.py')
-rw-r--r--mesonbuild/compilers.py185
1 files changed, 57 insertions, 128 deletions
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index 8772803..d36f6a8 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -23,12 +23,27 @@ from . import coredata
about. To support a new compiler, add its information below.
Also add corresponding autodetection code in environment.py."""
-header_suffixes = ['h', 'hh', 'hpp', 'hxx', 'H', 'ipp', 'moc', 'vapi', 'di']
-cpp_suffixes = ['cc', 'cpp', 'cxx', 'h', 'hh', 'hpp', 'ipp', 'hxx', 'c++']
-c_suffixes = ['c']
-clike_suffixes = c_suffixes + cpp_suffixes
-obj_suffixes = ['o', 'obj', 'res']
-lib_suffixes = ['a', 'lib', 'dll', 'dylib', 'so']
+header_suffixes = ('h', 'hh', 'hpp', 'hxx', 'H', 'ipp', 'moc', 'vapi', 'di')
+obj_suffixes = ('o', 'obj', 'res')
+lib_suffixes = ('a', 'lib', 'dll', 'dylib', 'so')
+# Mapping of language to suffixes of files that should always be in that language
+# This means we can't include .h headers here since they could be C, C++, ObjC, etc.
+lang_suffixes = {
+ 'c': ('c',),
+ 'cpp': ('cpp', 'cc', 'cxx', 'c++', 'hh', 'hpp', 'ipp', 'hxx'),
+ 'fortran': ('f', 'f90', 'f95'),
+ 'd': ('d', 'di'),
+ 'objc': ('m',),
+ 'objcpp': ('mm',),
+ 'rust': ('rs',),
+ 'vala': ('vala', 'vapi'),
+ 'cs': ('cs',),
+ 'swift': ('swift',),
+ 'java': ('java',),
+}
+cpp_suffixes = lang_suffixes['cpp'] + ('h',)
+c_suffixes = lang_suffixes['c'] + ('h',)
+clike_suffixes = lang_suffixes['c'] + lang_suffixes['cpp'] + ('h',)
def is_header(fname):
if hasattr(fname, 'fname'):
@@ -300,9 +315,23 @@ class Compiler():
self.exelist = exelist
else:
raise TypeError('Unknown argument to Compiler')
+ # In case it's been overriden by a child class already
+ if not hasattr(self, 'file_suffixes'):
+ self.file_suffixes = lang_suffixes[self.language]
+ if not hasattr(self, 'can_compile_suffixes'):
+ self.can_compile_suffixes = set(self.file_suffixes)
+ self.default_suffix = self.file_suffixes[0]
self.version = version
self.base_options = []
+ def can_compile(self, src):
+ if hasattr(src, 'fname'):
+ src = src.fname
+ suffix = os.path.splitext(src)[1].lower()
+ if suffix and suffix[1:] in self.can_compile_suffixes:
+ return True
+ return False
+
def get_always_args(self):
return []
@@ -391,11 +420,13 @@ class Compiler():
class CCompiler(Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
+ # If a child ObjC or CPP class has already set it, don't set it ourselves
+ if not hasattr(self, 'language'):
+ self.language = 'c'
super().__init__(exelist, version)
- self.language = 'c'
- self.default_suffix = 'c'
self.id = 'unknown'
self.is_cross = is_cross
+ self.can_compile_suffixes.add('h')
if isinstance(exe_wrapper, str):
self.exe_wrapper = [exe_wrapper]
else:
@@ -502,12 +533,6 @@ class CCompiler(Compiler):
return libstr.split(':')
return []
- def can_compile(self, filename):
- suffix = filename.split('.')[-1]
- if suffix == 'c' or suffix == 'h':
- return True
- return False
-
def get_pic_args(self):
return ['-fPIC']
@@ -976,15 +1001,10 @@ void bar() {
class CPPCompiler(CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
+ # 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)
- self.language = 'cpp'
- self.default_suffix = 'cpp'
-
- def can_compile(self, filename):
- suffix = filename.split('.')[-1]
- if suffix in cpp_suffixes:
- return True
- return False
def sanity_check(self, work_dir, environment):
code = 'class breakCCompiler;int main(int argc, char **argv) { return 0; }\n'
@@ -992,15 +1012,8 @@ class CPPCompiler(CCompiler):
class ObjCCompiler(CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
- CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.language = 'objc'
- self.default_suffix = 'm'
-
- def can_compile(self, filename):
- suffix = filename.split('.')[-1]
- if suffix == 'm' or suffix == 'h':
- return True
- return False
+ CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def sanity_check(self, work_dir, environment):
# TODO try to use sanity_check_impl instead of duplicated code
@@ -1026,15 +1039,8 @@ class ObjCCompiler(CCompiler):
class ObjCPPCompiler(CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
- CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.language = 'objcpp'
- self.default_suffix = 'mm'
-
- def can_compile(self, filename):
- suffix = filename.split('.')[-1]
- if suffix == 'mm' or suffix == 'h':
- return True
- return False
+ CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def sanity_check(self, work_dir, environment):
# TODO try to use sanity_check_impl instead of duplicated code
@@ -1061,9 +1067,8 @@ class ObjCPPCompiler(CPPCompiler):
class MonoCompiler(Compiler):
def __init__(self, exelist, version):
- super().__init__(exelist, version)
self.language = 'cs'
- self.default_suffix = 'cs'
+ super().__init__(exelist, version)
self.id = 'mono'
self.monorunner = 'mono'
@@ -1124,12 +1129,6 @@ class MonoCompiler(Compiler):
def get_std_shared_lib_link_args(self):
return []
- def can_compile(self, filename):
- suffix = filename.split('.')[-1]
- if suffix == 'cs':
- return True
- return False
-
def get_pic_args(self):
return []
@@ -1170,9 +1169,8 @@ class MonoCompiler(Compiler):
class JavaCompiler(Compiler):
def __init__(self, exelist, version):
- super().__init__(exelist, version)
self.language = 'java'
- self.default_suffix = 'java'
+ super().__init__(exelist, version)
self.id = 'unknown'
self.javarunner = 'java'
@@ -1232,12 +1230,6 @@ class JavaCompiler(Compiler):
def get_std_shared_lib_link_args(self):
return []
- def can_compile(self, filename):
- suffix = filename.split('.')[-1]
- if suffix == 'java':
- return True
- return False
-
def get_pic_args(self):
return []
@@ -1279,10 +1271,10 @@ class JavaCompiler(Compiler):
class ValaCompiler(Compiler):
def __init__(self, exelist, version):
+ self.language = 'vala'
super().__init__(exelist, version)
self.version = version
self.id = 'unknown'
- self.language = 'vala'
self.is_cross = False
def name_string(self):
@@ -1313,10 +1305,6 @@ class ValaCompiler(Compiler):
if pc.returncode != 0:
raise EnvironmentException('Vala compiler %s can not compile programs.' % self.name_string())
- def can_compile(self, filename):
- suffix = filename.split('.')[-1]
- return suffix in ('vala', 'vapi')
-
def get_buildtype_args(self, buildtype):
if buildtype == 'debug' or buildtype == 'debugoptimized' or buildtype == 'minsize':
return ['--debug']
@@ -1324,9 +1312,9 @@ class ValaCompiler(Compiler):
class RustCompiler(Compiler):
def __init__(self, exelist, version):
+ self.language = 'rust'
super().__init__(exelist, version)
self.id = 'unknown'
- self.language = 'rust'
def needs_static_linker(self):
return False
@@ -1357,9 +1345,6 @@ class RustCompiler(Compiler):
if subprocess.call(output_name) != 0:
raise EnvironmentException('Executables created by Rust compiler %s are not runnable.' % self.name_string())
- def can_compile(self, fname):
- return fname.endswith('.rs')
-
def get_dependency_gen_args(self, outfile):
return ['--dep-info', outfile]
@@ -1368,10 +1353,10 @@ class RustCompiler(Compiler):
class SwiftCompiler(Compiler):
def __init__(self, exelist, version):
+ self.language = 'swift'
super().__init__(exelist, version)
self.version = version
self.id = 'llvm'
- self.language = 'swift'
self.is_cross = False
def get_id(self):
@@ -1455,15 +1440,11 @@ class SwiftCompiler(Compiler):
if subprocess.call(output_name) != 0:
raise EnvironmentException('Executables created by Swift compiler %s are not runnable.' % self.name_string())
- def can_compile(self, filename):
- suffix = filename.split('.')[-1]
- return suffix in ('swift')
-
class DCompiler(Compiler):
def __init__(self, exelist, version, is_cross):
+ self.language = 'd'
super().__init__(exelist, version)
self.id = 'unknown'
- self.language = 'd'
self.is_cross = is_cross
def sanity_check(self, work_dir, environment):
@@ -1495,10 +1476,6 @@ class DCompiler(Compiler):
def get_language(self):
return self.language
- def can_compile(self, fname):
- suffix = fname.split('.')[-1]
- return suffix in ('d', 'di')
-
def get_linker_exelist(self):
return self.exelist[:]
@@ -1901,17 +1878,11 @@ class VisualStudioCCompiler(CCompiler):
class VisualStudioCPPCompiler(VisualStudioCCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
- VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.language = 'cpp'
+ VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.default_suffix = 'cpp'
self.base_options = ['b_pch'] # FIXME add lto, pgo and the like
- def can_compile(self, filename):
- suffix = filename.split('.')[-1]
- if suffix in cpp_suffixes:
- return True
- return False
-
def get_options(self):
return {'cpp_eh' : coredata.UserComboOption('cpp_eh',
'C++ exception handling type.',
@@ -2006,13 +1977,12 @@ class GnuCCompiler(GnuCompiler, CCompiler):
def __init__(self, exelist, version, gcc_type, is_cross, exe_wrapper=None):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
GnuCompiler.__init__(self, gcc_type)
+ # Gcc can do asm, too.
+ self.can_compile_suffixes.add('s')
self.warn_args = {'1': ['-Wall', '-Winvalid-pch'],
'2': ['-Wall', '-Wextra', '-Winvalid-pch'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch']}
- def can_compile(self, filename):
- return super().can_compile(filename) or filename.split('.')[-1].lower() == 's' # Gcc can do asm, too.
-
def get_options(self):
opts = {'c_std' : coredata.UserComboOption('c_std', 'C language standard to use',
['none', 'c89', 'c99', 'c11', 'gnu89', 'gnu99', 'gnu11'],
@@ -2125,6 +2095,8 @@ class ClangCCompiler(ClangCompiler, CCompiler):
def __init__(self, exelist, version, clang_type, is_cross, exe_wrapper=None):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
ClangCompiler.__init__(self, clang_type)
+ # Clang can do asm, too.
+ self.can_compile_suffixes.add('s')
self.warn_args = {'1': ['-Wall', '-Winvalid-pch'],
'2': ['-Wall', '-Wextra', '-Winvalid-pch'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch']}
@@ -2147,9 +2119,6 @@ class ClangCCompiler(ClangCompiler, CCompiler):
def has_argument(self, arg, env):
return super().has_argument(['-Werror=unknown-warning-option', arg], env)
- def can_compile(self, filename):
- return super().can_compile(filename) or filename.split('.')[-1].lower() == 's' # Clang can do asm, too.
-
class ClangCPPCompiler(ClangCompiler, CPPCompiler):
def __init__(self, exelist, version, cltype, is_cross, exe_wrapper=None):
@@ -2177,9 +2146,6 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler):
def has_argument(self, arg, env):
return super().has_argument(['-Werror=unknown-warning-option', arg], env)
- def can_compile(self, filename):
- return super().can_compile(filename) or filename.split('.')[-1].lower() == 's' # Clang can do asm, too.
-
class ClangObjCCompiler(GnuObjCCompiler):
def __init__(self, exelist, version, cltype, is_cross, exe_wrapper=None):
super().__init__(exelist, version, is_cross, exe_wrapper)
@@ -2202,10 +2168,10 @@ class ClangObjCPPCompiler(GnuObjCPPCompiler):
class FortranCompiler(Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
+ self.language = 'fortran'
super().__init__(exelist, version)
self.is_cross = is_cross
self.exe_wrapper = exe_wrapper
- self.language = 'fortran'
# Not really correct but I don't have Fortran compilers to test with. Sorry.
self.gcc_type = GCC_STANDARD
self.id = "IMPLEMENTATION CLASSES MUST SET THIS"
@@ -2291,14 +2257,6 @@ end program prog
def get_linker_output_args(self, outputname):
return ['-o', outputname]
- def can_compile(self, src):
- if hasattr(src, 'fname'):
- src = src.fname
- suffix = os.path.splitext(src)[1].lower()
- if suffix == '.f' or suffix == '.f95' or suffix == '.f90':
- return True
- return False
-
def get_include_args(self, path, is_system):
return ['-I' + path]
@@ -2381,18 +2339,13 @@ class IntelFortranCompiler(FortranCompiler):
std_warn_args = ['-warn', 'all']
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
+ self.file_suffixes = ('f', 'f90')
super().__init__(exelist, version, is_cross, exe_wrapper=None)
self.id = 'intel'
def get_module_outdir_args(self, path):
return ['-module', path]
- def can_compile(self, src):
- suffix = os.path.splitext(src)[1].lower()
- if suffix == '.f' or suffix == '.f90':
- return True
- return False
-
def get_warn_args(self, level):
return IntelFortranCompiler.std_warn_args
@@ -2406,12 +2359,6 @@ class PathScaleFortranCompiler(FortranCompiler):
def get_module_outdir_args(self, path):
return ['-module', path]
- def can_compile(self, src):
- suffix = os.path.splitext(src)[1].lower()
- if suffix == '.f' or suffix == '.f90' or suffix == '.f95':
- return True
- return False
-
def get_std_warn_args(self, level):
return PathScaleFortranCompiler.std_warn_args
@@ -2425,12 +2372,6 @@ class PGIFortranCompiler(FortranCompiler):
def get_module_outdir_args(self, path):
return ['-module', path]
- def can_compile(self, src):
- suffix = os.path.splitext(src)[1].lower()
- if suffix == '.f' or suffix == '.f90' or suffix == '.f95':
- return True
- return False
-
def get_warn_args(self, level):
return PGIFortranCompiler.std_warn_args
@@ -2445,12 +2386,6 @@ class Open64FortranCompiler(FortranCompiler):
def get_module_outdir_args(self, path):
return ['-module', path]
- def can_compile(self, src):
- suffix = os.path.splitext(src)[1].lower()
- if suffix == '.f' or suffix == '.f90' or suffix == '.f95':
- return True
- return False
-
def get_warn_args(self, level):
return Open64FortranCompiler.std_warn_args
@@ -2467,12 +2402,6 @@ class NAGFortranCompiler(FortranCompiler):
def get_always_args(self):
return []
- def can_compile(self, src):
- suffix = os.path.splitext(src)[1].lower()
- if suffix == '.f' or suffix == '.f90' or suffix == '.f95':
- return True
- return False
-
def get_warn_args(self, level):
return NAGFortranCompiler.std_warn_args