Merge pull request #4010 from Ericson2314/purge-cross-conditional-preview

Purge much `is_cross` and `<things>_cross` without changing user interfaces---includes on #5263
pull/5470/head
Jussi Pakkanen 6 years ago committed by GitHub
commit 06df6e463f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 15
      mesonbuild/ast/introspection.py
  2. 88
      mesonbuild/backend/backends.py
  3. 283
      mesonbuild/backend/ninjabackend.py
  4. 24
      mesonbuild/backend/vs2010backend.py
  5. 4
      mesonbuild/backend/xcodebackend.py
  6. 161
      mesonbuild/build.py
  7. 5
      mesonbuild/cmake/client.py
  8. 6
      mesonbuild/cmake/interpreter.py
  9. 50
      mesonbuild/compilers/c.py
  10. 39
      mesonbuild/compilers/clike.py
  11. 7
      mesonbuild/compilers/compilers.py
  12. 50
      mesonbuild/compilers/cpp.py
  13. 14
      mesonbuild/compilers/cs.py
  14. 6
      mesonbuild/compilers/cuda.py
  15. 26
      mesonbuild/compilers/d.py
  16. 52
      mesonbuild/compilers/fortran.py
  17. 6
      mesonbuild/compilers/java.py
  18. 20
      mesonbuild/compilers/objc.py
  19. 20
      mesonbuild/compilers/objcpp.py
  20. 8
      mesonbuild/compilers/rust.py
  21. 14
      mesonbuild/compilers/swift.py
  22. 20
      mesonbuild/compilers/vala.py
  23. 39
      mesonbuild/coredata.py
  24. 108
      mesonbuild/dependencies/base.py
  25. 28
      mesonbuild/dependencies/boost.py
  26. 22
      mesonbuild/dependencies/dev.py
  27. 12
      mesonbuild/dependencies/misc.py
  28. 13
      mesonbuild/dependencies/ui.py
  29. 235
      mesonbuild/environment.py
  30. 153
      mesonbuild/interpreter.py
  31. 88
      mesonbuild/mesonlib.py
  32. 2
      mesonbuild/modules/cmake.py
  33. 2
      mesonbuild/modules/gnome.py
  34. 2
      mesonbuild/modules/pkgconfig.py
  35. 2
      mesonbuild/modules/python.py
  36. 9
      mesonbuild/modules/windows.py
  37. 33
      mesonbuild/munstable_coredata.py
  38. 36
      run_project_tests.py
  39. 96
      run_unittests.py
  40. 7
      test cases/unit/55 pkg_config_path option/meson.build
  41. 5
      test cases/unit/58 identity cross/build_wrapper.py
  42. 5
      test cases/unit/58 identity cross/host_wrapper.py
  43. 15
      test cases/unit/58 identity cross/meson.build
  44. 27
      test cases/unit/58 identity cross/stuff.h

@ -18,6 +18,7 @@
from . import AstInterpreter
from .. import compilers, environment, mesonlib, optinterpreter
from .. import coredata as cdata
from ..mesonlib import MachineChoice
from ..interpreterbase import InvalidArguments
from ..build import Executable, Jar, SharedLibrary, SharedModule, StaticLibrary
from ..mparser import BaseNode, ArithmeticNode, ArrayNode, ElementaryNode, IdNode, FunctionNode, StringNode
@ -127,11 +128,11 @@ class IntrospectionInterpreter(AstInterpreter):
def func_add_languages(self, node, args, kwargs):
args = self.flatten_args(args)
need_cross_compiler = self.environment.is_cross_build()
for lang in sorted(args, key=compilers.sort_clink):
lang = lang.lower()
if lang not in self.coredata.compilers:
self.environment.detect_compilers(lang, need_cross_compiler)
for for_machine in [MachineChoice.BUILD, MachineChoice.HOST]:
for lang in sorted(args, key=compilers.sort_clink):
lang = lang.lower()
if lang not in self.coredata.compilers[for_machine]:
self.environment.detect_compiler_for(lang, for_machine)
def func_dependency(self, node, args, kwargs):
args = self.flatten_args(args)
@ -195,10 +196,10 @@ class IntrospectionInterpreter(AstInterpreter):
kwargs_reduced = {k: v for k, v in kwargs.items() if k in targetclass.known_kwargs and k in ['install', 'build_by_default', 'build_always']}
kwargs_reduced = {k: v.value if isinstance(v, ElementaryNode) else v for k, v in kwargs_reduced.items()}
kwargs_reduced = {k: v for k, v in kwargs_reduced.items() if not isinstance(v, BaseNode)}
is_cross = False
for_machine = MachineChoice.HOST
objects = []
empty_sources = [] # Passing the unresolved sources list causes errors
target = targetclass(name, self.subdir, self.subproject, is_cross, empty_sources, objects, self.environment, kwargs_reduced)
target = targetclass(name, self.subdir, self.subproject, for_machine, empty_sources, objects, self.environment, kwargs_reduced)
new_target = {
'name': target.get_basename(),

@ -195,14 +195,9 @@ class Backend:
self.environment.coredata.base_options)
def get_compiler_options_for_target(self, target):
if self.environment.is_cross_build() and not target.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
return OptionOverrideProxy(
target.option_overrides,
self.environment.coredata.compiler_options[for_machine])
self.environment.coredata.compiler_options[target.for_machine])
def get_option_for_target(self, option_name, target):
if option_name in target.option_overrides:
@ -357,17 +352,15 @@ class Backend:
with open(exe_data, 'wb') as f:
if isinstance(exe, dependencies.ExternalProgram):
exe_cmd = exe.get_command()
exe_is_native = True
exe_for_machine = exe.for_machine
elif isinstance(exe, (build.BuildTarget, build.CustomTarget)):
exe_cmd = [self.get_target_filename_abs(exe)]
exe_is_native = not exe.is_cross
exe_for_machine = exe.for_machine
else:
exe_cmd = [exe]
exe_is_native = True
is_cross_built = (not exe_is_native) and \
self.environment.is_cross_build() and \
self.environment.need_exe_wrapper()
if is_cross_built:
exe_for_machine = MachineChoice.BUILD
is_cross_built = not self.environment.machines.matches_build_machine(exe_for_machine)
if is_cross_built and self.environment.need_exe_wrapper():
exe_wrapper = self.environment.get_exe_wrapper()
if not exe_wrapper.found():
msg = 'The exe_wrapper {!r} defined in the cross file is ' \
@ -397,10 +390,7 @@ class Backend:
Otherwise, we query the target for the dynamic linker.
'''
if isinstance(target, build.StaticLibrary):
if target.is_cross:
return self.build.static_cross_linker, []
else:
return self.build.static_linker, []
return self.build.static_linker[target.for_machine], []
l, stdlib_args = target.get_clink_dynamic_linker_and_stdlibs()
return l, stdlib_args
@ -476,7 +466,8 @@ class Backend:
else:
source = os.path.relpath(os.path.join(build_dir, rel_src),
os.path.join(self.environment.get_source_dir(), target.get_subdir()))
return source.replace('/', '_').replace('\\', '_') + '.' + self.environment.get_object_suffix()
machine = self.environment.machines[target.for_machine]
return source.replace('/', '_').replace('\\', '_') + '.' + machine.get_object_suffix()
def determine_ext_objs(self, extobj, proj_dir_to_build_root):
result = []
@ -608,18 +599,14 @@ class Backend:
commands += compiler.get_optimization_args(self.get_option_for_target('optimization', target))
commands += compiler.get_debug_args(self.get_option_for_target('debug', target))
# Add compile args added using add_project_arguments()
commands += self.build.get_project_args(compiler, target.subproject, target.is_cross)
commands += self.build.get_project_args(compiler, target.subproject, target.for_machine)
# Add compile args added using add_global_arguments()
# These override per-project arguments
commands += self.build.get_global_args(compiler, target.is_cross)
if self.environment.is_cross_build() and not target.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
commands += self.build.get_global_args(compiler, target.for_machine)
# Compile args added from the env: CFLAGS/CXXFLAGS, etc, or the cross
# file. We want these to override all the defaults, but not the
# per-target compile args.
commands += self.environment.coredata.get_external_args(for_machine, compiler.get_language())
commands += self.environment.coredata.get_external_args(target.for_machine, compiler.get_language())
# Always set -fPIC for shared libraries
if isinstance(target, build.SharedLibrary):
commands += compiler.get_pic_args()
@ -679,11 +666,11 @@ class Backend:
def get_mingw_extra_paths(self, target):
paths = OrderedSet()
# The cross bindir
root = self.environment.properties.host.get_root()
root = self.environment.properties[target.for_machine].get_root()
if root:
paths.add(os.path.join(root, 'bin'))
# The toolchain bindir
sys_root = self.environment.properties.host.get_sys_root()
sys_root = self.environment.properties[target.for_machine].get_sys_root()
if sys_root:
paths.add(os.path.join(sys_root, 'bin'))
# Get program and library dirs from all target compilers
@ -693,7 +680,7 @@ class Backend:
paths.update(cc.get_library_dirs(self.environment))
return list(paths)
def determine_windows_extra_paths(self, target, extra_bdeps, is_cross=False):
def determine_windows_extra_paths(self, target: typing.Union[build.BuildTarget, str], extra_bdeps):
'''On Windows there is no such thing as an rpath.
We must determine all locations of DLLs that this exe
links to and return them so they can be used in unit
@ -713,7 +700,8 @@ class Backend:
continue
dirseg = os.path.join(self.environment.get_build_dir(), self.get_target_dir(ld))
result.add(dirseg)
if is_cross:
if (isinstance(target, build.BuildTarget) and
not self.environment.machines.matches_build_machine(target.for_machine)):
result.update(self.get_mingw_extra_paths(target))
return list(result)
@ -731,24 +719,23 @@ class Backend:
cmd = exe.get_command()
else:
cmd = [os.path.join(self.environment.get_build_dir(), self.get_target_filename(t.get_exe()))]
is_cross = self.environment.is_cross_build() and \
self.environment.need_exe_wrapper()
if isinstance(exe, build.BuildTarget):
is_cross = is_cross and exe.is_cross
if isinstance(exe, dependencies.ExternalProgram):
if isinstance(exe, (build.BuildTarget, dependencies.ExternalProgram)):
test_for_machine = exe.for_machine
else:
# E.g. an external verifier or simulator program run on a generated executable.
# Can always be run without a wrapper.
is_cross = False
if is_cross:
test_for_machine = MachineChoice.BUILD
is_cross = not self.environment.machines.matches_build_machine(test_for_machine)
if is_cross and self.environment.need_exe_wrapper():
exe_wrapper = self.environment.get_exe_wrapper()
else:
exe_wrapper = None
if mesonlib.for_windows(is_cross, self.environment) or \
mesonlib.for_cygwin(is_cross, self.environment):
machine = self.environment.machines[exe.for_machine]
if machine.is_windows() or machine.is_cygwin():
extra_bdeps = []
if isinstance(exe, build.CustomTarget):
extra_bdeps = exe.get_transitive_build_target_deps()
extra_paths = self.determine_windows_extra_paths(exe, extra_bdeps, is_cross)
extra_paths = self.determine_windows_extra_paths(exe, extra_bdeps)
else:
extra_paths = []
cmd_args = []
@ -811,15 +798,22 @@ class Backend:
return deps
def exe_object_to_cmd_array(self, exe):
if self.environment.is_cross_build() and \
isinstance(exe, build.BuildTarget) and exe.is_cross:
if self.environment.exe_wrapper is None and self.environment.need_exe_wrapper():
s = textwrap.dedent('''
Can not use target {} as a generator because it is cross-built
and no exe wrapper is defined or needs_exe_wrapper is true.
You might want to set it to native instead.'''.format(exe.name))
raise MesonException(s)
if isinstance(exe, build.BuildTarget):
if exe.for_machine is not MachineChoice.BUILD:
if (self.environment.is_cross_build() and
self.environment.exe_wrapper is None and
self.environment.need_exe_wrapper()):
s = textwrap.dedent('''
Cannot use target {} as a generator because it is built for the
host machine and no exe wrapper is defined or needs_exe_wrapper is
true. You might want to set `native: true` instead to build it for
the build machine.'''.format(exe.name))
raise MesonException(s)
else:
mlog.warning('''
Target {} is used as a generator, but is built for the host
machine. This means most cross builds will fail. You might want to
set `native: true` instead to build it for the build machine.'''.format(exe.name))
exe_arr = [os.path.join(self.environment.get_build_dir(), self.get_target_filename(exe))]
else:
exe_arr = exe.get_command()

@ -29,9 +29,11 @@ from .. import build
from .. import mlog
from .. import dependencies
from .. import compilers
from ..compilers import CompilerArgs, CCompiler, VisualStudioLikeCompiler, FortranCompiler
from ..compilers import Compiler, CompilerArgs, CCompiler, VisualStudioLikeCompiler, FortranCompiler
from ..linkers import ArLinker
from ..mesonlib import File, MachineChoice, MesonException, OrderedSet, LibType
from ..mesonlib import (
File, LibType, MachineChoice, MesonException, OrderedSet, PerMachine
)
from ..mesonlib import get_compiler_for_source, has_path_sep
from .backends import CleanTrees
from ..build import InvalidArguments
@ -202,6 +204,7 @@ class NinjaBackend(backends.Backend):
self.fortran_deps = {}
self.all_outputs = {}
self.introspection_data = {}
self.created_llvm_ir_rule = PerMachine(False, False)
def create_target_alias(self, to_target):
# We need to use aliases for targets that might be used as directory
@ -219,7 +222,8 @@ class NinjaBackend(backends.Backend):
def detect_vs_dep_prefix(self, tempfilename):
'''VS writes its dependency in a locale dependent format.
Detect the search prefix to use.'''
for compiler in self.environment.coredata.compilers.values():
# TODO don't hard-code host
for compiler in self.environment.coredata.compilers.host.values():
# Have to detect the dependency format
# IFort on windows is MSVC like, but doesn't have /showincludes
@ -314,10 +318,12 @@ int dummy;
# http://clang.llvm.org/docs/JSONCompilationDatabase.html
def generate_compdb(self):
pch_compilers = ['%s_PCH' % i for i in self.environment.coredata.compilers]
native_compilers = ['%s_COMPILER' % i for i in self.environment.coredata.compilers]
cross_compilers = ['%s_CROSS_COMPILER' % i for i in self.environment.coredata.cross_compilers]
ninja_compdb = [self.ninja_command, '-t', 'compdb'] + pch_compilers + native_compilers + cross_compilers
rules = []
for for_machine in MachineChoice:
for lang in self.environment.coredata.compilers[for_machine]:
rules += [self.get_compiler_rule_name(lang, for_machine)]
rules += [self.get_pch_rule_name(lang, for_machine)]
ninja_compdb = [self.ninja_command, '-t', 'compdb'] + rules
builddir = self.environment.get_build_dir()
try:
jsondb = subprocess.check_output(ninja_compdb, cwd=builddir)
@ -663,13 +669,10 @@ int dummy;
# the project, we need to set PATH so the DLLs are found. We use
# a serialized executable wrapper for that and check if the
# CustomTarget command needs extra paths first.
is_cross = self.environment.is_cross_build() and \
self.environment.need_exe_wrapper()
if mesonlib.for_windows(is_cross, self.environment) or \
mesonlib.for_cygwin(is_cross, self.environment):
machine = self.environment.machines[target.for_machine]
if machine.is_windows() or machine.is_cygwin():
extra_bdeps = target.get_transitive_build_target_deps()
extra_paths = self.determine_windows_extra_paths(target.command[0],
extra_bdeps, is_cross)
extra_paths = self.determine_windows_extra_paths(target.command[0], extra_bdeps)
if extra_paths:
serialize = True
if serialize:
@ -846,9 +849,7 @@ int dummy;
self.add_rule_comment(NinjaComment('Rules for compiling.'))
self.generate_compile_rules()
self.add_rule_comment(NinjaComment('Rules for linking.'))
if self.environment.is_cross_build():
self.generate_static_link_rules(True)
self.generate_static_link_rules(False)
self.generate_static_link_rules()
self.generate_dynamic_link_rules()
self.add_rule_comment(NinjaComment('Other rules'))
# Ninja errors out if you have deps = gcc but no depfile, so we must
@ -1014,10 +1015,10 @@ int dummy;
for dep in target.get_external_deps():
commands.extend_direct(dep.get_link_args())
commands += self.build.get_project_args(compiler, target.subproject, target.is_cross)
commands += self.build.get_global_args(compiler, target.is_cross)
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, 'cs_COMPILER', rel_srcs + generated_rel_srcs)
elem = NinjaBuildElement(self.all_outputs, outputs, self.get_compiler_rule_name('cs', target.for_machine), rel_srcs + generated_rel_srcs)
elem.add_dep(deps)
elem.add_item('ARGS', commands)
self.add_build(elem)
@ -1028,8 +1029,8 @@ int dummy;
def determine_single_java_compile_args(self, target, compiler):
args = []
args += compiler.get_buildtype_args(self.get_option_for_target('buildtype', target))
args += self.build.get_global_args(compiler, target.is_cross)
args += self.build.get_project_args(compiler, target.subproject, target.is_cross)
args += self.build.get_global_args(compiler, target.for_machine)
args += self.build.get_project_args(compiler, target.subproject, target.for_machine)
args += target.get_java_args()
args += compiler.get_output_args(self.get_target_private_dir(target))
args += target.get_classpath_args()
@ -1051,7 +1052,7 @@ int dummy;
rel_src = src.rel_to_builddir(self.build_to_src)
plain_class_path = src.fname[:-4] + 'class'
rel_obj = os.path.join(self.get_target_private_dir(target), plain_class_path)
element = NinjaBuildElement(self.all_outputs, rel_obj, compiler.get_language() + '_COMPILER', rel_src)
element = NinjaBuildElement(self.all_outputs, rel_obj, self.compiler_to_rule_name(compiler), rel_src)
element.add_dep(deps)
element.add_item('ARGS', args)
self.add_build(element)
@ -1248,7 +1249,7 @@ int dummy;
extra_dep_files += dependency_vapis
args += extra_args
element = NinjaBuildElement(self.all_outputs, valac_outputs,
valac.get_language() + '_COMPILER',
self.compiler_to_rule_name(valac),
all_files + dependency_vapis)
element.add_item('ARGS', args)
element.add_dep(extra_dep_files)
@ -1285,8 +1286,8 @@ int dummy;
args += ['--crate-name', target.name]
args += rustc.get_buildtype_args(self.get_option_for_target('buildtype', target))
args += rustc.get_debug_args(self.get_option_for_target('debug', target))
args += self.build.get_global_args(rustc, target.is_cross)
args += self.build.get_project_args(rustc, target.subproject, target.is_cross)
args += self.build.get_global_args(rustc, target.for_machine)
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')
@ -1334,10 +1335,7 @@ int dummy;
# installations
for rpath_arg in rpath_args:
args += ['-C', 'link-arg=' + rpath_arg + ':' + os.path.join(rustc.get_sysroot(), 'lib')]
crstr = ''
if target.is_cross:
crstr = '_CROSS'
compiler_name = 'rust%s_COMPILER' % crstr
compiler_name = self.get_compiler_rule_name('rust', target.for_machine)
element = NinjaBuildElement(self.all_outputs, target_name, compiler_name, main_rust_file)
if len(orderdeps) > 0:
element.add_orderdep(orderdeps)
@ -1349,6 +1347,26 @@ int dummy;
self.generate_shsym(target)
self.create_target_source_introspection(target, rustc, args, [main_rust_file], [])
@staticmethod
def get_rule_suffix(for_machine: MachineChoice) -> str:
return PerMachine('_FOR_BUILD', '')[for_machine]
@classmethod
def get_compiler_rule_name(cls, lang: str, for_machine: MachineChoice) -> str:
return '%s_COMPILER%s' % (lang, cls.get_rule_suffix(for_machine))
@classmethod
def get_pch_rule_name(cls, lang: str, for_machine: MachineChoice) -> str:
return '%s_PCH%s' % (lang, cls.get_rule_suffix(for_machine))
@classmethod
def compiler_to_rule_name(cls, compiler: Compiler) -> str:
return cls.get_compiler_rule_name(compiler.get_language(), compiler.for_machine)
@classmethod
def compiler_to_pch_rule_name(cls, compiler: Compiler) -> str:
return cls.get_pch_rule_name(compiler.get_language(), compiler.for_machine)
def swift_module_file_name(self, target):
return os.path.join(self.get_target_private_dir(target),
self.target_swift_modulename(target) + '.swiftmodule')
@ -1417,8 +1435,8 @@ int dummy;
compile_args += swiftc.get_optimization_args(self.get_option_for_target('optimization', target))
compile_args += swiftc.get_debug_args(self.get_option_for_target('debug', target))
compile_args += swiftc.get_module_args(module_name)
compile_args += self.build.get_project_args(swiftc, target.subproject, target.is_cross)
compile_args += self.build.get_global_args(swiftc, target.is_cross)
compile_args += self.build.get_project_args(swiftc, target.subproject, target.for_machine)
compile_args += self.build.get_global_args(swiftc, target.for_machine)
for i in reversed(target.get_include_dirs()):
basedir = i.get_curdir()
for d in i.get_incdirs():
@ -1430,8 +1448,8 @@ int dummy;
sargs = swiftc.get_include_args(srctreedir)
compile_args += sargs
link_args = swiftc.get_output_args(os.path.join(self.environment.get_build_dir(), self.get_target_filename(target)))
link_args += self.build.get_project_link_args(swiftc, target.subproject, target.is_cross)
link_args += self.build.get_global_link_args(swiftc, target.is_cross)
link_args += self.build.get_project_link_args(swiftc, target.subproject, target.for_machine)
link_args += self.build.get_global_link_args(swiftc, target.for_machine)
rundir = self.get_target_private_dir(target)
out_module_name = self.swift_module_file_name(target)
in_module_files = self.determine_swift_dep_modules(target)
@ -1458,17 +1476,17 @@ 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)
# Swiftc does not seem to be able to emit objects and module files in one go.
elem = NinjaBuildElement(self.all_outputs, rel_objects,
'swift_COMPILER',
abssrc)
elem = NinjaBuildElement(self.all_outputs, rel_objects, rulename, abssrc)
elem.add_dep(in_module_files + rel_generated)
elem.add_dep(abs_headers)
elem.add_item('ARGS', compile_args + header_imports + abs_generated + module_includes)
elem.add_item('RUNDIR', rundir)
self.add_build(elem)
elem = NinjaBuildElement(self.all_outputs, out_module_name,
'swift_COMPILER',
self.get_compiler_rule_name('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())
@ -1476,10 +1494,10 @@ int dummy;
self.add_build(elem)
if isinstance(target, build.StaticLibrary):
elem = self.generate_link(target, self.get_target_filename(target),
rel_objects, self.build.static_linker)
rel_objects, self.build.static_linker[target.for_machine])
self.add_build(elem)
elif isinstance(target, build.Executable):
elem = NinjaBuildElement(self.all_outputs, self.get_target_filename(target), 'swift_COMPILER', [])
elem = NinjaBuildElement(self.all_outputs, self.get_target_filename(target), rulename, [])
elem.add_dep(rel_objects)
elem.add_dep(link_deps)
elem.add_item('ARGS', link_args + swiftc.get_std_exe_link_args() + objects + abs_link_deps)
@ -1490,61 +1508,49 @@ int dummy;
# Introspection information
self.create_target_source_introspection(target, swiftc, compile_args + header_imports + module_includes, relsrc, rel_generated)
def generate_static_link_rules(self, is_cross):
def generate_static_link_rules(self):
num_pools = self.environment.coredata.backend_options['backend_max_links'].value
if 'java' in self.environment.coredata.compilers:
if not is_cross:
self.generate_java_link()
if is_cross:
if self.environment.is_cross_build():
static_linker = self.build.static_cross_linker
if 'java' in self.environment.coredata.compilers.host:
self.generate_java_link()
for for_machine in MachineChoice:
static_linker = self.build.static_linker[for_machine]
if static_linker is None:
return
rule = 'STATIC_LINKER%s' % self.get_rule_suffix(for_machine)
cmdlist = []
args = ['$in']
# FIXME: Must normalize file names with pathlib.Path before writing
# them out to fix this properly on Windows. See:
# https://github.com/mesonbuild/meson/issues/1517
# https://github.com/mesonbuild/meson/issues/1526
if isinstance(static_linker, ArLinker) and not mesonlib.is_windows():
# `ar` has no options to overwrite archives. It always appends,
# which is never what we want. Delete an existing library first if
# it exists. https://github.com/mesonbuild/meson/issues/1355
cmdlist = execute_wrapper + [c.format('$out') for c in rmfile_prefix]
cmdlist += static_linker.get_exelist()
cmdlist += ['$LINK_ARGS']
cmdlist += static_linker.get_output_args('$out')
description = 'Linking static target $out.'
if num_pools > 0:
pool = 'pool = link_pool'
else:
static_linker = self.build.static_linker
crstr = '_CROSS'
else:
static_linker = self.build.static_linker
crstr = ''
if static_linker is None:
return
rule = 'STATIC%s_LINKER' % crstr
cmdlist = []
args = ['$in']
# FIXME: Must normalize file names with pathlib.Path before writing
# them out to fix this properly on Windows. See:
# https://github.com/mesonbuild/meson/issues/1517
# https://github.com/mesonbuild/meson/issues/1526
if isinstance(static_linker, ArLinker) and not mesonlib.is_windows():
# `ar` has no options to overwrite archives. It always appends,
# which is never what we want. Delete an existing library first if
# it exists. https://github.com/mesonbuild/meson/issues/1355
cmdlist = execute_wrapper + [c.format('$out') for c in rmfile_prefix]
cmdlist += static_linker.get_exelist()
cmdlist += ['$LINK_ARGS']
cmdlist += static_linker.get_output_args('$out')
description = 'Linking static target $out.'
if num_pools > 0:
pool = 'pool = link_pool'
else:
pool = None
self.add_rule(NinjaRule(rule, cmdlist, args, description,
rspable=static_linker.can_linker_accept_rsp(),
extra=pool))
pool = None
self.add_rule(NinjaRule(rule, cmdlist, args, description,
rspable=static_linker.can_linker_accept_rsp(),
extra=pool))
def generate_dynamic_link_rules(self):
num_pools = self.environment.coredata.backend_options['backend_max_links'].value
ctypes = [(self.environment.coredata.compilers, False),
(self.environment.coredata.cross_compilers, True)]
for (complist, is_cross) in ctypes:
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':
continue
crstr = ''
if is_cross:
crstr = '_CROSS'
rule = '%s%s_LINKER' % (langname, crstr)
rule = '%s_LINKER%s' % (langname, 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.'
@ -1568,14 +1574,14 @@ int dummy;
self.add_rule(NinjaRule(symrule, symcmd, [], syndesc, extra=synstat))
def generate_java_compile_rule(self, compiler):
rule = '%s_COMPILER' % compiler.get_language()
rule = self.compiler_to_rule_name(compiler)
invoc = [ninja_quote(i) for i in compiler.get_exelist()]
command = invoc + ['$ARGS', '$in']
description = 'Compiling Java object $in.'
self.add_rule(NinjaRule(rule, command, [], description))
def generate_cs_compile_rule(self, compiler):
rule = '%s_COMPILER' % compiler.get_language()
rule = self.compiler_to_rule_name(compiler)
invoc = [ninja_quote(i) for i in compiler.get_exelist()]
command = invoc
args = ['$ARGS', '$in']
@ -1584,17 +1590,14 @@ int dummy;
rspable=mesonlib.is_windows()))
def generate_vala_compile_rules(self, compiler):
rule = '%s_COMPILER' % compiler.get_language()
rule = self.compiler_to_rule_name(compiler)
invoc = [ninja_quote(i) for i in compiler.get_exelist()]
command = invoc + ['$ARGS', '$in']
description = 'Compiling Vala source $in.'
self.add_rule(NinjaRule(rule, command, [], description, extra='restat = 1'))
def generate_rust_compile_rules(self, compiler, is_cross):
crstr = ''
if is_cross:
crstr = '_CROSS'
rule = '%s%s_COMPILER' % (compiler.get_language(), crstr)
def generate_rust_compile_rules(self, compiler):
rule = self.compiler_to_rule_name(compiler)
invoc = [ninja_quote(i) for i in compiler.get_exelist()]
command = invoc + ['$ARGS', '$in']
description = 'Compiling Rust source $in.'
@ -1604,7 +1607,7 @@ int dummy;
depfile=depfile))
def generate_swift_compile_rules(self, compiler):
rule = '%s_COMPILER' % compiler.get_language()
rule = self.compiler_to_rule_name(compiler)
full_exe = [ninja_quote(x) for x in self.environment.get_build_command()] + [
'--internal',
'dirchanger',
@ -1626,44 +1629,41 @@ https://groups.google.com/forum/#!topic/ninja-build/j-2RfBIOd_8
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
self.add_rule(NinjaRule(rule, cmd, [], 'Dep hack', extra='restat = 1'))
def generate_llvm_ir_compile_rule(self, compiler, is_cross):
if getattr(self, 'created_llvm_ir_rule', False):
def generate_llvm_ir_compile_rule(self, compiler):
if self.created_llvm_ir_rule[compiler.for_machine]:
return
rule = 'llvm_ir{}_COMPILER'.format('_CROSS' if is_cross else '')
rule = self.get_compiler_rule_name('llvm_ir', compiler.for_machine)
command = [ninja_quote(i) for i in compiler.get_exelist()]
args = ['$ARGS'] + compiler.get_output_args('$out') + compiler.get_compile_only_args() + ['$in']
description = 'Compiling LLVM IR object $in.'
self.add_rule(NinjaRule(rule, command, args, description,
rspable=compiler.can_linker_accept_rsp()))
self.created_llvm_ir_rule = True
self.created_llvm_ir_rule[compiler.for_machine] = True
def generate_compile_rule_for(self, langname, compiler, is_cross):
def generate_compile_rule_for(self, langname, compiler):
if langname == 'java':
if not is_cross:
if self.environment.machines.matches_build_machine(compiler.for_machine):
self.generate_java_compile_rule(compiler)
return
if langname == 'cs':
if not is_cross:
if self.environment.machines.matches_build_machine(compiler.for_machine):
self.generate_cs_compile_rule(compiler)
return
if langname == 'vala':
if not is_cross:
if self.environment.machines.matches_build_machine(compiler.for_machine):
self.generate_vala_compile_rules(compiler)
return
if langname == 'rust':
self.generate_rust_compile_rules(compiler, is_cross)
self.generate_rust_compile_rules(compiler)
return
if langname == 'swift':
if not is_cross:
if self.environment.machines.matches_build_machine(compiler.for_machine):
self.generate_swift_compile_rules(compiler)
return
if is_cross:
crstr = '_CROSS'
else:
crstr = ''
crstr = self.get_rule_suffix(compiler.for_machine)
if langname == 'fortran':
self.generate_fortran_dep_hack(crstr)
rule = '%s%s_COMPILER' % (langname, crstr)
rule = self.get_compiler_rule_name(langname, compiler.for_machine)
depargs = compiler.get_dependency_gen_args('$out', '$DEPFILE')
quoted_depargs = []
for d in depargs:
@ -1684,14 +1684,10 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
rspable=compiler.can_linker_accept_rsp(),
deps=deps, depfile=depfile))
def generate_pch_rule_for(self, langname, compiler, is_cross):
def generate_pch_rule_for(self, langname, compiler):
if langname != 'c' and langname != 'cpp':
return
if is_cross:
crstr = '_CROSS'
else:
crstr = ''
rule = '%s%s_PCH' % (langname, crstr)
rule = self.compiler_to_pch_rule_name(compiler)
depargs = compiler.get_dependency_gen_args('$out', '$DEPFILE')
quoted_depargs = []
@ -1715,18 +1711,13 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
depfile=depfile))
def generate_compile_rules(self):
for langname, compiler in self.environment.coredata.compilers.items():
if compiler.get_id() == 'clang':
self.generate_llvm_ir_compile_rule(compiler, False)
self.generate_compile_rule_for(langname, compiler, False)
self.generate_pch_rule_for(langname, compiler, False)
if self.environment.is_cross_build():
cclist = self.environment.coredata.cross_compilers
for langname, compiler in cclist.items():
for for_machine in MachineChoice:
clist = self.environment.coredata.compilers[for_machine]
for langname, compiler in clist.items():
if compiler.get_id() == 'clang':
self.generate_llvm_ir_compile_rule(compiler, True)
self.generate_compile_rule_for(langname, compiler, True)
self.generate_pch_rule_for(langname, compiler, True)
self.generate_llvm_ir_compile_rule(compiler)
self.generate_compile_rule_for(langname, compiler)
self.generate_pch_rule_for(langname, compiler)
def generate_generator_list_rules(self, target):
# CustomTargets have already written their rules and
@ -1820,7 +1811,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
Find all module and submodule made available in a Fortran code file.
"""
compiler = None
for lang, c in self.environment.coredata.compilers.items():
# TODO other compilers
for lang, c in self.environment.coredata.compilers.host.items():
if lang == 'fortran':
compiler = c
break
@ -1881,7 +1873,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
return mod_files
def get_cross_stdlib_args(self, target, compiler):
if not target.is_cross:
if self.environment.machines.matches_build_machine(target.for_machine):
return []
if not self.environment.properties.host.has_stdlib(compiler.language):
return []
@ -1964,7 +1956,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
src_filename = src
obj_basename = src_filename.replace('/', '_').replace('\\', '_')
rel_obj = os.path.join(self.get_target_private_dir(target), obj_basename)
rel_obj += '.' + self.environment.get_object_suffix()
rel_obj += '.' + self.environment.machines[target.for_machine].get_object_suffix()
commands += self.get_compile_debugfile_args(compiler, target, rel_obj)
if isinstance(src, File) and src.is_built:
rel_src = src.fname
@ -1973,7 +1965,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
else:
raise InvalidArguments('Invalid source type: {!r}'.format(src))
# Write the Ninja build command
compiler_name = 'llvm_ir{}_COMPILER'.format('_CROSS' if target.is_cross else '')
compiler_name = self.get_compiler_rule_name('llvm_ir', compiler.for_machine)
element = NinjaBuildElement(self.all_outputs, rel_obj, compiler_name, rel_src)
# Convert from GCC-style link argument naming to the naming used by the
# current compiler.
@ -2161,10 +2153,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
arr.append(i)
pch_dep = arr
crstr = ''
if target.is_cross:
crstr = '_CROSS'
compiler_name = '%s%s_COMPILER' % (compiler.get_language(), crstr)
compiler_name = self.compiler_to_rule_name(compiler)
extra_deps = []
if compiler.get_language() == 'fortran':
# Can't read source file to scan for deps if it's generated later
@ -2181,6 +2170,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
compiler.module_name_to_filename(modname))
if srcfile == src:
crstr = self.get_rule_suffix(target.for_machine)
depelem = NinjaBuildElement(self.all_outputs, modfile, 'FORTRAN_DEP_HACK' + crstr, rel_obj)
self.add_build(depelem)
commands += compiler.get_module_outdir_args(self.get_target_private_dir(target))
@ -2268,10 +2258,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 []
cstr = ''
pch_objects = []
if target.is_cross:
cstr = '_CROSS'
for lang in ['c', 'cpp']:
pch = target.get_pch(lang)
if not pch:
@ -2293,7 +2280,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
(commands, dep, dst, objs) = self.generate_gcc_pch_command(target, compiler, pch[0])
extradep = None
pch_objects += objs
rulename = compiler.get_language() + cstr + '_PCH'
rulename = self.compiler_to_pch_rule_name(compiler)
elem = NinjaBuildElement(self.all_outputs, dst, rulename, src)
if extradep is not None:
elem.add_dep(extradep)
@ -2310,11 +2297,12 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
symname = os.path.join(targetdir, target_name + '.symbols')
elem = NinjaBuildElement(self.all_outputs, symname, 'SHSYM', target_file)
if self.environment.is_cross_build():
elem.add_item('CROSS', '--cross-host=' + self.environment.machines.host.system)
elem.add_item('CROSS', '--cross-host=' + self.environment.machines[target.for_machine].system)
self.add_build(elem)
def get_cross_stdlib_link_args(self, target, linker):
if isinstance(target, build.StaticLibrary) or not target.is_cross:
if isinstance(target, build.StaticLibrary) or \
self.environment.machines.matches_build_machine(target.for_machine):
return []
if not self.environment.properties.host.has_stdlib(linker.language):
return []
@ -2455,10 +2443,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
linker_base = linker.get_language() # Fixme.
if isinstance(target, build.SharedLibrary):
self.generate_shsym(target)
crstr = ''
if target.is_cross:
crstr = '_CROSS'
linker_rule = linker_base + crstr + '_LINKER'
crstr = self.get_rule_suffix(target.for_machine)
linker_rule = linker_base + '_LINKER' + crstr
# Create an empty commands list, and start adding link arguments from
# various sources in the order in which they must override each other
# starting from hard-coded defaults followed by build options and so on.
@ -2492,20 +2478,15 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
if not isinstance(target, build.StaticLibrary):
commands += self.get_link_whole_args(linker, target)
if self.environment.is_cross_build() and not target.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
if not isinstance(target, build.StaticLibrary):
# Add link args added using add_project_link_arguments()
commands += self.build.get_project_link_args(linker, target.subproject, target.is_cross)
commands += self.build.get_project_link_args(linker, target.subproject, target.for_machine)
# Add link args added using add_global_link_arguments()
# These override per-project link arguments
commands += self.build.get_global_link_args(linker, target.is_cross)
commands += self.build.get_global_link_args(linker, target.for_machine)
# Link args added from the env: LDFLAGS. We want these to override
# all the defaults but not the per-target link args.
commands += self.environment.coredata.get_external_link_args(for_machine, linker.get_language())
commands += self.environment.coredata.get_external_link_args(target.for_machine, linker.get_language())
# Now we will add libraries and library paths from various sources
@ -2544,7 +2525,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
# to be after all internal and external libraries so that unresolved
# symbols from those can be found here. This is needed when the
# *_winlibs that we want to link to are static mingw64 libraries.
commands += linker.get_option_link_args(self.environment.coredata.compiler_options[for_machine])
commands += linker.get_option_link_args(self.environment.coredata.compiler_options[target.for_machine])
dep_targets = []
dep_targets.extend(self.guess_external_link_dependencies(linker, target, commands, internal))

@ -27,7 +27,7 @@ from .. import mlog
from .. import compilers
from ..compilers import CompilerArgs
from ..mesonlib import (
MesonException, MachineChoice, File, python_command, replace_if_different
MesonException, File, python_command, replace_if_different
)
from ..environment import Environment, build_filename
@ -720,7 +720,7 @@ class Vs2010Backend(backends.Backend):
# 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.items():
for lang, c in self.environment.coredata.compilers[target.for_machine].items():
if lang in ('c', 'cpp'):
return c
raise MesonException('Could not find a C or C++ compiler. MSVC can only build C/C++ projects.')
@ -883,27 +883,23 @@ class Vs2010Backend(backends.Backend):
file_inc_dirs = dict((lang, []) for lang in target.compilers)
# The order in which these compile args are added must match
# generate_single_compile() and generate_basic_compiler_args()
if self.environment.is_cross_build() and not target.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
for l, comp in target.compilers.items():
if l in file_args:
file_args[l] += compilers.get_base_compile_args(self.get_base_options_for_target(target), comp)
file_args[l] += comp.get_option_compile_args(self.environment.coredata.compiler_options[for_machine])
file_args[l] += comp.get_option_compile_args(self.environment.coredata.compiler_options[target.for_machine])
# Add compile args added using add_project_arguments()
for l, args in self.build.projects_args.get(target.subproject, {}).items():
for l, args in self.build.projects_args[target.for_machine].get(target.subproject, {}).items():
if l in file_args:
file_args[l] += args
# Add compile args added using add_global_arguments()
# These override per-project arguments
for l, args in self.build.global_args.items():
for l, args in self.build.global_args[target.for_machine].items():
if l in file_args:
file_args[l] += args
# Compile args added from the env or cross file: CFLAGS/CXXFLAGS, etc. We want these
# to override all the defaults, but not the per-target compile args.
for key, opt in self.environment.coredata.compiler_options[for_machine].items():
for key, opt in self.environment.coredata.compiler_options[target.for_machine].items():
l, suffix = key.split('_', 1)
if suffix == 'args' and l in file_args:
file_args[l] += opt.value
@ -1083,14 +1079,14 @@ class Vs2010Backend(backends.Backend):
options = self.environment.coredata.base_options
extra_link_args += compiler.get_std_shared_module_link_args(options)
# Add link args added using add_project_link_arguments()
extra_link_args += self.build.get_project_link_args(compiler, target.subproject, target.is_cross)
extra_link_args += self.build.get_project_link_args(compiler, target.subproject, target.for_machine)
# Add link args added using add_global_link_arguments()
# These override per-project link arguments
extra_link_args += self.build.get_global_link_args(compiler, target.is_cross)
extra_link_args += self.build.get_global_link_args(compiler, target.for_machine)
# Link args added from the env: LDFLAGS, or the cross file. We want
# these to override all the defaults but not the per-target link
# args.
extra_link_args += self.environment.coredata.get_external_link_args(for_machine, compiler.get_language())
extra_link_args += self.environment.coredata.get_external_link_args(target.for_machine, compiler.get_language())
# Only non-static built targets need link args and link dependencies
extra_link_args += target.link_args
# External deps must be last because target link libraries may depend on them.
@ -1113,7 +1109,7 @@ class Vs2010Backend(backends.Backend):
# to be after all internal and external libraries so that unresolved
# symbols from those can be found here. This is needed when the
# *_winlibs that we want to link to are static mingw64 libraries.
extra_link_args += compiler.get_option_link_args(self.environment.coredata.compiler_options[for_machine])
extra_link_args += compiler.get_option_link_args(self.environment.coredata.compiler_options[compiler.for_machine])
(additional_libpaths, additional_links, extra_link_args) = self.split_link_args(extra_link_args.to_native())
# Add more libraries to be linked if needed

@ -742,10 +742,10 @@ class XCodeBackend(backends.Backend):
if lang not in langnamemap:
continue
# Add compile args added using add_project_arguments()
pargs = self.build.projects_args.get(target.subproject, {}).get(lang, [])
pargs = self.build.projects_args[target.for_machine].get(target.subproject, {}).get(lang, [])
# Add compile args added using add_global_arguments()
# These override per-project arguments
gargs = self.build.global_args.get(lang, [])
gargs = self.build.global_args[target.for_machine].get(lang, [])
targs = target.get_extra_args(lang)
args = pargs + gargs + targs
if args:

@ -12,7 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import List
import copy, os, re
from collections import OrderedDict
import itertools, pathlib
@ -25,12 +24,12 @@ from . import environment
from . import dependencies
from . import mlog
from .mesonlib import (
File, MesonException, listify, extract_as_list, OrderedSet,
typeslistify, stringlistify, classify_unity_sources,
get_filenames_templates_dict, substitute_values,
for_windows, for_darwin, for_cygwin, for_android, has_path_sep
File, MesonException, MachineChoice, PerMachine, OrderedSet, listify,
extract_as_list, typeslistify, stringlistify, classify_unity_sources,
get_filenames_templates_dict, substitute_values, has_path_sep,
)
from .compilers import Compiler, is_object, clink_langs, sort_clink, lang_suffixes, get_macos_dylib_install_name
from .linkers import StaticLinker
from .interpreterbase import FeatureNew
pch_kwargs = set(['c_pch', 'cpp_pch'])
@ -114,21 +113,16 @@ class Build:
self.environment = environment
self.projects = {}
self.targets = OrderedDict()
self.global_args = {}
self.projects_args = {}
self.global_link_args = {}
self.projects_link_args = {}
self.cross_global_args = {}
self.cross_projects_args = {}
self.cross_global_link_args = {}
self.cross_projects_link_args = {}
self.global_args = PerMachine({}, {}) # type: PerMachine[typing.Dict[str, typing.List[str]]]
self.projects_args = PerMachine({}, {}) # type: PerMachine[typing.Dict[str, typing.List[str]]]
self.global_link_args = PerMachine({}, {}) # type: PerMachine[typing.Dict[str, typing.List[str]]]
self.projects_link_args = PerMachine({}, {}) # type: PerMachine[typing.Dict[str, typing.List[str]]]
self.tests = []
self.benchmarks = []
self.headers = []
self.man = []
self.data = []
self.static_linker = None
self.static_cross_linker = None
self.static_linker = PerMachine(None, None) # type: PerMachine[StaticLinker]
self.subprojects = {}
self.subproject_dir = ''
self.install_scripts = []
@ -137,7 +131,7 @@ class Build:
self.install_dirs = []
self.dep_manifest_name = None
self.dep_manifest = {}
self.cross_stdlibs = {}
self.stdlibs = PerMachine({}, {})
self.test_setups = {} # type: typing.Dict[str, TestSetup]
self.test_setup_default_name = None
self.find_overrides = {}
@ -157,12 +151,8 @@ class Build:
self.__dict__[k] = v
def ensure_static_linker(self, compiler):
if self.static_linker is None and compiler.needs_static_linker():
self.static_linker = self.environment.detect_static_linker(compiler)
def ensure_static_cross_linker(self, compiler):
if self.static_cross_linker is None and compiler.needs_static_linker():
self.static_cross_linker = self.environment.detect_static_linker(compiler)
if self.static_linker[compiler.for_machine] is None and compiler.needs_static_linker():
self.static_linker[compiler.for_machine] = self.environment.detect_static_linker(compiler)
def get_project(self):
return self.projects['']
@ -191,23 +181,23 @@ class Build:
def get_install_subdirs(self):
return self.install_dirs
def get_global_args(self, compiler, for_cross):
d = self.cross_global_args if for_cross else self.global_args
def get_global_args(self, compiler, for_machine):
d = self.global_args[for_machine]
return d.get(compiler.get_language(), [])
def get_project_args(self, compiler, project, for_cross):
d = self.cross_projects_args if for_cross else self.projects_args
def get_project_args(self, compiler, project, for_machine):
d = self.projects_args[for_machine]
args = d.get(project)
if not args:
return []
return args.get(compiler.get_language(), [])
def get_global_link_args(self, compiler, for_cross):
d = self.cross_global_link_args if for_cross else self.global_link_args
def get_global_link_args(self, compiler, for_machine):
d = self.global_link_args[for_machine]
return d.get(compiler.get_language(), [])
def get_project_link_args(self, compiler, project, for_cross):
d = self.cross_projects_link_args if for_cross else self.projects_link_args
def get_project_link_args(self, compiler, project, for_machine):
d = self.projects_link_args[for_machine]
link_args = d.get(project)
if not link_args:
@ -336,7 +326,7 @@ class EnvironmentVariables:
return env
class Target:
def __init__(self, name, subdir, subproject, build_by_default):
def __init__(self, name, subdir, subproject, build_by_default, for_machine: MachineChoice):
if has_path_sep(name):
# Fix failing test 53 when this becomes an error.
mlog.warning('''Target "%s" has a path separator in its name.
@ -346,6 +336,7 @@ a hard error in the future.''' % name)
self.subdir = subdir
self.subproject = subproject
self.build_by_default = build_by_default
self.for_machine = for_machine
self.install = False
self.build_always_stale = False
self.option_overrides = {}
@ -438,9 +429,8 @@ a hard error in the future.''' % name)
class BuildTarget(Target):
known_kwargs = known_build_target_kwargs
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
super().__init__(name, subdir, subproject, True)
self.is_cross = is_cross
def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources, objects, environment, kwargs):
super().__init__(name, subdir, subproject, True, for_machine)
unity_opt = environment.coredata.get_builtin_option('unity')
self.is_unity = unity_opt == 'on' or (unity_opt == 'subprojects' and subproject != '')
self.environment = environment
@ -483,7 +473,7 @@ class BuildTarget(Target):
raise InvalidArguments('Build target %s has no sources.' % name)
self.process_compilers_late()
self.validate_sources()
self.validate_cross_install(environment)
self.validate_install(environment)
self.check_module_linking()
def __lt__(self, other):
@ -493,9 +483,12 @@ class BuildTarget(Target):
repr_str = "<{0} {1}: {2}>"
return repr_str.format(self.__class__.__name__, self.get_id(), self.filename)
def validate_cross_install(self, environment):
if environment.is_cross_build() and not self.is_cross and self.need_install:
raise InvalidArguments('Tried to install a natively built target in a cross build.')
def validate_install(self, environment):
if self.for_machine is MachineChoice.BUILD and self.need_install:
if environment.is_cross_build():
raise InvalidArguments('Tried to install a target for the build machine in a cross build.')
else:
mlog.warning('Installing target build for the build machine. This will fail in a cross build.')
def check_unknown_kwargs(self, kwargs):
# Override this method in derived classes that have more
@ -562,10 +555,7 @@ class BuildTarget(Target):
which compiler to use if one hasn't been selected already.
"""
# Populate list of compilers
if self.is_cross:
compilers = self.environment.coredata.cross_compilers
else:
compilers = self.environment.coredata.compilers
compilers = self.environment.coredata.compilers[self.for_machine]
# did user override clink_langs for this target?
link_langs = [self.link_language] if self.link_language else clink_langs
@ -602,10 +592,7 @@ class BuildTarget(Target):
if not self.sources and not self.generated and not self.objects:
return
# Populate list of compilers
if self.is_cross:
compilers = self.environment.coredata.cross_compilers
else:
compilers = self.environment.coredata.compilers
compilers = self.environment.coredata.compilers[self.for_machine]
# Pre-existing sources
sources = list(self.sources)
# All generated sources
@ -928,13 +915,14 @@ This will become a hard error in a future Meson release.''')
# You can't disable PIC on OS X. The compiler ignores -fno-PIC.
# PIC is always on for Windows (all code is position-independent
# since library loading is done differently)
if for_darwin(self.is_cross, self.environment) or for_windows(self.is_cross, self.environment):
m = self.environment.machines[self.for_machine]
if m.is_darwin() or m.is_windows():
self.pic = True
else:
self.pic = self._extract_pic_pie(kwargs, 'pic')
if isinstance(self, Executable):
# Executables must be PIE on Android
if for_android(self.is_cross, self.environment):
if self.environment.machines[self.for_machine].is_android():
self.pie = True
else:
self.pie = self._extract_pic_pie(kwargs, 'pie')
@ -1073,8 +1061,12 @@ You probably should put it in link_with instead.''')
msg = "Can't link non-PIC static library {!r} into shared library {!r}. ".format(t.name, self.name)
msg += "Use the 'pic' option to static_library to build with PIC."
raise InvalidArguments(msg)
if not isinstance(t, (CustomTarget, CustomTargetIndex)) and self.is_cross != t.is_cross:
raise InvalidArguments('Tried to mix cross built and native libraries in target {!r}'.format(self.name))
if self.for_machine is not t.for_machine:
msg = 'Tried to mix libraries for machines {1} and {2} in target {!r}'.format(self.name, self.for_machine, t.for_machine)
if self.environment.is_cross_build():
raise InvalidArguments(msg + ' This is not possible in a cross build.')
else:
mlog.warning(msg + ' This will fail in cross build.')
self.link_targets.append(t)
def link_whole(self, target):
@ -1090,8 +1082,12 @@ You probably should put it in link_with instead.''')
msg = "Can't link non-PIC static library {!r} into shared library {!r}. ".format(t.name, self.name)
msg += "Use the 'pic' option to static_library to build with PIC."
raise InvalidArguments(msg)
if not isinstance(t, (CustomTarget, CustomTargetIndex)) and self.is_cross != t.is_cross:
raise InvalidArguments('Tried to mix cross built and native libraries in target {!r}'.format(self.name))
if self.for_machine is not t.for_machine:
msg = 'Tried to mix libraries for machines {1} and {2} in target {!r}'.format(self.name, self.for_machine, t.for_machine)
if self.environment.is_cross_build():
raise InvalidArguments(msg + ' This is not possible in a cross build.')
else:
mlog.warning(msg + ' This will fail in cross build.')
self.link_whole_targets.append(t)
def add_pch(self, language, pchlist):
@ -1148,7 +1144,7 @@ You probably should put it in link_with instead.''')
def get_aliases(self):
return {}
def get_langs_used_by_deps(self) -> List[str]:
def get_langs_used_by_deps(self) -> typing.List[str]:
'''
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++
@ -1192,10 +1188,7 @@ You probably should put it in link_with instead.''')
'''
# Populate list of all compilers, not just those being used to compile
# sources in this target
if self.is_cross:
all_compilers = self.environment.coredata.cross_compilers
else:
all_compilers = self.environment.coredata.compilers
all_compilers = self.environment.coredata.compilers[self.for_machine]
# Languages used by dependencies
dep_langs = self.get_langs_used_by_deps()
# Pick a compiler based on the language priority-order
@ -1253,7 +1246,7 @@ You probably should put it in link_with instead.''')
'''
for link_target in self.link_targets:
if isinstance(link_target, SharedModule):
if for_darwin(self.is_cross, self.environment):
if self.environment.machines[self.for_machine].is_darwin():
raise MesonException('''target links against shared modules.
This is not permitted on OSX''')
else:
@ -1425,19 +1418,19 @@ class GeneratedList:
class Executable(BuildTarget):
known_kwargs = known_exe_kwargs
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources, objects, environment, kwargs):
self.typename = 'executable'
if 'pie' not in kwargs and 'b_pie' in environment.coredata.base_options:
kwargs['pie'] = environment.coredata.base_options['b_pie'].value
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
# Unless overridden, executables have no suffix or prefix. Except on
# Windows and with C#/Mono executables where the suffix is 'exe'
if not hasattr(self, 'prefix'):
self.prefix = ''
if not hasattr(self, 'suffix'):
machine = environment.machines[for_machine]
# Executable for Windows or C#/Mono
if (for_windows(is_cross, environment) or
for_cygwin(is_cross, environment) or 'cs' in self.compilers):
if machine.is_windows() or machine.is_cygwin() or 'cs' in self.compilers:
self.suffix = 'exe'
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')):
@ -1446,7 +1439,7 @@ class Executable(BuildTarget):
'cpp' in self.compilers and self.compilers['cpp'].get_id().startswith('ccrx')):
self.suffix = 'abs'
else:
self.suffix = ''
self.suffix = environment.machines[for_machine].get_exe_suffix()
self.filename = self.name
if self.suffix:
self.filename += '.' + self.suffix
@ -1475,7 +1468,8 @@ class Executable(BuildTarget):
implib_basename = self.name + '.exe'
if not isinstance(kwargs.get('implib', False), bool):
implib_basename = kwargs['implib']
if for_windows(is_cross, environment) or for_cygwin(is_cross, environment):
m = environment.machines[for_machine]
if m.is_windows() or m.is_cygwin():
self.vs_import_filename = '{0}.lib'.format(implib_basename)
self.gcc_import_filename = 'lib{0}.a'.format(implib_basename)
if self.get_using_msvc():
@ -1515,11 +1509,11 @@ class Executable(BuildTarget):
class StaticLibrary(BuildTarget):
known_kwargs = known_stlib_kwargs
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources, objects, environment, kwargs):
self.typename = 'static library'
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, is_cross, sources, objects, environment, kwargs)
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
if 'cs' in self.compilers:
raise InvalidArguments('Static libraries not supported for C#.')
if 'rust' in self.compilers:
@ -1575,7 +1569,7 @@ class StaticLibrary(BuildTarget):
class SharedLibrary(BuildTarget):
known_kwargs = known_shlib_kwargs
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources, objects, environment, kwargs):
self.typename = 'shared library'
self.soversion = None
self.ltversion = None
@ -1588,7 +1582,7 @@ class SharedLibrary(BuildTarget):
self.vs_import_filename = None
# The import library that GCC would generate (and prefer)
self.gcc_import_filename = None
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
if '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':
@ -1602,7 +1596,7 @@ class SharedLibrary(BuildTarget):
if not hasattr(self, 'suffix'):
self.suffix = None
self.basic_filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
self.determine_filenames(is_cross, environment)
self.determine_filenames(environment)
def get_link_deps_mapping(self, prefix, environment):
result = {}
@ -1619,7 +1613,7 @@ class SharedLibrary(BuildTarget):
def get_default_install_dir(self, environment):
return environment.get_shared_lib_dir()
def determine_filenames(self, is_cross, env):
def determine_filenames(self, env):
"""
See https://github.com/mesonbuild/meson/pull/417 for details.
@ -1652,7 +1646,7 @@ class SharedLibrary(BuildTarget):
# C, C++, Swift, Vala
# Only Windows uses a separate import library for linking
# For all other targets/platforms import_filename stays None
elif for_windows(is_cross, env):
elif env.machines[self.for_machine].is_windows():
suffix = 'dll'
self.vs_import_filename = '{0}{1}.lib'.format(self.prefix if self.prefix is not None else '', self.name)
self.gcc_import_filename = '{0}{1}.dll.a'.format(self.prefix if self.prefix is not None else 'lib', self.name)
@ -1677,7 +1671,7 @@ class SharedLibrary(BuildTarget):
self.filename_tpl = '{0.prefix}{0.name}-{0.soversion}.{0.suffix}'
else:
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
elif for_cygwin(is_cross, env):
elif env.machines[self.for_machine].is_cygwin():
suffix = 'dll'
self.gcc_import_filename = '{0}{1}.dll.a'.format(self.prefix if self.prefix is not None else 'lib', self.name)
# Shared library is of the form cygfoo.dll
@ -1689,7 +1683,7 @@ class SharedLibrary(BuildTarget):
self.filename_tpl = '{0.prefix}{0.name}-{0.soversion}.{0.suffix}'
else:
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
elif for_darwin(is_cross, env):
elif env.machines[self.for_machine].is_darwin():
prefix = 'lib'
suffix = 'dylib'
# On macOS, the filename can only contain the major version
@ -1699,7 +1693,7 @@ class SharedLibrary(BuildTarget):
else:
# libfoo.dylib
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
elif for_android(is_cross, env):
elif env.machines[self.for_machine].is_android():
prefix = 'lib'
suffix = 'so'
# Android doesn't support shared_library versioning
@ -1764,7 +1758,7 @@ class SharedLibrary(BuildTarget):
def process_kwargs(self, kwargs, environment):
super().process_kwargs(kwargs, environment)
if not for_android(self.is_cross, self.environment):
if not self.environment.machines[self.for_machine].is_android():
supports_versioning = True
else:
supports_versioning = False
@ -1884,12 +1878,12 @@ class SharedLibrary(BuildTarget):
class SharedModule(SharedLibrary):
known_kwargs = known_shmod_kwargs
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources, objects, environment, kwargs):
if 'version' in kwargs:
raise MesonException('Shared modules must not specify the version kwarg.')
if 'soversion' in kwargs:
raise MesonException('Shared modules must not specify the soversion kwarg.')
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
self.typename = 'shared module'
def get_default_install_dir(self, environment):
@ -1917,7 +1911,8 @@ class CustomTarget(Target):
def __init__(self, name, subdir, subproject, kwargs, absolute_paths=False):
self.typename = 'custom'
super().__init__(name, subdir, subproject, False)
# TODO expose keyword arg to make MachineChoice.HOST configurable
super().__init__(name, subdir, subproject, False, MachineChoice.HOST)
self.dependencies = []
self.extra_depends = []
self.depend_files = [] # Files that this target depends on but are not on the command line.
@ -2171,7 +2166,8 @@ class CustomTarget(Target):
class RunTarget(Target):
def __init__(self, name, command, args, dependencies, subdir, subproject):
self.typename = 'run'
super().__init__(name, subdir, subproject, False)
# These don't produce output artifacts
super().__init__(name, subdir, subproject, False, MachineChoice.BUILD)
self.command = command
self.args = args
self.dependencies = dependencies
@ -2212,9 +2208,9 @@ class RunTarget(Target):
class Jar(BuildTarget):
known_kwargs = known_jar_kwargs
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
def __init__(self, name, subdir, subproject, for_machine: MachineChoice, sources, objects, environment, kwargs):
self.typename = 'jar'
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
super().__init__(name, subdir, subproject, for_machine, sources, objects, environment, kwargs)
for s in self.sources:
if not s.endswith('.java'):
raise InvalidArguments('Jar source %s is not a java file.' % s)
@ -2234,7 +2230,7 @@ class Jar(BuildTarget):
def get_java_args(self):
return self.java_args
def validate_cross_install(self, environment):
def validate_install(self, environment):
# All jar targets are installable.
pass
@ -2260,6 +2256,7 @@ class CustomTargetIndex:
self.typename = 'custom'
self.target = target
self.output = output
self.for_machine = target.for_machine
def __repr__(self):
return '<CustomTargetIndex: {!r}[{}]>'.format(

@ -18,6 +18,7 @@
from .common import CMakeException
from ..environment import Environment
from ..dependencies.base import CMakeDependency, ExternalProgram
from ..mesonlib import MachineChoice
from .. import mlog
from contextlib import contextmanager
from subprocess import Popen, PIPE, TimeoutExpired
@ -473,8 +474,8 @@ class CMakeClient:
def startup(self) -> None:
if self.proc is not None:
raise CMakeException('The CMake server was already started')
cmake_exe, cmake_vers, _ = CMakeDependency.find_cmake_binary(self.env)
for_machine = MachineChoice.HOST # TODO make parameter
cmake_exe, cmake_vers, _ = CMakeDependency.find_cmake_binary(self.env, for_machine)
if cmake_exe is None or cmake_exe is False:
raise CMakeException('Unable to find CMake')
assert(isinstance(cmake_exe, ExternalProgram))

@ -20,6 +20,7 @@ from .client import CMakeClient, RequestCMakeInputs, RequestConfigure, RequestCo
from .. import mlog
from ..build import Build
from ..environment import Environment
from ..mesonlib import MachineChoice
from ..mparser import Token, BaseNode, CodeBlockNode, FunctionNode, ArrayNode, ArgumentNode, AssignmentNode, BooleanNode, StringNode, IdNode, MethodNode
from ..backend.backends import Backend
from ..compilers.compilers import lang_suffixes, header_suffixes, obj_suffixes
@ -300,8 +301,9 @@ class CMakeInterpreter:
self.generated_targets = {}
def configure(self, extra_cmake_options: List[str]) -> None:
for_machine = MachineChoice.HOST # TODO make parameter
# Find CMake
cmake_exe, cmake_vers, _ = CMakeDependency.find_cmake_binary(self.env)
cmake_exe, cmake_vers, _ = CMakeDependency.find_cmake_binary(self.env, for_machine)
if cmake_exe is None or cmake_exe is False:
raise CMakeException('Unable to find CMake')
assert(isinstance(cmake_exe, ExternalProgram))
@ -312,7 +314,7 @@ class CMakeInterpreter:
cmake_args = cmake_exe.get_command()
# Map meson compiler to CMake variables
for lang, comp in self.env.coredata.compilers.items():
for lang, comp in self.env.coredata.compilers[for_machine].items():
if lang not in language_map:
continue
cmake_lang = language_map[lang]

@ -16,7 +16,7 @@ import os.path
import typing
from .. import coredata
from ..mesonlib import MesonException, version_compare, mlog
from ..mesonlib import MachineChoice, MesonException, mlog, version_compare
from .c_function_attributes import C_FUNC_ATTRIBUTES
from .clike import CLikeCompiler
@ -47,11 +47,11 @@ class CCompiler(CLikeCompiler, Compiler):
except KeyError:
raise MesonException('Unknown function attribute "{}"'.format(name))
def __init__(self, exelist, version, is_cross: bool,
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool,
exe_wrapper: typing.Optional[str] = None, **kwargs):
# If a child ObjC or CPP class has already set it, don't set it ourselves
self.language = 'c'
Compiler.__init__(self, exelist, version, **kwargs)
Compiler.__init__(self, exelist, version, for_machine, **kwargs)
CLikeCompiler.__init__(self, is_cross, exe_wrapper)
def get_no_stdinc_args(self):
@ -76,8 +76,8 @@ class CCompiler(CLikeCompiler, Compiler):
class ClangCCompiler(ClangCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
ClangCompiler.__init__(self, compiler_type)
default_warn_args = ['-Wall', '-Winvalid-pch']
self.warn_args = {'0': [],
@ -119,8 +119,8 @@ class ClangCCompiler(ClangCompiler, CCompiler):
class ArmclangCCompiler(ArmclangCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
ArmclangCompiler.__init__(self, compiler_type)
default_warn_args = ['-Wall', '-Winvalid-pch']
self.warn_args = {'0': [],
@ -148,8 +148,8 @@ class ArmclangCCompiler(ArmclangCompiler, CCompiler):
class GnuCCompiler(GnuCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, defines=None, **kwargs):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
GnuCompiler.__init__(self, compiler_type, defines)
default_warn_args = ['-Wall', '-Winvalid-pch']
self.warn_args = {'0': [],
@ -191,14 +191,14 @@ class GnuCCompiler(GnuCompiler, CCompiler):
class PGICCompiler(PGICompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
PGICompiler.__init__(self, compiler_type)
class ElbrusCCompiler(GnuCCompiler, ElbrusCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None, **kwargs):
GnuCCompiler.__init__(self, exelist, version, compiler_type, is_cross, exe_wrapper, defines, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, defines=None, **kwargs):
GnuCCompiler.__init__(self, exelist, version, compiler_type, for_machine, is_cross, exe_wrapper, defines, **kwargs)
ElbrusCompiler.__init__(self, compiler_type, defines)
# It does support some various ISO standards and c/gnu 90, 9x, 1x in addition to those which GNU CC supports.
@ -223,8 +223,8 @@ class ElbrusCCompiler(GnuCCompiler, ElbrusCompiler):
class IntelCCompiler(IntelGnuLikeCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
IntelGnuLikeCompiler.__init__(self, compiler_type)
self.lang_header = 'c-header'
default_warn_args = ['-Wall', '-w3', '-diag-disable:remark']
@ -267,14 +267,14 @@ class VisualStudioLikeCCompilerMixin:
class VisualStudioCCompiler(VisualStudioLikeCompiler, VisualStudioLikeCCompilerMixin, CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap, target: str):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrap, target: str):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrap)
VisualStudioLikeCompiler.__init__(self, target)
self.id = 'msvc'
class ClangClCCompiler(VisualStudioLikeCompiler, VisualStudioLikeCCompilerMixin, CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap, target):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrap, target):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrap)
VisualStudioLikeCompiler.__init__(self, target)
self.id = 'clang-cl'
@ -285,8 +285,8 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM
__have_warned = False
def __init__(self, exelist, version, is_cross, exe_wrap, target):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrap, target):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrap)
IntelVisualStudioLikeCompiler.__init__(self, target)
def get_options(self):
@ -310,8 +310,8 @@ class IntelClCCompiler(IntelVisualStudioLikeCompiler, VisualStudioLikeCCompilerM
class ArmCCompiler(ArmCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
ArmCompiler.__init__(self, compiler_type)
def get_options(self):
@ -329,8 +329,8 @@ class ArmCCompiler(ArmCompiler, CCompiler):
return args
class CcrxCCompiler(CcrxCompiler, CCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
CcrxCompiler.__init__(self, compiler_type)
# Override CCompiler.get_always_args

@ -30,7 +30,7 @@ import typing
from pathlib import Path
from .. import mesonlib
from ..mesonlib import MachineChoice, LibType
from ..mesonlib import LibType
from .. import mlog
from . import compilers
@ -274,9 +274,10 @@ class CLikeCompiler:
return []
def gen_export_dynamic_link_args(self, env):
if mesonlib.for_windows(env.is_cross_build(), env) or mesonlib.for_cygwin(env.is_cross_build(), env):
m = env.machines[self.for_machine]
if m.is_windows() or m.is_cygwin():
return ['-Wl,--export-all-symbols']
elif mesonlib.for_darwin(env.is_cross_build(), env):
elif env.machines[self.for_machine].is_darwin():
return []
else:
return ['-Wl,-export-dynamic']
@ -383,13 +384,9 @@ class CLikeCompiler:
# Select a CRT if needed since we're linking
if mode == 'link':
args += self.get_linker_debug_crt_args()
if env.is_cross_build() and not self.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
if mode in {'compile', 'preprocess'}:
# Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env
sys_args = env.coredata.get_external_args(for_machine, self.language)
sys_args = env.coredata.get_external_args(self.for_machine, self.language)
# Apparently it is a thing to inject linker flags both
# via CFLAGS _and_ LDFLAGS, even though the former are
# also used during linking. These flags can break
@ -398,7 +395,7 @@ class CLikeCompiler:
args += cleaned_sys_args
elif mode == 'link':
# Add LDFLAGS from the env
args += env.coredata.get_external_link_args(for_machine, self.language)
args += env.coredata.get_external_link_args(self.for_machine, self.language)
return args
def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
@ -884,7 +881,7 @@ class CLikeCompiler:
for p in prefixes:
for s in suffixes:
patterns.append(p + '{}.' + s)
if shared and mesonlib.for_openbsd(self.is_cross, env):
if shared and env.machines[self.for_machine].is_openbsd():
# Shared libraries on OpenBSD can be named libfoo.so.X.Y:
# https://www.openbsd.org/faq/ports/specialtopics.html#SharedLibs
#
@ -911,9 +908,9 @@ class CLikeCompiler:
else:
prefixes = ['lib', '']
# Library suffixes and prefixes
if mesonlib.for_darwin(env.is_cross_build(), env):
if env.machines[self.for_machine].is_darwin():
shlibext = ['dylib', 'so']
elif mesonlib.for_windows(env.is_cross_build(), env):
elif env.machines[self.for_machine].is_windows():
# FIXME: .lib files can be import or static so we should read the
# file, figure out which one it is, and reject the wrong kind.
if isinstance(self, compilers.VisualStudioLikeCompiler):
@ -922,7 +919,7 @@ class CLikeCompiler:
shlibext = ['dll.a', 'lib', 'dll']
# Yep, static libraries can also be foo.lib
stlibext += ['lib']
elif mesonlib.for_cygwin(env.is_cross_build(), env):
elif env.machines[self.for_machine].is_cygwin():
shlibext = ['dll', 'dll.a']
prefixes = ['cyg'] + prefixes
else:
@ -1073,11 +1070,7 @@ class CLikeCompiler:
commands = self.get_exelist() + ['-v', '-E', '-']
commands += self.get_always_args()
# Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS from the env
if env.is_cross_build() and not self.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
commands += env.coredata.get_external_args(for_machine, self.language)
commands += env.coredata.get_external_args(self.for_machine, self.language)
mlog.debug('Finding framework path by running: ', ' '.join(commands), '\n')
os_env = os.environ.copy()
os_env['LC_ALL'] = 'C'
@ -1126,12 +1119,14 @@ class CLikeCompiler:
return self.find_framework_impl(name, env, extra_dirs, allow_system)
def thread_flags(self, env):
if mesonlib.for_haiku(self.is_cross, env) or mesonlib.for_darwin(self.is_cross, env):
host_m = env.machines[self.for_machine]
if host_m.is_haiku() or host_m.is_darwin():
return []
return ['-pthread']
def thread_link_flags(self, env):
if mesonlib.for_haiku(self.is_cross, env) or mesonlib.for_darwin(self.is_cross, env):
host_m = env.machines[self.for_machine]
if host_m.is_haiku() or host_m.is_darwin():
return []
return ['-pthread']
@ -1189,8 +1184,8 @@ class CLikeCompiler:
def has_func_attribute(self, name, env):
# Just assume that if we're not on windows that dllimport and dllexport
# don't work
if not (mesonlib.for_windows(env.is_cross_build(), env) or
mesonlib.for_cygwin(env.is_cross_build(), env)):
m = env.machines[self.for_machine]
if not (m.is_windows() or m.is_cygwin()):
if name in ['dllimport', 'dllexport']:
return False, False

@ -21,7 +21,7 @@ from .. import coredata
from .. import mlog
from .. import mesonlib
from ..mesonlib import (
EnvironmentException, MesonException, OrderedSet,
EnvironmentException, MachineChoice, MesonException, OrderedSet,
version_compare, Popen_safe
)
from ..envconfig import (
@ -871,7 +871,7 @@ class Compiler:
# manually searched.
internal_libs = ()
def __init__(self, exelist, version, **kwargs):
def __init__(self, exelist, version, for_machine: MachineChoice, **kwargs):
if isinstance(exelist, str):
self.exelist = [exelist]
elif isinstance(exelist, list):
@ -889,6 +889,7 @@ class Compiler:
self.full_version = kwargs['full_version']
else:
self.full_version = None
self.for_machine = for_machine
self.base_options = []
def __repr__(self):
@ -2183,7 +2184,7 @@ class ClangCompiler(GnuLikeCompiler):
class ArmclangCompiler:
def __init__(self, compiler_type):
if not self.is_cross:
if self.is_cross:
raise EnvironmentException('armclang supports only cross-compilation.')
# Check whether 'armlink.exe' is available in path
self.linker_exe = 'armlink.exe'

@ -19,7 +19,7 @@ import typing
from .. import coredata
from .. import mlog
from ..mesonlib import MesonException, version_compare
from ..mesonlib import MesonException, MachineChoice, version_compare
from .compilers import (
gnu_winlibs,
@ -55,11 +55,11 @@ class CPPCompiler(CLikeCompiler, Compiler):
except KeyError:
raise MesonException('Unknown function attribute "{}"'.format(name))
def __init__(self, exelist, version, is_cross: bool,
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool,
exe_wrap: typing.Optional[str] = None, **kwargs):
# If a child ObjCPP class has already set it, don't set it ourselves
self.language = 'cpp'
Compiler.__init__(self, exelist, version, **kwargs)
Compiler.__init__(self, exelist, version, for_machine, **kwargs)
CLikeCompiler.__init__(self, is_cross, exe_wrap)
def get_display_language(self):
@ -147,8 +147,8 @@ class CPPCompiler(CLikeCompiler, Compiler):
class ClangCPPCompiler(ClangCompiler, CPPCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
ClangCompiler.__init__(self, compiler_type)
default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
self.warn_args = {'0': [],
@ -185,8 +185,8 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler):
class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
ArmclangCompiler.__init__(self, compiler_type)
default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
self.warn_args = {'0': [],
@ -221,8 +221,8 @@ class ArmclangCPPCompiler(ArmclangCompiler, CPPCompiler):
class GnuCPPCompiler(GnuCompiler, CPPCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrap, defines, **kwargs):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrap, defines, **kwargs):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrap, **kwargs)
GnuCompiler.__init__(self, compiler_type, defines)
default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
self.warn_args = {'0': [],
@ -272,14 +272,14 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
class PGICPPCompiler(PGICompiler, CPPCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
PGICompiler.__init__(self, compiler_type)
class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None, **kwargs):
GnuCPPCompiler.__init__(self, exelist, version, compiler_type, is_cross, exe_wrapper, defines, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, defines=None, **kwargs):
GnuCPPCompiler.__init__(self, exelist, version, compiler_type, for_machine, is_cross, exe_wrapper, defines, **kwargs)
ElbrusCompiler.__init__(self, compiler_type, defines)
# It does not support c++/gnu++ 17 and 1z, but still does support 0x, 1y, and gnu++98.
@ -308,8 +308,8 @@ class ElbrusCPPCompiler(GnuCPPCompiler, ElbrusCompiler):
class IntelCPPCompiler(IntelGnuLikeCompiler, CPPCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrap, **kwargs):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrap, **kwargs):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrap, **kwargs)
IntelGnuLikeCompiler.__init__(self, compiler_type)
self.lang_header = 'c++-header'
default_warn_args = ['-Wall', '-w3', '-diag-disable:remark',
@ -441,8 +441,8 @@ class CPP11AsCPP14Mixin:
class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap, target):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool, exe_wrap, target):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrap)
VisualStudioLikeCompiler.__init__(self, target)
self.base_options = ['b_pch', 'b_vscrt'] # FIXME add lto, pgo and the like
self.id = 'msvc'
@ -474,8 +474,8 @@ class VisualStudioCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixi
return args
class ClangClCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, VisualStudioLikeCompiler, CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap, target):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrap, target):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrap)
VisualStudioLikeCompiler.__init__(self, target)
self.id = 'clang-cl'
@ -486,8 +486,8 @@ class ClangClCPPCompiler(CPP11AsCPP14Mixin, VisualStudioLikeCPPCompilerMixin, Vi
class IntelClCPPCompiler(VisualStudioLikeCPPCompilerMixin, IntelVisualStudioLikeCompiler, CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap, target):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrap, target):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrap)
IntelVisualStudioLikeCompiler.__init__(self, target)
def get_options(self):
@ -497,8 +497,8 @@ class IntelClCPPCompiler(VisualStudioLikeCPPCompilerMixin, IntelVisualStudioLike
class ArmCPPCompiler(ArmCompiler, CPPCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrap=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrap=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrap, **kwargs)
ArmCompiler.__init__(self, compiler_type)
def get_options(self):
@ -525,8 +525,8 @@ class ArmCPPCompiler(ArmCompiler, CPPCompiler):
class CcrxCPPCompiler(CcrxCompiler, CPPCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrap=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrap=None, **kwargs):
CPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrap, **kwargs)
CcrxCompiler.__init__(self, compiler_type)
# Override CCompiler.get_always_args

@ -17,7 +17,7 @@ import os.path, subprocess
from ..mesonlib import EnvironmentException
from ..mesonlib import is_windows
from .compilers import Compiler, mono_buildtype_args
from .compilers import Compiler, MachineChoice, mono_buildtype_args
cs_optimization_args = {'0': [],
'g': [],
@ -28,9 +28,9 @@ cs_optimization_args = {'0': [],
}
class CsCompiler(Compiler):
def __init__(self, exelist, version, comp_id, runner=None):
def __init__(self, exelist, version, for_machine: MachineChoice, comp_id, runner=None):
self.language = 'cs'
super().__init__(exelist, version)
super().__init__(exelist, version, for_machine)
self.id = comp_id
self.is_cross = False
self.runner = runner
@ -143,14 +143,14 @@ class CsCompiler(Compiler):
return cs_optimization_args[optimization_level]
class MonoCompiler(CsCompiler):
def __init__(self, exelist, version):
super().__init__(exelist, version, 'mono',
def __init__(self, exelist, version, for_machine: MachineChoice):
super().__init__(exelist, version, for_machine, 'mono',
'mono')
class VisualStudioCsCompiler(CsCompiler):
def __init__(self, exelist, version):
super().__init__(exelist, version, 'csc')
def __init__(self, exelist, version, for_machine: MachineChoice):
super().__init__(exelist, version, for_machine, 'csc')
def get_buildtype_args(self, buildtype):
res = mono_buildtype_args[buildtype]

@ -15,15 +15,15 @@
import re, os.path
from .. import mlog
from ..mesonlib import EnvironmentException, Popen_safe
from ..mesonlib import EnvironmentException, MachineChoice, Popen_safe
from .compilers import (Compiler, cuda_buildtype_args, cuda_optimization_args,
cuda_debug_args, CompilerType, get_gcc_soname_args)
class CudaCompiler(Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper=None):
if not hasattr(self, 'language'):
self.language = 'cuda'
super().__init__(exelist, version)
super().__init__(exelist, version, for_machine)
self.is_cross = is_cross
self.exe_wrapper = exe_wrapper
self.id = 'nvcc'

@ -73,11 +73,10 @@ class DCompiler(Compiler):
'mtd': ['-mscrtlib=libcmtd'],
}
def __init__(self, exelist, version, is_cross, arch, **kwargs):
def __init__(self, exelist, version, for_machine: MachineChoice, arch, **kwargs):
self.language = 'd'
super().__init__(exelist, version, **kwargs)
super().__init__(exelist, version, for_machine, **kwargs)
self.id = 'unknown'
self.is_cross = is_cross
self.arch = arch
def sanity_check(self, work_dir, environment):
@ -308,17 +307,12 @@ class DCompiler(Compiler):
# Add link flags needed to find dependencies
args += d.get_link_args()
if env.is_cross_build() and not self.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
if mode == 'compile':
# Add DFLAGS from the env
args += env.coredata.get_external_args(for_machine, self.language)
args += env.coredata.get_external_args(self.for_machine, self.language)
elif mode == 'link':
# Add LDFLAGS from the env
args += env.coredata.get_external_link_args(for_machine, self.language)
args += env.coredata.get_external_link_args(self.for_machine, self.language)
# extra_args must override all other arguments, so we add them last
args += extra_args
return args
@ -494,8 +488,8 @@ class DCompiler(Compiler):
return ['-pthread']
class GnuDCompiler(DCompiler):
def __init__(self, exelist, version, is_cross, arch, **kwargs):
DCompiler.__init__(self, exelist, version, is_cross, arch, **kwargs)
def __init__(self, exelist, version, for_machine: MachineChoice, arch, **kwargs):
DCompiler.__init__(self, exelist, version, for_machine, arch, **kwargs)
self.id = 'gcc'
default_warn_args = ['-Wall', '-Wdeprecated']
self.warn_args = {'0': [],
@ -557,8 +551,8 @@ class GnuDCompiler(DCompiler):
return gnu_optimization_args[optimization_level]
class LLVMDCompiler(DCompiler):
def __init__(self, exelist, version, is_cross, arch, **kwargs):
DCompiler.__init__(self, exelist, version, is_cross, arch, **kwargs)
def __init__(self, exelist, version, for_machine: MachineChoice, arch, **kwargs):
DCompiler.__init__(self, exelist, version, for_machine, arch, **kwargs)
self.id = 'llvm'
self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt']
@ -595,8 +589,8 @@ class LLVMDCompiler(DCompiler):
class DmdDCompiler(DCompiler):
def __init__(self, exelist, version, is_cross, arch, **kwargs):
DCompiler.__init__(self, exelist, version, is_cross, arch, **kwargs)
def __init__(self, exelist, version, for_machine: MachineChoice, arch, **kwargs):
DCompiler.__init__(self, exelist, version, for_machine, arch, **kwargs)
self.id = 'dmd'
self.base_options = ['b_coverage', 'b_colorout', 'b_vscrt']

@ -40,9 +40,9 @@ from mesonbuild.mesonlib import (
class FortranCompiler(CLikeCompiler, Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwargs):
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwargs):
self.language = 'fortran'
Compiler.__init__(self, exelist, version, **kwargs)
Compiler.__init__(self, exelist, version, for_machine, **kwargs)
CLikeCompiler.__init__(self, is_cross, exe_wrapper)
self.id = 'unknown'
@ -62,12 +62,8 @@ class FortranCompiler(CLikeCompiler, Compiler):
source_name.write_text('print *, "Fortran compilation is working."; end')
if environment.is_cross_build() and not self.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
extra_flags = environment.coredata.get_external_args(for_machine, self.language)
extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
extra_flags = environment.coredata.get_external_args(self.for_machine, self.language)
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
extra_flags += self.get_always_args()
# %% build the test executable
pc = subprocess.Popen(self.exelist + extra_flags + [str(source_name), '-o', str(binary_name)])
@ -167,8 +163,8 @@ class FortranCompiler(CLikeCompiler, Compiler):
class GnuFortranCompiler(GnuCompiler, FortranCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None, **kwargs):
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, defines=None, **kwargs):
FortranCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwargs)
GnuCompiler.__init__(self, compiler_type, defines)
default_warn_args = ['-Wall']
self.warn_args = {'0': [],
@ -189,13 +185,13 @@ class GnuFortranCompiler(GnuCompiler, FortranCompiler):
return ['-lgfortran', '-lm']
class ElbrusFortranCompiler(GnuFortranCompiler, ElbrusCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None, **kwargs):
GnuFortranCompiler.__init__(self, exelist, version, compiler_type, is_cross, exe_wrapper, defines, **kwargs)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, defines=None, **kwargs):
GnuFortranCompiler.__init__(self, exelist, version, compiler_type, for_machine, is_cross, exe_wrapper, defines, **kwargs)
ElbrusCompiler.__init__(self, compiler_type, defines)
class G95FortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwags)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwags)
self.id = 'g95'
default_warn_args = ['-Wall']
self.warn_args = {'0': [],
@ -212,8 +208,8 @@ class G95FortranCompiler(FortranCompiler):
class SunFortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwags)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwags)
self.id = 'sun'
def get_dependency_gen_args(self, outtarget, outfile):
@ -236,9 +232,9 @@ class SunFortranCompiler(FortranCompiler):
class IntelFortranCompiler(IntelGnuLikeCompiler, FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags):
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwags):
self.file_suffixes = ('f90', 'f', 'for', 'ftn', 'fpp')
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwags)
FortranCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwags)
# FIXME: Add support for OS X and Windows in detect_fortran_compiler so
# we are sent the type of compiler
IntelGnuLikeCompiler.__init__(self, CompilerType.ICC_STANDARD)
@ -293,8 +289,8 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler):
class PathScaleFortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwags)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwags)
self.id = 'pathscale'
default_warn_args = ['-fullwarn']
self.warn_args = {'0': [],
@ -307,8 +303,8 @@ class PathScaleFortranCompiler(FortranCompiler):
class PGIFortranCompiler(PGICompiler, FortranCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwags)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwags)
PGICompiler.__init__(self, compiler_type)
def language_stdlib_only_link_flags(self) -> List[str]:
@ -316,8 +312,8 @@ class PGIFortranCompiler(PGICompiler, FortranCompiler):
'-lpgf90rtl', '-lpgftnrtl', '-lrt']
class FlangFortranCompiler(ClangCompiler, FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwags)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwags)
ClangCompiler.__init__(self, CompilerType.CLANG_STANDARD)
self.id = 'flang'
default_warn_args = ['-Minform=inform']
@ -327,8 +323,8 @@ class FlangFortranCompiler(ClangCompiler, FortranCompiler):
'3': default_warn_args}
class Open64FortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwags)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwags)
self.id = 'open64'
default_warn_args = ['-fullwarn']
self.warn_args = {'0': [],
@ -341,8 +337,8 @@ class Open64FortranCompiler(FortranCompiler):
class NAGFortranCompiler(FortranCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper, **kwags)
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper=None, **kwags):
FortranCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper, **kwags)
self.id = 'nagfor'
def get_warn_args(self, level):

@ -14,14 +14,14 @@
import os.path, shutil, subprocess
from ..mesonlib import EnvironmentException
from ..mesonlib import EnvironmentException, MachineChoice
from .compilers import Compiler, java_buildtype_args
class JavaCompiler(Compiler):
def __init__(self, exelist, version):
def __init__(self, exelist, version, for_machine: MachineChoice):
self.language = 'java'
super().__init__(exelist, version)
super().__init__(exelist, version, for_machine)
self.id = 'unknown'
self.is_cross = False
self.javarunner = 'java'

@ -21,9 +21,9 @@ from .clike import CLikeCompiler
from .compilers import Compiler, ClangCompiler, GnuCompiler
class ObjCCompiler(CLikeCompiler, Compiler):
def __init__(self, exelist, version, is_cross: bool, exe_wrap: typing.Optional[str]):
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool, exe_wrap: typing.Optional[str]):
self.language = 'objc'
Compiler.__init__(self, exelist, version)
Compiler.__init__(self, exelist, version, for_machine)
CLikeCompiler.__init__(self, is_cross, exe_wrap)
def get_display_language(self):
@ -33,15 +33,11 @@ class ObjCCompiler(CLikeCompiler, Compiler):
# TODO try to use sanity_check_impl instead of duplicated code
source_name = os.path.join(work_dir, 'sanitycheckobjc.m')
binary_name = os.path.join(work_dir, 'sanitycheckobjc')
if environment.is_cross_build() and not self.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
extra_flags = environment.coredata.get_external_args(for_machine, self.language)
extra_flags = environment.coredata.get_external_args(self.for_machine, self.language)
if self.is_cross:
extra_flags += self.get_compile_only_args()
else:
extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
with open(source_name, 'w') as ofile:
ofile.write('#import<stdio.h>\n'
'int main(int argc, char **argv) { return 0; }\n')
@ -59,8 +55,8 @@ class ObjCCompiler(CLikeCompiler, Compiler):
class GnuObjCCompiler(GnuCompiler, ObjCCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None):
ObjCCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, defines=None):
ObjCCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper)
GnuCompiler.__init__(self, compiler_type, defines)
default_warn_args = ['-Wall', '-Winvalid-pch']
self.warn_args = {'0': [],
@ -70,8 +66,8 @@ class GnuObjCCompiler(GnuCompiler, ObjCCompiler):
class ClangObjCCompiler(ClangCompiler, ObjCCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None):
ObjCCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None):
ObjCCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper)
ClangCompiler.__init__(self, compiler_type)
default_warn_args = ['-Wall', '-Winvalid-pch']
self.warn_args = {'0': [],

@ -21,9 +21,9 @@ from .clike import CLikeCompiler
from .compilers import Compiler, ClangCompiler, GnuCompiler
class ObjCPPCompiler(CLikeCompiler, Compiler):
def __init__(self, exelist, version, is_cross: bool, exe_wrap: typing.Optional[str]):
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross: bool, exe_wrap: typing.Optional[str]):
self.language = 'objcpp'
Compiler.__init__(self, exelist, version)
Compiler.__init__(self, exelist, version, for_machine)
CLikeCompiler.__init__(self, is_cross, exe_wrap)
def get_display_language(self):
@ -33,15 +33,11 @@ class ObjCPPCompiler(CLikeCompiler, Compiler):
# TODO try to use sanity_check_impl instead of duplicated code
source_name = os.path.join(work_dir, 'sanitycheckobjcpp.mm')
binary_name = os.path.join(work_dir, 'sanitycheckobjcpp')
if environment.is_cross_build() and not self.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
extra_flags = environment.coredata.get_external_args(for_machine, self.language)
extra_flags = environment.coredata.get_external_args(self.for_machine, self.language)
if self.is_cross:
extra_flags += self.get_compile_only_args()
else:
extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
with open(source_name, 'w') as ofile:
ofile.write('#import<stdio.h>\n'
'class MyClass;'
@ -60,8 +56,8 @@ class ObjCPPCompiler(CLikeCompiler, Compiler):
class GnuObjCPPCompiler(GnuCompiler, ObjCPPCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None):
ObjCPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None, defines=None):
ObjCPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper)
GnuCompiler.__init__(self, compiler_type, defines)
default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
self.warn_args = {'0': [],
@ -71,8 +67,8 @@ class GnuObjCPPCompiler(GnuCompiler, ObjCPPCompiler):
class ClangObjCPPCompiler(ClangCompiler, ObjCPPCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None):
ObjCPPCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
def __init__(self, exelist, version, compiler_type, for_machine: MachineChoice, is_cross, exe_wrapper=None):
ObjCPPCompiler.__init__(self, exelist, version, for_machine, is_cross, exe_wrapper)
ClangCompiler.__init__(self, compiler_type)
default_warn_args = ['-Wall', '-Winvalid-pch', '-Wnon-virtual-dtor']
self.warn_args = {'0': [],

@ -14,7 +14,7 @@
import subprocess, os.path
from ..mesonlib import EnvironmentException, Popen_safe
from ..mesonlib import EnvironmentException, MachineChoice, Popen_safe
from .compilers import Compiler, rust_buildtype_args, clike_debug_args
@ -27,12 +27,12 @@ rust_optimization_args = {'0': [],
}
class RustCompiler(Compiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None):
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross, exe_wrapper=None):
self.language = 'rust'
super().__init__(exelist, version)
self.is_cross = is_cross
super().__init__(exelist, version, for_machine)
self.exe_wrapper = exe_wrapper
self.id = 'rustc'
self.is_cross = is_cross
def needs_static_linker(self):
return False

@ -27,12 +27,12 @@ swift_optimization_args = {'0': [],
}
class SwiftCompiler(Compiler):
def __init__(self, exelist, version):
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross):
self.language = 'swift'
super().__init__(exelist, version)
super().__init__(exelist, version, for_machine)
self.version = version
self.id = 'llvm'
self.is_cross = False
self.is_cross = is_cross
def get_linker_exelist(self):
return self.exelist[:]
@ -102,15 +102,11 @@ class SwiftCompiler(Compiler):
src = 'swifttest.swift'
source_name = os.path.join(work_dir, src)
output_name = os.path.join(work_dir, 'swifttest')
if environment.is_cross_build() and not self.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
extra_flags = environment.coredata.get_external_args(for_machine, self.language)
extra_flags = environment.coredata.get_external_args(self.for_machine, self.language)
if self.is_cross:
extra_flags += self.get_compile_only_args()
else:
extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
with open(source_name, 'w') as ofile:
ofile.write('''print("Swift compilation is working.")
''')

@ -20,12 +20,12 @@ from ..mesonlib import EnvironmentException, MachineChoice, version_compare
from .compilers import Compiler
class ValaCompiler(Compiler):
def __init__(self, exelist, version):
def __init__(self, exelist, version, for_machine: MachineChoice, is_cross):
self.language = 'vala'
super().__init__(exelist, version)
super().__init__(exelist, version, for_machine)
self.version = version
self.is_cross = is_cross
self.id = 'valac'
self.is_cross = False
self.base_options = ['b_colorout']
def name_string(self):
@ -87,15 +87,11 @@ class ValaCompiler(Compiler):
def sanity_check(self, work_dir, environment):
code = 'class MesonSanityCheck : Object { }'
if environment.is_cross_build() and not self.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
extra_flags = environment.coredata.get_external_args(for_machine, self.language)
extra_flags = environment.coredata.get_external_args(self.for_machine, self.language)
if self.is_cross:
extra_flags += self.get_compile_only_args()
else:
extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
with self.cached_compile(code, environment.coredata, extra_args=extra_flags, mode='compile') as p:
if p.returncode != 0:
msg = 'Vala compiler {!r} can not compile programs' \
@ -114,11 +110,7 @@ class ValaCompiler(Compiler):
# no extra dirs are specified.
if not extra_dirs:
code = 'class MesonFindLibrary : Object { }'
if env.is_cross_build() and not self.is_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
args = env.coredata.get_external_args(for_machine, self.language)
args = env.coredata.get_external_args(self.for_machine, self.language)
vapi_args = ['--pkg', libname]
args += vapi_args
with self.cached_compile(code, env.coredata, extra_args=args, mode='compile') as p:

@ -365,13 +365,11 @@ class CoreData:
self.compiler_options = PerMachine({}, {})
self.base_options = {} # : Dict[str, UserOption]
self.cross_files = self.__load_config_files(options.cross_file, 'cross')
self.compilers = OrderedDict()
self.cross_compilers = OrderedDict()
self.compilers = PerMachine(OrderedDict(), OrderedDict())
build_cache = DependencyCache(self.builtins_per_machine, MachineChoice.BUILD)
host_cache = DependencyCache(self.builtins_per_machine, MachineChoice.BUILD)
self.deps = PerMachine(build_cache, host_cache) # type: PerMachine[DependencyCache]
self.compiler_check_cache = OrderedDict()
# Only to print a warning if it changes between Meson invocations.
self.config_files = self.__load_config_files(options.native_file, 'native')
@ -681,35 +679,20 @@ class CoreData:
self.set_options(options, subproject)
def process_new_compilers(self, lang: str, comp, cross_comp, env):
def process_new_compiler(self, lang: str, comp, env):
from . import compilers
self.compilers[lang] = comp
if cross_comp is not None:
self.cross_compilers[lang] = cross_comp
# Native compiler always exist so always add its options.
new_options_for_build = comp.get_and_default_options(env.properties.build)
if cross_comp is not None:
new_options_for_host = cross_comp.get_and_default_options(env.properties.host)
else:
new_options_for_host = comp.get_and_default_options(env.properties.host)
opts_machines_list = [
(new_options_for_build, MachineChoice.BUILD),
(new_options_for_host, MachineChoice.HOST),
]
self.compilers[comp.for_machine][lang] = comp
optprefix = lang + '_'
for new_options, for_machine in opts_machines_list:
for k, o in new_options.items():
if not k.startswith(optprefix):
raise MesonException('Internal error, %s has incorrect prefix.' % k)
# prefixed compiler options affect just this machine
opt_prefix = for_machine.get_prefix()
if opt_prefix + k in env.cmd_line_options:
o.set_value(env.cmd_line_options[opt_prefix + k])
self.compiler_options[for_machine].setdefault(k, o)
for k, o in comp.get_and_default_options(env.properties[comp.for_machine]).items():
if not k.startswith(optprefix):
raise MesonException('Internal error, %s has incorrect prefix.' % k)
# prefixed compiler options affect just this machine
opt_prefix = comp.for_machine.get_prefix()
if opt_prefix + k in env.cmd_line_options:
o.set_value(env.cmd_line_options[opt_prefix + k])
self.compiler_options[comp.for_machine].setdefault(k, o)
enabled_opts = []
for optname in comp.base_options:

@ -239,10 +239,13 @@ class InternalDependency(Dependency):
final_link_args, final_libraries, final_whole_libraries,
final_sources, final_deps)
class HasNativeKwarg:
def __init__(self, kwargs):
self.for_machine = MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST
class ExternalDependency(Dependency):
class ExternalDependency(Dependency, HasNativeKwarg):
def __init__(self, type_name, environment, language, kwargs):
super().__init__(type_name, kwargs)
Dependency.__init__(self, type_name, kwargs)
self.env = environment
self.name = type_name # default
self.is_found = False
@ -255,18 +258,12 @@ class ExternalDependency(Dependency):
self.static = kwargs.get('static', False)
if not isinstance(self.static, bool):
raise DependencyException('Static keyword must be boolean')
# Is this dependency for cross-compilation?
if 'native' in kwargs and self.env.is_cross_build():
self.want_cross = not kwargs['native']
else:
self.want_cross = self.env.is_cross_build()
# Is this dependency to be run on the build platform?
HasNativeKwarg.__init__(self, kwargs)
self.clib_compiler = None
# Set the compiler that will be used by this dependency
# This is only used for configuration checks
if self.want_cross:
compilers = self.env.coredata.cross_compilers
else:
compilers = self.env.coredata.compilers
compilers = self.env.coredata.compilers[self.for_machine]
# Set the compiler for this dependency if a language is specified,
# else try to pick something that looks usable.
if self.language:
@ -372,7 +369,6 @@ class ConfigToolDependency(ExternalDependency):
def __init__(self, name, environment, language, kwargs):
super().__init__('config-tool', environment, language, kwargs)
self.name = name
self.native = kwargs.get('native', False)
self.tools = listify(kwargs.get('tools', self.tools))
req_version = kwargs.get('version', None)
@ -426,12 +422,11 @@ class ConfigToolDependency(ExternalDependency):
if not isinstance(versions, list) and versions is not None:
versions = listify(versions)
for_machine = MachineChoice.BUILD if self.native else MachineChoice.HOST
tool = self.env.binaries[for_machine].lookup_entry(self.tool_name)
tool = self.env.binaries[self.for_machine].lookup_entry(self.tool_name)
if tool is not None:
tools = [tool]
else:
if self.env.is_cross_build() and not self.native:
if not self.env.machines.matches_build_machine(self.for_machine):
mlog.deprecation('No entry for {0} specified in your cross file. '
'Falling back to searching PATH. This may find a '
'native version of {0}! This will become a hard '
@ -561,18 +556,13 @@ class PkgConfigDependency(ExternalDependency):
# stored in the pickled coredata and recovered.
self.pkgbin = None
if not self.want_cross and environment.is_cross_build():
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
# Create an iterator of options
def search():
# Lookup in cross or machine file.
potential_pkgpath = environment.binaries[for_machine].lookup_entry('pkgconfig')
potential_pkgpath = environment.binaries[self.for_machine].lookup_entry('pkgconfig')
if potential_pkgpath is not None:
mlog.debug('Pkg-config binary for {} specified from cross file, native file, '
'or env var as {}'.format(for_machine, potential_pkgpath))
'or env var as {}'.format(self.for_machine, potential_pkgpath))
yield ExternalProgram.from_entry('pkgconfig', potential_pkgpath)
# We never fallback if the user-specified option is no good, so
# stop returning options.
@ -580,42 +570,42 @@ class PkgConfigDependency(ExternalDependency):
mlog.debug('Pkg-config binary missing from cross or native file, or env var undefined.')
# Fallback on hard-coded defaults.
# TODO prefix this for the cross case instead of ignoring thing.
if environment.machines.matches_build_machine(for_machine):
if environment.machines.matches_build_machine(self.for_machine):
for potential_pkgpath in environment.default_pkgconfig:
mlog.debug('Trying a default pkg-config fallback at', potential_pkgpath)
yield ExternalProgram(potential_pkgpath, silent=True)
# Only search for pkg-config for each machine the first time and store
# the result in the class definition
if PkgConfigDependency.class_pkgbin[for_machine] is False:
mlog.debug('Pkg-config binary for %s is cached as not found.' % for_machine)
elif PkgConfigDependency.class_pkgbin[for_machine] is not None:
mlog.debug('Pkg-config binary for %s is cached.' % for_machine)
if PkgConfigDependency.class_pkgbin[self.for_machine] is False:
mlog.debug('Pkg-config binary for %s is cached as not found.' % self.for_machine)
elif PkgConfigDependency.class_pkgbin[self.for_machine] is not None:
mlog.debug('Pkg-config binary for %s is cached.' % self.for_machine)
else:
assert PkgConfigDependency.class_pkgbin[for_machine] is None
mlog.debug('Pkg-config binary for %s is not cached.' % for_machine)
assert PkgConfigDependency.class_pkgbin[self.for_machine] is None
mlog.debug('Pkg-config binary for %s is not cached.' % self.for_machine)
for potential_pkgbin in search():
mlog.debug('Trying pkg-config binary {} for machine {} at {}'
.format(potential_pkgbin.name, for_machine, potential_pkgbin.command))
.format(potential_pkgbin.name, self.for_machine, potential_pkgbin.command))
version_if_ok = self.check_pkgconfig(potential_pkgbin)
if not version_if_ok:
continue
if not self.silent:
mlog.log('Found pkg-config:', mlog.bold(potential_pkgbin.get_path()),
'(%s)' % version_if_ok)
PkgConfigDependency.class_pkgbin[for_machine] = potential_pkgbin
PkgConfigDependency.class_pkgbin[self.for_machine] = potential_pkgbin
break
else:
if not self.silent:
mlog.log('Found Pkg-config:', mlog.red('NO'))
# Set to False instead of None to signify that we've already
# searched for it and not found it
PkgConfigDependency.class_pkgbin[for_machine] = False
PkgConfigDependency.class_pkgbin[self.for_machine] = False
self.pkgbin = PkgConfigDependency.class_pkgbin[for_machine]
self.pkgbin = PkgConfigDependency.class_pkgbin[self.for_machine]
if self.pkgbin is False:
self.pkgbin = None
msg = 'Pkg-config binary for machine %s not found. Giving up.' % for_machine
msg = 'Pkg-config binary for machine %s not found. Giving up.' % self.for_machine
if self.required:
raise DependencyException(msg)
else:
@ -665,12 +655,7 @@ class PkgConfigDependency(ExternalDependency):
else:
env = env.copy()
if not self.want_cross and self.env.is_cross_build():
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
extra_paths = self.env.coredata.builtins_per_machine[for_machine]['pkg_config_path'].value
extra_paths = self.env.coredata.builtins_per_machine[self.for_machine]['pkg_config_path'].value
new_pkg_config_path = ':'.join([p for p in extra_paths])
mlog.debug('PKG_CONFIG_PATH: ' + new_pkg_config_path)
env['PKG_CONFIG_PATH'] = new_pkg_config_path
@ -1059,7 +1044,7 @@ class CMakeDependency(ExternalDependency):
# List of successfully found modules
self.found_modules = []
self.cmakebin, self.cmakevers, for_machine = self.find_cmake_binary(environment, self.want_cross, self.silent)
self.cmakebin, self.cmakevers, for_machine = self.find_cmake_binary(environment, self.for_machine, self.silent)
if self.cmakebin is False:
self.cmakebin = None
msg = 'No CMake binary for machine %s not found. Giving up.' % for_machine
@ -1068,9 +1053,9 @@ class CMakeDependency(ExternalDependency):
mlog.debug(msg)
return
if CMakeDependency.class_cmakeinfo[for_machine] is None:
CMakeDependency.class_cmakeinfo[for_machine] = self._get_cmake_info()
self.cmakeinfo = CMakeDependency.class_cmakeinfo[for_machine]
if CMakeDependency.class_cmakeinfo[self.for_machine] is None:
CMakeDependency.class_cmakeinfo[self.for_machine] = self._get_cmake_info()
self.cmakeinfo = CMakeDependency.class_cmakeinfo[self.for_machine]
if self.cmakeinfo is None:
raise self._gen_exception('Unable to obtain CMake system information')
@ -1082,24 +1067,16 @@ class CMakeDependency(ExternalDependency):
if cm_path:
cm_args.append('-DCMAKE_MODULE_PATH=' + ';'.join(cm_path))
pref_path = self.env.coredata.builtins_per_machine[for_machine]['cmake_prefix_path'].value
pref_path = self.env.coredata.builtins_per_machine[self.for_machine]['cmake_prefix_path'].value
if pref_path:
cm_args.append('-DCMAKE_PREFIX_PATH={}'.format(';'.join(pref_path)))
if not self._preliminary_find_check(name, cm_path, pref_path, environment.machines[for_machine]):
if not self._preliminary_find_check(name, cm_path, pref_path, environment.machines[self.for_machine]):
return
self._detect_dep(name, modules, cm_args)
@staticmethod
def find_cmake_binary(environment: Environment, want_cross: bool = False, silent: bool = False) -> Tuple[str, str, MachineChoice]:
# When finding dependencies for cross-compiling, we don't care about
# the 'native' CMake binary
# TODO: Test if this works as expected
if environment.is_cross_build() and not want_cross:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
@classmethod
def find_cmake_binary(cls, environment: Environment, for_machine: MachineChoice, silent: bool = False) -> Tuple[str, str, MachineChoice]:
# Create an iterator of options
def search():
# Lookup in cross or machine file.
@ -1130,7 +1107,7 @@ class CMakeDependency(ExternalDependency):
for potential_cmakebin in search():
mlog.debug('Trying CMake binary {} for machine {} at {}'
.format(potential_cmakebin.name, for_machine, potential_cmakebin.command))
version_if_ok = CMakeDependency.check_cmake(potential_cmakebin)
version_if_ok = cls.check_cmake(potential_cmakebin)
if not version_if_ok:
continue
if not silent:
@ -2098,6 +2075,8 @@ class DubDependency(ExternalDependency):
class ExternalProgram:
windows_exts = ('exe', 'msc', 'com', 'bat', 'cmd')
# An 'ExternalProgram' always runs on the build machine
for_machine = MachineChoice.BUILD
def __init__(self, name: str, command: typing.Optional[typing.List[str]] = None,
silent: bool = False, search_dir: typing.Optional[str] = None):
@ -2479,7 +2458,7 @@ def get_dep_identifier(name, kwargs) -> Tuple:
identifier = (name, )
for key, value in kwargs.items():
# 'version' is irrelevant for caching; the caller must check version matches
# 'native' is handled above with `want_cross`
# 'native' is handled above with `for_machine`
# 'required' is irrelevant for caching; the caller handles it separately
# 'fallback' subprojects cannot be cached -- they must be initialized
# 'default_options' is only used in fallback case
@ -2520,12 +2499,9 @@ def find_external_dependency(name, env, kwargs):
# display the dependency name with correct casing
display_name = display_name_map.get(lname, lname)
# if this isn't a cross-build, it's uninteresting if native: is used or not
if not env.is_cross_build():
type_text = 'Dependency'
else:
type_text = 'Native' if kwargs.get('native', False) else 'Cross'
type_text += ' dependency'
for_machine = MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST
type_text = PerMachine('Build-time', 'Run-time')[for_machine] + ' dependency'
# build a list of dependency methods to try
candidates = _build_external_dependency_list(name, env, kwargs)
@ -2648,12 +2624,12 @@ def _build_external_dependency_list(name, env: Environment, kwargs: Dict[str, An
return candidates
def strip_system_libdirs(environment, link_args):
def strip_system_libdirs(environment, for_machine: MachineChoice, link_args):
"""Remove -L<system path> arguments.
leaving these in will break builds where a user has a version of a library
in the system path, and a different version not in the system path if they
want to link against the non-system path version.
"""
exclude = {'-L{}'.format(p) for p in environment.get_compiler_system_dirs()}
exclude = {'-L{}'.format(p) for p in environment.get_compiler_system_dirs(for_machine)}
return [l for l in link_args if l not in exclude]

@ -123,13 +123,13 @@ class BoostDependency(ExternalDependency):
self.libdir = os.environ['BOOST_LIBRARYDIR']
if self.boost_root is None:
if mesonlib.for_windows(self.want_cross, self.env):
if self.env.machines[self.for_machine].is_windows():
self.boost_roots = self.detect_win_roots()
else:
self.boost_roots = self.detect_nix_roots()
if self.incdir is None:
if mesonlib.for_windows(self.want_cross, self.env):
if self.env.machines[self.for_machine].is_windows():
self.incdir = self.detect_win_incdir()
else:
self.incdir = self.detect_nix_incdir()
@ -268,7 +268,7 @@ class BoostDependency(ExternalDependency):
pass
# 2. Fall back to the old method
else:
if mesonlib.for_windows(self.want_cross, self.env):
if self.env.machines[self.for_machine].is_windows():
self.detect_lib_modules_win()
else:
self.detect_lib_modules_nix()
@ -289,8 +289,8 @@ class BoostDependency(ExternalDependency):
def compiler_tag(self):
tag = None
compiler = self.env.detect_cpp_compiler(self.want_cross)
if mesonlib.for_windows(self.want_cross, self.env):
compiler = self.env.detect_cpp_compiler(self.for_machine)
if self.env.machines[self.for_machine].is_windows():
if compiler.get_id() in ['msvc', 'clang-cl']:
comp_ts_version = compiler.get_toolset_version()
compiler_ts = comp_ts_version.split('.')
@ -304,10 +304,10 @@ class BoostDependency(ExternalDependency):
if not self.is_multithreading:
return ''
if mesonlib.for_darwin(self.want_cross, self.env):
if self.env.machines[self.for_machine].is_darwin():
# - Mac: requires -mt for multithreading, so should not fall back to non-mt libraries.
return '-mt'
elif mesonlib.for_windows(self.want_cross, self.env):
elif self.env.machines[self.for_machine].is_windows():
# - Windows: requires -mt for multithreading, so should not fall back to non-mt libraries.
return '-mt'
else:
@ -323,12 +323,12 @@ class BoostDependency(ExternalDependency):
def arch_tag(self):
# currently only applies to windows msvc installed binaries
if self.env.detect_cpp_compiler(self.want_cross).get_id() not in ['msvc', 'clang-cl']:
if self.env.detect_cpp_compiler(self.for_machine).get_id() not in ['msvc', 'clang-cl']:
return ''
# pre-compiled binaries only added arch tag for versions > 1.64
if float(self.version) < 1.65:
return ''
arch = detect_cpu_family(self.env.coredata.compilers)
arch = detect_cpu_family(self.env.coredata.compilers.host)
if arch == 'x86':
return '-x32'
elif arch == 'x86_64':
@ -340,16 +340,16 @@ class BoostDependency(ExternalDependency):
# FIXME - how to handle different distributions, e.g. for Mac? Currently we handle homebrew and macports, but not fink.
def abi_tags(self):
if mesonlib.for_windows(self.want_cross, self.env):
if self.env.machines[self.for_machine].is_windows():
return [self.versioned_abi_tag(), self.threading_tag()]
else:
return [self.threading_tag()]
def sourceforge_dir(self):
if self.env.detect_cpp_compiler(self.want_cross).get_id() != 'msvc':
if self.env.detect_cpp_compiler(self.for_machine).get_id() != 'msvc':
return None
comp_ts_version = self.env.detect_cpp_compiler(self.want_cross).get_toolset_version()
arch = detect_cpu_family(self.env.coredata.compilers)
comp_ts_version = self.env.detect_cpp_compiler(self.for_machine).get_toolset_version()
arch = detect_cpu_family(self.env.coredata.compilers.host)
if arch == 'x86':
return 'lib32-msvc-{}'.format(comp_ts_version)
elif arch == 'x86_64':
@ -437,7 +437,7 @@ class BoostDependency(ExternalDependency):
def detect_lib_modules_nix(self):
if self.static:
libsuffix = 'a'
elif mesonlib.for_darwin(self.want_cross, self.env):
elif self.env.machines[self.for_machine].is_darwin():
libsuffix = 'dylib'
else:
libsuffix = 'so'

@ -24,20 +24,21 @@ from .. import mesonlib, mlog
from ..mesonlib import version_compare, stringlistify, extract_as_list, MachineChoice
from .base import (
DependencyException, DependencyMethods, ExternalDependency, PkgConfigDependency,
strip_system_libdirs, ConfigToolDependency, CMakeDependency
strip_system_libdirs, ConfigToolDependency, CMakeDependency, HasNativeKwarg
)
from .misc import ThreadDependency
from typing import List, Tuple
def get_shared_library_suffix(environment, native):
def get_shared_library_suffix(environment, for_machine: MachineChoice):
"""This is only gauranteed to work for languages that compile to machine
code, not for languages like C# that use a bytecode and always end in .dll
"""
if mesonlib.for_windows(native, environment):
m = environment.machines[for_machine]
if m.is_windows():
return '.dll'
elif mesonlib.for_darwin(native, environment):
elif m.is_darwin():
return '.dylib'
return '.so'
@ -203,6 +204,10 @@ class LLVMDependencyConfigTool(ConfigToolDependency):
__cpp_blacklist = {'-DNDEBUG'}
def __init__(self, environment, kwargs):
# Already called by `super().__init__`, but need `self.for_machine`
# before `super().__init__` is called.
HasNativeKwarg.__init__(self, kwargs)
# Ordered list of llvm-config binaries to try. Start with base, then try
# newest back to oldest (3.5 is arbitrary), and finally the devel version.
# Please note that llvm-config-6.0 is a development snapshot and it should
@ -227,8 +232,7 @@ class LLVMDependencyConfigTool(ConfigToolDependency):
# of bits in the isa that llvm targets, for example, on x86_64
# and aarch64 the name will be llvm-config-64, on x86 and arm
# it will be llvm-config-32.
m = MachineChoice.BUILD if environment.is_cross_build() and kwargs.get('native', True) else MachineChoice.HOST
if environment.machines[m].is_64_bit:
if environment.machines[self.for_machine].is_64_bit:
self.tools.append('llvm-config-64')
else:
self.tools.append('llvm-config-32')
@ -256,7 +260,7 @@ class LLVMDependencyConfigTool(ConfigToolDependency):
self._set_new_link_args(environment)
else:
self._set_old_link_args()
self.link_args = strip_system_libdirs(environment, self.link_args)
self.link_args = strip_system_libdirs(environment, self.for_machine, self.link_args)
self.link_args = self.__fix_bogus_link_args(self.link_args)
self._add_sub_dependency(ThreadDependency, environment, kwargs)
@ -271,7 +275,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['cpp']
cpp = self.env.coredata.compilers[self.for_machine]['cpp']
new_args = []
for arg in args:
@ -316,7 +320,7 @@ class LLVMDependencyConfigTool(ConfigToolDependency):
try:
self.__check_libfiles(True)
except DependencyException:
lib_ext = get_shared_library_suffix(environment, self.native)
lib_ext = get_shared_library_suffix(environment, self.for_machine)
libdir = self.get_config_value(['--libdir'], 'link_args')[0]
# Sort for reproducability
matches = sorted(glob.iglob(os.path.join(libdir, 'libLLVM*{}'.format(lib_ext))))

@ -213,7 +213,7 @@ class MPIDependency(ExternalDependency):
if not self.is_found and mesonlib.is_windows():
# only Intel Fortran compiler is compatible with Microsoft MPI at this time.
if language == 'fortran' and environment.detect_fortran_compiler(False).name_string() != 'intel':
if language == 'fortran' and environment.detect_fortran_compiler(self.for_machine).name_string() != 'intel':
return
result = self._try_msmpi()
if result is not None:
@ -228,7 +228,7 @@ class MPIDependency(ExternalDependency):
result = []
multi_args = ('-I', )
if self.language == 'fortran':
fc = self.env.coredata.compilers['fortran']
fc = self.env.coredata.compilers[self.for_machine]['fortran']
multi_args += fc.get_module_incdir_args()
include_next = False
@ -325,7 +325,7 @@ class MPIDependency(ExternalDependency):
if 'MSMPI_INC' not in os.environ:
return
incdir = os.environ['MSMPI_INC']
arch = detect_cpu_family(self.env.coredata.compilers)
arch = detect_cpu_family(self.env.coredata.compilers.host)
if arch == 'x86':
if 'MSMPI_LIB32' not in os.environ:
return
@ -396,7 +396,7 @@ class Python3Dependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('python3', environment, None, kwargs)
if self.want_cross:
if not environment.machines.matches_build_machine(self.for_machine):
return
self.name = 'python3'
@ -480,7 +480,7 @@ class Python3Dependency(ExternalDependency):
if pyarch is None:
self.is_found = False
return
arch = detect_cpu_family(env.coredata.compilers)
arch = detect_cpu_family(env.coredata.compilers.host)
if arch == 'x86':
arch = '32'
elif arch == 'x86_64':
@ -560,7 +560,7 @@ class PcapDependency(ExternalDependency):
def get_pcap_lib_version(ctdep):
# Since we seem to need to run a program to discover the pcap version,
# we can't do that when cross-compiling
if ctdep.want_cross:
if not ctdep.env.machines.matches_build_machine(ctdep.for_machine):
return None
v = ctdep.clib_compiler.get_return_value('pcap_lib_version', 'string',

@ -23,8 +23,7 @@ from collections import OrderedDict
from .. import mlog
from .. import mesonlib
from ..mesonlib import (
MesonException, Popen_safe, extract_as_list, for_windows,
version_compare_many
MesonException, Popen_safe, extract_as_list, version_compare_many
)
from ..environment import detect_cpu
@ -38,13 +37,13 @@ class GLDependency(ExternalDependency):
def __init__(self, environment, kwargs):
super().__init__('gl', environment, None, kwargs)
if mesonlib.for_darwin(self.want_cross, self.env):
if self.env.machines[self.for_machine].is_darwin():
self.is_found = True
# FIXME: Use AppleFrameworks dependency
self.link_args = ['-framework', 'OpenGL']
# FIXME: Detect version using self.clib_compiler
return
if mesonlib.for_windows(self.want_cross, self.env):
if self.env.machines[self.for_machine].is_windows():
self.is_found = True
# FIXME: Use self.clib_compiler.find_library()
self.link_args = ['-lopengl32']
@ -310,7 +309,7 @@ class QtBaseDependency(ExternalDependency):
language=self.language)
modules['Core'] = core
if for_windows(self.env.is_cross_build(), self.env) and self.qtmain:
if self.env.machines[self.for_machine].is_windows() and self.qtmain:
# Check if we link with debug binaries
debug_lib_name = self.qtpkgname + 'Core' + self._get_modules_lib_suffix(True)
is_debug = False
@ -414,7 +413,7 @@ class QtBaseDependency(ExternalDependency):
break
self.link_args.append(libfile)
if for_windows(self.env.is_cross_build(), self.env) and self.qtmain:
if self.env.machines[self.for_machine].is_windows() and self.qtmain:
if not self._link_with_qtmain(is_debug, libdir):
self.is_found = False
@ -422,7 +421,7 @@ class QtBaseDependency(ExternalDependency):
def _get_modules_lib_suffix(self, is_debug):
suffix = ''
if for_windows(self.env.is_cross_build(), self.env):
if self.env.machines[self.for_machine].is_windows():
if is_debug:
suffix += 'd'
if self.qtver == '4':

@ -510,23 +510,6 @@ class Environment:
self.default_cmake = ['cmake']
self.default_pkgconfig = ['pkg-config']
# Various prefixes and suffixes for import libraries, shared libraries,
# static libraries, and executables.
# Versioning is added to these names in the backends as-needed.
cross = self.is_cross_build()
if mesonlib.for_windows(cross, self):
self.exe_suffix = 'exe'
self.object_suffix = 'obj'
self.win_libdir_layout = True
elif mesonlib.for_cygwin(cross, self):
self.exe_suffix = 'exe'
self.object_suffix = 'o'
self.win_libdir_layout = True
else:
self.exe_suffix = ''
self.object_suffix = 'o'
self.win_libdir_layout = False
def create_new_coredata(self, options):
# WARNING: Don't use any values from coredata in __init__. It gets
# re-initialized with project options by the interpreter during
@ -632,17 +615,11 @@ class Environment:
return CompilerType.GCC_CYGWIN
return CompilerType.GCC_STANDARD
def _get_compilers(self, lang, want_cross):
def _get_compilers(self, lang, for_machine):
'''
The list of compilers is detected in the exact same way for
C, C++, ObjC, ObjC++, Fortran, CS so consolidate it here.
'''
# This morally assumes `want_cross = !native`. It may not yet be
# consistently set that way in the non cross build case, but it doesn't
# really matter since both options are the same in that case.
for_machine = MachineChoice.HOST if want_cross else MachineChoice.BUILD
value = self.binaries[for_machine].lookup_entry(lang)
if value is not None:
compilers, ccache = BinaryTable.parse_entry(value)
@ -655,13 +632,11 @@ class Environment:
ccache = BinaryTable.detect_ccache()
if self.machines.matches_build_machine(for_machine):
is_cross = False
exe_wrap = None
else:
is_cross = True
exe_wrap = self.get_exe_wrapper()
return compilers, ccache, is_cross, exe_wrap
return compilers, ccache, exe_wrap
def _handle_exceptions(self, exceptions, binaries, bintype='compiler'):
errmsg = 'Unknown {}(s): {}'.format(bintype, binaries)
@ -671,9 +646,10 @@ class Environment:
errmsg += '\nRunning "{0}" gave "{1}"'.format(c, e)
raise EnvironmentException(errmsg)
def _detect_c_or_cpp_compiler(self, lang, want_cross):
def _detect_c_or_cpp_compiler(self, lang, for_machine):
popen_exceptions = {}
compilers, ccache, is_cross, exe_wrap = self._get_compilers(lang, want_cross)
compilers, ccache, exe_wrap = self._get_compilers(lang, for_machine)
is_cross = not self.machines.matches_build_machine(for_machine)
for compiler in compilers:
if isinstance(compiler, str):
@ -738,7 +714,7 @@ class Environment:
else:
version = self.get_gnu_version_from_defines(defines)
cls = GnuCCompiler if lang == 'c' else GnuCPPCompiler
return cls(ccache + compiler, version, compiler_type, is_cross, exe_wrap, defines, full_version=full_version)
return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, defines, full_version=full_version)
if 'armclang' in out:
# The compiler version is not present in the first line of output,
@ -756,7 +732,7 @@ class Environment:
full_version = arm_ver_str
compiler_type = CompilerType.ARM_WIN
cls = ArmclangCCompiler if lang == 'c' else ArmclangCPPCompiler
return cls(ccache + compiler, version, compiler_type, is_cross, exe_wrap, full_version=full_version)
return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'CL.EXE COMPATIBILITY' in out:
# if this is clang-cl masquerading as cl, detect it as cl, not
# clang
@ -772,21 +748,22 @@ class Environment:
else:
target = 'unknown target'
cls = ClangClCCompiler if lang == 'c' else ClangClCPPCompiler
return cls(compiler, version, is_cross, exe_wrap, target)
return cls(compiler, version, for_machine, is_cross, exe_wrap, target)
if 'clang' in out:
if 'Apple' in out or mesonlib.for_darwin(want_cross, self):
if 'Apple' in out or self.machines[for_machine].is_darwin():
compiler_type = CompilerType.CLANG_OSX
elif 'windows' in out or mesonlib.for_windows(want_cross, self):
elif 'windows' in out or self.machines[for_machine].is_windows():
compiler_type = CompilerType.CLANG_MINGW
else:
compiler_type = CompilerType.CLANG_STANDARD
cls = ClangCCompiler if lang == 'c' else ClangCPPCompiler
return cls(ccache + compiler, version, compiler_type, is_cross, exe_wrap, full_version=full_version)
return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, full_version=full_version)
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
return cls(compiler, version, is_cross, exe_wrap, target)
return cls(compiler, version, for_machine, is_cross, exe_wrap, target)
return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'Microsoft' in out or 'Microsoft' in err:
# Latest versions of Visual Studio print version
# number to stderr but earlier ones print version
@ -805,47 +782,46 @@ class Environment:
else:
target = 'x86'
cls = VisualStudioCCompiler if lang == 'c' else VisualStudioCPPCompiler
return cls(compiler, version, is_cross, exe_wrap, target)
return cls(compiler, version, for_machine, is_cross, exe_wrap, target)
if 'PGI Compilers' in out:
if mesonlib.for_darwin(want_cross, self):
if self.machines[for_machine].is_darwin():
compiler_type = CompilerType.PGI_OSX
elif mesonlib.for_windows(want_cross, self):
elif self.machines[for_machine].is_windows():
compiler_type = CompilerType.PGI_WIN
else:
compiler_type = CompilerType.PGI_STANDARD
cls = PGICCompiler if lang == 'c' else PGICPPCompiler
return cls(ccache + compiler, version, compiler_type, is_cross, exe_wrap)
return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, compiler_type, exe_wrap)
if '(ICC)' in out:
if mesonlib.for_darwin(want_cross, self):
if self.machines[for_machine].is_darwin():
compiler_type = CompilerType.ICC_OSX
elif mesonlib.for_windows(want_cross, self):
elif self.machines[for_machine].is_windows():
# TODO: fix ICC on Windows
compiler_type = CompilerType.ICC_WIN
else:
compiler_type = CompilerType.ICC_STANDARD
cls = IntelCCompiler if lang == 'c' else IntelCPPCompiler
return cls(ccache + compiler, version, compiler_type, is_cross, exe_wrap, full_version=full_version)
return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'ARM' in out:
compiler_type = CompilerType.ARM_WIN
cls = ArmCCompiler if lang == 'c' else ArmCPPCompiler
return cls(ccache + compiler, version, compiler_type, is_cross, exe_wrap, full_version=full_version)
return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'RX Family' in out:
compiler_type = CompilerType.CCRX_WIN
cls = CcrxCCompiler if lang == 'c' else CcrxCPPCompiler
return cls(ccache + compiler, version, compiler_type, is_cross, exe_wrap, full_version=full_version)
return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, full_version=full_version)
self._handle_exceptions(popen_exceptions, compilers)
def detect_c_compiler(self, want_cross):
return self._detect_c_or_cpp_compiler('c', want_cross)
def detect_c_compiler(self, for_machine):
return self._detect_c_or_cpp_compiler('c', for_machine)
def detect_cpp_compiler(self, want_cross):
return self._detect_c_or_cpp_compiler('cpp', want_cross)
def detect_cpp_compiler(self, for_machine):
return self._detect_c_or_cpp_compiler('cpp', for_machine)
def detect_cuda_compiler(self, want_cross):
def detect_cuda_compiler(self, for_machine):
popen_exceptions = {}
compilers, ccache, is_cross, exe_wrap = self._get_compilers('cuda', want_cross)
compilers, ccache, exe_wrap = self._get_compilers('cuda', for_machine)
for compiler in compilers:
if isinstance(compiler, str):
compiler = [compiler]
@ -874,12 +850,13 @@ class Environment:
# the full version:
version = out.strip().split('V')[-1]
cls = CudaCompiler
return cls(ccache + compiler, version, is_cross, exe_wrap)
return cls(ccache + compiler, version, for_machine, exe_wrap)
raise EnvironmentException('Could not find suitable CUDA compiler: "' + ' '.join(compilers) + '"')
def detect_fortran_compiler(self, want_cross):
def detect_fortran_compiler(self, for_machine):
popen_exceptions = {}
compilers, ccache, is_cross, exe_wrap = self._get_compilers('fortran', want_cross)
compilers, ccache, exe_wrap = self._get_compilers('fortran', for_machine)
is_cross = not self.machines.matches_build_machine(for_machine)
for compiler in compilers:
if isinstance(compiler, str):
compiler = [compiler]
@ -911,14 +888,14 @@ class Environment:
else:
version = self.get_gnu_version_from_defines(defines)
cls = GnuFortranCompiler
return cls(compiler, version, compiler_type, is_cross, exe_wrap, defines, full_version=full_version)
return cls(compiler, version, compiler_type, for_machine, is_cross, exe_wrap, defines, full_version=full_version)
if 'G95' in out:
return G95FortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
return G95FortranCompiler(compiler, version, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'Sun Fortran' in err:
version = search_version(err)
return SunFortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
return SunFortranCompiler(compiler, version, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'Intel(R) Visual Fortran' in err:
version = search_version(err)
@ -926,36 +903,37 @@ class Environment:
return IntelClFortranCompiler(compiler, version, is_cross, target, exe_wrap)
if 'ifort (IFORT)' in out:
return IntelFortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
return IntelFortranCompiler(compiler, version, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'PathScale EKOPath(tm)' in err:
return PathScaleFortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
return PathScaleFortranCompiler(compiler, version, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'PGI Compilers' in out:
if mesonlib.for_darwin(want_cross, self):
if self.machine[for_machine].is_darwin():
compiler_type = CompilerType.PGI_OSX
elif mesonlib.for_windows(want_cross, self):
elif self.machines[for_machine].is_windows():
compiler_type = CompilerType.PGI_WIN
else:
compiler_type = CompilerType.PGI_STANDARD
return PGIFortranCompiler(compiler, version, compiler_type, is_cross, exe_wrap, full_version=full_version)
return PGIFortranCompiler(compiler, version, compiler_type, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'flang' in out or 'clang' in out:
return FlangFortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
return FlangFortranCompiler(compiler, version, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'Open64 Compiler Suite' in err:
return Open64FortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
return Open64FortranCompiler(compiler, version, for_machine, is_cross, exe_wrap, full_version=full_version)
if 'NAG Fortran' in err:
return NAGFortranCompiler(compiler, version, is_cross, exe_wrap, full_version=full_version)
return NAGFortranCompiler(compiler, version, for_machine, is_cross, exe_wrap, full_version=full_version)
self._handle_exceptions(popen_exceptions, compilers)
def get_scratch_dir(self):
return self.scratch_dir
def detect_objc_compiler(self, want_cross):
def detect_objc_compiler(self, for_machine):
popen_exceptions = {}
compilers, ccache, is_cross, exe_wrap = self._get_compilers('objc', want_cross)
compilers, ccache, exe_wrap = self._get_compilers('objc', for_machine)
is_cross = not self.machines.matches_build_machine(for_machine)
for compiler in compilers:
if isinstance(compiler, str):
compiler = [compiler]
@ -973,18 +951,19 @@ class Environment:
continue
compiler_type = self.get_gnu_compiler_type(defines)
version = self.get_gnu_version_from_defines(defines)
return GnuObjCCompiler(ccache + compiler, version, compiler_type, is_cross, exe_wrap, defines)
return GnuObjCCompiler(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, defines)
if out.startswith('Apple LLVM'):
return ClangObjCCompiler(ccache + compiler, version, CompilerType.CLANG_OSX, is_cross, exe_wrap)
return ClangObjCCompiler(ccache + compiler, version, CompilerType.CLANG_OSX, for_machine, is_cross, exe_wrap)
if 'windows' in out:
return ClangObjCCompiler(ccache + compiler, version, CompilerType.CLANG_MINGW, is_cross, exe_wrap)
return ClangObjCCompiler(ccache + compiler, version, CompilerType.CLANG_MINGW, for_machine, is_cross, exe_wrap)
if out.startswith(('clang', 'OpenBSD clang')):
return ClangObjCCompiler(ccache + compiler, version, CompilerType.CLANG_STANDARD, is_cross, exe_wrap)
return ClangObjCCompiler(ccache + compiler, version, CompilerType.CLANG_STANDARD, for_machine, is_cross, exe_wrap)
self._handle_exceptions(popen_exceptions, compilers)
def detect_objcpp_compiler(self, want_cross):
def detect_objcpp_compiler(self, for_machine):
popen_exceptions = {}
compilers, ccache, is_cross, exe_wrap = self._get_compilers('objcpp', want_cross)
compilers, ccache, exe_wrap = self._get_compilers('objcpp', for_machine)
is_cross = not self.machines.matches_build_machine(for_machine)
for compiler in compilers:
if isinstance(compiler, str):
compiler = [compiler]
@ -1002,16 +981,16 @@ class Environment:
continue
compiler_type = self.get_gnu_compiler_type(defines)
version = self.get_gnu_version_from_defines(defines)
return GnuObjCPPCompiler(ccache + compiler, version, compiler_type, is_cross, exe_wrap, defines)
return GnuObjCPPCompiler(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap, defines)
if out.startswith('Apple LLVM'):
return ClangObjCPPCompiler(ccache + compiler, version, CompilerType.CLANG_OSX, is_cross, exe_wrap)
return ClangObjCPPCompiler(ccache + compiler, version, CompilerType.CLANG_OSX, for_machine, is_cross, exe_wrap)
if 'windows' in out:
return ClangObjCPPCompiler(ccache + compiler, version, CompilerType.CLANG_MINGW, is_cross, exe_wrap)
return ClangObjCPPCompiler(ccache + compiler, version, CompilerType.CLANG_MINGW, for_machine, is_cross, exe_wrap)
if out.startswith(('clang', 'OpenBSD clang')):
return ClangObjCPPCompiler(ccache + compiler, version, CompilerType.CLANG_STANDARD, is_cross, exe_wrap)
return ClangObjCPPCompiler(ccache + compiler, version, CompilerType.CLANG_STANDARD, for_machine, is_cross, exe_wrap)
self._handle_exceptions(popen_exceptions, compilers)
def detect_java_compiler(self):
def detect_java_compiler(self, for_machine):
exelist = self.binaries.host.lookup_entry('java')
if exelist is None:
# TODO support fallback
@ -1027,11 +1006,11 @@ class Environment:
parts = (err if 'javac' in err else out).split()
if len(parts) > 1:
version = parts[1]
return JavaCompiler(exelist, version)
return JavaCompiler(exelist, version, for_machine)
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
def detect_cs_compiler(self):
compilers, ccache, is_cross, exe_wrap = self._get_compilers('cs', False)
def detect_cs_compiler(self, for_machine):
compilers, ccache, exe_wrap = self._get_compilers('cs', for_machine)
popen_exceptions = {}
for comp in compilers:
if not isinstance(comp, list):
@ -1044,14 +1023,15 @@ class Environment:
version = search_version(out)
if 'Mono' in out:
return MonoCompiler(comp, version)
return MonoCompiler(comp, version, for_machine)
elif "Visual C#" in out:
return VisualStudioCsCompiler(comp, version)
return VisualStudioCsCompiler(comp, version, for_machine)
self._handle_exceptions(popen_exceptions, compilers)
def detect_vala_compiler(self):
def detect_vala_compiler(self, for_machine):
exelist = self.binaries.host.lookup_entry('vala')
is_cross = not self.machines.matches_build_machine(for_machine)
if exelist is None:
# TODO support fallback
exelist = [self.default_vala[0]]
@ -1062,12 +1042,13 @@ class Environment:
raise EnvironmentException('Could not execute Vala compiler "%s"' % ' '.join(exelist))
version = search_version(out)
if 'Vala' in out:
return ValaCompiler(exelist, version)
return ValaCompiler(exelist, version, for_machine, is_cross)
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
def detect_rust_compiler(self, want_cross):
def detect_rust_compiler(self, for_machine):
popen_exceptions = {}
compilers, ccache, is_cross, exe_wrap = self._get_compilers('rust', want_cross)
compilers, ccache, exe_wrap = self._get_compilers('rust', for_machine)
is_cross = not self.machines.matches_build_machine(for_machine)
for compiler in compilers:
if isinstance(compiler, str):
compiler = [compiler]
@ -1081,13 +1062,12 @@ class Environment:
version = search_version(out)
if 'rustc' in out:
return RustCompiler(compiler, version, is_cross, exe_wrap)
return RustCompiler(compiler, version, for_machine, is_cross, exe_wrap)
self._handle_exceptions(popen_exceptions, compilers)
def detect_d_compiler(self, want_cross):
is_cross = want_cross and self.is_cross_build()
exelist = self.binaries.host.lookup_entry('d')
def detect_d_compiler(self, for_machine: MachineChoice):
exelist = self.binaries[for_machine].lookup_entry('d')
# Search for a D compiler.
# We prefer LDC over GDC unless overridden with the DC
# environment variable because LDC has a much more
@ -1116,22 +1096,23 @@ class Environment:
c_compiler = {}
is_msvc = mesonlib.is_windows() and 'VCINSTALLDIR' in os.environ
if is_msvc:
c_compiler = {'c': self.detect_c_compiler(want_cross)} # MSVC compiler is required for correct platform detection.
c_compiler = {'c': self.detect_c_compiler(for_machine)} # MSVC compiler is required for correct platform detection.
arch = detect_cpu_family(c_compiler)
if is_msvc and arch == 'x86':
arch = 'x86_mscoff'
if 'LLVM D compiler' in out:
return compilers.LLVMDCompiler(exelist, version, is_cross, arch, full_version=full_version)
return compilers.LLVMDCompiler(exelist, version, for_machine, arch, full_version=full_version)
elif 'gdc' in out:
return compilers.GnuDCompiler(exelist, version, is_cross, arch, full_version=full_version)
return compilers.GnuDCompiler(exelist, version, for_machine, arch, full_version=full_version)
elif 'The D Language Foundation' in out or 'Digital Mars' in out:
return compilers.DmdDCompiler(exelist, version, is_cross, arch, full_version=full_version)
return compilers.DmdDCompiler(exelist, version, for_machine, arch, full_version=full_version)
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
def detect_swift_compiler(self):
def detect_swift_compiler(self, for_machine):
exelist = self.binaries.host.lookup_entry('swift')
is_cross = not self.machines.matches_build_machine(for_machine)
if exelist is None:
# TODO support fallback
exelist = [self.default_swift[0]]
@ -1142,53 +1123,47 @@ class Environment:
raise EnvironmentException('Could not execute Swift compiler "%s"' % ' '.join(exelist))
version = search_version(err)
if 'Swift' in err:
return compilers.SwiftCompiler(exelist, version)
return compilers.SwiftCompiler(exelist, version, for_machine, is_cross)
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
def compiler_from_language(self, lang: str, want_cross: bool):
def compiler_from_language(self, lang: str, for_machine: MachineChoice):
if lang == 'c':
comp = self.detect_c_compiler(want_cross)
comp = self.detect_c_compiler(for_machine)
elif lang == 'cpp':
comp = self.detect_cpp_compiler(want_cross)
comp = self.detect_cpp_compiler(for_machine)
elif lang == 'objc':
comp = self.detect_objc_compiler(want_cross)
comp = self.detect_objc_compiler(for_machine)
elif lang == 'cuda':
comp = self.detect_cuda_compiler(want_cross)
comp = self.detect_cuda_compiler(for_machine)
elif lang == 'objcpp':
comp = self.detect_objcpp_compiler(want_cross)
comp = self.detect_objcpp_compiler(for_machine)
elif lang == 'java':
comp = self.detect_java_compiler() # Java is platform independent.
comp = self.detect_java_compiler(for_machine)
elif lang == 'cs':
comp = self.detect_cs_compiler() # C# is platform independent.
comp = self.detect_cs_compiler(for_machine)
elif lang == 'vala':
comp = self.detect_vala_compiler() # Vala compiles to platform-independent C
comp = self.detect_vala_compiler(for_machine)
elif lang == 'd':
comp = self.detect_d_compiler(want_cross)
comp = self.detect_d_compiler(for_machine)
elif lang == 'rust':
comp = self.detect_rust_compiler(want_cross)
comp = self.detect_rust_compiler(for_machine)
elif lang == 'fortran':
comp = self.detect_fortran_compiler(want_cross)
comp = self.detect_fortran_compiler(for_machine)
elif lang == 'swift':
if want_cross:
raise EnvironmentException('Cross compilation with Swift is not working yet.')
comp = self.detect_swift_compiler()
comp = self.detect_swift_compiler(for_machine)
else:
comp = None
return comp
def detect_compilers(self, lang: str, need_cross_compiler: bool):
comp = self.compiler_from_language(lang, False)
if need_cross_compiler:
cross_comp = self.compiler_from_language(lang, True)
else:
cross_comp = None
def detect_compiler_for(self, lang: str, for_machine: MachineChoice):
comp = self.compiler_from_language(lang, for_machine)
if comp is not None:
self.coredata.process_new_compilers(lang, comp, cross_comp, self)
return comp, cross_comp
assert comp.for_machine == for_machine
self.coredata.process_new_compiler(lang, comp, self)
return comp
def detect_static_linker(self, compiler):
for_machine = MachineChoice.HOST if compiler.is_cross else MachineChoice.BUILD
linker = self.binaries[for_machine].lookup_entry('ar')
linker = self.binaries[compiler.for_machine].lookup_entry('ar')
if linker is not None:
linkers = [linker]
else:
@ -1256,9 +1231,6 @@ class Environment:
def get_build_dir(self):
return self.build_dir
def get_exe_suffix(self):
return self.exe_suffix
def get_import_lib_dir(self) -> str:
"Install dir for the import library (library used for linking)"
return self.get_libdir()
@ -1269,7 +1241,9 @@ class Environment:
def get_shared_lib_dir(self) -> str:
"Install dir for the shared library"
if self.win_libdir_layout:
m = self.machines.host
# Windows has no RPATH or similar, so DLLs must be next to EXEs.
if m.is_windows() or m.is_cygwin():
return self.get_bindir()
return self.get_libdir()
@ -1277,9 +1251,6 @@ class Environment:
"Install dir for the static library"
return self.get_libdir()
def get_object_suffix(self):
return self.object_suffix
def get_prefix(self) -> str:
return self.coredata.get_builtin_option('prefix')
@ -1301,8 +1272,8 @@ class Environment:
def get_datadir(self) -> str:
return self.coredata.get_builtin_option('datadir')
def get_compiler_system_dirs(self):
for comp in self.coredata.compilers.values():
def get_compiler_system_dirs(self, for_machine: MachineChoice):
for comp in self.coredata.compilers[for_machine].values():
if isinstance(comp, compilers.ClangCompiler):
index = 1
break

@ -21,7 +21,7 @@ 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
from .mesonlib import FileMode, MachineChoice, PerMachine, Popen_safe, listify, extract_as_list, has_path_sep
from .dependencies import ExternalProgram
from .dependencies import InternalDependency, Dependency, NotFoundDependency, DependencyException
from .interpreterbase import InterpreterBase
@ -738,7 +738,7 @@ class BuildTargetHolder(TargetHolder):
return r.format(self.__class__.__name__, h.get_id(), h.filename)
def is_cross(self):
return self.held_object.is_cross()
return not self.held_object.environment.machines.matches_build_machine(self.held_object.for_machine)
@noPosargs
@permittedKwargs({})
@ -1035,12 +1035,8 @@ class CompilerHolder(InterpreterObject):
idir = os.path.join(self.environment.get_source_dir(),
i.held_object.get_curdir(), idir)
args += self.compiler.get_include_args(idir, False)
native = kwargs.get('native', None)
if native:
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
if not nobuiltins:
for_machine = Interpreter.machine_from_native_kwarg(kwargs)
opts = self.environment.coredata.compiler_options[for_machine]
args += self.compiler.get_option_compile_args(opts)
if mode == 'link':
@ -1696,8 +1692,10 @@ class ModuleHolder(InterpreterObject, ObjectHolder):
data=self.interpreter.build.data,
headers=self.interpreter.build.get_headers(),
man=self.interpreter.build.get_man(),
global_args=self.interpreter.build.global_args,
project_args=self.interpreter.build.projects_args.get(self.interpreter.subproject, {}),
#global_args_for_build = self.interpreter.build.global_args.build,
global_args = self.interpreter.build.global_args.host,
#project_args_for_build = self.interpreter.build.projects_args.build.get(self.interpreter.subproject, {}),
project_args = self.interpreter.build.projects_args.host.get(self.interpreter.subproject, {}),
build_machine=self.interpreter.builtin['build_machine'].held_object,
host_machine=self.interpreter.builtin['host_machine'].held_object,
target_machine=self.interpreter.builtin['target_machine'].held_object,
@ -1839,18 +1837,10 @@ class MesonMain(InterpreterObject):
if len(args) != 1:
raise InterpreterException('get_compiler_method must have one and only one argument.')
cname = args[0]
native = kwargs.get('native', None)
if native is None:
if self.build.environment.is_cross_build():
native = False
else:
native = True
native = kwargs.get('native', False)
if not isinstance(native, bool):
raise InterpreterException('Type of "native" must be a boolean.')
if native:
clist = self.interpreter.coredata.compilers
else:
clist = self.interpreter.coredata.cross_compilers
clist = self.interpreter.coredata.compilers[MachineChoice.BUILD if native else MachineChoice.HOST]
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)
@ -2085,7 +2075,7 @@ class Interpreter(InterpreterBase):
# have the compilers needed to gain more knowledge, so wipe out old
# inferrence and start over.
machines = self.build.environment.machines.miss_defaulting()
machines.build = environment.detect_machine_info(self.coredata.compilers)
machines.build = environment.detect_machine_info(self.coredata.compilers.build)
self.build.environment.machines = machines.default_missing()
assert self.build.environment.machines.build.cpu is not None
assert self.build.environment.machines.host.cpu is not None
@ -2237,10 +2227,10 @@ class Interpreter(InterpreterBase):
def get_variables(self):
return self.variables
def check_cross_stdlibs(self):
if self.build.environment.is_cross_build():
props = self.build.environment.properties.host
for l in self.coredata.cross_compilers.keys():
def check_stdlibs(self):
for for_machine in MachineChoice:
props = self.build.environment.properties[for_machine]
for l in self.coredata.compilers[for_machine].keys():
try:
di = mesonlib.stringlistify(props.get_stdlib(l))
if len(di) != 2:
@ -2248,7 +2238,7 @@ class Interpreter(InterpreterBase):
% l)
projname, depname = di
subproj = self.do_subproject(projname, 'meson', {})
self.build.cross_stdlibs[l] = subproj.get_variable_method([depname], {})
self.build.stdlibs.host[l] = subproj.get_variable_method([depname], {})
except KeyError:
pass
except InvalidArguments:
@ -2729,7 +2719,7 @@ external dependencies (including libraries) must go to "dependencies".''')
mlog.log('Project version:', mlog.bold(self.project_version))
self.add_languages(proj_langs, True)
if not self.is_subproject():
self.check_cross_stdlibs()
self.check_stdlibs()
@permittedKwargs(permitted_kwargs['add_languages'])
@stringArgs
@ -2786,37 +2776,38 @@ external dependencies (including libraries) must go to "dependencies".''')
raise Exception()
def add_languages(self, args, required):
success = self.add_languages_for(args, required, MachineChoice.BUILD)
success &= self.add_languages_for(args, required, MachineChoice.HOST)
return success
def add_languages_for(self, args, required, for_machine: MachineChoice):
success = True
need_cross_compiler = self.environment.is_cross_build()
for lang in sorted(args, key=compilers.sort_clink):
lang = lang.lower()
if lang in self.coredata.compilers:
comp = self.coredata.compilers[lang]
cross_comp = self.coredata.cross_compilers.get(lang, None)
clist = self.coredata.compilers[for_machine]
machine_name = for_machine.get_lower_case_name()
if lang in clist:
comp = clist[lang]
else:
try:
(comp, cross_comp) = self.environment.detect_compilers(lang, need_cross_compiler)
comp = self.environment.detect_compiler_for(lang, for_machine)
if comp is None:
raise InvalidArguments('Tried to use unknown language "%s".' % lang)
comp.sanity_check(self.environment.get_scratch_dir(), self.environment)
if cross_comp:
cross_comp.sanity_check(self.environment.get_scratch_dir(), self.environment)
except Exception:
if not required:
mlog.log('Compiler for language', mlog.bold(lang), 'not found.')
mlog.log('Compiler for language',
mlog.bold(lang), 'for the', machine_name,
'machine not found.')
success = False
continue
else:
raise
mlog.log('Native', comp.get_display_language(), 'compiler:',
mlog.log(comp.get_display_language(), 'compiler for the', machine_name, 'machine:',
mlog.bold(' '.join(comp.get_exelist())), comp.get_version_string())
self.build.ensure_static_linker(comp)
if need_cross_compiler:
mlog.log('Cross', cross_comp.get_display_language(), 'compiler:',
mlog.bold(' '.join(cross_comp.get_exelist())), cross_comp.get_version_string())
self.build.ensure_static_cross_linker(cross_comp)
langs = self.coredata.compilers.keys()
langs = self.coredata.compilers[for_machine].keys()
if 'vala' in langs:
if 'c' not in langs:
raise InterpreterException('Compiling Vala requires C. Add C to your project languages and rerun Meson.')
@ -2935,14 +2926,9 @@ external dependencies (including libraries) must go to "dependencies".''')
)
def _find_cached_dep(self, name, kwargs):
# Check if we want this as a cross-dep or a native-dep
# FIXME: Not all dependencies support such a distinction right now,
# and we repeat this check inside dependencies that do. We need to
# consolidate this somehow.
if self.environment.is_cross_build() and kwargs.get('native', False):
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
# Check if we want this as a build-time / build machine or runt-time /
# host machine dep.
for_machine = Interpreter.machine_from_native_kwarg(kwargs)
identifier = dependencies.get_dep_identifier(name, kwargs)
cached_dep = self.coredata.deps[for_machine].get(identifier)
@ -3097,10 +3083,7 @@ external dependencies (including libraries) must go to "dependencies".''')
# cannot cache them. They must always be evaluated else
# we won't actually read all the build files.
if dep.found():
if self.environment.is_cross_build() and kwargs.get('native', False):
for_machine = MachineChoice.BUILD
else:
for_machine = MachineChoice.HOST
for_machine = MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST
self.coredata.deps[for_machine].put(identifier, dep)
return DependencyHolder(dep, self.subproject)
@ -3849,45 +3832,47 @@ different subdirectory.
env = self.unpack_env_kwarg(kwargs)
self.build.test_setups[setup_name] = build.TestSetup(exe_wrapper, gdb, timeout_multiplier, env)
def get_argdict_on_crossness(self, native_dict, cross_dict, kwargs):
# TODO make cross agnostic, just taking into account for_machine
# TODO PerMachine[T], Iterator[T]
def get_argdict_on_crossness(self, dicts_per_machine: PerMachine, kwargs) -> typing.Iterator:
for_native = kwargs.get('native', not self.environment.is_cross_build())
if not isinstance(for_native, bool):
raise InterpreterException('Keyword native must be a boolean.')
if for_native:
return native_dict
if self.environment.is_cross_build():
if for_native:
return iter([dicts_per_machine[MachineChoice.BUILD]])
else:
return iter([dicts_per_machine[MachineChoice.HOST]])
else:
return cross_dict
if for_native:
return iter([dicts_per_machine[MachineChoice.BUILD],
dicts_per_machine[MachineChoice.HOST]])
else:
return iter([])
@permittedKwargs(permitted_kwargs['add_global_arguments'])
@stringArgs
def func_add_global_arguments(self, node, args, kwargs):
argdict = self.get_argdict_on_crossness(self.build.global_args,
self.build.cross_global_args,
kwargs)
self.add_global_arguments(node, argdict, args, kwargs)
for argdict in self.get_argdict_on_crossness(self.build.global_args, kwargs):
self.add_global_arguments(node, argdict, args, kwargs)
@permittedKwargs(permitted_kwargs['add_global_link_arguments'])
@stringArgs
def func_add_global_link_arguments(self, node, args, kwargs):
argdict = self.get_argdict_on_crossness(self.build.global_link_args,
self.build.cross_global_link_args,
kwargs)
self.add_global_arguments(node, argdict, args, kwargs)
for argdict in self.get_argdict_on_crossness(self.build.global_link_args, kwargs):
self.add_global_arguments(node, argdict, args, kwargs)
@permittedKwargs(permitted_kwargs['add_project_arguments'])
@stringArgs
def func_add_project_arguments(self, node, args, kwargs):
argdict = self.get_argdict_on_crossness(self.build.projects_args,
self.build.cross_projects_args,
kwargs)
self.add_project_arguments(node, argdict, args, kwargs)
for argdict in self.get_argdict_on_crossness(self.build.projects_args, kwargs):
self.add_project_arguments(node, argdict, args, kwargs)
@permittedKwargs(permitted_kwargs['add_project_link_arguments'])
@stringArgs
def func_add_project_link_arguments(self, node, args, kwargs):
argdict = self.get_argdict_on_crossness(self.build.projects_link_args,
self.build.cross_projects_link_args, kwargs)
self.add_project_arguments(node, argdict, args, kwargs)
for argdict in self.get_argdict_on_crossness(self.build.projects_link_args, kwargs):
self.add_project_arguments(node, argdict, args, kwargs)
def add_global_arguments(self, node, argsdict, args, kwargs):
if self.is_subproject():
@ -3940,7 +3925,8 @@ different subdirectory.
self.print_extra_warnings()
def print_extra_warnings(self):
for c in self.coredata.compilers.values():
# TODO cross compilation
for c in self.coredata.compilers.host.values():
if c.get_id() == 'clang':
self.check_clang_asan_lundef()
break
@ -4091,13 +4077,7 @@ Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_s
if not args:
raise InterpreterException('Target does not have a name.')
name, *sources = args
if self.environment.is_cross_build():
if kwargs.get('native', False):
is_cross = False
else:
is_cross = True
else:
is_cross = False
for_machine = Interpreter.machine_from_native_kwarg(kwargs)
if 'sources' in kwargs:
sources += listify(kwargs['sources'])
sources = self.source_strings_to_files(sources)
@ -4128,9 +4108,9 @@ Try setting b_lundef to false instead.'''.format(self.coredata.base_options['b_s
kwargs = {k: v for k, v in kwargs.items() if k in targetclass.known_kwargs}
kwargs['include_directories'] = self.extract_incdirs(kwargs)
target = targetclass(name, self.subdir, self.subproject, is_cross, sources, objs, self.environment, kwargs)
target = targetclass(name, self.subdir, self.subproject, for_machine, sources, objs, self.environment, kwargs)
if is_cross:
if not self.environment.machines.matches_build_machine(for_machine):
self.add_cross_stdlib_info(target)
l = targetholder(target, self)
self.add_target(name, l.held_object)
@ -4157,18 +4137,21 @@ This will become a hard error in the future.''', location=self.current_node)
def get_used_languages(self, target):
result = {}
for i in target.sources:
for lang, c in self.coredata.compilers.items():
# TODO other platforms
for lang, c in self.coredata.compilers.host.items():
if c.can_compile(i):
result[lang] = True
break
return result
def add_cross_stdlib_info(self, target):
if target.for_machine != MachineChoice.HOST:
return
for l in self.get_used_languages(target):
props = self.environment.properties.host
if props.has_stdlib(l) \
and self.subproject != props.get_stdlib(l)[0]:
target.add_deps(self.build.cross_stdlibs[l])
target.add_deps(self.build.stdlibs.host[l])
def check_sources_exist(self, subdir, sources):
for s in sources:
@ -4236,3 +4219,7 @@ This will become a hard error in the future.''', location=self.current_node)
raise InvalidCode('Is_variable takes two arguments.')
varname = args[0]
return varname in self.variables
@staticmethod
def machine_from_native_kwarg(kwargs):
return MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST

@ -463,94 +463,6 @@ def is_dragonflybsd() -> bool:
def is_freebsd() -> bool:
return platform.system().lower() == 'freebsd'
def _get_machine_is_cross(env, is_cross):
"""
This is not morally correct, but works for now. For cross builds the build
and host machines differ. `is_cross == true` means the host machine, while
`is_cross == false` means the build machine. Both are used in practice,
even though the documentation refers to the host machine implying we should
hard-code it. For non-cross builds `is_cross == false` is passed but the
host and build machines are identical so it doesn't matter.
Users for `for_*` should instead specify up front which machine they want
and query that like:
env.machines[MachineChoice.HOST].is_haiku()
"""
for_machine = MachineChoice.HOST if is_cross else MachineChoice.BUILD
return env.machines[for_machine]
def for_windows(is_cross, env):
"""
Host machine is windows?
Deprecated: Please use `env.machines[for_machine].is_windows()`.
Note: 'host' is the machine on which compiled binaries will run
"""
return _get_machine_is_cross(env, is_cross).is_windows()
def for_cygwin(is_cross, env):
"""
Host machine is cygwin?
Deprecated: Please use `env.machines[for_machine].is_cygwin()`.
Note: 'host' is the machine on which compiled binaries will run
"""
return _get_machine_is_cross(env, is_cross).is_cygwin()
def for_linux(is_cross, env):
"""
Host machine is linux?
Deprecated: Please use `env.machines[for_machine].is_linux()`.
Note: 'host' is the machine on which compiled binaries will run
"""
return _get_machine_is_cross(env, is_cross).is_linux()
def for_darwin(is_cross, env):
"""
Host machine is Darwin (iOS/OS X)?
Deprecated: Please use `env.machines[for_machine].is_darwin()`.
Note: 'host' is the machine on which compiled binaries will run
"""
return _get_machine_is_cross(env, is_cross).is_darwin()
def for_android(is_cross, env):
"""
Host machine is Android?
Deprecated: Please use `env.machines[for_machine].is_android()`.
Note: 'host' is the machine on which compiled binaries will run
"""
return _get_machine_is_cross(env, is_cross).is_android()
def for_haiku(is_cross, env):
"""
Host machine is Haiku?
Deprecated: Please use `env.machines[for_machine].is_haiku()`.
Note: 'host' is the machine on which compiled binaries will run
"""
return _get_machine_is_cross(env, is_cross).is_haiku()
def for_openbsd(is_cross, env):
"""
Host machine is OpenBSD?
Deprecated: Please use `env.machines[for_machine].is_openbsd()`.
Note: 'host' is the machine on which compiled binaries will run
"""
return _get_machine_is_cross(env, is_cross).is_openbsd()
def exe_exists(arglist: List[str]) -> bool:
try:
if subprocess.run(arglist, timeout=10).returncode == 0:

@ -110,7 +110,7 @@ class CmakeModule(ExtensionModule):
self.snippets.add('subproject')
def detect_voidp_size(self, env):
compilers = env.coredata.compilers
compilers = env.coredata.compilers.host
compiler = compilers.get('c', None)
if not compiler:
compiler = compilers.get('cpp', None)

@ -1048,7 +1048,7 @@ This will become a hard error in the future.''')
if state.environment.is_cross_build():
compiler = state.environment.coredata.cross_compilers.get('c')
else:
compiler = state.environment.coredata.compilers.get('c')
compiler = state.environment.coredata.compilers.host.get('c')
compiler_flags = self._get_langs_compilers_flags(state, [('c', compiler)])
cflags.extend(compiler_flags[0])

@ -397,7 +397,7 @@ class PkgConfigModule(ExtensionModule):
dversions = kwargs.get('d_module_versions', None)
if dversions:
compiler = state.environment.coredata.compilers.get('d')
compiler = state.environment.coredata.compilers.host.get('d')
if compiler:
deps.add_cflags(compiler.get_feature_args({'versions': dversions}, None))

@ -211,7 +211,7 @@ class PythonDependency(ExternalDependency):
if pyarch is None:
self.is_found = False
return
arch = detect_cpu_family(env.coredata.compilers)
arch = detect_cpu_family(env.coredata.compilers.host)
if arch == 'x86':
arch = '32'
elif arch == 'x86_64':

@ -18,7 +18,7 @@ import re
from .. import mlog
from .. import mesonlib, build
from ..mesonlib import MesonException, extract_as_list
from ..mesonlib import MachineChoice, MesonException, extract_as_list
from . import get_include_args
from . import ModuleReturnValue
from . import ExtensionModule
@ -41,16 +41,17 @@ class WindowsModule(ExtensionModule):
def _find_resource_compiler(self, state):
# FIXME: Does not handle `native: true` executables, see
# See https://github.com/mesonbuild/meson/issues/1531
# But given a machine, we can un-hardcode `binaries.host` below.
# Take a parameter instead of the hardcoded definition below
for_machine = MachineChoice.HOST
if hasattr(self, '_rescomp'):
return self._rescomp
# Will try cross / native file and then env var
rescomp = ExternalProgram.from_bin_list(state.environment.binaries.host, 'windres')
rescomp = ExternalProgram.from_bin_list(state.environment.binaries[for_machine], 'windres')
if not rescomp or not rescomp.found():
comp = self.detect_compiler(state.environment.coredata.compilers)
comp = self.detect_compiler(state.environment.coredata.compilers[for_machine])
if comp.id in {'msvc', 'clang-cl', 'intel-cl'}:
rescomp = ExternalProgram('rc', silent=True)
else:

@ -14,6 +14,7 @@
from . import coredata as cdata
from .mesonlib import MachineChoice
import os.path
import pprint
@ -91,18 +92,11 @@ def run(options):
if v:
print('Native File: ' + ' '.join(v))
elif k == 'compilers':
print('Cached native compilers:')
dump_compilers(v)
elif k == 'cross_compilers':
print('Cached cross compilers:')
dump_compilers(v)
for for_machine in MachineChoice:
print('Cached {} machine compilers:'.format(
for_machine.get_lower_case_name()))
dump_compilers(v[for_machine])
elif k == 'deps':
native = list(sorted(v.build.items()))
if v.host is not v.build:
cross = list(sorted(v.host.items()))
else:
cross = []
def print_dep(dep_key, dep):
print(' ' + dep_key[0] + ": ")
print(' compile args: ' + repr(dep.get_compile_args()))
@ -111,16 +105,13 @@ def run(options):
print(' sources: ' + repr(dep.get_sources()))
print(' version: ' + repr(dep.get_version()))
if native:
print('Cached native dependencies:')
for dep_key, deps in native:
for dep in deps:
print_dep(dep_key, dep)
if cross:
print('Cached dependencies:')
for dep_key, deps in cross:
for dep in deps:
print_dep(dep_key, dep)
for for_machine in iter(MachineChoice):
items_list = list(sorted(v[for_machine].items()))
if items_list:
print('Cached dependencies for {} machine' % for_machine.get_lower_case_name())
for dep_key, deps in items_list:
for dep in deps:
print_dep(dep_key, dep)
else:
print(k + ':')
print(textwrap.indent(pprint.pformat(v), ' '))

@ -31,7 +31,7 @@ from mesonbuild import compilers
from mesonbuild import mesonlib
from mesonbuild import mlog
from mesonbuild import mtest
from mesonbuild.mesonlib import stringlistify, Popen_safe
from mesonbuild.mesonlib import MachineChoice, stringlistify, Popen_safe
from mesonbuild.coredata import backendlist
import argparse
import xml.etree.ElementTree as ET
@ -126,14 +126,14 @@ def platform_fix_name(fname, compiler, env):
canonical_compiler = compiler
if '?lib' in fname:
if mesonlib.for_windows(env.is_cross_build(), env) and canonical_compiler == 'msvc':
if env.machines.host.is_windows() and canonical_compiler == 'msvc':
fname = re.sub(r'lib/\?lib(.*)\.', r'bin/\1.', fname)
fname = re.sub(r'/\?lib/', r'/bin/', fname)
elif mesonlib.for_windows(env.is_cross_build(), env):
elif env.machines.host.is_windows():
fname = re.sub(r'lib/\?lib(.*)\.', r'bin/lib\1.', fname)
fname = re.sub(r'\?lib(.*)\.dll$', r'lib\1.dll', fname)
fname = re.sub(r'/\?lib/', r'/bin/', fname)
elif mesonlib.for_cygwin(env.is_cross_build(), env):
elif env.machines.host.is_cygwin():
fname = re.sub(r'lib/\?lib(.*)\.so$', r'bin/cyg\1.dll', fname)
fname = re.sub(r'lib/\?lib(.*)\.', r'bin/cyg\1.', fname)
fname = re.sub(r'\?lib(.*)\.dll$', r'cyg\1.dll', fname)
@ -143,7 +143,7 @@ def platform_fix_name(fname, compiler, env):
if fname.endswith('?exe'):
fname = fname[:-4]
if mesonlib.for_windows(env.is_cross_build(), env) or mesonlib.for_cygwin(env.is_cross_build(), env):
if env.machines.host.is_windows() or env.machines.host.is_cygwin():
return fname + '.exe'
if fname.startswith('?msvc:'):
@ -158,40 +158,40 @@ def platform_fix_name(fname, compiler, env):
if fname.startswith('?cygwin:'):
fname = fname[8:]
if not mesonlib.for_cygwin(env.is_cross_build(), env):
if not env.machines.host.is_cygwin():
return None
if fname.startswith('?!cygwin:'):
fname = fname[9:]
if mesonlib.for_cygwin(env.is_cross_build(), env):
if env.machines.host.is_cygwin():
return None
if fname.endswith('?so'):
if mesonlib.for_windows(env.is_cross_build(), env) and canonical_compiler == 'msvc':
if env.machines.host.is_windows() and canonical_compiler == 'msvc':
fname = re.sub(r'lib/([^/]*)\?so$', r'bin/\1.dll', fname)
fname = re.sub(r'/(?:lib|)([^/]*?)\?so$', r'/\1.dll', fname)
return fname
elif mesonlib.for_windows(env.is_cross_build(), env):
elif env.machines.host.is_windows():
fname = re.sub(r'lib/([^/]*)\?so$', r'bin/\1.dll', fname)
fname = re.sub(r'/([^/]*?)\?so$', r'/\1.dll', fname)
return fname
elif mesonlib.for_cygwin(env.is_cross_build(), env):
elif env.machines.host.is_cygwin():
fname = re.sub(r'lib/([^/]*)\?so$', r'bin/\1.dll', fname)
fname = re.sub(r'/lib([^/]*?)\?so$', r'/cyg\1.dll', fname)
fname = re.sub(r'/([^/]*?)\?so$', r'/\1.dll', fname)
return fname
elif mesonlib.for_darwin(env.is_cross_build(), env):
elif env.machines.host.is_darwin():
return fname[:-3] + '.dylib'
else:
return fname[:-3] + '.so'
if fname.endswith('?implib') or fname.endswith('?implibempty'):
if mesonlib.for_windows(env.is_cross_build(), env) and canonical_compiler == 'msvc':
if env.machines.host.is_windows() and canonical_compiler == 'msvc':
# only MSVC doesn't generate empty implibs
if fname.endswith('?implibempty') and compiler == 'msvc':
return None
return re.sub(r'/(?:lib|)([^/]*?)\?implib(?:empty|)$', r'/\1.lib', fname)
elif mesonlib.for_windows(env.is_cross_build(), env) or mesonlib.for_cygwin(env.is_cross_build(), env):
elif env.machines.host.is_windows() or env.machines.host.is_cygwin():
return re.sub(r'\?implib(?:empty|)$', r'.dll.a', fname)
else:
return None
@ -465,12 +465,12 @@ def have_objc_compiler():
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir:
env = environment.Environment(None, build_dir, get_fake_options('/'))
try:
objc_comp = env.detect_objc_compiler(False)
objc_comp = env.detect_objc_compiler(MachineChoice.HOST)
except mesonlib.MesonException:
return False
if not objc_comp:
return False
env.coredata.process_new_compilers('objc', objc_comp, None, env)
env.coredata.process_new_compiler('objc', objc_comp, env)
try:
objc_comp.sanity_check(env.get_scratch_dir(), env)
except mesonlib.MesonException:
@ -481,12 +481,12 @@ def have_objcpp_compiler():
with AutoDeletedDir(tempfile.mkdtemp(prefix='b ', dir='.')) as build_dir:
env = environment.Environment(None, build_dir, get_fake_options('/'))
try:
objcpp_comp = env.detect_objcpp_compiler(False)
objcpp_comp = env.detect_objcpp_compiler(MachineChoice.HOST)
except mesonlib.MesonException:
return False
if not objcpp_comp:
return False
env.coredata.process_new_compilers('objcpp', objcpp_comp, None, env)
env.coredata.process_new_compiler('objcpp', objcpp_comp, env)
try:
objcpp_comp.sanity_check(env.get_scratch_dir(), env)
except mesonlib.MesonException:
@ -793,7 +793,7 @@ def detect_system_compiler():
print()
for lang in sorted(compilers.all_languages):
try:
comp = env.compiler_from_language(lang, env.is_cross_build())
comp = env.compiler_from_language(lang, MachineChoice.HOST)
details = '%s %s' % (' '.join(comp.get_exelist()), comp.get_version_string())
except mesonlib.MesonException:
comp = None

@ -46,9 +46,9 @@ 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, is_osx, is_cygwin, is_dragonflybsd, is_openbsd, is_haiku,
windows_proof_rmtree, python_command, version_compare,
BuildDirLock, Version, PerMachine, LibType
)
from mesonbuild.environment import detect_ninja
from mesonbuild.mesonlib import MesonException, EnvironmentException
@ -184,10 +184,7 @@ def skip_if_not_language(lang):
try:
env = get_fake_env()
f = getattr(env, 'detect_{}_compiler'.format(lang))
if lang in ['cs', 'vala', 'java', 'swift']:
f()
else:
f(False)
f(MachineChoice.HOST)
except EnvironmentException:
raise unittest.SkipTest('No {} compiler found.'.format(lang))
return func(*args, **kwargs)
@ -223,7 +220,7 @@ def skip_if_not_base_option(feature):
@functools.wraps(f)
def wrapped(*args, **kwargs):
env = get_fake_env()
cc = env.detect_c_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
if feature not in cc.base_options:
raise unittest.SkipTest(
'{} not available with {}'.format(feature, cc.id))
@ -344,7 +341,7 @@ class InternalTests(unittest.TestCase):
def test_compiler_args_class(self):
cargsfunc = mesonbuild.compilers.CompilerArgs
cc = mesonbuild.compilers.CCompiler([], 'fake', False)
cc = mesonbuild.compilers.CCompiler([], 'fake', False, MachineChoice.HOST)
# Test that bad initialization fails
self.assertRaises(TypeError, cargsfunc, [])
self.assertRaises(TypeError, cargsfunc, [], [])
@ -430,7 +427,7 @@ class InternalTests(unittest.TestCase):
def test_compiler_args_class_gnuld(self):
cargsfunc = mesonbuild.compilers.CompilerArgs
## Test --start/end-group
gcc = mesonbuild.compilers.GnuCCompiler([], 'fake', mesonbuild.compilers.CompilerType.GCC_STANDARD, False)
gcc = mesonbuild.compilers.GnuCCompiler([], 'fake', mesonbuild.compilers.CompilerType.GCC_STANDARD, False, MachineChoice.HOST)
## Test that 'direct' append and extend works
l = cargsfunc(gcc, ['-Lfoodir', '-lfoo'])
self.assertEqual(l.to_native(copy=True), ['-Lfoodir', '-Wl,--start-group', '-lfoo', '-Wl,--end-group'])
@ -764,7 +761,7 @@ class InternalTests(unittest.TestCase):
'{}.dll.a', '{}.lib', '{}.dll'),
'static': msvc_static}}
env = get_fake_env()
cc = env.detect_c_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
if is_osx():
self._test_all_naming(cc, env, patterns, 'darwin')
elif is_cygwin():
@ -807,8 +804,8 @@ class InternalTests(unittest.TestCase):
with tempfile.TemporaryDirectory() as tmpdir:
pkgbin = ExternalProgram('pkg-config', command=['pkg-config'], silent=True)
env = get_fake_env()
compiler = env.detect_c_compiler(False)
env.coredata.compilers = {'c': compiler}
compiler = env.detect_c_compiler(MachineChoice.HOST)
env.coredata.compilers.host = {'c': compiler}
env.coredata.compiler_options.host['c_link_args'] = FakeCompilerOptions()
p1 = Path(tmpdir) / '1'
p2 = Path(tmpdir) / '2'
@ -989,7 +986,7 @@ class InternalTests(unittest.TestCase):
Ensure that the toolset version returns the correct value for this MSVC
'''
env = get_fake_env()
cc = env.detect_c_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
if cc.get_argument_syntax() != 'msvc':
raise unittest.SkipTest('Test only applies to MSVC-like compilers')
toolset_ver = cc.get_toolset_version()
@ -1045,8 +1042,8 @@ class DataTests(unittest.TestCase):
self.assertIsNotNone(md)
env = get_fake_env()
# FIXME: Support other compilers
cc = env.detect_c_compiler(False)
cpp = env.detect_cpp_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
cpp = env.detect_cpp_compiler(MachineChoice.HOST)
for comp in (cc, cpp):
for opt in comp.get_options().keys():
self.assertIn(opt, md)
@ -1606,7 +1603,7 @@ class AllPlatformTests(BasePlatformTests):
def test_clike_get_library_dirs(self):
env = get_fake_env()
cc = env.detect_c_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
for d in cc.get_library_dirs(env):
self.assertTrue(os.path.exists(d))
self.assertTrue(os.path.isdir(d))
@ -1622,7 +1619,7 @@ class AllPlatformTests(BasePlatformTests):
'''
testdir = os.path.join(self.common_test_dir, '3 static')
env = get_fake_env(testdir, self.builddir, self.prefix)
cc = env.detect_c_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
static_linker = env.detect_static_linker(cc)
if is_windows():
raise unittest.SkipTest('https://github.com/mesonbuild/meson/issues/1526')
@ -1977,7 +1974,7 @@ class AllPlatformTests(BasePlatformTests):
for lang, evar in langs:
# Detect with evar and do sanity checks on that
if evar in os.environ:
ecc = getattr(env, 'detect_{}_compiler'.format(lang))(False)
ecc = getattr(env, 'detect_{}_compiler'.format(lang))(MachineChoice.HOST)
self.assertTrue(ecc.version)
elinker = env.detect_static_linker(ecc)
# Pop it so we don't use it for the next detection
@ -2005,7 +2002,7 @@ class AllPlatformTests(BasePlatformTests):
# Check that we actually used the evalue correctly as the compiler
self.assertEqual(ecc.get_exelist(), shlex.split(evalue))
# Do auto-detection of compiler based on platform, PATH, etc.
cc = getattr(env, 'detect_{}_compiler'.format(lang))(False)
cc = getattr(env, 'detect_{}_compiler'.format(lang))(MachineChoice.HOST)
self.assertTrue(cc.version)
linker = env.detect_static_linker(cc)
# Check compiler type
@ -2056,7 +2053,7 @@ class AllPlatformTests(BasePlatformTests):
for w in wrappercc:
wrappercc_s += shlex.quote(w) + ' '
os.environ[evar] = wrappercc_s
wcc = getattr(env, 'detect_{}_compiler'.format(lang))(False)
wcc = getattr(env, 'detect_{}_compiler'.format(lang))(MachineChoice.HOST)
# Check static linker too
wrapperlinker = python_command + [wrapper] + linker.get_exelist() + linker.get_always_args()
wrapperlinker_s = ''
@ -2081,7 +2078,7 @@ class AllPlatformTests(BasePlatformTests):
testdir = os.path.join(self.common_test_dir, '138 c cpp and asm')
# Skip if building with MSVC
env = get_fake_env(testdir, self.builddir, self.prefix)
if env.detect_c_compiler(False).get_id() == 'msvc':
if env.detect_c_compiler(MachineChoice.HOST).get_id() == 'msvc':
raise unittest.SkipTest('MSVC can\'t compile assembly')
self.init(testdir)
commands = {'c-asm': {}, 'cpp-asm': {}, 'cpp-c-asm': {}, 'c-cpp-asm': {}}
@ -2224,7 +2221,7 @@ class AllPlatformTests(BasePlatformTests):
testdir = os.path.join(self.common_test_dir, '5 linkstatic')
env = get_fake_env(testdir, self.builddir, self.prefix)
if env.detect_c_compiler(False).get_id() == 'clang' and is_windows():
if env.detect_c_compiler(MachineChoice.HOST).get_id() == 'clang' and is_windows():
raise unittest.SkipTest('LTO not (yet) supported by windows clang')
self.init(testdir, extra_args='-Db_lto=true')
@ -2367,7 +2364,7 @@ int main(int argc, char **argv) {
def detect_prebuild_env(self):
env = get_fake_env()
cc = env.detect_c_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
stlinker = env.detect_static_linker(cc)
if mesonbuild.mesonlib.is_windows():
object_suffix = 'obj'
@ -2852,7 +2849,7 @@ recommended as it is not supported on some platforms''')
testdirlib = os.path.join(testdirbase, 'lib')
extra_args = None
env = get_fake_env(testdirlib, self.builddir, self.prefix)
if env.detect_c_compiler(False).get_id() not in {'msvc', 'clang-cl', 'intel-cl'}:
if env.detect_c_compiler(MachineChoice.HOST).get_id() not in {'msvc', 'clang-cl', 'intel-cl'}:
# static libraries are not linkable with -l with msvc because meson installs them
# as .a files which unix_args_to_native will not know as it expects libraries to use
# .lib as extension. For a DLL the import library is installed as .lib. Thus for msvc
@ -3821,7 +3818,7 @@ class FailureTests(BasePlatformTests):
raise unittest.SkipTest('wx-config, wx-config-3.0 or wx-config-gtk3 found')
self.assertMesonRaises("dependency('wxwidgets')", self.dnf)
self.assertMesonOutputs("dependency('wxwidgets', required : false)",
"Dependency .*WxWidgets.* found: .*NO.*")
"Run-time dependency .*WxWidgets.* found: .*NO.*")
def test_wx_dependency(self):
if not shutil.which('wx-config-3.0') and not shutil.which('wx-config') and not shutil.which('wx-config-gtk3'):
@ -3868,8 +3865,8 @@ class FailureTests(BasePlatformTests):
'''
env = get_fake_env()
try:
env.detect_objc_compiler(False)
env.detect_objcpp_compiler(False)
env.detect_objc_compiler(MachineChoice.HOST)
env.detect_objcpp_compiler(MachineChoice.HOST)
except EnvironmentException:
code = "add_languages('objc')\nadd_languages('objcpp')"
self.assertMesonRaises(code, "Unknown compiler")
@ -4022,7 +4019,7 @@ class WindowsTests(BasePlatformTests):
'''
testdir = os.path.join(self.platform_test_dir, '1 basic')
env = get_fake_env(testdir, self.builddir, self.prefix)
cc = env.detect_c_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
if cc.get_argument_syntax() != 'msvc':
raise unittest.SkipTest('Not using MSVC')
# To force people to update this test, and also test
@ -4035,7 +4032,7 @@ class WindowsTests(BasePlatformTests):
# resource compiler depfile generation is not yet implemented for msvc
env = get_fake_env(testdir, self.builddir, self.prefix)
depfile_works = env.detect_c_compiler(False).get_id() not in {'msvc', 'clang-cl', 'intel-cl'}
depfile_works = env.detect_c_compiler(MachineChoice.HOST).get_id() not in {'msvc', 'clang-cl', 'intel-cl'}
self.init(testdir)
self.build()
@ -4066,7 +4063,7 @@ class WindowsTests(BasePlatformTests):
testdir = os.path.join(self.unit_test_dir, '45 vscpp17')
env = get_fake_env(testdir, self.builddir, self.prefix)
cc = env.detect_c_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
if cc.get_argument_syntax() != 'msvc':
raise unittest.SkipTest('Test only applies to MSVC-like compilers')
@ -4100,7 +4097,7 @@ class DarwinTests(BasePlatformTests):
# Try with bitcode enabled
out = self.init(testdir, extra_args='-Db_bitcode=true')
env = get_fake_env(testdir, self.builddir, self.prefix)
cc = env.detect_c_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
if cc.id != 'clang':
raise unittest.SkipTest('Not using Clang on OSX')
# Warning was printed
@ -4360,10 +4357,10 @@ class LinuxlikeTests(BasePlatformTests):
mesonlog = self.get_meson_log()
if qt4 == 0:
self.assertRegex('\n'.join(mesonlog),
r'Dependency qt4 \(modules: Core\) found: YES 4.* \(pkg-config\)\n')
r'Run-time dependency qt4 \(modules: Core\) found: YES 4.* \(pkg-config\)\n')
if qt5 == 0:
self.assertRegex('\n'.join(mesonlog),
r'Dependency qt5 \(modules: Core\) found: YES 5.* \(pkg-config\)\n')
r'Run-time dependency qt5 \(modules: Core\) found: YES 5.* \(pkg-config\)\n')
@skip_if_not_base_option('b_sanitize')
def test_generate_gir_with_address_sanitizer(self):
@ -4394,7 +4391,7 @@ class LinuxlikeTests(BasePlatformTests):
# Confirm that the dependency was found with qmake
mesonlog = self.get_meson_log()
self.assertRegex('\n'.join(mesonlog),
r'Dependency qt5 \(modules: Core\) found: YES .* \((qmake|qmake-qt5)\)\n')
r'Run-time dependency qt5 \(modules: Core\) found: YES .* \((qmake|qmake-qt5)\)\n')
def _test_soname_impl(self, libpath, install):
if is_cygwin() or is_osx():
@ -4519,7 +4516,7 @@ class LinuxlikeTests(BasePlatformTests):
'''
testdir = os.path.join(self.common_test_dir, '1 trivial')
env = get_fake_env(testdir, self.builddir, self.prefix)
cc = env.detect_c_compiler(False)
cc = env.detect_c_compiler(MachineChoice.HOST)
self._test_stds_impl(testdir, cc, 'c')
def test_compiler_cpp_stds(self):
@ -4529,7 +4526,7 @@ class LinuxlikeTests(BasePlatformTests):
'''
testdir = os.path.join(self.common_test_dir, '2 cpp')
env = get_fake_env(testdir, self.builddir, self.prefix)
cpp = env.detect_cpp_compiler(False)
cpp = env.detect_cpp_compiler(MachineChoice.HOST)
self._test_stds_impl(testdir, cpp, 'cpp')
def test_unity_subproj(self):
@ -5196,7 +5193,10 @@ endian = 'little'
@skipIfNoPkgconfig
def test_pkg_config_option(self):
testdir = os.path.join(self.unit_test_dir, '55 pkg_config_path option')
self.init(testdir, extra_args=['-Dpkg_config_path=' + os.path.join(testdir, 'host_extra_path')])
self.init(testdir, extra_args=[
'-Dbuild.pkg_config_path=' + os.path.join(testdir, 'build_extra_path'),
'-Dpkg_config_path=' + os.path.join(testdir, 'host_extra_path'),
])
def test_std_remains(self):
# C_std defined in project options must be in effect also when native compiling.
@ -5206,6 +5206,18 @@ endian = 'little'
self.assertRegex(compdb[0]['command'], '-std=c99')
self.build()
def test_identity_cross(self):
testdir = os.path.join(self.unit_test_dir, '58 identity cross')
crossfile = tempfile.NamedTemporaryFile(mode='w')
os.environ['CC'] = '"' + os.path.join(testdir, 'build_wrapper.py') + '"'
crossfile.write('''[binaries]
c = ['{0}']
'''.format(os.path.join(testdir, 'host_wrapper.py')))
crossfile.flush()
self.meson_cross_file = crossfile.name
# TODO should someday be explicit about build platform only here
self.init(testdir)
def should_run_cross_arm_tests():
return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm')
@ -5781,17 +5793,16 @@ class NativeFileTests(BasePlatformTests):
f.write('@py -3 {} %*'.format(filename))
return batfile
def helper_for_compiler(self, lang, cb):
def helper_for_compiler(self, lang, cb, for_machine = MachineChoice.HOST):
"""Helper for generating tests for overriding compilers for langaugages
with more than one implementation, such as C, C++, ObjC, ObjC++, and D.
"""
env = get_fake_env()
getter = getattr(env, 'detect_{}_compiler'.format(lang))
if lang not in ['cs']:
getter = functools.partial(getter, False)
getter = functools.partial(getter, for_machine)
cc = getter()
binary, newid = cb(cc)
env.binaries.host.binaries[lang] = binary
env.binaries[for_machine].binaries[lang] = binary
compiler = getter()
self.assertEqual(compiler.id, newid)
@ -5956,8 +5967,7 @@ class NativeFileTests(BasePlatformTests):
wrapper = self.helper_create_binary_wrapper(binary, version=version_str)
env = get_fake_env()
getter = getattr(env, 'detect_{}_compiler'.format(lang))
if lang in ['rust']:
getter = functools.partial(getter, False)
getter = functools.partial(getter, MachineChoice.HOST)
env.binaries.host.binaries[lang] = wrapper
compiler = getter()
self.assertEqual(compiler.version, version)
@ -5985,7 +5995,7 @@ class NativeFileTests(BasePlatformTests):
'swiftc', version='Swift 1.2345', outfile='stderr')
env = get_fake_env()
env.binaries.host.binaries['swift'] = wrapper
compiler = env.detect_swift_compiler()
compiler = env.detect_swift_compiler(MachineChoice.HOST)
self.assertEqual(compiler.version, '1.2345')
def test_native_file_dirs(self):

@ -3,10 +3,5 @@ project('pkg_config_path option')
build = dependency('totally_made_up_dep', native: true, method : 'pkg-config')
host = dependency('totally_made_up_dep', native: false, method : 'pkg-config')
# TODO always test we can do this separately
if meson.is_cross_build()
assert(build.version() == '4.5.6', 'wrong version for build machine dependency')
else
assert(host.version() == '1.2.3', 'wrong version for host machine dependency')
endif
assert(build.version() == '4.5.6', 'wrong version for build machine dependency')
assert(host.version() == '1.2.3', 'wrong version for host machine dependency')

@ -0,0 +1,5 @@
#!/usr/bin/env python
import subprocess, sys
subprocess.call(["cc", "-DEXTERNAL_BUILD"] + sys.argv[1:])

@ -0,0 +1,5 @@
#!/usr/bin/env python
import subprocess, sys
subprocess.call(["cc", "-DEXTERNAL_HOST"] + sys.argv[1:])

@ -0,0 +1,15 @@
project('identity cross test', 'c')
assert(meson.get_compiler('c', native: true).get_define(
'GOT',
args : [ '-DARG_BUILD' ],
prefix : '#include "stuff.h"',
include_directories: include_directories('.'),
) == 'BUILD', 'did not get BUILD from native: true compiler')
assert(meson.get_compiler('c', native: false).get_define(
'GOT',
args : [ '-DARG_HOST' ],
prefix : '#include "stuff.h"',
include_directories: include_directories('.'),
) == 'HOST', 'did not get HOST from native: false compiler')

@ -0,0 +1,27 @@
#ifdef EXTERNAL_BUILD
#ifndef ARG_BUILD
#error "External is build but arg_build is not set."
#elif defined(ARG_HOST)
#error "External is build but arg_host is set."
#else
#define GOT BUILD
#endif
#endif
#ifdef EXTERNAL_HOST
#ifndef ARG_HOST
#error "External is host but arg_host is not set."
#elif defined(ARG_BUILD)
#error "External is host but arg_build is set."
#else
#define GOT HOST
#endif
#endif
#if defined(EXTERNAL_BUILD) && defined(EXTERNAL_HOST)
#error "Both external build and external host set."
#endif
#if !defined(EXTERNAL_BUILD) && !defined(EXTERNAL_HOST)
#error "Neither external build nor external host is set."
#endif
Loading…
Cancel
Save