aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Ericson <John.Ericson@Obsidian.Systems>2018-08-09 16:06:55 -0400
committerJohn Ericson <John.Ericson@Obsidian.Systems>2019-01-02 16:22:47 -0500
commit2b22576fb6a8bb52434068d95eff188a201e6bc5 (patch)
treeb169c0c8c5cf56f68cf8a1d75f35a0fb71ad295f
parentdbf080afe99a8bbb04a3bfb19a81363d3b78e7b4 (diff)
downloadmeson-2b22576fb6a8bb52434068d95eff188a201e6bc5.zip
meson-2b22576fb6a8bb52434068d95eff188a201e6bc5.tar.gz
meson-2b22576fb6a8bb52434068d95eff188a201e6bc5.tar.bz2
Remove cross_info; cross file is parsed up front and discarded
-rw-r--r--mesonbuild/backend/backends.py22
-rw-r--r--mesonbuild/backend/ninjabackend.py18
-rw-r--r--mesonbuild/compilers/c.py2
-rw-r--r--mesonbuild/compilers/compilers.py11
-rw-r--r--mesonbuild/dependencies/base.py120
-rw-r--r--mesonbuild/dependencies/ui.py24
-rw-r--r--mesonbuild/environment.py313
-rw-r--r--mesonbuild/interpreter.py33
-rw-r--r--mesonbuild/modules/gnome.py8
-rw-r--r--mesonbuild/modules/python.py9
-rw-r--r--mesonbuild/modules/python3.py9
-rw-r--r--mesonbuild/modules/windows.py22
-rwxr-xr-xrun_tests.py6
-rwxr-xr-xrun_unittests.py23
14 files changed, 333 insertions, 287 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 187f302..22920f4 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -343,7 +343,7 @@ class Backend:
exe_is_native = True
is_cross_built = (not exe_is_native) and \
self.environment.is_cross_build() and \
- self.environment.cross_info.need_exe_wrapper()
+ self.environment.need_exe_wrapper()
if is_cross_built:
exe_wrapper = self.environment.get_exe_wrapper()
if not exe_wrapper.found():
@@ -639,11 +639,11 @@ class Backend:
def get_mingw_extra_paths(self, target):
paths = OrderedSet()
# The cross bindir
- root = self.environment.cross_info.get_root()
+ root = self.environment.properties.host.get_root()
if root:
paths.add(os.path.join(root, 'bin'))
# The toolchain bindir
- sys_root = self.environment.cross_info.get_sys_root()
+ sys_root = self.environment.properties.host.get_sys_root()
if sys_root:
paths.add(os.path.join(sys_root, 'bin'))
# Get program and library dirs from all target compilers
@@ -692,7 +692,7 @@ class Backend:
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.cross_info.need_exe_wrapper()
+ self.environment.need_exe_wrapper()
if isinstance(exe, build.BuildTarget):
is_cross = is_cross and exe.is_cross
if isinstance(exe, dependencies.ExternalProgram):
@@ -763,7 +763,7 @@ class Backend:
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.cross_info.need_exe_wrapper():
+ 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.
@@ -977,15 +977,13 @@ class Backend:
def create_install_data_files(self):
install_data_file = os.path.join(self.environment.get_scratch_dir(), 'install.dat')
- if self.environment.is_cross_build():
- bins = self.environment.cross_info.config['binaries']
- if 'strip' not in bins:
+ strip_bin = self.environment.binaries.host.lookup_entry('strip')
+ if strip_bin is None:
+ if self.environment.is_cross_build():
mlog.warning('Cross file does not specify strip binary, result will not be stripped.')
- strip_bin = None
else:
- strip_bin = mesonlib.stringlistify(bins['strip'])
- else:
- strip_bin = self.environment.native_strip_bin
+ # TODO go through all candidates, like others
+ strip_bin = [self.environment.default_strip[0]]
d = InstallData(self.environment.get_source_dir(),
self.environment.get_build_dir(),
self.environment.get_prefix(),
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index ee7d203..44bdaab 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -536,7 +536,7 @@ int dummy;
# 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.cross_info.need_exe_wrapper()
+ self.environment.need_exe_wrapper()
if mesonlib.for_windows(is_cross, self.environment) or \
mesonlib.for_cygwin(is_cross, self.environment):
extra_bdeps = target.get_transitive_build_target_deps()
@@ -1337,7 +1337,7 @@ int dummy;
if not is_cross:
self.generate_java_link(outfile)
if is_cross:
- if self.environment.cross_info.is_cross_build():
+ if self.environment.is_cross_build():
static_linker = self.build.static_cross_linker
else:
static_linker = self.build.static_linker
@@ -1381,6 +1381,8 @@ int dummy;
ctypes = [(self.build.compilers, False)]
if self.environment.is_cross_build():
ctypes.append((self.build.cross_compilers, True))
+ else:
+ ctypes.append((self.build.cross_compilers, True))
for (complist, is_cross) in ctypes:
for langname, compiler in complist.items():
if langname == 'java' \
@@ -1389,13 +1391,9 @@ int dummy;
or langname == 'cs':
continue
crstr = ''
- cross_args = []
+ cross_args = self.environment.properties.host.get_external_link_args(langname)
if is_cross:
crstr = '_CROSS'
- try:
- cross_args = self.environment.cross_info.config['properties'][langname + '_link_args']
- except KeyError:
- pass
rule = 'rule %s%s_LINKER\n' % (langname, crstr)
if compiler.can_linker_accept_rsp():
command_template = ''' command = {executable} @$out.rsp
@@ -1823,7 +1821,7 @@ rule FORTRAN_DEP_HACK%s
def get_cross_stdlib_args(self, target, compiler):
if not target.is_cross:
return []
- if not self.environment.cross_info.has_stdlib(compiler.language):
+ if not self.environment.properties.host.has_stdlib(compiler.language):
return []
return compiler.get_no_stdinc_args()
@@ -2224,13 +2222,13 @@ rule FORTRAN_DEP_HACK%s
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.cross_info.config['host_machine']['system'])
+ elem.add_item('CROSS', '--cross-host=' + self.environment.machines.host.system)
elem.write(outfile)
def get_cross_stdlib_link_args(self, target, linker):
if isinstance(target, build.StaticLibrary) or not target.is_cross:
return []
- if not self.environment.cross_info.has_stdlib(linker.language):
+ if not self.environment.properties.host.has_stdlib(linker.language):
return []
return linker.get_no_stdlib_link_args()
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 46f4181..92a9fa6 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -757,7 +757,7 @@ class CCompiler(Compiler):
varname = 'has function ' + funcname
varname = varname.replace(' ', '_')
if self.is_cross:
- val = env.cross_info.config['properties'].get(varname, None)
+ val = env.properties.host.get(varname, None)
if val is not None:
if isinstance(val, bool):
return val
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 31047b1..2be6ef1 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -1045,13 +1045,10 @@ class Compiler:
def get_cross_extra_flags(self, environment, link):
extra_flags = []
if self.is_cross and environment:
- if 'properties' in environment.cross_info.config:
- props = environment.cross_info.config['properties']
- lang_args_key = self.language + '_args'
- extra_flags += mesonlib.stringlistify(props.get(lang_args_key, []))
- lang_link_args_key = self.language + '_link_args'
- if link:
- extra_flags += mesonlib.stringlistify(props.get(lang_link_args_key, []))
+ props = environment.properties.host
+ extra_flags += props.get_external_args(self.language)
+ if link:
+ extra_flags += props.get_external_link_args(self.language)
return extra_flags
def _get_compile_output(self, dirname, mode):
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index cd02939..35237d0 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -33,7 +33,8 @@ from pathlib import PurePath
from .. import mlog
from .. import mesonlib
from ..compilers import clib_langs
-from ..mesonlib import MesonException, OrderedSet
+from ..environment import BinaryTable
+from ..mesonlib import MachineChoice, MesonException, OrderedSet, PerMachine
from ..mesonlib import Popen_safe, version_compare_many, version_compare, listify
# These must be defined in this file to avoid cyclical references.
@@ -393,24 +394,21 @@ class ConfigToolDependency(ExternalDependency):
if not isinstance(versions, list) and versions is not None:
versions = listify(versions)
- if self.env.is_cross_build() and not self.native:
- cross_file = self.env.cross_info.config['binaries']
- try:
- tools = [cross_file[self.tool_name]]
- except KeyError:
+ for_machine = MachineChoice.BUILD if self.native else MachineChoice.HOST
+ tool = self.env.binaries[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:
mlog.warning('No entry for {0} specified in your cross file. '
'Falling back to searching PATH. This may find a '
'native version of {0}!'.format(self.tool_name))
- tools = self.tools
- elif self.tool_name in self.env.config_info.binaries:
- tools = [self.env.config_info.binaries[self.tool_name]]
- else:
- tools = self.tools
+ tools = [[t] for t in self.tools]
best_match = (None, None)
for tool in tools:
try:
- p, out = Popen_safe([tool, '--version'])[:2]
+ p, out = Popen_safe(tool + ['--version'])[:2]
except (FileNotFoundError, PermissionError):
continue
if p.returncode != 0:
@@ -447,12 +445,12 @@ class ConfigToolDependency(ExternalDependency):
mlog.log('Found', mlog.bold(self.tool_name), repr(req_version),
mlog.red('NO'))
return False
- mlog.log('Found {}:'.format(self.tool_name), mlog.bold(shutil.which(self.config)),
+ mlog.log('Found {}:'.format(self.tool_name), mlog.bold(shutil.which(self.config[0])),
'({})'.format(version))
return True
def get_config_value(self, args, stage):
- p, out, err = Popen_safe([self.config] + args)
+ p, out, err = Popen_safe(self.config + args)
# This is required to keep shlex from stripping path separators on
# Windows. Also, don't put escape sequences in config values, okay?
out = out.replace('\\', '\\\\')
@@ -469,7 +467,7 @@ class ConfigToolDependency(ExternalDependency):
return [DependencyMethods.AUTO, DependencyMethods.CONFIG_TOOL]
def get_configtool_variable(self, variable_name):
- p, out, _ = Popen_safe([self.config, '--{}'.format(variable_name)])
+ p, out, _ = Popen_safe(self.config + ['--{}'.format(variable_name)])
if p.returncode != 0:
if self.required:
raise DependencyException(
@@ -486,7 +484,7 @@ class ConfigToolDependency(ExternalDependency):
class PkgConfigDependency(ExternalDependency):
# The class's copy of the pkg-config path. Avoids having to search for it
# multiple times in the same Meson invocation.
- class_pkgbin = None
+ class_pkgbin = PerMachine(None, None, None)
# We cache all pkg-config subprocess invocations to avoid redundant calls
pkgbin_cache = {}
@@ -498,31 +496,56 @@ class PkgConfigDependency(ExternalDependency):
# stored in the pickled coredata and recovered.
self.pkgbin = None
- # When finding dependencies for cross-compiling, we don't care about
- # the 'native' pkg-config
- if self.want_cross:
- if 'pkgconfig' not in environment.cross_info.config['binaries']:
- if self.required:
- raise DependencyException('Pkg-config binary missing from cross file')
+ if not self.want_cross and environment.is_cross_build():
+ for_machine = MachineChoice.BUILD
+ else:
+ for_machine = MachineChoice.HOST
+
+ # Create a nested function for sake of early return
+ def search():
+ # Only search for the pkg-config for each machine the first time and
+ # store the result in the class definition
+ if PkgConfigDependency.class_pkgbin[for_machine] is None:
+ mlog.debug('Pkg-config binary for %s is not cached.' % for_machine)
+ else:
+ mlog.debug('Pkg-config binary for %s is cached.' % for_machine)
+ choice = PkgConfigDependency.class_pkgbin[for_machine]
+ assert choice is not None
+ return choice
+ # Lookup in cross or machine file.
+ bt = environment.binaries[for_machine]
+ potential_pkgpath = bt.lookup_entry('pkgconfig')
+ if potential_pkgpath is None:
+ mlog.debug('Pkg-config binary missing from cross or native file, or PKG_CONFIG undefined.')
else:
- potential_pkgbin = ExternalProgram.from_bin_list(
- environment.cross_info.config['binaries'], 'pkgconfig')
- if potential_pkgbin.found():
- self.pkgbin = potential_pkgbin
+ mlog.debug('Pkg-config binary for %s specified from config file as %s.', for_machine, potential_pkgpath)
+ potential_pkgbin = ExternalProgram.from_entry('pkgconfig', potential_pkgpath)
+ if not potential_pkgbin.found():
+ mlog.debug(
+ 'Pkg-config %s for machine %s specified at %s but not found.',
+ potential_pkgbin.name, for_machine, potential_pkgbin.command)
else:
- mlog.debug('Cross pkg-config %s not found.' % potential_pkgbin.name)
- # Only search for the native pkg-config the first time and
- # store the result in the class definition
- elif PkgConfigDependency.class_pkgbin is None:
- self.pkgbin = self.check_pkgconfig()
- PkgConfigDependency.class_pkgbin = self.pkgbin
- else:
- self.pkgbin = PkgConfigDependency.class_pkgbin
+ return potential_pkgbin
+ # Fallback on hard-coded defaults.
+ if environment.machines.matches_build_machine(for_machine):
+ for potential_pkgpath in environment.default_pkgconfig:
+ potential_pkgbin = self.check_pkgconfig(potential_pkgpath)
+ if potential_pkgbin is None:
+ mlog.debug(
+ 'default Pkg-config fallback %s for machine %s specified at %s but not found.',
+ potential_pkgbin.name, for_machine, potential_pkgbin.command)
+ else:
+ return potential_pkgbin
- if not self.pkgbin:
+ self.pkgbin = search()
+ if self.pkgbin is None:
+ msg = 'Pkg-config binary for machine %s not found.' % for_machine
if self.required:
- raise DependencyException('Pkg-config not found.')
- return
+ raise DependencyException(msg)
+ else:
+ mlog.debug(msg)
+ else:
+ PkgConfigDependency.class_pkgbin[for_machine] = self.pkgbin
mlog.debug('Determining dependency {!r} with pkg-config executable '
'{!r}'.format(name, self.pkgbin.get_path()))
@@ -785,12 +808,7 @@ class PkgConfigDependency(ExternalDependency):
def get_methods():
return [DependencyMethods.PKGCONFIG]
- def check_pkgconfig(self):
- evar = 'PKG_CONFIG'
- if evar in os.environ:
- pkgbin = os.environ[evar].strip()
- else:
- pkgbin = 'pkg-config'
+ def check_pkgconfig(self, pkgbin):
pkgbin = ExternalProgram(pkgbin, silent=True)
if pkgbin.found():
try:
@@ -1688,14 +1706,15 @@ class ExternalProgram:
'''Human friendly description of the command'''
return ' '.join(self.command)
- @staticmethod
- def from_bin_list(bins, name):
- if name not in bins:
+ @classmethod
+ def from_bin_list(cls, bt: BinaryTable, name):
+ command = bt.lookup_entry(name)
+ if command is None:
return NonExistingExternalProgram()
- command = bins[name]
- if not isinstance(command, (list, str)):
- raise MesonException('Invalid type {!r} for binary {!r} in cross file'
- ''.format(command, name))
+ return cls.from_entry(name, command)
+
+ @staticmethod
+ def from_entry(name, command):
if isinstance(command, list):
if len(command) == 1:
command = command[0]
@@ -1703,6 +1722,7 @@ class ExternalProgram:
# need to search if the path is an absolute path.
if isinstance(command, list) or os.path.isabs(command):
return ExternalProgram(name, command=command, silent=True)
+ assert isinstance(command, str)
# Search for the command using the specified string!
return ExternalProgram(command, silent=True)
diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py
index 7b3d051..03c96f2 100644
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -333,22 +333,18 @@ class QtBaseDependency(ExternalDependency):
if prefix:
self.bindir = os.path.join(prefix, 'bin')
- def _find_qmake(self, qmake):
- # Even when cross-compiling, if a cross-info qmake is not specified, we
- # fallback to using the qmake in PATH because that's what we used to do
- if self.env.is_cross_build():
- if 'qmake' in self.env.cross_info.config['binaries']:
- return ExternalProgram.from_bin_list(self.env.cross_info.config['binaries'], 'qmake')
- elif self.env.config_info:
- # Prefer suffixed to unsuffixed version
- p = ExternalProgram.from_bin_list(self.env.config_info.binaries, 'qmake')
- if p.found():
- return p
- return ExternalProgram(qmake, silent=True)
-
def _qmake_detect(self, mods, kwargs):
for qmake in ('qmake-' + self.name, 'qmake'):
- self.qmake = self._find_qmake(qmake)
+ self.qmake = ExternalProgram.from_bin_list(
+ self.env.binaries.host, qmake)
+ if not self.qmake.found():
+ # Even when cross-compiling, if a cross-info qmake is not
+ # specified, we fallback to using the qmake in PATH because
+ # that's what we used to do
+ self.qmake = ExternalProgram.from_bin_list(
+ self.env.binaries.build, qmake)
+ if not self.qmake.found():
+ self.qmake = ExternalProgram(qmake, silent=True)
if not self.qmake.found():
continue
# Check that the qmake is for qt5
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index f1145e5..97aaa27 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -17,7 +17,9 @@ import configparser, os, platform, re, sys, shlex, shutil, subprocess
from . import coredata
from .linkers import ArLinker, ArmarLinker, VisualStudioLinker, DLinker, CcrxLinker
from . import mesonlib
-from .mesonlib import MesonException, EnvironmentException, PerMachine, Popen_safe
+from .mesonlib import (
+ MesonException, EnvironmentException, MachineChoice, PerMachine, Popen_safe
+)
from . import mlog
from . import compilers
@@ -336,32 +338,45 @@ class Environment:
else:
# Just create a fresh coredata in this case
self.create_new_coredata(options)
- self.exe_wrapper = None
self.machines = MachineInfos()
# Will be fully initialized later using compilers later.
self.machines.detect_build()
- if self.coredata.cross_file:
- self.cross_info = CrossBuildInfo(self.coredata.cross_file)
- if 'exe_wrapper' in self.cross_info.config['binaries']:
- from .dependencies import ExternalProgram
- self.exe_wrapper = ExternalProgram.from_bin_list(
- self.cross_info.config['binaries'], 'exe_wrapper')
- if 'host_machine' in self.cross_info.config:
- self.machines.host = MachineInfo.from_literal(
- self.cross_info.config['host_machine'])
- if 'target_machine' in self.cross_info.config:
- self.machines.target = MachineInfo.from_literal(
- self.cross_info.config['target_machine'])
- else:
- self.cross_info = None
- self.machines.default_missing()
- if self.coredata.config_files:
- self.config_info = coredata.ConfigData(
+ # Similar to coredata.compilers and build.compilers, but lower level in
+ # that there is no meta data, only names/paths.
+ self.binaries = PerMachineDefaultable()
+
+ # Misc other properties about each machine.
+ self.properties = PerMachine(Properties(), Properties(), Properties())
+
+ if self.coredata.config_files is not None:
+ config_info = coredata.ConfigData(
coredata.load_configs(self.coredata.config_files))
else:
- self.config_info = coredata.ConfigData()
+ config_info = coredata.ConfigData()
+ self.binaries.build = BinaryTable(config_info.binaries)
+
+ if self.coredata.cross_file is not None:
+ config = MesonConfigFile.parse_datafile(self.coredata.cross_file)
+ self.properties.host.properties = config.get('properties', {})
+ self.binaries.host = BinaryTable(config.get('binaries', {}), False)
+ if 'host_machine' in config:
+ self.machines.host = MachineInfo.from_literal(config['host_machine'])
+ if 'target_machine' in config:
+ self.machines.target = MachineInfo.from_literal(config['target_machine'])
+
+ self.machines.default_missing()
+ self.binaries.default_missing()
+
+ exe_wrapper = self.binaries.host.lookup_entry('exe_wrapper')
+ if exe_wrapper is not None:
+ from .dependencies import ExternalProgram
+ self.exe_wrapper = ExternalProgram.from_bin_list(
+ self.binaries.host,
+ 'exe_wrapper')
+ else:
+ self.exe_wrapper = None
self.cmd_line_options = options.cmd_line_options.copy()
@@ -385,10 +400,12 @@ class Environment:
self.default_swift = ['swiftc']
self.default_vala = ['valac']
self.default_static_linker = ['ar']
+ self.default_strip = ['strip']
self.vs_static_linker = ['lib']
self.clang_cl_static_linker = ['llvm-lib']
self.gcc_static_linker = ['gcc-ar']
self.clang_static_linker = ['llvm-ar']
+ self.default_pkgconfig = ['pkg-config']
# Various prefixes and suffixes for import libraries, shared libraries,
# static libraries, and executables.
@@ -406,11 +423,6 @@ class Environment:
self.exe_suffix = ''
self.object_suffix = 'o'
self.win_libdir_layout = False
- if 'STRIP' in os.environ:
- self.native_strip_bin = shlex.split(
- os.environ[BinaryTable.evarMap['strip']])
- else:
- self.native_strip_bin = ['strip']
def create_new_coredata(self, options):
# WARNING: Don't use any values from coredata in __init__. It gets
@@ -422,7 +434,7 @@ class Environment:
self.first_invocation = True
def is_cross_build(self):
- return self.cross_info is not None
+ return not self.machines.matches_build_machine(MachineChoice.HOST)
def dump_coredata(self):
return coredata.save(self.coredata, self.get_build_dir())
@@ -521,32 +533,30 @@ class Environment:
The list of compilers is detected in the exact same way for
C, C++, ObjC, ObjC++, Fortran, CS so consolidate it here.
'''
- is_cross = False
- exe_wrap = None
- evar = BinaryTable.evarMap[lang]
-
- if self.is_cross_build() and want_cross:
- if lang not in self.cross_info.config['binaries']:
- raise EnvironmentException('{!r} compiler binary not defined in cross file'.format(lang))
- compilers, ccache = BinaryTable.parse_entry(
- mesonlib.stringlistify(self.cross_info.config['binaries'][lang]))
- BinaryTable.warn_about_lang_pointing_to_cross(compilers[0], evar)
- # Return value has to be a list of compiler 'choices'
- compilers = [compilers]
- is_cross = True
- exe_wrap = self.get_exe_wrapper()
- elif evar in os.environ:
- compilers, ccache = BinaryTable.parse_entry(
- shlex.split(os.environ[evar]))
+
+ # 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)
# Return value has to be a list of compiler 'choices'
compilers = [compilers]
- elif lang in self.config_info.binaries:
- compilers, ccache = BinaryTable.parse_entry(
- mesonlib.stringlistify(self.config_info.binaries[lang]))
- compilers = [compilers]
else:
+ if not self.machines.matches_build_machine(for_machine):
+ raise EnvironmentException('{!r} compiler binary not defined in cross or native file'.format(lang))
compilers = getattr(self, 'default_' + lang)
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
def _handle_exceptions(self, exceptions, binaries, bintype='compiler'):
@@ -826,9 +836,8 @@ class Environment:
self._handle_exceptions(popen_exceptions, compilers)
def detect_java_compiler(self):
- if 'java' in self.config_info.binaries:
- exelist = mesonlib.stringlistify(self.config_info.binaries['java'])
- else:
+ exelist = self.binaries.host.lookup_entry('java')
+ if exelist is None:
# TODO support fallback
exelist = [self.default_java[0]]
@@ -862,13 +871,11 @@ class Environment:
self._handle_exceptions(popen_exceptions, compilers)
def detect_vala_compiler(self):
- if 'VALAC' in os.environ:
- exelist = shlex.split(os.environ['VALAC'])
- elif 'vala' in self.config_info.binaries:
- exelist = mesonlib.stringlistify(self.config_info.binaries['vala'])
- else:
+ exelist = self.binaries.host.lookup_entry('vala')
+ if exelist is None:
# TODO support fallback
exelist = [self.default_vala[0]]
+
try:
p, out = Popen_safe(exelist + ['--version'])[0:2]
except OSError:
@@ -899,20 +906,15 @@ class Environment:
self._handle_exceptions(popen_exceptions, compilers)
def detect_d_compiler(self, want_cross):
- is_cross = False
+ is_cross = want_cross and self.is_cross_build()
+ exelist = self.binaries.host.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
# up to date language version at time (2016).
- if 'DC' in os.environ:
- exelist = shlex.split(os.environ['DC'])
+ if exelist is not None:
if os.path.basename(exelist[-1]).startswith(('ldmd', 'gdmd')):
raise EnvironmentException('Meson doesn\'t support %s as it\'s only a DMD frontend for another compiler. Please provide a valid value for DC or unset it so that Meson can resolve the compiler by itself.' % exelist[-1])
- elif self.is_cross_build() and want_cross:
- exelist = mesonlib.stringlistify(self.cross_info.config['binaries']['d'])
- is_cross = True
- elif 'd' in self.config_info.binaries:
- exelist = mesonlib.stringlistify(self.config_info.binaries['d'])
else:
for d in self.default_d:
if shutil.which(d):
@@ -947,11 +949,11 @@ class Environment:
raise EnvironmentException('Unknown compiler "' + ' '.join(exelist) + '"')
def detect_swift_compiler(self):
- if 'swift' in self.config_info.binaries:
- exelist = mesonlib.stringlistify(self.config_info.binaries['swift'])
- else:
+ exelist = self.binaries.host.lookup_entry('swift')
+ if exelist is None:
# TODO support fallback
exelist = [self.default_swift[0]]
+
try:
p, _, err = Popen_safe(exelist + ['-v'])
except OSError:
@@ -1013,16 +1015,11 @@ class Environment:
return comp, cross_comp
def detect_static_linker(self, compiler):
- if compiler.is_cross:
- linker = self.cross_info.config['binaries']['ar']
- if isinstance(linker, str):
- linker = [linker]
+ linker = self.binaries.host.lookup_entry('ar')
+ if linker is not None:
linkers = [linker]
else:
- evar = BinaryTable.evarMap['ar']
- if evar in os.environ:
- linkers = [shlex.split(os.environ[evar])]
- elif isinstance(compiler, compilers.VisualStudioCCompiler):
+ if isinstance(compiler, compilers.VisualStudioCCompiler):
linkers = [self.vs_static_linker, self.clang_cl_static_linker]
elif isinstance(compiler, compilers.GnuCompiler):
# Use gcc-ar if available; needed for LTO
@@ -1140,37 +1137,37 @@ class Environment:
out = out.split('\n')[index].lstrip('libraries: =').split(':')
return [os.path.normpath(p) for p in out]
+ def need_exe_wrapper(self, for_machine: MachineChoice = MachineChoice.HOST):
+ value = self.properties[for_machine].get('needs_exe_wrapper', None)
+ if value is not None:
+ return value
+ return not self.machines[for_machine].can_run()
+
def get_exe_wrapper(self):
- if not self.cross_info.need_exe_wrapper():
+ if not self.need_exe_wrapper():
from .dependencies import EmptyExternalProgram
return EmptyExternalProgram()
return self.exe_wrapper
-
-class CrossBuildInfo:
- def __init__(self, filename):
- self.config = {'properties': {}}
- self.parse_datafile(filename)
- if 'host_machine' not in self.config and 'target_machine' not in self.config:
- raise mesonlib.MesonException('Cross info file must have either host or a target machine.')
- if 'host_machine' in self.config and 'binaries' not in self.config:
- raise mesonlib.MesonException('Cross file with "host_machine" is missing "binaries".')
-
- def ok_type(self, i):
- return isinstance(i, (str, int, bool))
-
- def parse_datafile(self, filename):
+class MesonConfigFile:
+ @classmethod
+ def parse_datafile(cls, filename):
config = configparser.ConfigParser()
try:
with open(filename, 'r') as f:
config.read_file(f, filename)
except FileNotFoundError:
raise EnvironmentException('File not found: %s.' % filename)
+ return cls.from_config_parser(config)
+
+ @classmethod
+ def from_config_parser(cls, parser: configparser.ConfigParser):
+ out = {}
# This is a bit hackish at the moment.
- for s in config.sections():
- self.config[s] = {}
- for entry in config[s]:
- value = config[s][entry]
+ for s in parser.sections():
+ section = {}
+ for entry in parser[s]:
+ value = parser[s][entry]
if ' ' in entry or '\t' in entry or "'" in entry or '"' in entry:
raise EnvironmentException('Malformed variable name %s in cross file..' % entry)
try:
@@ -1178,56 +1175,55 @@ class CrossBuildInfo:
except Exception:
raise EnvironmentException('Malformed value in cross file variable %s.' % entry)
- if self.ok_type(res):
- self.config[s][entry] = res
+ if cls._ok_type(res):
+ section[entry] = res
elif isinstance(res, list):
for i in res:
- if not self.ok_type(i):
+ if not self._ok_type(i):
raise EnvironmentException('Malformed value in cross file variable %s.' % entry)
- self.config[s][entry] = res
+ section[entry] = res
else:
raise EnvironmentException('Malformed value in cross file variable %s.' % entry)
+ out[s] = section
+ return out
+
+ @classmethod
+ def _ok_type(cls, i):
+ return isinstance(i, (str, int, bool))
+
+class Properties:
+ def __init__(self):
+ self.properties = {}
- def has_host(self):
- return 'host_machine' in self.config
+ def get_external_args(self, language):
+ return mesonlib.stringlistify(self.properties.get(language + '_args', []))
- def has_target(self):
- return 'target_machine' in self.config
+ def get_external_link_args(self, language):
+ return mesonlib.stringlistify(self.properties.get(language + '_link_args', []))
def has_stdlib(self, language):
- return language + '_stdlib' in self.config['properties']
+ return language + '_stdlib' in self.properties
def get_stdlib(self, language):
- return self.config['properties'][language + '_stdlib']
-
- def get_host_system(self):
- "Name of host system like 'linux', or None"
- if self.has_host():
- return self.config['host_machine']['system']
- return None
-
- def get_properties(self):
- return self.config['properties']
+ return self.properties[language + '_stdlib']
def get_root(self):
- return self.get_properties().get('root', None)
+ return self.properties.get('root', None)
def get_sys_root(self):
- return self.get_properties().get('sys_root', None)
+ return self.properties.get('sys_root', None)
- def need_exe_wrapper(self):
- value = self.config['properties'].get('needs_exe_wrapper', None)
- if value is not None:
- return value
- # Can almost always run 32-bit binaries on 64-bit natively if the host
- # and build systems are the same. We don't pass any compilers to
- # detect_cpu_family() here because we always want to know the OS
- # architecture, not what the compiler environment tells us.
- if self.has_host() and detect_cpu_family({}) == 'x86_64' and \
- self.config['host_machine']['cpu_family'] == 'x86' and \
- self.config['host_machine']['system'] == detect_system():
- return False
- return True
+ # TODO consider removing so Properties is less freeform
+ def __getitem__(self, key):
+ return self.properties[key]
+
+ # TODO consider removing so Properties is less freeform
+ def __contains__(self, item):
+ return item in self.properties
+
+ # TODO consider removing, for same reasons as above
+ def get(self, key, default=None):
+ return self.properties.get(key, default)
class MachineInfo:
def __init__(self, system, cpu_family, cpu, endian):
@@ -1349,7 +1345,26 @@ class MachineInfo:
return self.is_windows() \
or self.is_cygwin()
-class MachineInfos(PerMachine):
+ # TODO make this compare two `MachineInfo`s purely. How important is the
+ # `detect_cpu_family({})` distinction? It is the one impediment to that.
+ def can_run(self):
+ """Whether we can run binaries for this machine on the current machine.
+
+ Can almost always run 32-bit binaries on 64-bit natively if the host
+ and build systems are the same. We don't pass any compilers to
+ detect_cpu_family() here because we always want to know the OS
+ architecture, not what the compiler environment tells us.
+ """
+ if self.system != detect_system():
+ return False
+ true_build_cpu_family = detect_cpu_family({})
+ return \
+ (self.cpu_family == true_build_cpu_family) or \
+ ((true_build_cpu_family == 'x86_64') and (self.cpu_family == 'x86'))
+
+class PerMachineDefaultable(PerMachine):
+ """Extends `PerMachine` with the ability to default from `None`s.
+ """
def __init__(self):
super().__init__(None, None, None)
@@ -1377,10 +1392,24 @@ class MachineInfos(PerMachine):
if self.host == self.build:
self.host = None
+class MachineInfos(PerMachineDefaultable):
def detect_build(self, compilers = None):
self.build = MachineInfo.detect(compilers)
+ def matches_build_machine(self, machine: MachineChoice):
+ return self.build == self[machine]
+
class BinaryTable:
+ def __init__(self, binaries = {}, fallback = True):
+ self.binaries = binaries
+ self.fallback = fallback
+ for name, command in self.binaries.items():
+ if not isinstance(command, (list, str)):
+ # TODO generalize message
+ raise mesonlib.MesonException(
+ 'Invalid type {!r} for binary {!r} in cross file'
+ ''.format(command, name))
+
# Map from language identifiers to environment variables.
evarMap = {
# Compilers
@@ -1397,6 +1426,9 @@ class BinaryTable:
# Binutils
'strip': 'STRIP',
'ar': 'AR',
+ 'windres': 'WINDRES',
+
+ 'pkgconfig': 'PKG_CONFIG',
}
@classmethod
@@ -1412,7 +1444,7 @@ class BinaryTable:
return cmdlist
@classmethod
- def warn_about_lang_pointing_to_cross(cls, compiler_exe, evar):
+ def _warn_about_lang_pointing_to_cross(cls, compiler_exe, evar):
evar_str = os.environ.get(evar, 'WHO_WOULD_CALL_THEIR_COMPILER_WITH_THIS_NAME')
if evar_str == compiler_exe:
mlog.warning('''Env var %s seems to point to the cross compiler.
@@ -1429,3 +1461,26 @@ This is probably wrong, it should always point to the native compiler.''' % evar
ccache = []
# Return value has to be a list of compiler 'choices'
return compiler, ccache
+
+ def lookup_entry(self, name):
+ """Lookup binary
+
+ Returns command with args as list if found, Returns `None` if nothing is
+ found.
+
+ First tries looking in explicit map, then tries environment variable.
+ """
+ # Try explict map, don't fall back on env var
+ command = self.binaries.get(name)
+ if command is not None:
+ command = mesonlib.stringlistify(command)
+ # Relies on there being no "" env var
+ evar = self.evarMap.get(name, "")
+ self._warn_about_lang_pointing_to_cross(command[0], evar)
+ elif self.fallback:
+ # Relies on there being no "" env var
+ evar = self.evarMap.get(name, "")
+ command = os.environ.get(evar)
+ if command is not None:
+ command = shlex.split(command)
+ return command
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 50f6a42..f849f3c 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -21,7 +21,7 @@ from . import optinterpreter
from . import compilers
from .wrap import wrap, WrapMode
from . import mesonlib
-from .mesonlib import FileMode, Popen_safe, listify, extract_as_list, has_path_sep
+from .mesonlib import FileMode, MachineChoice, Popen_safe, listify, extract_as_list, has_path_sep
from .dependencies import ExternalProgram
from .dependencies import InternalDependency, Dependency, NotFoundDependency, DependencyException
from .interpreterbase import InterpreterBase
@@ -1760,7 +1760,7 @@ class MesonMain(InterpreterObject):
@permittedKwargs({})
def has_exe_wrapper_method(self, args, kwargs):
if self.is_cross_build_method(None, None) and \
- self.build.environment.cross_info.need_exe_wrapper():
+ self.build.environment.need_exe_wrapper():
if self.build.environment.exe_wrapper is None:
return False
# We return True when exe_wrap is defined, when it's not needed, and
@@ -1866,7 +1866,7 @@ class MesonMain(InterpreterObject):
if not isinstance(propname, str):
raise InterpreterException('Property name must be string.')
try:
- props = self.interpreter.environment.cross_info.get_properties()
+ props = self.interpreter.environment.properties.host
return props[propname]
except Exception:
if len(args) == 2:
@@ -2164,10 +2164,10 @@ class Interpreter(InterpreterBase):
def check_cross_stdlibs(self):
if self.build.environment.is_cross_build():
- cross_info = self.build.environment.cross_info
+ props = self.build.environment.properties.host
for l, c in self.build.cross_compilers.items():
try:
- di = mesonlib.stringlistify(cross_info.get_stdlib(l))
+ di = mesonlib.stringlistify(props.get_stdlib(l))
if len(di) != 2:
raise InterpreterException('Stdlib definition for %s should have exactly two elements.'
% l)
@@ -2735,7 +2735,8 @@ external dependencies (including libraries) must go to "dependencies".''')
self.coredata. base_options[optname] = oobj
self.emit_base_options_warnings(enabled_opts)
- def _program_from_file(self, prognames, bins, silent):
+ def program_from_file_for(self, for_machine, prognames, silent):
+ bins = self.environment.binaries[for_machine]
for p in prognames:
if hasattr(p, 'held_object'):
p = p.held_object
@@ -2748,14 +2749,6 @@ external dependencies (including libraries) must go to "dependencies".''')
return ExternalProgramHolder(prog)
return None
- def program_from_cross_file(self, prognames, silent=False):
- bins = self.environment.cross_info.config['binaries']
- return self._program_from_file(prognames, bins, silent)
-
- def program_from_config_file(self, prognames, silent=False):
- bins = self.environment.config_info.binaries
- return self._program_from_file(prognames, bins, silent)
-
def program_from_system(self, args, silent=False):
# Search for scripts relative to current subdir.
# Do not cache found programs because find_program('foobar')
@@ -2813,11 +2806,8 @@ external dependencies (including libraries) must go to "dependencies".''')
progobj = self.program_from_overrides(args, silent=silent)
if progobj is None:
- if self.build.environment.is_cross_build() and not native:
- progobj = self.program_from_cross_file(args, silent=silent)
- else:
- progobj = self.program_from_config_file(args, silent=silent)
-
+ for_machine = MachineChoice.BUILD if native else MachineChoice.HOST
+ progobj = self.program_from_file_for(for_machine, args, silent=silent)
if progobj is None:
progobj = self.program_from_system(args, silent=silent)
if required and (progobj is None or not progobj.found()):
@@ -4121,8 +4111,9 @@ This will become a hard error in the future.''')
def add_cross_stdlib_info(self, target):
for l in self.get_used_languages(target):
- if self.environment.cross_info.has_stdlib(l) \
- and self.subproject != self.environment.cross_info.get_stdlib(l)[0]:
+ 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])
def check_sources_exist(self, subdir, sources):
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index be99059..2ab575c 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -532,7 +532,7 @@ class GnomeModule(ExtensionModule):
for lang in langs:
if state.environment.is_cross_build():
- link_args = state.environment.cross_info.config["properties"].get(lang + '_link_args', "")
+ link_args = state.environment.properties.host.get_external_link_args(lang)
else:
link_args = state.environment.coredata.get_external_link_args(lang)
@@ -715,7 +715,7 @@ class GnomeModule(ExtensionModule):
ret = []
for lang in langs:
if state.environment.is_cross_build():
- ret += state.environment.cross_info.config["properties"].get(lang + '_args', "")
+ ret += state.environment.properties.host.get_external_args(lang)
else:
ret += state.environment.coredata.get_external_args(lang)
return ret
@@ -1043,8 +1043,8 @@ This will become a hard error in the future.''')
ldflags.update(external_ldflags)
if state.environment.is_cross_build():
- cflags.update(state.environment.cross_info.config["properties"].get('c_args', ""))
- ldflags.update(state.environment.cross_info.config["properties"].get('c_link_args', ""))
+ cflags.update(state.environment.properties.host.get_external_args('c'))
+ ldflags.update(state.environment.properties.host.get_external_link_args('c'))
compiler = state.environment.coredata.cross_compilers.get('c')
else:
cflags.update(state.environment.coredata.get_external_args('c'))
diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py
index 9643ebc..c14ac85 100644
--- a/mesonbuild/modules/python.py
+++ b/mesonbuild/modules/python.py
@@ -501,20 +501,17 @@ class PythonModule(ExtensionModule):
if len(args) > 1:
raise InvalidArguments('find_installation takes zero or one positional argument.')
- if 'python' in state.environment.config_info.binaries:
- name_or_path = state.environment.config_info.binaries['python']
- elif args:
+ name_or_path = state.environment.binaries.host.lookup_entry('python')
+ if name_or_path is None and args:
name_or_path = args[0]
if not isinstance(name_or_path, str):
raise InvalidArguments('find_installation argument must be a string.')
- else:
- name_or_path = None
if not name_or_path:
mlog.log("Using meson's python {}".format(mesonlib.python_command))
python = ExternalProgram('python3', mesonlib.python_command, silent=True)
else:
- python = ExternalProgram(name_or_path, silent = True)
+ python = ExternalProgram.from_entry('python3', name_or_path)
if not python.found() and mesonlib.is_windows():
pythonpath = self._get_win_pythonpath(name_or_path)
diff --git a/mesonbuild/modules/python3.py b/mesonbuild/modules/python3.py
index f664632..46f15f0 100644
--- a/mesonbuild/modules/python3.py
+++ b/mesonbuild/modules/python3.py
@@ -48,10 +48,11 @@ class Python3Module(ExtensionModule):
@noKwargs
def find_python(self, state, args, kwargs):
- options = [state.environment.config_info.binaries.get('python3')]
- if not options[0]: # because this would be [None]
- options = ['python3', mesonlib.python_command]
- py3 = dependencies.ExternalProgram(*options, silent=True)
+ command = state.environment.binaries.host.lookup_entry('python3')
+ if command is not None:
+ py3 = dependencies.ExternalProgram.from_entry('python3', command)
+ else:
+ py3 = dependencies.ExternalProgram('python3', mesonlib.python_command, silent=True)
return ModuleReturnValue(py3, [py3])
@noKwargs
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index d185d89..e8d266e 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -41,29 +41,13 @@ 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.
if hasattr(self, '_rescomp'):
return self._rescomp
- rescomp = None
- if state.environment.is_cross_build():
- # If cross compiling see if windres has been specified in the
- # cross file before trying to find it another way.
- bins = state.environment.cross_info.config['binaries']
- rescomp = ExternalProgram.from_bin_list(bins, 'windres')
-
- if not rescomp or not rescomp.found():
- if 'WINDRES' in os.environ:
- # Pick-up env var WINDRES if set. This is often used for
- # specifying an arch-specific windres.
- rescomp = ExternalProgram('windres', command=os.environ.get('WINDRES'), silent=True)
-
- if not rescomp or not rescomp.found():
- # Take windres from the config file after the environment, which is
- # in keeping with the expectations on unix-like OSes that
- # environment variables trump config files.
- bins = state.environment.config_info.binaries
- rescomp = ExternalProgram.from_bin_list(bins, 'windres')
+ # Will try cross / native file and then env var
+ rescomp = ExternalProgram.from_bin_list(state.environment.binaries.host, 'windres')
if not rescomp or not rescomp.found():
comp = self.detect_compiler(state.compilers)
diff --git a/run_tests.py b/run_tests.py
index aa8a589..25a2d7f 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -76,8 +76,10 @@ def get_fake_options(prefix):
opts.native_file = []
return opts
-def get_fake_env(sdir, bdir, prefix):
- env = Environment(sdir, bdir, get_fake_options(prefix))
+def get_fake_env(sdir, bdir, prefix, opts = None):
+ if opts is None:
+ opts = get_fake_options(prefix)
+ env = Environment(sdir, bdir, opts)
env.coredata.compiler_options['c_args'] = FakeCompilerOptions()
return env
diff --git a/run_unittests.py b/run_unittests.py
index 07e6bf9..46f93e7 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -54,7 +54,7 @@ import mesonbuild.modules.pkgconfig
from run_tests import (
Backend, FakeBuild, FakeCompilerOptions,
ensure_backend_detects_changes, exe_suffix, get_backend_commands,
- get_builddir_target_args, get_fake_env, get_meson_script,
+ get_builddir_target_args, get_fake_env, get_fake_options, get_meson_script,
run_configure_inprocess, run_mtest_inprocess
)
@@ -542,7 +542,10 @@ class InternalTests(unittest.TestCase):
config.write(configfile)
configfile.flush()
configfile.close()
- detected_value = mesonbuild.environment.CrossBuildInfo(configfile.name).need_exe_wrapper()
+ opts = get_fake_options('')
+ opts.cross_file = configfilename
+ env = get_fake_env('', '', '', opts)
+ detected_value = env.need_exe_wrapper()
os.unlink(configfilename)
desired_value = not detected_value
@@ -554,7 +557,10 @@ class InternalTests(unittest.TestCase):
configfilename = configfile.name
config.write(configfile)
configfile.close()
- forced_value = mesonbuild.environment.CrossBuildInfo(configfile.name).need_exe_wrapper()
+ opts = get_fake_options('')
+ opts.cross_file = configfilename
+ env = get_fake_env('', '', '', opts)
+ forced_value = env.need_exe_wrapper()
os.unlink(configfilename)
self.assertEqual(forced_value, desired_value)
@@ -744,8 +750,9 @@ class InternalTests(unittest.TestCase):
old_call = PkgConfigDependency._call_pkgbin
old_check = PkgConfigDependency.check_pkgconfig
+ old_pkgbin = PkgConfigDependency.class_pkgbin
PkgConfigDependency._call_pkgbin = fake_call_pkgbin
- PkgConfigDependency.check_pkgconfig = lambda x: pkgbin
+ PkgConfigDependency.check_pkgconfig = lambda x, _: pkgbin
# Test begins
kwargs = {'required': True, 'silent': True}
foo_dep = PkgConfigDependency('foo', env, kwargs)
@@ -766,7 +773,7 @@ class InternalTests(unittest.TestCase):
PkgConfigDependency.check_pkgconfig = old_check
# Reset dependency class to ensure that in-process configure doesn't mess up
PkgConfigDependency.pkgbin_cache = {}
- PkgConfigDependency.class_pkgbin = None
+ PkgConfigDependency.class_pkgbin = old_pkgbin
def test_version_compare(self):
comparefunc = mesonbuild.mesonlib.version_compare_many
@@ -4843,7 +4850,7 @@ class NativeFileTests(BasePlatformTests):
getter = functools.partial(getter, False)
cc = getter()
binary, newid = cb(cc)
- env.config_info.binaries = {lang: binary}
+ env.binaries.host.binaries[lang] = binary
compiler = getter()
self.assertEqual(compiler.id, newid)
@@ -4998,7 +5005,7 @@ class NativeFileTests(BasePlatformTests):
getter = getattr(env, 'detect_{}_compiler'.format(lang))
if lang in ['rust']:
getter = functools.partial(getter, False)
- env.config_info.binaries = {lang: wrapper}
+ env.binaries.host.binaries[lang] = wrapper
compiler = getter()
self.assertEqual(compiler.version, version)
@@ -5024,7 +5031,7 @@ class NativeFileTests(BasePlatformTests):
wrapper = self.helper_create_binary_wrapper(
'swiftc', version='Swift 1.2345', outfile='stderr')
env = get_fake_env('', '', '')
- env.config_info.binaries = {'swift': wrapper}
+ env.binaries.host.binaries['swift'] = wrapper
compiler = env.detect_swift_compiler()
self.assertEqual(compiler.version, '1.2345')