aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ericson <git@JohnEricson.me>2020-04-21 11:48:30 -0400
committerJohn Ericson <git@JohnEricson.me>2020-04-21 11:55:07 -0400
commit87aa98c1787d800145853a8e84654e4c54ee1078 (patch)
tree8802cdb36b9fb44bfa27b6a9460599d889b479bb
parented6bf2b4017b42d7a3ee0a74fabaa6097c9404dd (diff)
downloadmeson-87aa98c1787d800145853a8e84654e4c54ee1078.zip
meson-87aa98c1787d800145853a8e84654e4c54ee1078.tar.gz
meson-87aa98c1787d800145853a8e84654e4c54ee1078.tar.bz2
More progress
-rw-r--r--mesonbuild/backend/backends.py15
-rw-r--r--mesonbuild/backend/ninjabackend.py82
-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.py6
-rw-r--r--mesonbuild/cmake/interpreter.py24
-rw-r--r--mesonbuild/compilers/compilers.py2
-rw-r--r--mesonbuild/compilers/mixins/gnu.py15
-rw-r--r--mesonbuild/coredata.py6
-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/environment.py82
-rw-r--r--mesonbuild/interpreter.py29
-rw-r--r--mesonbuild/mesonlib.py47
-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/scripts/clangformat.py2
-rw-r--r--mesonbuild/scripts/clangtidy.py2
-rw-r--r--mesonbuild/templates/mesontemplates.py4
-rw-r--r--mesonbuild/templates/samplefactory.py20
32 files changed, 331 insertions, 271 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 31ddfb4..926a07d 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -20,9 +20,10 @@ from .. import mesonlib
from .. import mlog
import json
import subprocess
-from ..mesonlib import MachineChoice, MesonException, OrderedSet, OptionOverrideProxy
-from ..mesonlib import classify_unity_sources, unholder
-from ..mesonlib import File
+from ..mesonlib import (
+ File, Language, MachineChoice, MesonException, OrderedSet,
+ OptionOverrideProxy, classify_unity_sources, unholder,
+)
from ..compilers import CompilerArgs, VisualStudioLikeCompiler
from ..interpreter import Interpreter
from collections import OrderedDict
@@ -635,7 +636,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:
@@ -644,7 +645,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
@@ -654,7 +655,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)
@@ -668,7 +669,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 22fe8f4..ef9b809 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -374,7 +374,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
@@ -412,7 +412,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):
@@ -458,7 +458,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': [],
@@ -502,10 +502,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
@@ -520,7 +520,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, \
@@ -618,10 +618,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():
@@ -919,7 +919,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 = ''
@@ -994,10 +994,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 = CompilerArgs(compiler, target.extra_args.get('cs', []))
+ commands = CompilerArgs(compiler, 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))
@@ -1031,7 +1031,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)
@@ -1159,7 +1159,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 = []
@@ -1251,7 +1251,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)
@@ -1271,7 +1271,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.
@@ -1313,7 +1313,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()
@@ -1359,7 +1359,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)
@@ -1436,7 +1436,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 = []
@@ -1500,7 +1500,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)
@@ -1510,7 +1510,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())
@@ -1534,7 +1534,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]
@@ -1569,12 +1569,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 = '%s_LINKER%s' % (langname, self.get_rule_suffix(for_machine))
+ rule = '%s_LINKER%s' % (langname.get_lower_case_name(), self.get_rule_suffix(for_machine))
command = compiler.get_linker_exelist()
args = ['$ARGS'] + compiler.get_linker_output_args('$out') + ['$in', '$LINK_ARGS']
description = 'Linking target $out'
@@ -1667,26 +1667,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 = compiler.get_dependency_gen_args('$out', '$DEPFILE')
@@ -1710,7 +1710,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')
@@ -1832,7 +1832,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:
@@ -2059,7 +2059,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)
@@ -2096,7 +2096,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
@@ -2175,7 +2175,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.
@@ -2237,7 +2237,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]
@@ -2267,7 +2267,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']
@@ -2279,7 +2279,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
@@ -2470,7 +2470,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 ef849e1..b776d7a 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -585,9 +585,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):
@@ -724,13 +724,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.')
@@ -1047,7 +1047,7 @@ class Vs2010Backend(backends.Backend):
pch_sources = {}
if self.environment.coredata.base_options.get('b_pch', False):
pch_node = ET.SubElement(clconf, 'PrecompiledHeader')
- 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 c200261..ddecb6e 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -24,7 +24,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
)
@@ -456,8 +456,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
@@ -659,7 +660,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.
@@ -687,21 +688,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
@@ -844,11 +847,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)
@@ -858,7 +869,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:
@@ -982,7 +993,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
@@ -1208,7 +1219,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++
@@ -1492,20 +1503,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()
@@ -1549,7 +1560,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'
@@ -1599,9 +1610,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')
@@ -1619,7 +1630,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'
@@ -1670,7 +1681,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"')
@@ -1727,7 +1738,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 ddf2a6d..349c8ec 100644
--- a/mesonbuild/cmake/executor.py
+++ b/mesonbuild/cmake/executor.py
@@ -280,9 +280,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 125f18b..6208696 100644
--- a/mesonbuild/cmake/interpreter.py
+++ b/mesonbuild/cmake/interpreter.py
@@ -24,7 +24,7 @@ from .executor import CMakeExecutor
from .traceparser import CMakeTraceParser, CMakeGeneratorTarget
from .. import mlog
from ..environment import Environment
-from ..mesonlib import MachineChoice, OrderedSet, version_compare
+from ..mesonlib import Language, MachineChoice, OrderedSet, version_compare
from ..compilers.compilers import lang_suffixes, header_suffixes, obj_suffixes, lib_suffixes, is_header
from enum import Enum
from functools import lru_cache
@@ -77,15 +77,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 = {
@@ -253,7 +253,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:
@@ -281,7 +281,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/compilers.py b/mesonbuild/compilers/compilers.py
index ffd8d06..ecdb70d 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -817,7 +817,7 @@ class Compiler:
@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
diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py
index a1541bd..7cfb2c2 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: mesonlib.Language) -> 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, disable_cache=False, want_output=True) 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/coredata.py b/mesonbuild/coredata.py
index 8d043aa..06f07f3 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -642,9 +642,9 @@ class CoreData:
cls,
outer # : PerMachine[Dict[Language, T.Dict[str, V]]]
) -> T.Iterable[T.Tuple[str, _V]]:
- self.get_prefixed_options_per_machine(
- self.compiler_options.map(lambda opts_per_lang:
- self.flatten_lang_iterator(opts_per_lang)))
+ cls.get_prefixed_options_per_machine(
+ outer.map(lambda opts_per_lang:
+ cls.flatten_lang_iterator(opts_per_lang)))
@staticmethod
def _flatten_pair_iterator(
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index c0ec089..8cee491 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -36,9 +36,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,
+)
if T.TYPE_CHECKING:
from ..compilers.compilers import CompilerType # noqa: F401
@@ -710,7 +712,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()
@@ -1046,14 +1048,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))
@@ -1590,7 +1592,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
@@ -2087,8 +2089,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)
@@ -2558,7 +2560,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 13054f5..3341f3e 100644
--- a/mesonbuild/dependencies/boost.py
+++ b/mesonbuild/dependencies/boost.py
@@ -339,7 +339,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 9c189be..063fa6d 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 04dee06..de05a79 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 4cec814..6e54e8e 100644
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -69,7 +69,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', [])
@@ -181,7 +181,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":
@@ -547,7 +547,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/environment.py b/mesonbuild/environment.py
index 18b7773..0e3ae8c 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -739,7 +739,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):
@@ -970,10 +970,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)
@@ -983,7 +983,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 cannot be queried to get the version out of it (it
# ignores -Wl,--version and doesn't have an alternative).
@@ -1012,7 +1012,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(
@@ -1032,7 +1032,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,
@@ -1043,9 +1043,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
@@ -1065,7 +1065,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(
@@ -1090,33 +1090,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(
@@ -1124,7 +1124,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(
@@ -1132,7 +1132,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(
@@ -1142,15 +1142,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 = not self.machines.matches_build_machine(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):
@@ -1188,7 +1188,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 = not self.machines.matches_build_machine(for_machine)
info = self.machines[for_machine]
for compiler in compilers:
@@ -1307,7 +1307,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 = not self.machines.matches_build_machine(for_machine)
info = self.machines[for_machine]
@@ -1351,7 +1351,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
@@ -1373,7 +1373,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:
@@ -1398,7 +1398,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 = not self.machines.matches_build_machine(for_machine)
info = self.machines[for_machine]
if exelist is None:
@@ -1418,7 +1418,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 = not self.machines.matches_build_machine(for_machine)
info = self.machines[for_machine]
@@ -1500,8 +1500,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 = {}
@@ -1511,7 +1511,7 @@ class Environment:
popen_exceptions = {}
is_cross = not self.machines.matches_build_machine(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
@@ -1600,7 +1600,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 = not self.machines.matches_build_machine(for_machine)
info = self.machines[for_machine]
if exelist is None:
@@ -1624,29 +1624,29 @@ class Environment:
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
def compiler_from_language(self, lang: Language, for_machine: MachineChoice):
- if lang == 'c':
+ 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
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index fb606ca..bd783c7 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
@@ -1965,12 +1968,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({})
@@ -3091,8 +3095,11 @@ external dependencies (including libraries) must go to "dependencies".''')
def add_languages_for(self, args, required, for_machine: MachineChoice):
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:
@@ -3100,8 +3107,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:
@@ -3128,8 +3135,8 @@ external dependencies (including libraries) must go to "dependencies".''')
self.build.ensure_static_linker(comp)
langs = self.coredata.compilers[for_machine].keys()
- if 'vala' in langs:
- if 'c' not in langs:
+ if Language.VALA in langs:
+ if Language.C not in langs:
raise InterpreterException('Compiling Vala requires C. Add C to your project languages and rerun Meson.')
return success
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index 0ce3df1..73a9139 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -20,6 +20,7 @@ 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
@@ -473,18 +474,18 @@ class Language(Enum):
# Alphabetized for now, but order comparisons explicitly disallowed so it
# shouldn't matter.
- C = 0
- CPP = 1
- CS = 2
- CUDA = 3
- D = 4
- FORTRAN = 5
- JAVA = 6
- OBJC = 7
- OBJCPP = 8
- RUST = 9
- SWIFT = 10
- VALA = 11
+ 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 {
@@ -502,8 +503,8 @@ class Language(Enum):
Language.VALA: 'vala',
}[self]
- @staticmethod
- def from_lower_case_name(lang_name: str) -> Language:
+ @classmethod
+ def from_lower_case_name(cls, lang_name: str) -> T.Optional['Language']:
return {
'c': Language.C,
'cpp': Language.CPP,
@@ -517,7 +518,23 @@ class Language(Enum):
'rust': Language.RUST,
'swift': Language.SWIFT,
'vala': Language.VALA,
- }[lang_name]
+ }.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 4238ecd..c636053 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 6c4098b..0283d11 100644
--- a/mesonbuild/modules/cmake.py
+++ b/mesonbuild/modules/cmake.py
@@ -129,9 +129,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 8317629..21360a2 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -559,7 +559,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
@@ -1062,11 +1062,11 @@ This will become a hard error in the future.''')
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 666a93d..ac51e36 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -325,7 +325,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
@@ -343,7 +343,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):
@@ -463,7 +463,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 b3e4983..f939782 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/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)