aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/backends.py12
-rw-r--r--mesonbuild/backend/ninjabackend.py88
-rw-r--r--mesonbuild/backend/vs2010backend.py10
-rw-r--r--mesonbuild/backend/xcodebackend.py12
-rw-r--r--mesonbuild/build.py73
-rw-r--r--mesonbuild/cmake/executor.py10
-rw-r--r--mesonbuild/cmake/interpreter.py24
-rw-r--r--mesonbuild/compilers/c.py4
-rw-r--r--mesonbuild/compilers/compilers.py81
-rw-r--r--mesonbuild/compilers/cpp.py4
-rw-r--r--mesonbuild/compilers/cs.py4
-rw-r--r--mesonbuild/compilers/cuda.py13
-rw-r--r--mesonbuild/compilers/d.py4
-rw-r--r--mesonbuild/compilers/fortran.py4
-rw-r--r--mesonbuild/compilers/java.py4
-rw-r--r--mesonbuild/compilers/mixins/clike.py2
-rw-r--r--mesonbuild/compilers/mixins/gnu.py15
-rw-r--r--mesonbuild/compilers/mixins/pgi.py3
-rw-r--r--mesonbuild/compilers/objc.py4
-rw-r--r--mesonbuild/compilers/objcpp.py4
-rw-r--r--mesonbuild/compilers/rust.py4
-rw-r--r--mesonbuild/compilers/swift.py4
-rw-r--r--mesonbuild/compilers/vala.py4
-rw-r--r--mesonbuild/coredata.py38
-rw-r--r--mesonbuild/dependencies/base.py24
-rw-r--r--mesonbuild/dependencies/boost.py2
-rw-r--r--mesonbuild/dependencies/coarrays.py8
-rw-r--r--mesonbuild/dependencies/cuda.py13
-rw-r--r--mesonbuild/dependencies/dev.py10
-rw-r--r--mesonbuild/dependencies/hdf5.py12
-rw-r--r--mesonbuild/dependencies/misc.py6
-rw-r--r--mesonbuild/dependencies/mpi.py30
-rw-r--r--mesonbuild/dependencies/scalapack.py2
-rw-r--r--mesonbuild/dependencies/ui.py6
-rw-r--r--mesonbuild/envconfig.py4
-rw-r--r--mesonbuild/environment.py94
-rw-r--r--mesonbuild/interpreter.py28
-rw-r--r--mesonbuild/mconf.py9
-rw-r--r--mesonbuild/mesonlib.py77
-rw-r--r--mesonbuild/minit.py36
-rw-r--r--mesonbuild/modules/cmake.py4
-rw-r--r--mesonbuild/modules/gnome.py10
-rw-r--r--mesonbuild/modules/pkgconfig.py6
-rw-r--r--mesonbuild/modules/windows.py2
-rw-r--r--mesonbuild/optinterpreter.py2
-rw-r--r--mesonbuild/scripts/clangformat.py2
-rw-r--r--mesonbuild/scripts/clangtidy.py2
-rw-r--r--mesonbuild/templates/mesontemplates.py4
-rw-r--r--mesonbuild/templates/samplefactory.py20
-rwxr-xr-xrun_unittests.py2
50 files changed, 494 insertions, 346 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index c84bb75..86d20f7 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -30,8 +30,8 @@ from .. import dependencies
from .. import mesonlib
from .. import mlog
from ..mesonlib import (
- File, MachineChoice, MesonException, OrderedSet, OptionOverrideProxy,
- classify_unity_sources, unholder
+ File, Language, MachineChoice, MesonException, OrderedSet,
+ OptionOverrideProxy, classify_unity_sources, unholder,
)
if T.TYPE_CHECKING:
@@ -704,7 +704,7 @@ class Backend:
if not dep.found():
continue
- if compiler.language == 'vala':
+ if compiler.language == Language.VALA:
if isinstance(dep, dependencies.PkgConfigDependency):
if dep.name == 'glib-2.0' and dep.version_reqs is not None:
for req in dep.version_reqs:
@@ -713,7 +713,7 @@ class Backend:
break
commands += ['--pkg', dep.name]
elif isinstance(dep, dependencies.ExternalLibrary):
- commands += dep.get_link_args('vala')
+ commands += dep.get_link_args(Language.VALA)
else:
commands += compiler.get_dependency_compile_args(dep)
# Qt needs -fPIC for executables
@@ -723,7 +723,7 @@ class Backend:
# For 'automagic' deps: Boost and GTest. Also dependency('threads').
# pkg-config puts the thread flags itself via `Cflags:`
# Fortran requires extra include directives.
- if compiler.language == 'fortran':
+ if compiler.language == Language.FORTRAN:
for lt in target.link_targets:
priv_dir = self.get_target_private_dir(lt)
commands += compiler.get_include_args(priv_dir, False)
@@ -737,7 +737,7 @@ class Backend:
arg = self.get_target_filename_for_linking(d)
if not arg:
continue
- if compiler.get_language() == 'd':
+ if compiler.get_language() == Language.D:
arg = '-Wl,' + arg
else:
arg = compiler.get_linker_lib_prefix() + arg
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 32fb8db..968ad7c 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -40,7 +40,7 @@ from ..compilers import (
)
from ..linkers import ArLinker, VisualStudioLinker
from ..mesonlib import (
- File, LibType, MachineChoice, MesonException, OrderedSet, PerMachine,
+ File, LibType, Language, MachineChoice, MesonException, OrderedSet, PerMachine,
ProgressBar, quote_arg, unholder,
)
from ..mesonlib import get_compiler_for_source, has_path_sep
@@ -565,7 +565,7 @@ int dummy;
for src in genlist.get_outputs():
if self.environment.is_header(src):
header_deps.append(self.get_target_generated_dir(target, genlist, src))
- if 'vala' in target.compilers and not isinstance(target, build.Executable):
+ if Language.VALA in target.compilers and not isinstance(target, build.Executable):
vala_header = File.from_built_file(self.get_target_dir(target), target.vala_header)
header_deps.append(vala_header)
# Recurse and find generated headers
@@ -603,7 +603,7 @@ int dummy;
# Languages that can mix with C or C++ but don't support unity builds yet
# because the syntax we use for unity builds is specific to C/++/ObjC/++.
# Assembly files cannot be unitified and neither can LLVM IR files
- langs_cant_unity = ('d', 'fortran')
+ langs_cant_unity = (Language.D, Language.FORTRAN)
def get_target_source_can_unity(self, target, source):
if isinstance(source, File):
@@ -649,7 +649,7 @@ int dummy;
parameters = comp.compute_parameters_with_absolute_paths(parameters, self.build_dir)
# The new entry
src_block = {
- 'language': lang,
+ 'language': lang.get_lower_case_name(),
'compiler': comp.get_exelist(),
'parameters': parameters,
'sources': [],
@@ -693,10 +693,10 @@ int dummy;
if self.is_rust_target(target):
self.generate_rust_target(target)
return
- if 'cs' in target.compilers:
+ if Language.CS in target.compilers:
self.generate_cs_target(target)
return
- if 'swift' in target.compilers:
+ if Language.SWIFT in target.compilers:
self.generate_swift_target(target)
return
@@ -711,7 +711,7 @@ int dummy;
# path to source relative to build root and the generating target/list
# vala_generated_sources:
# Array of sources generated by valac that have to be compiled
- if 'vala' in target.compilers:
+ if Language.VALA in target.compilers:
# Sources consumed by valac are filtered out. These only contain
# C/C++ sources, objects, generated libs, and unknown sources now.
target_sources, generated_sources, \
@@ -809,10 +809,10 @@ int dummy;
# after `header_deps` (above) is fully generated
vala_generated_source_files.append(raw_src)
for src in vala_generated_source_files:
- # Passing 'vala' here signifies that we want the compile
+ # Passing Language.VALA here signifies that we want the compile
# arguments to be specialized for C code generated by
# valac. For instance, no warnings should be emitted.
- obj_list.append(self.generate_single_compile(target, src, 'vala', [], header_deps))
+ obj_list.append(self.generate_single_compile(target, src, Language.VALA, [], header_deps))
# Generate compile targets for all the pre-existing sources for this target
for src in target_sources.values():
@@ -1126,7 +1126,7 @@ int dummy;
outname_rel = os.path.join(self.get_target_dir(target), fname)
src_list = target.get_sources()
class_list = []
- compiler = target.compilers['java']
+ compiler = target.compilers[Language.JAVA]
c = 'c'
m = 'm'
e = ''
@@ -1201,10 +1201,10 @@ int dummy;
fname = target.get_filename()
outname_rel = os.path.join(self.get_target_dir(target), fname)
src_list = target.get_sources()
- compiler = target.compilers['cs']
+ compiler = target.compilers[Language.CS]
rel_srcs = [os.path.normpath(s.rel_to_builddir(self.build_to_src)) for s in src_list]
deps = []
- commands = compiler.compiler_args(target.extra_args.get('cs', []))
+ commands = compiler.compiler_args(target.extra_args.get(Language.CS, []))
commands += compiler.get_buildtype_args(buildtype)
commands += compiler.get_optimization_args(self.get_option_for_target('optimization', target))
commands += compiler.get_debug_args(self.get_option_for_target('debug', target))
@@ -1238,7 +1238,7 @@ int dummy;
commands += self.build.get_project_args(compiler, target.subproject, target.for_machine)
commands += self.build.get_global_args(compiler, target.for_machine)
- elem = NinjaBuildElement(self.all_outputs, outputs, self.get_compiler_rule_name('cs', target.for_machine), rel_srcs + generated_rel_srcs)
+ elem = NinjaBuildElement(self.all_outputs, outputs, self.get_compiler_rule_name(Language.CS, target.for_machine), rel_srcs + generated_rel_srcs)
elem.add_dep(deps)
elem.add_item('ARGS', commands)
self.add_build(elem)
@@ -1366,7 +1366,7 @@ int dummy;
msg = 'Vala library {!r} has no Vala or Genie source files.'
raise InvalidArguments(msg.format(target.name))
- valac = target.compilers['vala']
+ valac = target.compilers[Language.VALA]
c_out_dir = self.get_target_private_dir(target)
# C files generated by valac
vala_c_src = []
@@ -1458,7 +1458,7 @@ int dummy;
args += ['--gresources=' + gres_xml]
extra_args = []
- for a in target.extra_args.get('vala', []):
+ for a in target.extra_args.get(Language.VALA, []):
if isinstance(a, File):
relname = a.rel_to_builddir(self.build_to_src)
extra_dep_files.append(relname)
@@ -1478,7 +1478,7 @@ int dummy;
return other_src[0], other_src[1], vala_c_src
def generate_rust_target(self, target):
- rustc = target.compilers['rust']
+ rustc = target.compilers[Language.RUST]
# Rust compiler takes only the main file as input and
# figures out what other files are needed via import
# statements and magic.
@@ -1520,7 +1520,7 @@ int dummy;
args += self.build.get_project_args(rustc, target.subproject, target.for_machine)
depfile = os.path.join(target.subdir, target.name + '.d')
args += ['--emit', 'dep-info={}'.format(depfile), '--emit', 'link']
- args += target.get_extra_args('rust')
+ args += target.get_extra_args(Language.RUST)
args += ['-o', os.path.join(target.subdir, target.get_filename())]
orderdeps = [os.path.join(t.subdir, t.get_filename()) for t in target.link_targets]
linkdirs = OrderedDict()
@@ -1567,7 +1567,7 @@ int dummy;
# installations
for rpath_arg in rpath_args:
args += ['-C', 'link-arg=' + rpath_arg + ':' + os.path.join(rustc.get_sysroot(), 'lib')]
- compiler_name = self.get_compiler_rule_name('rust', target.for_machine)
+ compiler_name = self.get_compiler_rule_name(Language.RUST, target.for_machine)
element = NinjaBuildElement(self.all_outputs, target_name, compiler_name, main_rust_file)
if len(orderdeps) > 0:
element.add_orderdep(orderdeps)
@@ -1585,11 +1585,11 @@ int dummy;
@classmethod
def get_compiler_rule_name(cls, lang: str, for_machine: MachineChoice) -> str:
- return '{}_COMPILER{}'.format(lang, cls.get_rule_suffix(for_machine))
+ return '{}_COMPILER{}'.format(lang.get_lower_case_name(), cls.get_rule_suffix(for_machine))
@classmethod
def get_pch_rule_name(cls, lang: str, for_machine: MachineChoice) -> str:
- return '{}_PCH{}'.format(lang, cls.get_rule_suffix(for_machine))
+ return '{}_PCH{}'.format(lang.get_lower_case_name(), cls.get_rule_suffix(for_machine))
@classmethod
def compiler_to_rule_name(cls, compiler: Compiler) -> str:
@@ -1644,7 +1644,7 @@ int dummy;
def generate_swift_target(self, target):
module_name = self.target_swift_modulename(target)
- swiftc = target.compilers['swift']
+ swiftc = target.compilers[Language.SWIFT]
abssrc = []
relsrc = []
abs_headers = []
@@ -1708,7 +1708,7 @@ int dummy;
objects.append(oname)
rel_objects.append(os.path.join(self.get_target_private_dir(target), oname))
- rulename = self.get_compiler_rule_name('swift', target.for_machine)
+ rulename = self.get_compiler_rule_name(Language.SWIFT, target.for_machine)
# Swiftc does not seem to be able to emit objects and module files in one go.
elem = NinjaBuildElement(self.all_outputs, rel_objects, rulename, abssrc)
@@ -1718,7 +1718,7 @@ int dummy;
elem.add_item('RUNDIR', rundir)
self.add_build(elem)
elem = NinjaBuildElement(self.all_outputs, out_module_name,
- self.get_compiler_rule_name('swift', target.for_machine),
+ self.get_compiler_rule_name(Language.SWIFT, target.for_machine),
abssrc)
elem.add_dep(in_module_files + rel_generated)
elem.add_item('ARGS', compile_args + abs_generated + module_includes + swiftc.get_mod_gen_args())
@@ -1742,7 +1742,7 @@ int dummy;
def generate_static_link_rules(self):
num_pools = self.environment.coredata.backend_options['backend_max_links'].value
- if 'java' in self.environment.coredata.compilers.host:
+ if Language.JAVA in self.environment.coredata.compilers.host:
self.generate_java_link()
for for_machine in MachineChoice:
static_linker = self.build.static_linker[for_machine]
@@ -1778,12 +1778,12 @@ int dummy;
for for_machine in MachineChoice:
complist = self.environment.coredata.compilers[for_machine]
for langname, compiler in complist.items():
- if langname == 'java' \
- or langname == 'vala' \
- or langname == 'rust' \
- or langname == 'cs':
+ if langname == Language.JAVA \
+ or langname == Language.VALA \
+ or langname == Language.RUST \
+ or langname == Language.CS:
continue
- rule = '{}_LINKER{}'.format(langname, self.get_rule_suffix(for_machine))
+ rule = '{}_LINKER{}'.format(langname.get_lower_case_name(), self.get_rule_suffix(for_machine))
command = compiler.get_linker_exelist()
args = ['$ARGS'] + NinjaCommandArg.list(compiler.get_linker_output_args('$out'), Quoting.none) + ['$in', '$LINK_ARGS']
description = 'Linking target $out'
@@ -1875,26 +1875,26 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
self.created_llvm_ir_rule[compiler.for_machine] = True
def generate_compile_rule_for(self, langname, compiler):
- if langname == 'java':
+ if langname == Language.JAVA:
if self.environment.machines.matches_build_machine(compiler.for_machine):
self.generate_java_compile_rule(compiler)
return
- if langname == 'cs':
+ if langname == Language.CS:
if self.environment.machines.matches_build_machine(compiler.for_machine):
self.generate_cs_compile_rule(compiler)
return
- if langname == 'vala':
+ if langname == Language.VALA:
self.generate_vala_compile_rules(compiler)
return
- if langname == 'rust':
+ if langname == Language.RUST:
self.generate_rust_compile_rules(compiler)
return
- if langname == 'swift':
+ if langname == Language.SWIFT:
if self.environment.machines.matches_build_machine(compiler.for_machine):
self.generate_swift_compile_rules(compiler)
return
crstr = self.get_rule_suffix(compiler.for_machine)
- if langname == 'fortran':
+ if langname == Language.FORTRAN:
self.generate_fortran_dep_hack(crstr)
rule = self.get_compiler_rule_name(langname, compiler.for_machine)
depargs = NinjaCommandArg.list(compiler.get_dependency_gen_args('$out', '$DEPFILE'), Quoting.none)
@@ -1914,7 +1914,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
deps=deps, depfile=depfile))
def generate_pch_rule_for(self, langname, compiler):
- if langname != 'c' and langname != 'cpp':
+ if langname != Language.C and langname != Language.CPP:
return
rule = self.compiler_to_pch_rule_name(compiler)
depargs = compiler.get_dependency_gen_args('$out', '$DEPFILE')
@@ -2031,7 +2031,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
compiler = None
# TODO other compilers
for lang, c in self.environment.coredata.compilers.host.items():
- if lang == 'fortran':
+ if lang == Language.FORTRAN:
compiler = c
break
if compiler is None:
@@ -2257,7 +2257,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
compiler)
# The code generated by valac is usually crap and has tons of unused
# variables and such, so disable warnings for Vala C sources.
- no_warn_args = (is_generated == 'vala')
+ no_warn_args = (is_generated == Language.VALA)
# Add compiler args and include paths from several sources; defaults,
# build options, external dependencies, etc.
commands += self.generate_basic_compiler_args(target, compiler, no_warn_args)
@@ -2294,7 +2294,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
target.get_extra_args(compiler.get_language()))
# D specific additional flags
- if compiler.language == 'd':
+ if compiler.language == Language.D:
commands += compiler.get_feature_args(target.d_features, self.build_to_src)
# Add source dir and build dir. Project-specific and target-specific
@@ -2373,7 +2373,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
compiler_name = self.compiler_to_rule_name(compiler)
extra_deps = []
- if compiler.get_language() == 'fortran':
+ if compiler.get_language() == Language.FORTRAN:
# Can't read source file to scan for deps if it's generated later
# at build-time. Skip scanning for deps, and just set the module
# outdir argument instead.
@@ -2432,7 +2432,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
# The real deps are then detected via dep file generation from the compiler. This breaks on compilers that
# produce incorrect dep files but such is life.
def get_fortran_orderdeps(self, target, compiler):
- if compiler.language != 'fortran':
+ if compiler.language != Language.FORTRAN:
return []
return [os.path.join(self.get_target_dir(lt), lt.get_filename()) for lt in target.link_targets]
@@ -2462,7 +2462,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
def generate_gcc_pch_command(self, target, compiler, pch):
commands = self._generate_single_compile(target, compiler)
- if pch.split('.')[-1] == 'h' and compiler.language == 'cpp':
+ if pch.split('.')[-1] == 'h' and compiler.language == Language.CPP:
# Explicitly compile pch headers as C++. If Clang is invoked in C++ mode, it actually warns if
# this option is not set, and for gcc it also makes sense to use it.
commands += ['-x', 'c++-header']
@@ -2474,7 +2474,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
def generate_pch(self, target, header_deps=None):
header_deps = header_deps if header_deps is not None else []
pch_objects = []
- for lang in ['c', 'cpp']:
+ for lang in [Language.C, Language.CPP]:
pch = target.get_pch(lang)
if not pch:
continue
@@ -2665,7 +2665,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
if isinstance(target, build.StaticLibrary):
linker_base = 'STATIC'
else:
- linker_base = linker.get_language() # Fixme.
+ linker_base = linker.get_language().get_lower_case_name() # Fixme.
if isinstance(target, build.SharedLibrary):
self.generate_shsym(target)
crstr = self.get_rule_suffix(target.for_machine)
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index f282d02..7e28cfb 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -587,9 +587,9 @@ class Vs2010Backend(backends.Backend):
def lang_from_source_file(cls, src):
ext = src.split('.')[-1]
if ext in compilers.c_suffixes:
- return 'c'
+ return Language.C
if ext in compilers.cpp_suffixes:
- return 'cpp'
+ return Language.CPP
raise MesonException('Could not guess language from source file %s.' % src)
def add_pch(self, pch_sources, lang, inc_cl):
@@ -726,13 +726,13 @@ class Vs2010Backend(backends.Backend):
def _get_cl_compiler(self, target):
for lang, c in target.compilers.items():
- if lang in ('c', 'cpp'):
+ if lang in (Language.C, Language.CPP):
return c
# No source files, only objects, but we still need a compiler, so
# return a found compiler
if len(target.objects) > 0:
for lang, c in self.environment.coredata.compilers[target.for_machine].items():
- if lang in ('c', 'cpp'):
+ if lang in (Language.C, Language.CPP):
return c
raise MesonException('Could not find a C or C++ compiler. MSVC can only build C/C++ projects.')
@@ -1060,7 +1060,7 @@ class Vs2010Backend(backends.Backend):
# Note: SuppressStartupBanner is /NOLOGO and is 'true' by default
pch_sources = {}
if self.environment.coredata.base_options.get('b_pch', False):
- for lang in ['c', 'cpp']:
+ for lang in [Language.C, Language.CPP]:
pch = target.get_pch(lang)
if not pch:
continue
diff --git a/mesonbuild/backend/xcodebackend.py b/mesonbuild/backend/xcodebackend.py
index 3fe6574..4625468 100644
--- a/mesonbuild/backend/xcodebackend.py
+++ b/mesonbuild/backend/xcodebackend.py
@@ -702,7 +702,12 @@ class XCodeBackend(backends.Backend):
self.write_line('};')
# Now finally targets.
- langnamemap = {'c': 'C', 'cpp': 'CPLUSPLUS', 'objc': 'OBJC', 'objcpp': 'OBJCPLUSPLUS'}
+ langnamemap = {
+ Language.C: 'C',
+ Language.CPP: 'CPLUSPLUS',
+ Language.OBJC: 'OBJC',
+ Language.OBJCPP: 'OBJCPLUSPLUS',
+ }
for target_name, target in self.build.targets.items():
for buildtype in self.buildtypes:
dep_libs = []
@@ -773,7 +778,10 @@ class XCodeBackend(backends.Backend):
# Xcode uses GCC_PREFIX_HEADER which only allows one file per target/executable. Precompiling various header files and
# applying a particular pch to each source file will require custom scripts (as a build phase) and build flags per each
# file. Since Xcode itself already discourages precompiled headers in favor of modules we don't try much harder here.
- pchs = target.get_pch('c') + target.get_pch('cpp') + target.get_pch('objc') + target.get_pch('objcpp')
+ pchs = target.get_pch(Language.C)
+ + target.get_pch(Language.CPP)
+ + target.get_pch(Language.OBJC)
+ + target.get_pch(Language.OBJCPP)
# Make sure to use headers (other backends require implementation files like *.c *.cpp, etc; these should not be used here)
pchs = [pch for pch in pchs if pch.endswith('.h') or pch.endswith('.hh') or pch.endswith('hpp')]
if pchs:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 5e6db73..e3b67de 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -26,7 +26,7 @@ from . import environment
from . import dependencies
from . import mlog
from .mesonlib import (
- File, MesonException, MachineChoice, PerMachine, OrderedSet, listify,
+ File, Language, MesonException, MachineChoice, PerMachine, OrderedSet, listify,
extract_as_list, typeslistify, stringlistify, classify_unity_sources,
get_filenames_templates_dict, substitute_values, has_path_sep, unholder
)
@@ -459,8 +459,9 @@ a hard error in the future.'''.format(name))
for k, v in option_overrides.items():
if '_' in k:
- lang, k2 = k.split('_', 1)
- if lang in all_languages:
+ lang_str, k2 = k.split('_', 1)
+ lang = Language.from_lower_case_name(lang_str)
+ if lang is not None:
self.option_overrides_compiler[lang][k2] = v
continue
self.option_overrides_base[k] = v
@@ -668,7 +669,7 @@ class BuildTarget(Target):
# Don't add Vala sources since that will pull in the Vala
# compiler even though we will never use it since we are
# dealing with compiled C code.
- if not s.endswith(lang_suffixes['vala']):
+ if not s.endswith(lang_suffixes[Language.VALA]):
sources.append(s)
if sources:
# For each source, try to add one compiler that can compile it.
@@ -696,21 +697,23 @@ class BuildTarget(Target):
# If all our sources are Vala, our target also needs the C compiler but
# it won't get added above.
- if 'vala' in self.compilers and 'c' not in self.compilers:
- self.compilers['c'] = compilers['c']
+ if Language.VALA in self.compilers and Language.C not in self.compilers:
+ self.compilers[Language.C] = compilers[Language.C]
def validate_sources(self):
if not self.sources:
return
- for lang in ('cs', 'java'):
+ for lang in (Language.CS, Language.JAVA):
if lang in self.compilers:
check_sources = list(self.sources)
compiler = self.compilers[lang]
if not self.can_compile_remove_sources(compiler, check_sources):
- m = 'No {} sources found in target {!r}'.format(lang, self.name)
+ m = 'No {} sources found in target {!r}'.format(
+ lang.get_lower_case_name(), self.name)
raise InvalidArguments(m)
if check_sources:
- m = '{0} targets can only contain {0} files:\n'.format(lang.capitalize())
+ m = '{0} targets can only contain {0} files:\n'.format(
+ lang.get_display_name())
m += '\n'.join([repr(c) for c in check_sources])
raise InvalidArguments(m)
# CSharp and Java targets can't contain any other file types
@@ -854,11 +857,19 @@ just like those detected with the dependency() function.''')
c_pchlist, cpp_pchlist, clist, cpplist, cudalist, cslist, valalist, objclist, objcpplist, fortranlist, rustlist \
= [extract_as_list(kwargs, c) for c in ['c_pch', 'cpp_pch', 'c_args', 'cpp_args', 'cuda_args', 'cs_args', 'vala_args', 'objc_args', 'objcpp_args', 'fortran_args', 'rust_args']]
- self.add_pch('c', c_pchlist)
- self.add_pch('cpp', cpp_pchlist)
- compiler_args = {'c': clist, 'cpp': cpplist, 'cuda': cudalist, 'cs': cslist, 'vala': valalist, 'objc': objclist, 'objcpp': objcpplist,
- 'fortran': fortranlist, 'rust': rustlist
- }
+ self.add_pch(Language.C, c_pchlist)
+ self.add_pch(Language.CPP, cpp_pchlist)
+ compiler_args = {
+ Language.CPP: cpplist,
+ Language.CS: cslist,
+ Language.CUDA: cudalist,
+ Language.FORTRAN: fortranlist,
+ Language.OBJC: objclist,
+ Language.OBJCPP: objcpplist,
+ Language.RUST: rustlist,
+ Language.VALA: valalist,
+ Language.C: clist,
+ }
for key, value in compiler_args.items():
self.add_compiler_args(key, value)
@@ -868,7 +879,7 @@ just like those detected with the dependency() function.''')
self.vala_gir = kwargs.get('vala_gir', None)
dlist = stringlistify(kwargs.get('d_args', []))
- self.add_compiler_args('d', dlist)
+ self.add_compiler_args(Language.D, dlist)
dfeatures = dict()
dfeature_unittest = kwargs.get('d_unittest', False)
if dfeature_unittest:
@@ -992,7 +1003,7 @@ This will become a hard error in a future Meson release.''')
def _extract_pic_pie(self, kwargs, arg):
# Check if we have -fPIC, -fpic, -fPIE, or -fpie in cflags
- all_flags = self.extra_args['c'] + self.extra_args['cpp']
+ all_flags = self.extra_args[Language.C] + self.extra_args[Language.CPP]
if '-f' + arg.lower() in all_flags or '-f' + arg.upper() in all_flags:
mlog.warning("Use the '{}' kwarg instead of passing '{}' manually to {!r}".format(arg, '-f' + arg, self.name))
return True
@@ -1214,7 +1225,7 @@ You probably should put it in link_with instead.''')
def get_aliases(self):
return {}
- def get_langs_used_by_deps(self) -> T.List[str]:
+ def get_langs_used_by_deps(self) -> T.List[Language]:
'''
Sometimes you want to link to a C++ library that exports C API, which
means the linker must link in the C++ stdlib, and we must use a C++
@@ -1500,20 +1511,20 @@ class Executable(BuildTarget):
if not hasattr(self, 'suffix'):
machine = environment.machines[for_machine]
# Executable for Windows or C#/Mono
- if machine.is_windows() or machine.is_cygwin() or 'cs' in self.compilers:
+ if machine.is_windows() or machine.is_cygwin() or Language.CS in self.compilers:
self.suffix = 'exe'
elif machine.system.startswith('wasm') or machine.system == 'emscripten':
self.suffix = 'js'
- elif ('c' in self.compilers and self.compilers['c'].get_id().startswith('arm') or
- 'cpp' in self.compilers and self.compilers['cpp'].get_id().startswith('arm')):
+ elif (Language.C in self.compilers and self.compilers[Language.C].get_id().startswith('arm') or
+ Language.CPP in self.compilers and self.compilers[Language.CPP].get_id().startswith('arm')):
self.suffix = 'axf'
- elif ('c' in self.compilers and self.compilers['c'].get_id().startswith('ccrx') or
- 'cpp' in self.compilers and self.compilers['cpp'].get_id().startswith('ccrx')):
+ elif (Language.C in self.compilers and self.compilers[Language.C].get_id().startswith('ccrx') or
+ Language.CPP in self.compilers and self.compilers[Language.CPP].get_id().startswith('ccrx')):
self.suffix = 'abs'
- elif ('c' in self.compilers and self.compilers['c'].get_id().startswith('xc16')):
+ elif (Language.C in self.compilers and self.compilers[Language.C].get_id().startswith('xc16')):
self.suffix = 'elf'
- elif ('c' in self.compilers and self.compilers['c'].get_id().startswith('c2000') or
- 'cpp' in self.compilers and self.compilers['cpp'].get_id().startswith('c2000')):
+ elif (Language.C in self.compilers and self.compilers[Language.C].get_id().startswith('c2000') or
+ Language.CPP in self.compilers and self.compilers[Language.CPP].get_id().startswith('c2000')):
self.suffix = 'out'
else:
self.suffix = environment.machines[for_machine].get_exe_suffix()
@@ -1557,7 +1568,7 @@ class Executable(BuildTarget):
else:
self.import_filename = self.gcc_import_filename
- if m.is_windows() and ('cs' in self.compilers or
+ if m.is_windows() and (Language.CS in self.compilers or
self.get_using_rustc() or
self.get_using_msvc()):
self.debug_filename = self.name + '.pdb'
@@ -1607,9 +1618,9 @@ class StaticLibrary(BuildTarget):
if 'pic' not in kwargs and 'b_staticpic' in environment.coredata.base_options:
kwargs['pic'] = environment.coredata.base_options['b_staticpic'].value
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
- if 'cs' in self.compilers:
+ if Language.CS in self.compilers:
raise InvalidArguments('Static libraries not supported for C#.')
- if 'rust' in self.compilers:
+ if Language.RUST in self.compilers:
# If no crate type is specified, or it's the generic lib type, use rlib
if not hasattr(self, 'rust_crate_type') or self.rust_crate_type == 'lib':
mlog.debug('Defaulting Rust static library target crate type to rlib')
@@ -1627,7 +1638,7 @@ class StaticLibrary(BuildTarget):
if not hasattr(self, 'prefix'):
self.prefix = 'lib'
if not hasattr(self, 'suffix'):
- if 'rust' in self.compilers:
+ if Language.RUST in self.compilers:
if not hasattr(self, 'rust_crate_type') or self.rust_crate_type == 'rlib':
# default Rust static library suffix
self.suffix = 'rlib'
@@ -1678,7 +1689,7 @@ class SharedLibrary(BuildTarget):
# The debugging information file this target will generate
self.debug_filename = None
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
- if 'rust' in self.compilers:
+ if Language.RUST in self.compilers:
# If no crate type is specified, or it's the generic lib type, use dylib
if not hasattr(self, 'rust_crate_type') or self.rust_crate_type == 'lib':
mlog.debug('Defaulting Rust dynamic library target crate type to "dylib"')
@@ -1735,7 +1746,7 @@ class SharedLibrary(BuildTarget):
self.filename_tpl = self.basic_filename_tpl
# NOTE: manual prefix/suffix override is currently only tested for C/C++
# C# and Mono
- if 'cs' in self.compilers:
+ if Language.CS in self.compilers:
prefix = ''
suffix = 'dll'
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
diff --git a/mesonbuild/cmake/executor.py b/mesonbuild/cmake/executor.py
index 148a999..d41cd22 100644
--- a/mesonbuild/cmake/executor.py
+++ b/mesonbuild/cmake/executor.py
@@ -252,7 +252,7 @@ class CMakeExecutor:
fallback = os.path.realpath(__file__) # A file used as a fallback wehen everything else fails
compilers = self.environment.coredata.compilers[MachineChoice.BUILD]
- def make_abs(exe: str, lang: str) -> str:
+ def make_abs(exe: str, lang: Language) -> str:
if os.path.isabs(exe):
return exe
@@ -262,7 +262,7 @@ class CMakeExecutor:
p = fallback
return p
- def choose_compiler(lang: str) -> T.Tuple[str, str]:
+ def choose_compiler(lang: Language) -> T.Tuple[str, str]:
exe_list = []
if lang in compilers:
exe_list = compilers[lang].get_exelist()
@@ -282,9 +282,9 @@ class CMakeExecutor:
mlog.debug('Failed to find a {} compiler for CMake. This might cause CMake to fail.'.format(lang))
return fallback, ''
- c_comp, c_launcher = choose_compiler('c')
- cxx_comp, cxx_launcher = choose_compiler('cpp')
- fortran_comp, fortran_launcher = choose_compiler('fortran')
+ c_comp, c_launcher = choose_compiler(Language.C)
+ cxx_comp, cxx_launcher = choose_compiler(Language.CPP)
+ fortran_comp, fortran_launcher = choose_compiler(Language.FORTRAN)
# on Windows, choose_compiler returns path with \ as separator - replace by / before writing to CMAKE file
c_comp = c_comp.replace('\\', '/')
diff --git a/mesonbuild/cmake/interpreter.py b/mesonbuild/cmake/interpreter.py
index f404109..91700c7 100644
--- a/mesonbuild/cmake/interpreter.py
+++ b/mesonbuild/cmake/interpreter.py
@@ -22,7 +22,7 @@ from .executor import CMakeExecutor
from .traceparser import CMakeTraceParser, CMakeGeneratorTarget
from .. import mlog, mesonlib
from ..environment import Environment
-from ..mesonlib import MachineChoice, OrderedSet, version_compare
+from ..mesonlib import Language, MachineChoice, OrderedSet, version_compare
from ..mesondata import mesondata
from ..compilers.compilers import lang_suffixes, header_suffixes, obj_suffixes, lib_suffixes, is_header
from enum import Enum
@@ -76,15 +76,15 @@ backend_generator_map = {
}
language_map = {
- 'c': 'C',
- 'cpp': 'CXX',
- 'cuda': 'CUDA',
- 'objc': 'OBJC',
- 'objcpp': 'OBJCXX',
- 'cs': 'CSharp',
- 'java': 'Java',
- 'fortran': 'Fortran',
- 'swift': 'Swift',
+ Language.C: 'C',
+ Language.CPP: 'CXX',
+ Language.CUDA: 'CUDA',
+ Language.OBJC: 'OBJC',
+ Language.OBJCPP: 'OBJCXX',
+ Language.CS: 'CSharp',
+ Language.JAVA: 'Java',
+ Language.FORTRAN: 'Fortran',
+ Language.SWIFT: 'Swift',
}
target_type_map = {
@@ -252,7 +252,7 @@ class ConverterTarget:
for i in target.files:
# Determine the meson language
lang_cmake_to_meson = {val.lower(): key for key, val in language_map.items()}
- lang = lang_cmake_to_meson.get(i.language.lower(), 'c')
+ lang = lang_cmake_to_meson.get(i.language.lower(), Language.C)
if lang not in self.languages:
self.languages += [lang]
if lang not in self.compile_opts:
@@ -280,7 +280,7 @@ class ConverterTarget:
def postprocess(self, output_target_map: OutputTargetMap, root_src_dir: str, subdir: str, install_prefix: str, trace: CMakeTraceParser) -> None:
# Detect setting the C and C++ standard
- for i in ['c', 'cpp']:
+ for i in [Language.C, Language.CPP]:
if i not in self.compile_opts:
continue
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index aac99b4..feae8ac 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -16,7 +16,7 @@ import os.path
import typing as T
from .. import coredata
-from ..mesonlib import MachineChoice, MesonException, mlog, version_compare
+from ..mesonlib import Language, MachineChoice, MesonException, mlog, version_compare
from ..linkers import LinkerEnvVarsMixin
from .c_function_attributes import C_FUNC_ATTRIBUTES
from .mixins.clike import CLikeCompiler
@@ -50,7 +50,7 @@ class CCompiler(CLikeCompiler, Compiler):
except KeyError:
raise MesonException('Unknown function attribute "{}"'.format(name))
- language = 'c'
+ language = Language.C
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool,
info: 'MachineInfo', exe_wrapper: T.Optional[str] = None, **kwargs):
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 0de59a4..c31439c 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -23,7 +23,7 @@ from .. import mlog
from .. import mesonlib
from ..linkers import LinkerEnvVarsMixin
from ..mesonlib import (
- EnvironmentException, MachineChoice, MesonException,
+ EnvironmentException, Language, MachineChoice, MesonException,
Popen_safe, split_args
)
from ..envconfig import (
@@ -49,52 +49,67 @@ lib_suffixes = ('a', 'lib', 'dll', 'dll.a', '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', 'ino'),
- 'cuda': ('cu',),
+ Language.C: ('c',),
+ Language.CPP: ('cpp', 'cc', 'cxx', 'c++', 'hh', 'hpp', 'ipp', 'hxx', 'ino'),
+ Language.CUDA: ('cu',),
# f90, f95, f03, f08 are for free-form fortran ('f90' recommended)
# f, for, ftn, fpp are for fixed-form fortran ('f' or 'for' recommended)
- 'fortran': ('f90', 'f95', 'f03', 'f08', 'f', 'for', 'ftn', 'fpp'),
- 'd': ('d', 'di'),
- 'objc': ('m',),
- 'objcpp': ('mm',),
- 'rust': ('rs',),
- 'vala': ('vala', 'vapi', 'gs'),
- 'cs': ('cs',),
- 'swift': ('swift',),
- 'java': ('java',),
+ Language.FORTRAN: ('f90', 'f95', 'f03', 'f08', 'f', 'for', 'ftn', 'fpp'),
+ Language.D: ('d', 'di'),
+ Language.OBJC: ('m',),
+ Language.OBJCPP: ('mm',),
+ Language.RUST: ('rs',),
+ Language.VALA: ('vala', 'vapi', 'gs'),
+ Language.CS: ('cs',),
+ Language.SWIFT: ('swift',),
+ Language.JAVA: ('java',),
}
all_languages = lang_suffixes.keys()
-cpp_suffixes = lang_suffixes['cpp'] + ('h',)
-c_suffixes = lang_suffixes['c'] + ('h',)
+cpp_suffixes = lang_suffixes[Language.CPP] + ('h',)
+c_suffixes = lang_suffixes[Language.C] + ('h',)
# List of languages that by default consume and output libraries following the
# C ABI; these can generally be used interchangebly
-clib_langs = ('objcpp', 'cpp', 'objc', 'c', 'fortran',)
+clib_langs = (Language.OBJCPP, Language.CPP, Language.OBJC, Language.C, Language.FORTRAN,)
# List of languages that can be linked with C code directly by the linker
# used in build.py:process_compilers() and build.py:get_dynamic_linker()
-clink_langs = ('d', 'cuda') + clib_langs
+clink_langs = (Language.D, Language.CUDA) + clib_langs
clink_suffixes = ()
-for _l in clink_langs + ('vala',):
+for _l in clink_langs + (Language.VALA,):
clink_suffixes += lang_suffixes[_l]
clink_suffixes += ('h', 'll', 's')
all_suffixes = set(itertools.chain(*lang_suffixes.values(), clink_suffixes))
# Languages that should use LDFLAGS arguments when linking.
-languages_using_ldflags = {'objcpp', 'cpp', 'objc', 'c', 'fortran', 'd', 'cuda'}
+languages_using_ldflags = {
+ Language.OBJCPP,
+ Language.CPP,
+ Language.OBJC,
+ Language.C,
+ Language.FORTRAN,
+ Language.D,
+ Language.CUDA
+}
# Languages that should use CPPFLAGS arguments when linking.
-languages_using_cppflags = {'c', 'cpp', 'objc', 'objcpp'}
+languages_using_cppflags = {
+ Language.C,
+ Language.CPP,
+ Language.OBJC,
+ Language.OBJCPP,
+}
soregex = re.compile(r'.*\.so(\.[0-9]+)?(\.[0-9]+)?(\.[0-9]+)?$')
# Environment variables that each lang uses.
-cflags_mapping = {'c': 'CFLAGS',
- 'cpp': 'CXXFLAGS',
- 'cuda': 'CUFLAGS',
- 'objc': 'OBJCFLAGS',
- 'objcpp': 'OBJCXXFLAGS',
- 'fortran': 'FFLAGS',
- 'd': 'DFLAGS',
- 'vala': 'VALAFLAGS',
- 'rust': 'RUSTFLAGS'}
+cflags_mapping = {
+ Language.C: 'CFLAGS',
+ Language.CPP: 'CXXFLAGS',
+ Language.CUDA: 'CUFLAGS',
+ Language.OBJC: 'OBJCFLAGS',
+ Language.OBJCPP: 'OBJCXXFLAGS',
+ Language.FORTRAN: 'FFLAGS',
+ Language.D: 'DFLAGS',
+ Language.VALA: 'VALAFLAGS',
+ Language.RUST: 'RUSTFLAGS',
+}
# All these are only for C-linkable languages; see `clink_langs` above.
@@ -474,7 +489,7 @@ class Compiler(metaclass=abc.ABCMeta):
@classmethod
def get_display_language(cls) -> str:
- return cls.language.capitalize()
+ return cls.language.get_display_name()
def get_default_suffix(self) -> str:
return self.default_suffix
@@ -909,7 +924,7 @@ def get_largefile_args(compiler):
return []
-def get_args_from_envvars(lang: str,
+def get_args_from_envvars(lang: Language,
for_machine: MachineChoice,
is_cross: bool,
use_linker_args: bool) -> T.Tuple[T.List[str], T.List[str]]:
@@ -946,7 +961,7 @@ def get_args_from_envvars(lang: str,
return compile_flags, link_flags
-def get_global_options(lang: str,
+def get_global_options(lang: Language,
comp: T.Type[Compiler],
for_machine: MachineChoice,
is_cross: bool,
@@ -970,7 +985,7 @@ def get_global_options(lang: str,
comp.INVOKES_LINKER)
for k, o in opts.items():
- user_k = lang + '_' + k
+ user_k = lang.get_lower_case_name() + '_' + k
if user_k in properties:
# Get from configuration files.
o.set_value(properties[user_k])
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index f5b0c05..71a300a 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -19,7 +19,7 @@ import typing as T
from .. import coredata
from .. import mlog
-from ..mesonlib import MesonException, MachineChoice, version_compare
+from ..mesonlib import Language, MesonException, MachineChoice, version_compare
from ..linkers import LinkerEnvVarsMixin
from .compilers import (
@@ -60,7 +60,7 @@ class CPPCompiler(CLikeCompiler, Compiler):
except KeyError:
raise MesonException('Unknown function attribute "{}"'.format(name))
- language = 'cpp'
+ language = Language.CPP
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool,
info: 'MachineInfo', exe_wrap: T.Optional[str] = None, **kwargs):
diff --git a/mesonbuild/compilers/cs.py b/mesonbuild/compilers/cs.py
index 843348e..bc917cb 100644
--- a/mesonbuild/compilers/cs.py
+++ b/mesonbuild/compilers/cs.py
@@ -15,7 +15,7 @@
import os.path, subprocess
import typing as T
-from ..mesonlib import EnvironmentException
+from ..mesonlib import Language, EnvironmentException
from .compilers import Compiler, MachineChoice, mono_buildtype_args
from .mixins.islinker import BasicLinkerIsCompilerMixin
@@ -34,7 +34,7 @@ cs_optimization_args = {'0': [],
class CsCompiler(BasicLinkerIsCompilerMixin, Compiler):
- language = 'cs'
+ language = Language.CS
def __init__(self, exelist, version, for_machine: MachineChoice,
info: 'MachineInfo', comp_id, runner=None):
diff --git a/mesonbuild/compilers/cuda.py b/mesonbuild/compilers/cuda.py
index 934ad12..b109572 100644
--- a/mesonbuild/compilers/cuda.py
+++ b/mesonbuild/compilers/cuda.py
@@ -18,9 +18,14 @@ from functools import partial
from .. import coredata
from .. import mlog
-from ..mesonlib import EnvironmentException, MachineChoice, Popen_safe, OptionOverrideProxy, is_windows, LibType
-from .compilers import (Compiler, cuda_buildtype_args, cuda_optimization_args,
- cuda_debug_args)
+from ..mesonlib import (
+ EnvironmentException, Language, LibType, MachineChoice, OptionOverrideProxy,
+ Popen_safe, is_windows
+)
+from .compilers import (
+ Compiler, cuda_buildtype_args, cuda_optimization_args,
+ cuda_debug_args
+)
if T.TYPE_CHECKING:
from ..environment import Environment # noqa: F401
@@ -30,7 +35,7 @@ if T.TYPE_CHECKING:
class CudaCompiler(Compiler):
LINKER_PREFIX = '-Xlinker='
- language = 'cuda'
+ language = Language.CUDA
_universal_flags = {'compiler': ['-I', '-D', '-U', '-E'], 'linker': ['-l', '-L']}
diff --git a/mesonbuild/compilers/d.py b/mesonbuild/compilers/d.py
index 32919e4..d233713 100644
--- a/mesonbuild/compilers/d.py
+++ b/mesonbuild/compilers/d.py
@@ -16,7 +16,7 @@ import os.path, subprocess
import typing as T
from ..mesonlib import (
- EnvironmentException, MachineChoice, version_compare,
+ EnvironmentException, Language, MachineChoice, version_compare,
)
from .compilers import (
@@ -436,7 +436,7 @@ class DCompiler(Compiler):
'mtd': ['-mscrtlib=libcmtd'],
}
- language = 'd'
+ language = Language.D
def __init__(self, exelist, version, for_machine: MachineChoice,
info: 'MachineInfo', arch, is_cross, exe_wrapper, **kwargs):
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index af83c0e56..31b8558 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -32,7 +32,7 @@ from .mixins.pgi import PGICompiler
from .. import mlog
from mesonbuild.mesonlib import (
- version_compare, EnvironmentException, MesonException, MachineChoice, LibType
+ version_compare, EnvironmentException, Language, MesonException, MachineChoice, LibType
)
if T.TYPE_CHECKING:
@@ -41,7 +41,7 @@ if T.TYPE_CHECKING:
class FortranCompiler(CLikeCompiler, Compiler):
- language = 'fortran'
+ language = Language.FORTRAN
def __init__(self, exelist, version, for_machine: MachineChoice,
is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs):
diff --git a/mesonbuild/compilers/java.py b/mesonbuild/compilers/java.py
index 5aeb250..c9a7af9 100644
--- a/mesonbuild/compilers/java.py
+++ b/mesonbuild/compilers/java.py
@@ -17,7 +17,7 @@ import shutil
import subprocess
import typing as T
-from ..mesonlib import EnvironmentException, MachineChoice
+from ..mesonlib import EnvironmentException, Language, MachineChoice
from .compilers import Compiler, java_buildtype_args
from .mixins.islinker import BasicLinkerIsCompilerMixin
@@ -26,7 +26,7 @@ if T.TYPE_CHECKING:
class JavaCompiler(BasicLinkerIsCompilerMixin, Compiler):
- language = 'java'
+ language = Language.JAVA
def __init__(self, exelist, version, for_machine: MachineChoice,
info: 'MachineInfo'):
diff --git a/mesonbuild/compilers/mixins/clike.py b/mesonbuild/compilers/mixins/clike.py
index 95b9592..a42b050 100644
--- a/mesonbuild/compilers/mixins/clike.py
+++ b/mesonbuild/compilers/mixins/clike.py
@@ -388,7 +388,7 @@ class CLikeCompiler:
cargs += cleaned_sys_args
if mode == 'link':
- ld_value = env.lookup_binary_entry(self.for_machine, self.language + '_ld')
+ ld_value = env.lookup_binary_entry(self.for_machine, self.language.get_lower_case_name() + '_ld')
if ld_value is not None:
largs += self.use_linker_args(ld_value[0])
diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py
index 83f7047..f5fd7ef 100644
--- a/mesonbuild/compilers/mixins/gnu.py
+++ b/mesonbuild/compilers/mixins/gnu.py
@@ -23,6 +23,7 @@ import subprocess
import typing as T
from ... import mesonlib
+from ...mesonlib import Language
from ... import mlog
if T.TYPE_CHECKING:
@@ -84,12 +85,12 @@ gnu_color_args = {
@functools.lru_cache(maxsize=None)
-def gnulike_default_include_dirs(compiler: T.Tuple[str], lang: str) -> T.List[str]:
+def gnulike_default_include_dirs(compiler: T.Tuple[str], lang: Language) -> T.List[str]:
lang_map = {
- 'c': 'c',
- 'cpp': 'c++',
- 'objc': 'objective-c',
- 'objcpp': 'objective-c++'
+ Language.C: 'c',
+ Language.CPP: 'c++',
+ Language.OBJC: 'objective-c',
+ Language.OBJCPP: 'objective-c++'
}
if lang not in lang_map:
return []
@@ -364,9 +365,9 @@ class GnuCompiler(GnuLikeCompiler):
# another language, but still complete with exit_success
with self._build_wrapper(code, env, args, None, mode) as p:
result = p.returncode == 0
- if self.language in {'cpp', 'objcpp'} and 'is valid for C/ObjC' in p.stde:
+ if self.language in {Language.CPP, Language.OBJCPP} and 'is valid for C/ObjC' in p.stde:
result = False
- if self.language in {'c', 'objc'} and 'is valid for C++/ObjC++' in p.stde:
+ if self.language in {Language.C, Language.OBJC} and 'is valid for C++/ObjC++' in p.stde:
result = False
return result, p.cached
diff --git a/mesonbuild/compilers/mixins/pgi.py b/mesonbuild/compilers/mixins/pgi.py
index 77a7a28..e5df38e 100644
--- a/mesonbuild/compilers/mixins/pgi.py
+++ b/mesonbuild/compilers/mixins/pgi.py
@@ -18,6 +18,7 @@ import typing as T
import os
from pathlib import Path
+from ...mesonlib import Language
from ..compilers import clike_debug_args, clike_optimization_args
pgi_buildtype_args = {
@@ -87,7 +88,7 @@ class PGICompiler:
def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]:
# PGI supports PCH for C++ only.
hdr = Path(pch_dir).resolve().parent / header
- if self.language == 'cpp':
+ if self.language == Language.CPP:
return ['--pch',
'--pch_dir', str(hdr.parent),
'-I{}'.format(hdr.parent)]
diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py
index d351c88..f642a1f 100644
--- a/mesonbuild/compilers/objc.py
+++ b/mesonbuild/compilers/objc.py
@@ -15,7 +15,7 @@
import os.path, subprocess
import typing as T
-from ..mesonlib import EnvironmentException, MachineChoice
+from ..mesonlib import EnvironmentException, Language, MachineChoice
from .compilers import Compiler
from .mixins.clike import CLikeCompiler
@@ -28,7 +28,7 @@ if T.TYPE_CHECKING:
class ObjCCompiler(CLikeCompiler, Compiler):
- language = 'objc'
+ language = Language.OBJC
def __init__(self, exelist, version, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo',
diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py
index 10555b4..871a0a6 100644
--- a/mesonbuild/compilers/objcpp.py
+++ b/mesonbuild/compilers/objcpp.py
@@ -15,7 +15,7 @@
import os.path, subprocess
import typing as T
-from ..mesonlib import EnvironmentException, MachineChoice
+from ..mesonlib import EnvironmentException, Language, MachineChoice
from .mixins.clike import CLikeCompiler
from .compilers import Compiler
@@ -27,7 +27,7 @@ if T.TYPE_CHECKING:
class ObjCPPCompiler(CLikeCompiler, Compiler):
- language = 'objcpp'
+ language = Language.OBJCPP
def __init__(self, exelist, version, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo',
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index c2e21c4..46832c5 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -15,7 +15,7 @@
import subprocess, os.path
import typing as T
-from ..mesonlib import EnvironmentException, MachineChoice, Popen_safe
+from ..mesonlib import EnvironmentException, Language, MachineChoice, Popen_safe
from .compilers import Compiler, rust_buildtype_args, clike_debug_args
if T.TYPE_CHECKING:
@@ -33,7 +33,7 @@ rust_optimization_args = {'0': [],
class RustCompiler(Compiler):
# rustc doesn't invoke the compiler itself, it doesn't need a LINKER_PREFIX
- language = 'rust'
+ language = Language.RUST
def __init__(self, exelist, version, for_machine: MachineChoice,
is_cross, info: 'MachineInfo', exe_wrapper=None, **kwargs):
diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py
index 1942120..c7d0041 100644
--- a/mesonbuild/compilers/swift.py
+++ b/mesonbuild/compilers/swift.py
@@ -15,7 +15,7 @@
import subprocess, os.path
import typing as T
-from ..mesonlib import EnvironmentException, MachineChoice
+from ..mesonlib import EnvironmentException, Language, MachineChoice
from .compilers import Compiler, swift_buildtype_args, clike_debug_args
@@ -33,7 +33,7 @@ swift_optimization_args = {'0': [],
class SwiftCompiler(Compiler):
LINKER_PREFIX = ['-Xlinker']
- language = 'swift'
+ language = Language.SWIFT
def __init__(self, exelist, version, for_machine: MachineChoice,
is_cross, info: 'MachineInfo', **kwargs):
diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py
index a5d49b6..635cce3 100644
--- a/mesonbuild/compilers/vala.py
+++ b/mesonbuild/compilers/vala.py
@@ -16,7 +16,7 @@ import os.path
import typing as T
from .. import mlog
-from ..mesonlib import EnvironmentException, MachineChoice, version_compare
+from ..mesonlib import EnvironmentException, Language, MachineChoice, version_compare
from .compilers import Compiler
@@ -25,7 +25,7 @@ if T.TYPE_CHECKING:
class ValaCompiler(Compiler):
- language = 'vala'
+ language = Language.VALA
def __init__(self, exelist, version, for_machine: MachineChoice,
is_cross, info: 'MachineInfo'):
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 724e111..f2f092b 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -19,7 +19,7 @@ from itertools import chain
from pathlib import PurePath
from collections import OrderedDict, defaultdict
from .mesonlib import (
- MesonException, EnvironmentException, MachineChoice, PerMachine,
+ Language, EnvironmentException, MesonException, MachineChoice, PerMachine, OrderedSet,
default_libdir, default_libexecdir, default_prefix, split_args
)
from .wrap import WrapMode
@@ -372,8 +372,8 @@ class CoreData:
self.compiler_options = PerMachine(
defaultdict(dict),
defaultdict(dict),
- ) # type: PerMachine[T.defaultdict[str, OptionDictType]]
- self.base_options = {} # type: OptionDictType
+ ) # type: PerMachine[T.defaultdict[Language, OptionDictType]]
+ self.base_options = {} # : OptionDictType
self.cross_files = self.__load_config_files(options, scratch_dir, 'cross')
self.compilers = PerMachine(OrderedDict(), OrderedDict())
@@ -623,29 +623,41 @@ class CoreData:
options_per_machine # : PerMachine[T.Dict[str, _V]]]
) -> T.Iterable[T.Tuple[str, _V]]:
return cls._flatten_pair_iterator(
- (for_machine.get_prefix(), options_per_machine[for_machine])
+ (for_machine.get_prefix(), options_per_machine[for_machine].items())
for for_machine in iter(MachineChoice)
)
@classmethod
def flatten_lang_iterator(
cls,
- outer # : T.Iterable[T.Tuple[str, T.Dict[str, _V]]]
+ outer # : T.Iterable[T.Tuple[Language, T.Dict[str, V]]]
) -> T.Iterable[T.Tuple[str, _V]]:
- return cls._flatten_pair_iterator((lang + '_', opts) for lang, opts in outer)
+ return cls._flatten_pair_iterator(
+ (lang.get_lower_case_name() + '_', inner.items())
+ for lang, inner in outer
+ )
+
+ @classmethod
+ def flatten_lang_iterator_per_machine(
+ cls,
+ outer # : PerMachine[Dict[Language, T.Dict[str, V]]]
+ ) -> T.Iterable[T.Tuple[str, _V]]:
+ cls.get_prefixed_options_per_machine(
+ outer.map(lambda opts_per_lang:
+ cls.flatten_lang_iterator(opts_per_lang)))
@staticmethod
def _flatten_pair_iterator(
- outer # : T.Iterable[T.Tuple[str, T.Dict[str, _V]]]
+ outer # : T.Iterable[T.Tuple[str, T.Iterable[T.Tuple[str, _V]]]]
) -> T.Iterable[T.Tuple[str, _V]]:
for k0, v0 in outer:
- for k1, v1 in v0.items():
+ for k1, v1 in v0:
yield (k0 + k1, v1)
def _get_all_nonbuiltin_options(self) -> T.Iterable[T.Dict[str, UserOption]]:
yield self.backend_options
yield self.user_options
- yield dict(self.flatten_lang_iterator(self.get_prefixed_options_per_machine(self.compiler_options)))
+ yield dict(flatten_lang_iterator_per_machine(self.compiler_options))
yield self.base_options
def _get_all_builtin_options(self) -> T.Iterable[T.Dict[str, UserOption]]:
@@ -667,10 +679,10 @@ class CoreData:
.with_traceback(sys.exc_info()[2])
raise MesonException('Tried to validate unknown option %s.' % option_name)
- def get_external_args(self, for_machine: MachineChoice, lang):
+ def get_external_args(self, for_machine: MachineChoice, lang: Language):
return self.compiler_options[for_machine][lang]['args'].value
- def get_external_link_args(self, for_machine: MachineChoice, lang):
+ def get_external_link_args(self, for_machine: MachineChoice, lang: Language):
return self.compiler_options[for_machine][lang]['link_args'].value
def merge_user_options(self, options):
@@ -790,7 +802,7 @@ class CoreData:
self.set_options(options, subproject=subproject)
- def add_lang_args(self, lang: str, comp: T.Type['Compiler'],
+ def add_lang_args(self, lang: Language, comp: T.Type['Compiler'],
for_machine: MachineChoice, env: 'Environment') -> None:
"""Add global language arguments that are needed before compiler/linker detection."""
from .compilers import compilers
@@ -806,7 +818,7 @@ class CoreData:
o.set_value(env.compiler_options[for_machine][lang][k])
self.compiler_options[for_machine][lang].setdefault(k, o)
- def process_new_compiler(self, lang: str, comp: 'Compiler', env: 'Environment') -> None:
+ def process_new_compiler(self, lang: Language, comp: 'Compiler', env: 'Environment') -> None:
from . import compilers
self.compilers[comp.for_machine][lang] = comp
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index c726a7e..3c204b9 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -35,9 +35,11 @@ from ..compilers import clib_langs
from ..envconfig import get_env_var
from ..environment import BinaryTable, Environment, MachineInfo
from ..cmake import CMakeExecutor, CMakeTraceParser, CMakeException
-from ..mesonlib import MachineChoice, MesonException, OrderedSet, PerMachine
-from ..mesonlib import Popen_safe, version_compare_many, version_compare, listify, stringlistify, extract_as_list, split_args
-from ..mesonlib import Version, LibType
+from ..mesonlib import (
+ Language, MachineChoice, MesonException, OrderedSet, PerMachine,
+ Popen_safe, version_compare_many, version_compare, listify, stringlistify, extract_as_list, split_args,
+ Version, LibType,
+)
from ..mesondata import mesondata
if T.TYPE_CHECKING:
@@ -709,7 +711,7 @@ class PkgConfigDependency(ExternalDependency):
def _set_cargs(self):
env = None
- if self.language == 'fortran':
+ if self.language == Language.FORTRAN:
# gfortran doesn't appear to look in system paths for INCLUDE files,
# so don't allow pkg-config to suppress -I flags for system paths
env = os.environ.copy()
@@ -1045,14 +1047,14 @@ class CMakeDependency(ExternalDependency):
else:
compilers = environment.coredata.compilers.host
- candidates = ['c', 'cpp', 'fortran', 'objc', 'objcxx']
+ candidates = [Language.C, Language.CPP, Language.FORTRAN, Language.OBJC, Language.OBJCPP]
self.language_list += [x for x in candidates if x in compilers]
else:
self.language_list += [language]
# Add additional languages if required
- if 'fortran' in self.language_list:
- self.language_list += ['c']
+ if Language.FORTRAN in self.language_list:
+ self.language_list += [Language.C]
# Ensure that the list is unique
self.language_list = list(set(self.language_list))
@@ -1586,7 +1588,7 @@ class DubDependency(ExternalDependency):
class_dubbin = None
def __init__(self, name, environment, kwargs):
- super().__init__('dub', environment, kwargs, language='d')
+ super().__init__('dub', environment, kwargs, language=Language.D)
self.name = name
self.compiler = super().get_compiler()
self.module_path = None
@@ -2095,8 +2097,8 @@ class ExternalLibrary(ExternalDependency):
'''
# Using a vala library in a non-vala target, or a non-vala library in a vala target
# XXX: This should be extended to other non-C linkers such as Rust
- if (self.language == 'vala' and language != 'vala') or \
- (language == 'vala' and self.language != 'vala'):
+ if (self.language == Language.VALA and language != Language.VALA) or \
+ (language == Language.VALA and self.language != Language.VALA):
return []
return super().get_link_args(**kwargs)
@@ -2566,7 +2568,7 @@ def detect_compiler(name: str, env: Environment, for_machine: MachineChoice,
if language not in compilers:
m = name.capitalize() + ' requires a {0} compiler, but ' \
'{0} is not in the list of project languages'
- raise DependencyException(m.format(language.capitalize()))
+ raise DependencyException(m.format(language.get_display_name()))
return compilers[language]
else:
for lang in clib_langs:
diff --git a/mesonbuild/dependencies/boost.py b/mesonbuild/dependencies/boost.py
index 3ad534e..3dd0fd6 100644
--- a/mesonbuild/dependencies/boost.py
+++ b/mesonbuild/dependencies/boost.py
@@ -340,7 +340,7 @@ class BoostLibraryFile():
class BoostDependency(ExternalDependency):
def __init__(self, environment: Environment, kwargs):
- super().__init__('boost', environment, kwargs, language='cpp')
+ super().__init__('boost', environment, kwargs, language=Language.CPP)
self.debug = environment.coredata.get_builtin_option('buildtype').startswith('debug')
self.multithreading = kwargs.get('threading', 'multi') == 'multi'
diff --git a/mesonbuild/dependencies/coarrays.py b/mesonbuild/dependencies/coarrays.py
index 84c3412..cbed98e 100644
--- a/mesonbuild/dependencies/coarrays.py
+++ b/mesonbuild/dependencies/coarrays.py
@@ -25,7 +25,7 @@ if T.TYPE_CHECKING:
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE, DependencyMethods.SYSTEM})
def coarray_factory(env: 'Environment', for_machine: 'MachineChoice',
kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List['DependencyType']:
- fcid = detect_compiler('coarray', env, for_machine, 'fortran').get_id()
+ fcid = detect_compiler('coarray', env, for_machine, Language.FORTRAN).get_id()
candidates = [] # type: T.List[DependencyType]
if fcid == 'gcc':
@@ -33,13 +33,13 @@ def coarray_factory(env: 'Environment', for_machine: 'MachineChoice',
if DependencyMethods.PKGCONFIG in methods:
for pkg in ['caf-openmpi', 'caf']:
candidates.append(functools.partial(
- PkgConfigDependency, pkg, env, kwargs, language='fortran'))
+ PkgConfigDependency, pkg, env, kwargs, language=Language.FORTRAN))
if DependencyMethods.CMAKE in methods:
if 'modules' not in kwargs:
kwargs['modules'] = 'OpenCoarrays::caf_mpi'
candidates.append(functools.partial(
- CMakeDependency, 'OpenCoarrays', env, kwargs, language='fortran'))
+ CMakeDependency, 'OpenCoarrays', env, kwargs, language=Language.FORTRAN))
if DependencyMethods.SYSTEM in methods:
candidates.append(functools.partial(CoarrayDependency, env, kwargs))
@@ -57,7 +57,7 @@ class CoarrayDependency(ExternalDependency):
low-level MPI calls.
"""
def __init__(self, environment, kwargs: dict):
- super().__init__('coarray', environment, kwargs, language='fortran')
+ super().__init__('coarray', environment, kwargs, language=Language.FORTRAN)
kwargs['required'] = False
kwargs['silent'] = True
diff --git a/mesonbuild/dependencies/cuda.py b/mesonbuild/dependencies/cuda.py
index c962cae..d197f8c 100644
--- a/mesonbuild/dependencies/cuda.py
+++ b/mesonbuild/dependencies/cuda.py
@@ -18,6 +18,7 @@ import os
from .. import mlog
from .. import mesonlib
+from ..mesonlib import Language
from ..environment import detect_cpu_family
from .base import (DependencyException, ExternalDependency)
@@ -25,7 +26,7 @@ from .base import (DependencyException, ExternalDependency)
class CudaDependency(ExternalDependency):
- supported_languages = ['cuda', 'cpp', 'c'] # see also _default_language
+ supported_languages = [Language.CUDA, Language.CPP, Language.C] # see also _default_language
def __init__(self, environment, kwargs):
compilers = environment.coredata.compilers[self.get_for_machine_from_kwargs(kwargs)]
@@ -33,7 +34,7 @@ class CudaDependency(ExternalDependency):
if language not in self.supported_languages:
raise DependencyException('Language \'{}\' is not supported by the CUDA Toolkit. Supported languages are {}.'.format(language, self.supported_languages))
- super().__init__('cuda', environment, kwargs, language=language)
+ super().__init__(Language.CUDA, environment, kwargs, language=language)
self.requested_modules = self.get_requested(kwargs)
if 'cudart' not in self.requested_modules:
self.requested_modules = ['cudart'] + self.requested_modules
@@ -47,11 +48,11 @@ class CudaDependency(ExternalDependency):
# nvcc already knows where to find the CUDA Toolkit, but if we're compiling
# a mixed C/C++/CUDA project, we still need to make the include dir searchable
- if self.language != 'cuda' or len(compilers) > 1:
+ if self.language != Language.CUDA or len(compilers) > 1:
self.incdir = os.path.join(self.cuda_path, 'include')
self.compile_args += ['-I{}'.format(self.incdir)]
- if self.language != 'cuda':
+ if self.language != Language.CUDA:
arch_libdir = self._detect_arch_libdir()
self.libdir = os.path.join(self.cuda_path, arch_libdir)
mlog.debug('CUDA library directory is', mlog.bold(self.libdir))
@@ -72,7 +73,7 @@ class CudaDependency(ExternalDependency):
mlog.debug('Default path env var:', mlog.bold(self.env_var))
version_reqs = self.version_reqs
- if self.language == 'cuda':
+ if self.language == Language.CUDA:
nvcc_version = self._strip_patch_version(self.get_compiler().version)
mlog.debug('nvcc version:', mlog.bold(nvcc_version))
if version_reqs:
@@ -144,7 +145,7 @@ class CudaDependency(ExternalDependency):
def _cuda_paths_nix(self):
# include /usr/local/cuda default only if no env_var was found
pattern = '/usr/local/cuda-*' if self.env_var else '/usr/local/cuda*'
- return [(path, os.path.basename(path) == 'cuda') for path in glob.iglob(pattern)]
+ return [(path, os.path.basename(path) == Language.CUDA) for path in glob.iglob(pattern)]
toolkit_version_regex = re.compile(r'^CUDA Version\s+(.*)$')
path_version_win_regex = re.compile(r'^v(.*)$')
diff --git a/mesonbuild/dependencies/dev.py b/mesonbuild/dependencies/dev.py
index 67d7e65..c9c5d96 100644
--- a/mesonbuild/dependencies/dev.py
+++ b/mesonbuild/dependencies/dev.py
@@ -49,7 +49,7 @@ def get_shared_library_suffix(environment, for_machine: MachineChoice):
class GTestDependencySystem(ExternalDependency):
def __init__(self, name: str, environment, kwargs):
- super().__init__(name, environment, kwargs, language='cpp')
+ super().__init__(name, environment, kwargs, language=Language.CPP)
self.main = kwargs.get('main', False)
self.src_dirs = ['/usr/src/gtest/src', '/usr/src/googletest/googletest/src']
if not self._add_sub_dependency(threads_factory(environment, self.for_machine, {})):
@@ -119,7 +119,7 @@ class GTestDependencyPC(PkgConfigDependency):
class GMockDependencySystem(ExternalDependency):
def __init__(self, name: str, environment, kwargs):
- super().__init__(name, environment, kwargs, language='cpp')
+ super().__init__(name, environment, kwargs, language=Language.CPP)
self.main = kwargs.get('main', False)
if not self._add_sub_dependency(threads_factory(environment, self.for_machine, {})):
self.is_found = False
@@ -214,7 +214,7 @@ class LLVMDependencyConfigTool(ConfigToolDependency):
# It's necessary for LLVM <= 3.8 to use the C++ linker. For 3.9 and 4.0
# the C linker works fine if only using the C API.
- super().__init__(name, environment, kwargs, language='cpp')
+ super().__init__(name, environment, kwargs, language=Language.CPP)
self.provided_modules = []
self.required_modules = set()
self.module_details = []
@@ -251,7 +251,7 @@ class LLVMDependencyConfigTool(ConfigToolDependency):
"-L IBPATH:...", if we're using an msvc like compilers convert
that to "/LIBPATH", otherwise to "-L ..."
"""
- cpp = self.env.coredata.compilers[self.for_machine]['cpp']
+ cpp = self.env.coredata.compilers[self.for_machine][Language.CPP]
new_args = []
for arg in args:
@@ -391,7 +391,7 @@ class LLVMDependencyCMake(CMakeDependency):
def __init__(self, name: str, env, kwargs):
self.llvm_modules = stringlistify(extract_as_list(kwargs, 'modules'))
self.llvm_opt_modules = stringlistify(extract_as_list(kwargs, 'optional_modules'))
- super().__init__(name, env, kwargs, language='cpp')
+ super().__init__(name, env, kwargs, language=Language.CPP)
# Cmake will always create a statically linked binary, so don't use
# cmake if dynamic is required
diff --git a/mesonbuild/dependencies/hdf5.py b/mesonbuild/dependencies/hdf5.py
index fadd109..36b258b 100644
--- a/mesonbuild/dependencies/hdf5.py
+++ b/mesonbuild/dependencies/hdf5.py
@@ -26,14 +26,14 @@ from .base import (DependencyException, DependencyMethods, ExternalDependency, E
class HDF5Dependency(ExternalDependency):
def __init__(self, environment, kwargs):
- language = kwargs.get('language', 'c')
+ language = kwargs.get('language', Language.C)
super().__init__('hdf5', environment, kwargs, language=language)
kwargs['required'] = False
kwargs['silent'] = True
self.is_found = False
methods = listify(self.methods)
- if language not in ('c', 'cpp', 'fortran'):
+ if language not in (Language.C, Language.CPP, Language.FORTRAN):
raise DependencyException('Language {} is not supported with HDF5.'.format(language))
if set([DependencyMethods.AUTO, DependencyMethods.PKGCONFIG]).intersection(methods):
@@ -74,9 +74,9 @@ class HDF5Dependency(ExternalDependency):
# additionally, some pkgconfig HDF5 HL files are malformed so let's be sure to find HL anyway
if lpath.is_file():
hl = []
- if language == 'cpp':
+ if language == Language.CPP:
hl += ['_hl_cpp', '_cpp']
- elif language == 'fortran':
+ elif language == Language.FORTRAN:
hl += ['_hl_fortran', 'hl_fortran', '_fortran']
hl += ['_hl'] # C HL library, always needed
@@ -97,11 +97,11 @@ class HDF5Dependency(ExternalDependency):
return
if DependencyMethods.AUTO in methods:
- wrappers = {'c': 'h5cc', 'cpp': 'h5c++', 'fortran': 'h5fc'}
+ wrappers = {Language.C: 'h5cc', Language.CPP: 'h5c++', Language.FORTRAN: 'h5fc'}
comp_args = []
link_args = []
# have to always do C as well as desired language
- for lang in set([language, 'c']):
+ for lang in set([language, Language.C]):
prog = ExternalProgram(wrappers[lang], silent=True)
if not prog.found():
return
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index 47694af..f19566b 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -38,14 +38,14 @@ if T.TYPE_CHECKING:
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CMAKE})
def netcdf_factory(env: 'Environment', for_machine: 'MachineChoice',
kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List['DependencyType']:
- language = kwargs.get('language', 'c')
- if language not in ('c', 'cpp', 'fortran'):
+ language = kwargs.get('language', Language.C)
+ if language not in (Language.C, Language.CPP, Language.FORTRAN):
raise DependencyException('Language {} is not supported with NetCDF.'.format(language))
candidates = [] # type: T.List['DependencyType']
if DependencyMethods.PKGCONFIG in methods:
- if language == 'fortran':
+ if language == Language.FORTRAN:
pkg = 'netcdf-fortran'
else:
pkg = 'netcdf'
diff --git a/mesonbuild/dependencies/mpi.py b/mesonbuild/dependencies/mpi.py
index a20fb9c..ac97647 100644
--- a/mesonbuild/dependencies/mpi.py
+++ b/mesonbuild/dependencies/mpi.py
@@ -30,8 +30,8 @@ if T.TYPE_CHECKING:
@factory_methods({DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL, DependencyMethods.SYSTEM})
def mpi_factory(env: 'Environment', for_machine: 'MachineChoice',
kwargs: T.Dict[str, T.Any], methods: T.List[DependencyMethods]) -> T.List['DependencyType']:
- language = kwargs.get('language', 'c')
- if language not in {'c', 'cpp', 'fortran'}:
+ language = kwargs.get('language', Language.C)
+ if language not in {Language.C, Language.CPP, Language.FORTRAN}:
# OpenMPI doesn't work without any other languages
return []
@@ -42,11 +42,11 @@ def mpi_factory(env: 'Environment', for_machine: 'MachineChoice',
# Only OpenMPI has pkg-config, and it doesn't work with the intel compilers
if DependencyMethods.PKGCONFIG in methods and not compiler_is_intel:
pkg_name = None
- if language == 'c':
+ if language == Language.C:
pkg_name = 'ompi-c'
- elif language == 'cpp':
+ elif language == Language.CPP:
pkg_name = 'ompi-cxx'
- elif language == 'fortran':
+ elif language == Language.FORTRAN:
pkg_name = 'ompi-fort'
candidates.append(functools.partial(
PkgConfigDependency, pkg_name, env, kwargs, language=language))
@@ -59,11 +59,11 @@ def mpi_factory(env: 'Environment', for_machine: 'MachineChoice',
nwargs['version_arg'] = '-v'
nwargs['returncode_value'] = 3
- if language == 'c':
+ if language == Language.C:
tool_names = [os.environ.get('I_MPI_CC'), 'mpiicc']
- elif language == 'cpp':
+ elif language == Language.CPP:
tool_names = [os.environ.get('I_MPI_CXX'), 'mpiicpc']
- elif language == 'fortran':
+ elif language == Language.FORTRAN:
tool_names = [os.environ.get('I_MPI_F90'), 'mpiifort']
cls = IntelMPIConfigToolDependency # type: T.Type[ConfigToolDependency]
@@ -71,11 +71,11 @@ def mpi_factory(env: 'Environment', for_machine: 'MachineChoice',
#
# We try the environment variables for the tools first, but then
# fall back to the hardcoded names
- if language == 'c':
+ if language == Language.C:
tool_names = [os.environ.get('MPICC'), 'mpicc']
- elif language == 'cpp':
+ elif language == Language.CPP:
tool_names = [os.environ.get('MPICXX'), 'mpic++', 'mpicxx', 'mpiCC']
- elif language == 'fortran':
+ elif language == Language.FORTRAN:
tool_names = [os.environ.get(e) for e in ['MPIFC', 'MPIF90', 'MPIF77']]
tool_names.extend(['mpifort', 'mpif90', 'mpif77'])
@@ -104,8 +104,8 @@ class _MPIConfigToolDependency(ConfigToolDependency):
"""
result = []
multi_args = ('-I', )
- if self.language == 'fortran':
- fc = self.env.coredata.compilers[self.for_machine]['fortran']
+ if self.language == Language.FORTRAN:
+ fc = self.env.coredata.compilers[self.for_machine][Language.FORTRAN]
multi_args += fc.get_module_incdir_args()
include_next = False
@@ -203,7 +203,7 @@ class MSMPIDependency(ExternalDependency):
language: T.Optional[str] = None):
super().__init__(name, env, kwargs, language=language)
# MSMPI only supports the C API
- if language not in {'c', 'fortran', None}:
+ if language not in {Language.C, Language.FORTRAN, None}:
self.is_found = False
return
# MSMPI is only for windows, obviously
@@ -227,5 +227,5 @@ class MSMPIDependency(ExternalDependency):
self.is_found = True
self.link_args = ['-l' + os.path.join(libdir, 'msmpi')]
self.compile_args = ['-I' + incdir, '-I' + os.path.join(incdir, post)]
- if self.language == 'fortran':
+ if self.language == Language.FORTRAN:
self.link_args.append('-l' + os.path.join(libdir, 'msmpifec'))
diff --git a/mesonbuild/dependencies/scalapack.py b/mesonbuild/dependencies/scalapack.py
index 8774746..0d295c5 100644
--- a/mesonbuild/dependencies/scalapack.py
+++ b/mesonbuild/dependencies/scalapack.py
@@ -134,7 +134,7 @@ class MKLPkgConfigDependency(PkgConfigDependency):
def _set_cargs(self):
env = None
- if self.language == 'fortran':
+ if self.language == Language.FORTRAN:
# gfortran doesn't appear to look in system paths for INCLUDE files,
# so don't allow pkg-config to suppress -I flags for system paths
env = os.environ.copy()
diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py
index 95dfe2b..fc0824c 100644
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -71,7 +71,7 @@ class GnuStepDependency(ConfigToolDependency):
tool_name = 'gnustep-config'
def __init__(self, environment, kwargs):
- super().__init__('gnustep', environment, kwargs, language='objc')
+ super().__init__('gnustep', environment, kwargs, language=Language.OBJC)
if not self.is_found:
return
self.modules = kwargs.get('modules', [])
@@ -183,7 +183,7 @@ class QtExtraFrameworkDependency(ExtraFrameworkDependency):
class QtBaseDependency(ExternalDependency):
def __init__(self, name, env, kwargs):
- super().__init__(name, env, kwargs, language='cpp')
+ super().__init__(name, env, kwargs, language=Language.CPP)
self.qtname = name.capitalize()
self.qtver = name[-1]
if self.qtver == "4":
@@ -570,7 +570,7 @@ class WxDependency(ConfigToolDependency):
tool_name = 'wx-config'
def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
- super().__init__('WxWidgets', environment, kwargs, language='cpp')
+ super().__init__('WxWidgets', environment, kwargs, language=Language.CPP)
if not self.is_found:
return
self.requested_modules = self.get_requested(kwargs)
diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py
index 9402d38..7d87fb7 100644
--- a/mesonbuild/envconfig.py
+++ b/mesonbuild/envconfig.py
@@ -127,13 +127,13 @@ class Properties:
self.properties = properties or {} # type: T.Dict[str, T.Union[str, T.List[str]]]
def has_stdlib(self, language: str) -> bool:
- return language + '_stdlib' in self.properties
+ return language.get_lower_case_name() + '_stdlib' in self.properties
# Some of get_stdlib, get_root, get_sys_root are wider than is actually
# true, but without heterogenious dict annotations it's not practical to
# narrow them
def get_stdlib(self, language: str) -> T.Union[str, T.List[str]]:
- return self.properties[language + '_stdlib']
+ return self.properties[language.get_lower_case_name() + '_stdlib']
def get_root(self) -> T.Optional[T.Union[str, T.List[str]]]:
return self.properties.get('root', None)
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index bf75c80..7cb7286 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -22,7 +22,7 @@ from . import coredata
from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker, CcrxLinker, Xc16Linker, C2000Linker, IntelVisualStudioLinker
from . import mesonlib
from .mesonlib import (
- MesonException, EnvironmentException, MachineChoice, Popen_safe,
+ MesonException, EnvironmentException, Language, MachineChoice, Popen_safe,
PerMachineDefaultable, PerThreeMachineDefaultable, split_args, quote_arg
)
from . import mlog
@@ -921,7 +921,7 @@ class Environment:
else:
if not self.machines.matches_build_machine(for_machine):
raise EnvironmentException('{!r} compiler binary not defined in cross or native file'.format(lang))
- compilers = getattr(self, 'default_' + lang)
+ compilers = getattr(self, 'default_' + lang.get_lower_case_name())
ccache = BinaryTable.detect_ccache()
if self.machines.matches_build_machine(for_machine):
@@ -956,7 +956,7 @@ class Environment:
check_args += self.coredata.compiler_options[for_machine][comp_class.language]['args'].value
override = [] # type: T.List[str]
- value = self.lookup_binary_entry(for_machine, comp_class.language + '_ld')
+ value = self.lookup_binary_entry(for_machine, comp_class.language.get_lower_case_name() + '_ld')
if value is not None:
override = comp_class.use_linker_args(value[0])
check_args += override
@@ -1023,7 +1023,7 @@ class Environment:
check_args = comp_class.LINKER_PREFIX + ['--version'] + extra_args
override = [] # type: T.List[str]
- value = self.lookup_binary_entry(for_machine, comp_class.language + '_ld')
+ value = self.lookup_binary_entry(for_machine, comp_class.language.get_lower_case_name() + '_ld')
if value is not None:
override = comp_class.use_linker_args(value[0])
check_args += override
@@ -1087,7 +1087,7 @@ class Environment:
raise EnvironmentException('Unable to determine dynamic linker')
return linker
- def _detect_c_or_cpp_compiler(self, lang: str, for_machine: MachineChoice) -> Compiler:
+ def _detect_c_or_cpp_compiler(self, lang: Language, for_machine: MachineChoice) -> Compiler:
popen_exceptions = {}
compilers, ccache, exe_wrap = self._get_compilers(lang, for_machine)
is_cross = self.is_cross_build(for_machine)
@@ -1161,10 +1161,10 @@ class Environment:
if guess_gcc_or_lcc == 'lcc':
version = self.get_lcc_version_from_defines(defines)
- cls = ElbrusCCompiler if lang == 'c' else ElbrusCPPCompiler
+ cls = ElbrusCCompiler if lang == Language.C else ElbrusCPPCompiler
else:
version = self.get_gnu_version_from_defines(defines)
- cls = GnuCCompiler if lang == 'c' else GnuCPPCompiler
+ cls = GnuCCompiler if lang == Language.C else GnuCPPCompiler
linker = self._guess_nix_linker(compiler, cls, for_machine)
@@ -1174,7 +1174,7 @@ class Environment:
linker=linker)
if 'Emscripten' in out:
- cls = EmscriptenCCompiler if lang == 'c' else EmscriptenCPPCompiler
+ cls = EmscriptenCCompiler if lang == Language.C else EmscriptenCPPCompiler
self.coredata.add_lang_args(cls.language, cls, for_machine, self)
# emcc requires a file input in order to pass arguments to the
@@ -1206,7 +1206,7 @@ class Environment:
# Override previous values
version = search_version(arm_ver_str)
full_version = arm_ver_str
- cls = ArmclangCCompiler if lang == 'c' else ArmclangCPPCompiler
+ cls = ArmclangCCompiler if lang == Language.C else ArmclangCPPCompiler
linker = ArmClangDynamicLinker(for_machine, version=version)
self.coredata.add_lang_args(cls.language, cls, for_machine, self)
return cls(
@@ -1226,7 +1226,7 @@ class Environment:
target = match.group(1)
else:
target = 'unknown target'
- cls = ClangClCCompiler if lang == 'c' else ClangClCPPCompiler
+ cls = ClangClCCompiler if lang == Language.C else ClangClCPPCompiler
linker = self._guess_win_linker(['lld-link'], cls, for_machine)
return cls(
compiler, version, for_machine, is_cross, info, exe_wrap,
@@ -1239,9 +1239,9 @@ class Environment:
# Even if the for_machine is darwin, we could be using vanilla
# clang.
if 'Apple' in out:
- cls = AppleClangCCompiler if lang == 'c' else AppleClangCPPCompiler
+ cls = AppleClangCCompiler if lang == Language.C else AppleClangCPPCompiler
else:
- cls = ClangCCompiler if lang == 'c' else ClangCPPCompiler
+ cls = ClangCCompiler if lang == Language.C else ClangCPPCompiler
if 'windows' in out or self.machines[for_machine].is_windows():
# If we're in a MINGW context this actually will use a gnu
@@ -1261,7 +1261,7 @@ class Environment:
if 'Intel(R) C++ Intel(R)' in err:
version = search_version(err)
target = 'x86' if 'IA-32' in err else 'x86_64'
- cls = IntelClCCompiler if lang == 'c' else IntelClCPPCompiler
+ cls = IntelClCCompiler if lang == Language.C else IntelClCPPCompiler
self.coredata.add_lang_args(cls.language, cls, for_machine, self)
linker = XilinkDynamicLinker(for_machine, [], version=version)
return cls(
@@ -1286,33 +1286,33 @@ class Environment:
else:
m = 'Failed to detect MSVC compiler target architecture: \'cl /?\' output is\n{}'
raise EnvironmentException(m.format(cl_signature))
- cls = VisualStudioCCompiler if lang == 'c' else VisualStudioCPPCompiler
+ cls = VisualStudioCCompiler if lang == Language.C else VisualStudioCPPCompiler
linker = self._guess_win_linker(['link'], cls, for_machine)
return cls(
compiler, version, for_machine, is_cross, info, exe_wrap,
target, linker=linker)
if 'PGI Compilers' in out:
- cls = PGICCompiler if lang == 'c' else PGICPPCompiler
+ cls = PGICCompiler if lang == Language.C else PGICPPCompiler
self.coredata.add_lang_args(cls.language, cls, for_machine, self)
linker = PGIDynamicLinker(compiler, for_machine, cls.LINKER_PREFIX, [], version=version)
return cls(
ccache + compiler, version, for_machine, is_cross,
info, exe_wrap, linker=linker)
if '(ICC)' in out:
- cls = IntelCCompiler if lang == 'c' else IntelCPPCompiler
+ cls = IntelCCompiler if lang == Language.C else IntelCPPCompiler
l = self._guess_nix_linker(compiler, cls, for_machine)
return cls(
ccache + compiler, version, for_machine, is_cross, info,
exe_wrap, full_version=full_version, linker=l)
if 'ARM' in out:
- cls = ArmCCompiler if lang == 'c' else ArmCPPCompiler
+ cls = ArmCCompiler if lang == Language.C else ArmCPPCompiler
self.coredata.add_lang_args(cls.language, cls, for_machine, self)
linker = ArmDynamicLinker(for_machine, version=version)
return cls(
ccache + compiler, version, for_machine, is_cross,
info, exe_wrap, full_version=full_version, linker=linker)
if 'RX Family' in out:
- cls = CcrxCCompiler if lang == 'c' else CcrxCPPCompiler
+ cls = CcrxCCompiler if lang == Language.C else CcrxCPPCompiler
self.coredata.add_lang_args(cls.language, cls, for_machine, self)
linker = CcrxDynamicLinker(for_machine, version=version)
return cls(
@@ -1320,7 +1320,7 @@ class Environment:
exe_wrap, full_version=full_version, linker=linker)
if 'Microchip Technology' in out:
- cls = Xc16CCompiler if lang == 'c' else Xc16CCompiler
+ cls = Xc16CCompiler if lang == Language.C else Xc16CCompiler
self.coredata.add_lang_args(cls.language, cls, for_machine, self)
linker = Xc16DynamicLinker(for_machine, version=version)
return cls(
@@ -1328,7 +1328,7 @@ class Environment:
exe_wrap, full_version=full_version, linker=linker)
if 'TMS320C2000 C/C++' in out:
- cls = C2000CCompiler if lang == 'c' else C2000CPPCompiler
+ cls = C2000CCompiler if lang == Language.C else C2000CPPCompiler
self.coredata.add_lang_args(cls.language, cls, for_machine, self)
linker = C2000DynamicLinker(for_machine, version=version)
return cls(
@@ -1338,15 +1338,15 @@ class Environment:
self._handle_exceptions(popen_exceptions, compilers)
def detect_c_compiler(self, for_machine):
- return self._detect_c_or_cpp_compiler('c', for_machine)
+ return self._detect_c_or_cpp_compiler(Language.C, for_machine)
def detect_cpp_compiler(self, for_machine):
- return self._detect_c_or_cpp_compiler('cpp', for_machine)
+ return self._detect_c_or_cpp_compiler(Language.CPP, for_machine)
def detect_cuda_compiler(self, for_machine):
popen_exceptions = {}
is_cross = self.is_cross_build(for_machine)
- compilers, ccache, exe_wrap = self._get_compilers('cuda', for_machine)
+ compilers, ccache, exe_wrap = self._get_compilers(Language.CUDA, for_machine)
info = self.machines[for_machine]
for compiler in compilers:
if isinstance(compiler, str):
@@ -1384,7 +1384,7 @@ class Environment:
def detect_fortran_compiler(self, for_machine: MachineChoice):
popen_exceptions = {}
- compilers, ccache, exe_wrap = self._get_compilers('fortran', for_machine)
+ compilers, ccache, exe_wrap = self._get_compilers(Language.FORTRAN, for_machine)
is_cross = self.is_cross_build(for_machine)
info = self.machines[for_machine]
for compiler in compilers:
@@ -1503,7 +1503,7 @@ class Environment:
def _detect_objc_or_objcpp_compiler(self, for_machine: MachineInfo, objc: bool) -> 'Compiler':
popen_exceptions = {}
- compilers, ccache, exe_wrap = self._get_compilers('objc' if objc else 'objcpp', for_machine)
+ compilers, ccache, exe_wrap = self._get_compilers(Language.OBJC if objc else Language.OBJCPP, for_machine)
is_cross = self.is_cross_build(for_machine)
info = self.machines[for_machine]
@@ -1547,7 +1547,7 @@ class Environment:
self._handle_exceptions(popen_exceptions, compilers)
def detect_java_compiler(self, for_machine):
- exelist = self.lookup_binary_entry(for_machine, 'java')
+ exelist = self.lookup_binary_entry(for_machine, Language.JAVA)
info = self.machines[for_machine]
if exelist is None:
# TODO support fallback
@@ -1569,7 +1569,7 @@ class Environment:
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
def detect_cs_compiler(self, for_machine):
- compilers, ccache, exe_wrap = self._get_compilers('cs', for_machine)
+ compilers, ccache, exe_wrap = self._get_compilers(Language.CS, for_machine)
popen_exceptions = {}
info = self.machines[for_machine]
for comp in compilers:
@@ -1594,7 +1594,7 @@ class Environment:
self._handle_exceptions(popen_exceptions, compilers)
def detect_vala_compiler(self, for_machine):
- exelist = self.lookup_binary_entry(for_machine, 'vala')
+ exelist = self.lookup_binary_entry(for_machine, Language.VALA)
is_cross = self.is_cross_build(for_machine)
info = self.machines[for_machine]
if exelist is None:
@@ -1614,7 +1614,7 @@ class Environment:
def detect_rust_compiler(self, for_machine):
popen_exceptions = {}
- compilers, ccache, exe_wrap = self._get_compilers('rust', for_machine)
+ compilers, ccache, exe_wrap = self._get_compilers(Language.RUST, for_machine)
is_cross = self.is_cross_build(for_machine)
info = self.machines[for_machine]
@@ -1696,8 +1696,8 @@ class Environment:
# Detect the target architecture, required for proper architecture handling on Windows.
# MSVC compiler is required for correct platform detection.
- c_compiler = {'c': self.detect_c_compiler(for_machine)}
- is_msvc = isinstance(c_compiler['c'], VisualStudioCCompiler)
+ c_compiler = {Language.C: self.detect_c_compiler(for_machine)}
+ is_msvc = isinstance(c_compiler[Language.C], VisualStudioCCompiler)
if not is_msvc:
c_compiler = {}
@@ -1707,7 +1707,7 @@ class Environment:
popen_exceptions = {}
is_cross = self.is_cross_build(for_machine)
- results, ccache, exe_wrap = self._get_compilers('d', for_machine)
+ results, ccache, exe_wrap = self._get_compilers(Language.D, for_machine)
for exelist in results:
# Search for a D compiler.
# We prefer LDC over GDC unless overridden with the DC
@@ -1796,7 +1796,7 @@ class Environment:
self._handle_exceptions(popen_exceptions, compilers)
def detect_swift_compiler(self, for_machine):
- exelist = self.lookup_binary_entry(for_machine, 'swift')
+ exelist = self.lookup_binary_entry(for_machine, Language.SWIFT)
is_cross = self.is_cross_build(for_machine)
info = self.machines[for_machine]
if exelist is None:
@@ -1819,36 +1819,36 @@ class Environment:
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
- def compiler_from_language(self, lang: str, for_machine: MachineChoice):
- if lang == 'c':
+ def compiler_from_language(self, lang: Language, for_machine: MachineChoice):
+ if lang == Language.C:
comp = self.detect_c_compiler(for_machine)
- elif lang == 'cpp':
+ elif lang == Language.CPP:
comp = self.detect_cpp_compiler(for_machine)
- elif lang == 'objc':
+ elif lang == Language.OBJC:
comp = self.detect_objc_compiler(for_machine)
- elif lang == 'cuda':
+ elif lang == Language.CUDA:
comp = self.detect_cuda_compiler(for_machine)
- elif lang == 'objcpp':
+ elif lang == Language.OBJCPP:
comp = self.detect_objcpp_compiler(for_machine)
- elif lang == 'java':
+ elif lang == Language.JAVA:
comp = self.detect_java_compiler(for_machine)
- elif lang == 'cs':
+ elif lang == Language.CS:
comp = self.detect_cs_compiler(for_machine)
- elif lang == 'vala':
+ elif lang == Language.VALA:
comp = self.detect_vala_compiler(for_machine)
- elif lang == 'd':
+ elif lang == Language.D:
comp = self.detect_d_compiler(for_machine)
- elif lang == 'rust':
+ elif lang == Language.RUST:
comp = self.detect_rust_compiler(for_machine)
- elif lang == 'fortran':
+ elif lang == Language.FORTRAN:
comp = self.detect_fortran_compiler(for_machine)
- elif lang == 'swift':
+ elif lang == Language.SWIFT:
comp = self.detect_swift_compiler(for_machine)
else:
comp = None
return comp
- def detect_compiler_for(self, lang: str, for_machine: MachineChoice):
+ def detect_compiler_for(self, lang: Language, for_machine: MachineChoice):
comp = self.compiler_from_language(lang, for_machine)
if comp is not None:
assert comp.for_machine == for_machine
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index cf7f282..4d541bf 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -21,7 +21,10 @@ from . import optinterpreter
from . import compilers
from .wrap import wrap, WrapMode
from . import mesonlib
-from .mesonlib import FileMode, MachineChoice, Popen_safe, listify, extract_as_list, has_path_sep, unholder
+from .mesonlib import (
+ FileMode, Language, MachineChoice, Popen_safe,
+ listify, extract_as_list, has_path_sep, unholder,
+)
from .dependencies import ExternalProgram
from .dependencies import InternalDependency, Dependency, NotFoundDependency, DependencyException
from .depfile import DepFile
@@ -2082,12 +2085,13 @@ class MesonMain(InterpreterObject):
def get_compiler_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('get_compiler_method must have one and only one argument.')
- cname = args[0]
+ cname = Language.from_lower_case_name(args[0])
+ if cname is None:
+ raise InterpreterException('Tried to access compiler for unspecified language "%s".' % cname)
for_machine = Interpreter.machine_from_native_kwarg(kwargs)
clist = self.interpreter.coredata.compilers[for_machine]
- if cname in clist:
- return CompilerHolder(clist[cname], self.build.environment, self.interpreter.subproject)
- raise InterpreterException('Tried to access compiler for unspecified language "%s".' % cname)
+ assert cname in clist
+ return CompilerHolder(clist[cname], self.build.environment, self.interpreter.subproject)
@noPosargs
@permittedKwargs({})
@@ -2950,8 +2954,7 @@ external dependencies (including libraries) must go to "dependencies".''')
for opts in [
self.coredata.base_options, compilers.base_options, self.coredata.builtins,
dict(self.coredata.get_prefixed_options_per_machine(self.coredata.builtins_per_machine)),
- dict(self.coredata.flatten_lang_iterator(
- self.coredata.get_prefixed_options_per_machine(self.coredata.compiler_options))),
+ dict(self.coredata.flatten_lang_iterator_per_machine(self.coredata.compiler_options)),
]:
v = opts.get(optname)
if v is None or v.yielding:
@@ -3253,8 +3256,11 @@ external dependencies (including libraries) must go to "dependencies".''')
raise InterpreterException('Compiling Vala requires C. Add C to your project languages and rerun Meson.')
success = True
- for lang in sorted(args, key=compilers.sort_clink):
- lang = lang.lower()
+ for lang_str in sorted(args, key=compilers.sort_clink):
+ lang_str = lang_str.lower()
+ lang = Language.from_lower_case_name(lang_str)
+ if lang is None:
+ raise InvalidArguments('Tried to use unknown language "%s".' % lang_str)
clist = self.coredata.compilers[for_machine]
machine_name = for_machine.get_lower_case_name()
if lang in clist:
@@ -3262,8 +3268,8 @@ external dependencies (including libraries) must go to "dependencies".''')
else:
try:
comp = self.environment.detect_compiler_for(lang, for_machine)
- if comp is None:
- raise InvalidArguments('Tried to use unknown language "%s".' % lang)
+ # lang is our enum, not string, should have compiler.
+ assert comp is not None
if self.should_skip_sanity_check(for_machine):
mlog.log_once('Cross compiler sanity tests disabled via the cross file.')
else:
diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py
index f070355..b38df85 100644
--- a/mesonbuild/mconf.py
+++ b/mesonbuild/mconf.py
@@ -200,13 +200,10 @@ class Conf:
return k[:idx + 1] + 'build.' + k[idx + 1:]
core_options = self.split_options_per_subproject(core_options)
- host_compiler_options = self.split_options_per_subproject(
- dict(self.coredata.flatten_lang_iterator(
- self.coredata.compiler_options.host.items())))
build_compiler_options = self.split_options_per_subproject(
- dict(self.coredata.flatten_lang_iterator(
- (insert_build_prefix(k), o)
- for k, o in self.coredata.compiler_options.build.items())))
+ dict((insert_build_prefix(k), o)
+ for k, o in self.coredata.flatten_lang_iterator(
+ self.coredata.compiler_options.build.items())))
project_options = self.split_options_per_subproject(self.coredata.user_options)
show_build_options = self.default_values_only or self.build.environment.is_cross_build()
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index 2c563e4..e0f48f5 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -14,11 +14,13 @@
"""A library of random helper functionality."""
from pathlib import Path
+import copy
import sys
import stat
import time
import platform, subprocess, operator, os, shlex, shutil, re
import collections
+import enum
from enum import Enum
from functools import lru_cache, wraps
from itertools import tee, filterfalse
@@ -375,6 +377,12 @@ class PerMachine(T.Generic[_T]):
def __setitem__(self, machine: MachineChoice, val: _T) -> None:
setattr(self, machine.get_lower_case_name(), val)
+ def map(self, fun):
+ return PerMachine(
+ fun(self.build),
+ fun(self.host),
+ )
+
def miss_defaulting(self) -> "PerMachineDefaultable[T.Optional[_T]]":
"""Unset definition duplicated from their previous to None
@@ -473,6 +481,75 @@ class PerThreeMachineDefaultable(PerMachineDefaultable, PerThreeMachine[T.Option
return 'PerThreeMachineDefaultable({!r}, {!r}, {!r})'.format(self.build, self.host, self.target)
+class Language(Enum):
+
+ """Enum class representing the languages Meson supports.
+ """
+
+ # Alphabetized for now, but order comparisons explicitly disallowed so it
+ # shouldn't matter.
+ C = enum.auto()
+ CPP = enum.auto()
+ CS = enum.auto()
+ CUDA = enum.auto()
+ D = enum.auto()
+ FORTRAN = enum.auto()
+ JAVA = enum.auto()
+ OBJC = enum.auto()
+ OBJCPP = enum.auto()
+ RUST = enum.auto()
+ SWIFT = enum.auto()
+ VALA = enum.auto()
+
+ def get_lower_case_name(self) -> str:
+ return {
+ Language.C: 'c',
+ Language.CPP: 'cpp',
+ Language.CS: 'cs',
+ Language.CUDA: 'cuda',
+ Language.D: 'd',
+ Language.FORTRAN: 'fortran',
+ Language.JAVA: 'java',
+ Language.OBJC: 'objc',
+ Language.OBJCPP: 'objcpp',
+ Language.RUST: 'rust',
+ Language.SWIFT: 'swift',
+ Language.VALA: 'vala',
+ }[self]
+
+ @classmethod
+ def from_lower_case_name(cls, lang_name: str) -> T.Optional['Language']:
+ return {
+ 'c': Language.C,
+ 'cpp': Language.CPP,
+ 'cs': Language.CS,
+ 'cuda': Language.CUDA,
+ 'd': Language.D,
+ 'fortran': Language.FORTRAN,
+ 'java': Language.JAVA,
+ 'objc': Language.OBJC,
+ 'objcpp': Language.OBJCPP,
+ 'rust': Language.RUST,
+ 'swift': Language.SWIFT,
+ 'vala': Language.VALA,
+ }.get(lang_name, None)
+
+ def get_display_name(self) -> str:
+ return {
+ Language.C: 'C',
+ Language.CPP: 'C++',
+ Language.CS: 'C#',
+ Language.CUDA: 'Cuda',
+ Language.D: 'D',
+ Language.FORTRAN: 'Fortran',
+ Language.JAVA: 'Java',
+ Language.OBJC: 'Objective-C',
+ Language.OBJCPP: 'Objective-C++',
+ Language.RUST: 'Rust',
+ Language.SWIFT: 'Swift',
+ Language.VALA: 'Vala',
+ }[self]
+
def is_sunos() -> bool:
return platform.system().lower() == 'sunos'
diff --git a/mesonbuild/minit.py b/mesonbuild/minit.py
index d0aff49..191c735 100644
--- a/mesonbuild/minit.py
+++ b/mesonbuild/minit.py
@@ -24,6 +24,7 @@ import re
from glob import glob
from mesonbuild import mesonlib
from mesonbuild.environment import detect_ninja
+from mesonbuild.mesonlib import Language
from mesonbuild.templates.samplefactory import sameple_generator
'''
@@ -33,7 +34,18 @@ from mesonbuild.templates.mesontemplates import create_meson_build
FORTRAN_SUFFIXES = {'.f', '.for', '.F', '.f90', '.F90'}
LANG_SUFFIXES = {'.c', '.cc', '.cpp', '.cs', '.cu', '.d', '.m', '.mm', '.rs', '.java'} | FORTRAN_SUFFIXES
-LANG_SUPPORTED = {'c', 'cpp', 'cs', 'cuda', 'd', 'fortran', 'java', 'rust', 'objc', 'objcpp'}
+LANG_SUPPORTED = {
+ Language.C,
+ Language.CPP,
+ Language.CS,
+ Language.CUDA,
+ Language.D,
+ Language.FORTRAN,
+ Language.JAVA,
+ Language.RUST,
+ Language.OBJC,
+ Language.OBJCPP,
+}
DEFAULT_PROJECT = 'executable'
DEFAULT_VERSION = '0.1'
@@ -96,34 +108,34 @@ def autodetect_options(options, sample: bool = False) -> None:
if not options.language:
for f in options.srcfiles:
if f.suffix == '.c':
- options.language = 'c'
+ options.language = Language.C
break
if f.suffix in ('.cc', '.cpp'):
- options.language = 'cpp'
+ options.language = Language.CPP
break
if f.suffix in '.cs':
- options.language = 'cs'
+ options.language = Language.CS
break
if f.suffix == '.cu':
- options.language = 'cuda'
+ options.language = Language.CUDA
break
if f.suffix == '.d':
- options.language = 'd'
+ options.language = Language.D
break
if f.suffix in FORTRAN_SUFFIXES:
- options.language = 'fortran'
+ options.language = Language.FORTRAN
break
if f.suffix == '.rs':
- options.language = 'rust'
+ options.language = Language.RUST
break
if f.suffix == '.m':
- options.language = 'objc'
+ options.language = Language.OBJC
break
if f.suffix == '.mm':
- options.language = 'objcpp'
+ options.language = Language.OBJCPP
break
if f.suffix == '.java':
- options.language = 'java'
+ options.language = Language.JAVA
break
if not options.language:
raise SystemExit("Can't autodetect language, please specify it with -l.")
@@ -158,7 +170,7 @@ def run(options) -> int:
autodetect_options(options, sample=True)
if not options.language:
print('Defaulting to generating a C language project.')
- options.language = 'c'
+ options.language = Language.C
create_sample(options)
else:
autodetect_options(options)
diff --git a/mesonbuild/modules/cmake.py b/mesonbuild/modules/cmake.py
index ca98b1c..e6587e4 100644
--- a/mesonbuild/modules/cmake.py
+++ b/mesonbuild/modules/cmake.py
@@ -210,9 +210,9 @@ class CmakeModule(ExtensionModule):
def detect_voidp_size(self, env):
compilers = env.coredata.compilers.host
- compiler = compilers.get('c', None)
+ compiler = compilers.get(Language.C, None)
if not compiler:
- compiler = compilers.get('cpp', None)
+ compiler = compilers.get(Language.CPP, None)
if not compiler:
raise mesonlib.MesonException('Requires a C or C++ compiler to compute sizeof(void *).')
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 1faa128..de674db 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -566,7 +566,7 @@ class GnomeModule(ExtensionModule):
for girtarget in girtargets:
for lang, compiler in girtarget.compilers.items():
# XXX: Can you use g-i with any other language?
- if lang in ('c', 'cpp', 'objc', 'objcpp', 'd'):
+ if lang in (Language.C, Language.CPP, Language.OBJC, Language.OBJCPP, Language.D):
ret.append((lang, compiler))
break
@@ -1056,11 +1056,11 @@ class GnomeModule(ExtensionModule):
ldflags.extend(internal_ldflags)
ldflags.extend(external_ldflags)
- cflags.extend(state.environment.coredata.get_external_args(MachineChoice.HOST, 'c'))
- ldflags.extend(state.environment.coredata.get_external_link_args(MachineChoice.HOST, 'c'))
- compiler = state.environment.coredata.compilers[MachineChoice.HOST]['c']
+ cflags.extend(state.environment.coredata.get_external_args(MachineChoice.HOST, Language.C))
+ ldflags.extend(state.environment.coredata.get_external_link_args(MachineChoice.HOST, Language.C))
+ compiler = state.environment.coredata.compilers[MachineChoice.HOST][Language.C]
- compiler_flags = self._get_langs_compilers_flags(state, [('c', compiler)])
+ compiler_flags = self._get_langs_compilers_flags(state, [(Language.C, compiler)])
cflags.extend(compiler_flags[0])
ldflags.extend(compiler_flags[1])
ldflags.extend(compiler_flags[2])
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index 1cb7698..f81ee2f 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -376,7 +376,7 @@ class PkgConfigModule(ExtensionModule):
install_dir = l.get_custom_install_dir()[0]
if install_dir is False:
continue
- if 'cs' in l.compilers:
+ if Language.CS in l.compilers:
if isinstance(install_dir, str):
Lflag = '-r${prefix}/%s/%s' % (self._escape(self._make_relative(prefix, install_dir)), l.filename)
else: # install_dir is True
@@ -394,7 +394,7 @@ class PkgConfigModule(ExtensionModule):
# find the library
if l.name_suffix_set:
mlog.warning(msg.format(l.name, 'name_suffix', lname, pcfile))
- if 'cs' not in l.compilers:
+ if Language.CS not in l.compilers:
yield '-l%s' % lname
def get_uninstalled_include_dirs(libs):
@@ -507,7 +507,7 @@ class PkgConfigModule(ExtensionModule):
dversions = kwargs.get('d_module_versions', None)
if dversions:
- compiler = state.environment.coredata.compilers.host.get('d')
+ compiler = state.environment.coredata.compilers.host.get(Language.D)
if compiler:
deps.add_cflags(compiler.get_feature_args({'versions': dversions}, None))
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index 6050705..c154ab2 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -33,7 +33,7 @@ class ResourceCompilerType(enum.Enum):
class WindowsModule(ExtensionModule):
def detect_compiler(self, compilers):
- for l in ('c', 'cpp'):
+ for l in (Language.C, Language.CPP):
if l in compilers:
return compilers[l]
raise MesonException('Resource compilation requires a C or C++ compiler.')
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index d47a3d2..56f8984 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -23,7 +23,7 @@ from . import mparser
from .interpreterbase import FeatureNew
forbidden_option_names = set(coredata.builtin_options.keys())
-forbidden_prefixes = [lang + '_' for lang in compilers.all_languages] + ['b_', 'backend_']
+forbidden_prefixes = [lang.get_lower_case_name() + '_' for lang in compilers.all_languages] + ['b_', 'backend_']
reserved_prefixes = ['cross_']
def is_invalid_name(name: str, *, log: bool = True) -> bool:
diff --git a/mesonbuild/scripts/clangformat.py b/mesonbuild/scripts/clangformat.py
index 4b441de..cdcec64 100644
--- a/mesonbuild/scripts/clangformat.py
+++ b/mesonbuild/scripts/clangformat.py
@@ -21,7 +21,7 @@ from ..compilers import lang_suffixes
def clangformat(exelist, srcdir_name, builddir_name):
srcdir = pathlib.Path(srcdir_name)
- suffixes = set(lang_suffixes['c']).union(set(lang_suffixes['cpp']))
+ suffixes = set(lang_suffixes[Language.C]).union(set(lang_suffixes[Language.CPP]))
suffixes.add('h')
futures = []
with ThreadPoolExecutor() as e:
diff --git a/mesonbuild/scripts/clangtidy.py b/mesonbuild/scripts/clangtidy.py
index 0452086..402cb41 100644
--- a/mesonbuild/scripts/clangtidy.py
+++ b/mesonbuild/scripts/clangtidy.py
@@ -21,7 +21,7 @@ from ..compilers import lang_suffixes
def manual_clangformat(srcdir_name, builddir_name):
srcdir = pathlib.Path(srcdir_name)
- suffixes = set(lang_suffixes['c']).union(set(lang_suffixes['cpp']))
+ suffixes = set(lang_suffixes[Language.C]).union(set(lang_suffixes[Language.CPP]))
suffixes.add('h')
futures = []
returncode = 0
diff --git a/mesonbuild/templates/mesontemplates.py b/mesonbuild/templates/mesontemplates.py
index 6b341a2..b7fd80c 100644
--- a/mesonbuild/templates/mesontemplates.py
+++ b/mesonbuild/templates/mesontemplates.py
@@ -39,7 +39,7 @@ def create_meson_build(options):
'supported only for project type "executable".\n'
'Run meson init in an empty directory to create a sample project.')
default_options = ['warning_level=3']
- if options.language == 'cpp':
+ if options.language == Language.CPP:
# This shows how to set this very common option.
default_options += ['cpp_std=c++14']
# If we get a meson.build autoformatter one day, this code could
@@ -52,7 +52,7 @@ def create_meson_build(options):
depspec += ',\n '.join("dependency('{}')".format(x)
for x in options.deps.split(','))
depspec += '],'
- if options.language != 'java':
+ if options.language != Language.JAVA:
content = meson_executable_template.format(project_name=options.name,
language=options.language,
version=options.version,
diff --git a/mesonbuild/templates/samplefactory.py b/mesonbuild/templates/samplefactory.py
index 1da2bc1..2e91e42 100644
--- a/mesonbuild/templates/samplefactory.py
+++ b/mesonbuild/templates/samplefactory.py
@@ -25,14 +25,14 @@ from mesonbuild.templates.ctemplates import CProject
def sameple_generator(options):
return {
- 'c': CProject,
- 'cpp': CppProject,
- 'cs': CSharpProject,
- 'cuda': CudaProject,
- 'objc': ObjCProject,
- 'objcpp': ObjCppProject,
- 'java': JavaProject,
- 'd': DlangProject,
- 'rust': RustProject,
- 'fortran': FortranProject
+ Language.C: CProject,
+ Language.CPP: CppProject,
+ Language.CS: CSharpProject,
+ Language.CUDA: CudaProject,
+ Language.OBJC: ObjCProject,
+ Language.OBJCPP: ObjCppProject,
+ Language.JAVA: JavaProject,
+ Language.D: DlangProject,
+ Language.RUST: RustProject,
+ Language.FORTRAN: FortranProject
}[options.language](options)
diff --git a/run_unittests.py b/run_unittests.py
index 6d7eba2..4b4fe34 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -55,7 +55,7 @@ import mesonbuild.modules.gnome
from mesonbuild.interpreter import Interpreter, ObjectHolder
from mesonbuild.ast import AstInterpreter
from mesonbuild.mesonlib import (
- BuildDirLock, LibType, MachineChoice, PerMachine, Version, is_windows,
+ BuildDirLock, Language, LibType, MachineChoice, PerMachine, Version, is_windows,
is_osx, is_cygwin, is_dragonflybsd, is_openbsd, is_haiku, is_sunos,
windows_proof_rmtree, python_command, version_compare, split_args,
quote_arg, relpath, is_linux