aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2018-06-29 19:33:17 +0530
committerNirbheek Chauhan <nirbheek.chauhan@gmail.com>2018-07-01 13:59:48 +0000
commitec29f19c1274d72e3a2639e47caf4a7f17ffa436 (patch)
tree70ffad6c031159508e92b05ff69acbc052262480
parentae8d044cb6dca20c1d6504a27660bcbed16db438 (diff)
downloadmeson-ec29f19c1274d72e3a2639e47caf4a7f17ffa436.zip
meson-ec29f19c1274d72e3a2639e47caf4a7f17ffa436.tar.gz
meson-ec29f19c1274d72e3a2639e47caf4a7f17ffa436.tar.bz2
Add a helper for fetching of binaries from cross files
A number of cases have to be taken care of while doing this, so refactor it into a helper on ExternalProgram and use it everywhere. 1. Command is a list of len > 1, use it as-is 2. Command is a list of len == 1 (or a string), use as a string 3. If command is an absolute path, use it as-is 4. If command is not an absolute path, search for it
-rw-r--r--mesonbuild/dependencies/base.py21
-rw-r--r--mesonbuild/dependencies/ui.py6
-rw-r--r--mesonbuild/interpreter.py17
-rw-r--r--mesonbuild/modules/windows.py18
4 files changed, 38 insertions, 24 deletions
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index 8319cb7..07d06a1 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -438,8 +438,7 @@ class PkgConfigDependency(ExternalDependency):
if self.required:
raise DependencyException('Pkg-config binary missing from cross file')
else:
- pkgname = environment.cross_info.config['binaries']['pkgconfig']
- potential_pkgbin = ExternalProgram(pkgname, silent=True)
+ potential_pkgbin = ExternalProgram.from_cross_info(environment.cross_info, 'pkgconfig')
if potential_pkgbin.found():
self.pkgbin = potential_pkgbin
PkgConfigDependency.class_pkgbin = self.pkgbin
@@ -799,6 +798,24 @@ class ExternalProgram:
return r.format(self.__class__.__name__, self.name, self.command)
@staticmethod
+ def from_cross_info(cross_info, name):
+ if name not in cross_info.config['binaries']:
+ return NonExistingExternalProgram()
+ command = cross_info.config['binaries'][name]
+ if not isinstance(command, (list, str)):
+ raise MesonException('Invalid type {!r} for binary {!r} in cross file'
+ ''.format(command, name))
+ if isinstance(command, list):
+ if len(command) == 1:
+ command = command[0]
+ # We cannot do any searching if the command is a list, and we don't
+ # 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)
+ # Search for the command using the specified string!
+ return ExternalProgram(command, silent=True)
+
+ @staticmethod
def _shebang_to_cmd(script):
"""
Check if the file has a shebang and manually parse it to figure out
diff --git a/mesonbuild/dependencies/ui.py b/mesonbuild/dependencies/ui.py
index 72958dd..324f9fa 100644
--- a/mesonbuild/dependencies/ui.py
+++ b/mesonbuild/dependencies/ui.py
@@ -291,10 +291,10 @@ class QtBaseDependency(ExternalDependency):
self.bindir = os.path.join(prefix, 'bin')
def _find_qmake(self, qmake):
- # Even when cross-compiling, if we don't get a cross-info qmake, we
+ # 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():
- qmake = self.env.cross_info.config['binaries'].get('qmake', qmake)
+ if self.env.is_cross_build() and 'qmake' in self.env.cross_info.config['binaries']:
+ return ExternalProgram.from_cross_info(self.env.cross_info, 'qmake')
return ExternalProgram(qmake, silent=True)
def _qmake_detect(self, mods, kwargs):
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 8f6f79d..5a9cc22 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -2618,23 +2618,18 @@ external dependencies (including libraries) must go to "dependencies".''')
self.emit_base_options_warnings(enabled_opts)
def program_from_cross_file(self, prognames, silent=False):
- bins = self.environment.cross_info.config['binaries']
+ cross_info = self.environment.cross_info
for p in prognames:
if hasattr(p, 'held_object'):
p = p.held_object
if isinstance(p, mesonlib.File):
continue # Always points to a local (i.e. self generated) file.
if not isinstance(p, str):
- raise InterpreterException('Executable name must be a string.')
- if p in bins:
- command = bins[p]
- if isinstance(command, (list, str)):
- extprog = dependencies.ExternalProgram(p, command=command, silent=silent)
- else:
- raise InterpreterException('Invalid type {!r} for binary {!r} in cross file'
- ''.format(command, p))
- progobj = ExternalProgramHolder(extprog)
- return progobj
+ raise InterpreterException('Executable name must be a string')
+ prog = ExternalProgram.from_cross_info(cross_info, p)
+ if prog.found():
+ return ExternalProgramHolder(prog)
+ return None
def program_from_system(self, args, silent=False):
# Search for scripts relative to current subdir.
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index 44a9ebb..19f3e2b 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -15,13 +15,14 @@
import os
from .. import mlog
-from .. import mesonlib, dependencies, build
+from .. import mesonlib, build
from ..mesonlib import MesonException, extract_as_list
from . import get_include_args
from . import ModuleReturnValue
from . import ExtensionModule
from ..interpreter import CustomTargetHolder
from ..interpreterbase import permittedKwargs, FeatureNewKwargs
+from ..dependencies import ExternalProgram
class WindowsModule(ExtensionModule):
@@ -49,7 +50,7 @@ class WindowsModule(ExtensionModule):
extra_args += get_include_args(inc_dirs)
if comp.id == 'msvc':
- rescomp = dependencies.ExternalProgram('rc', silent=True)
+ rescomp = ExternalProgram('rc', silent=True)
res_args = extra_args + ['/nologo', '/fo@OUTPUT@', '@INPUT@']
suffix = 'res'
else:
@@ -58,22 +59,23 @@ class WindowsModule(ExtensionModule):
for arg in extra_args:
if ' ' in arg:
mlog.warning(m.format(arg))
- rescomp_name = None
+ rescomp = None
# FIXME: Does not handle `native: true` executables, see
# https://github.com/mesonbuild/meson/issues/1531
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.
- rescomp_name = state.environment.cross_info.config['binaries'].get('windres')
- if rescomp_name is None:
+ cross_info = state.environment.cross_info
+ rescomp = ExternalProgram.from_cross_info(cross_info, 'windres')
+ if not rescomp or not rescomp.found():
# Pick-up env var WINDRES if set. This is often used for
# specifying an arch-specific windres.
- rescomp_name = os.environ.get('WINDRES', 'windres')
- rescomp = dependencies.ExternalProgram(rescomp_name, silent=True)
+ rescomp = ExternalProgram(os.environ.get('WINDRES', 'windres'), silent=True)
res_args = extra_args + ['@INPUT@', '@OUTPUT@']
suffix = 'o'
if not rescomp.found():
- raise MesonException('Could not find Windows resource compiler "%s".' % rescomp_name)
+ raise MesonException('Could not find Windows resource compiler {!r}'
+ ''.format(rescomp.get_path()))
res_targets = []