Allow passing a compiler object to run_command()

Sometimes it is needed to run the current compiler with specific options
not to compile a file but rather to obtain additional info. For example,
GCC has several -print-* options to query it about the paths to
different libraries and development files. One use case is to get the
location of development files for GCC plugins, which is not easily
obtainable by other means:

  gcc -print-file-name=plugin

For this purpose, it would be convenient if the compiler object returned
by meson.get_compiler(lang) could be used in run_command() directly.
This commit implements it.

Signed-off-by: Evgenii Shatokhin <eshatokhin@virtuozzo.com>
pull/3191/head
Evgenii Shatokhin 7 years ago committed by Jussi Pakkanen
parent 048508c989
commit 19718a8d9c
  1. 10
      docs/markdown/Reference-manual.md
  2. 10
      docs/markdown/snippets/compiler-object-run_command.md
  3. 11
      mesonbuild/interpreter.py
  4. 8
      run_unittests.py
  5. 10
      test cases/unit/23 compiler run_command/meson.build

@ -980,9 +980,13 @@ Project supports the following keyword arguments.
runresult run_command(command, list_of_args)
```
Runs the command specified in positional arguments. Returns [an opaque
object](#run-result-object) containing the result of the
invocation. The script is run from an *unspecified* directory, and
Runs the command specified in positional arguments.
`command` can be a string, or the output of [`find_program()`](#find_program),
[`files()`](#files) or [`configure_file()`](#configure_file), or
[a compiler object](#compiler-object).
Returns [an opaque object](#run-result-object) containing the result of the
invocation. The command is run from an *unspecified* directory, and
Meson will set three environment variables `MESON_SOURCE_ROOT`,
`MESON_BUILD_ROOT` and `MESON_SUBDIR` that specify the source
directory, build directory and subdirectory the target was defined in,

@ -0,0 +1,10 @@
## Compiler object can now be passed to run_command()
This can be used to run the current compiler with the specified arguments
to obtain additional information from it.
One of the use cases is to get the location of development files for the
GCC plugins:
cc = meson.get_compiler('c')
result = run_command(cc, '-print-file-name=plugin')
plugin_dev_path = result.stdout().strip()

@ -1679,10 +1679,17 @@ external dependencies (including libraries) must go to "dependencies".''')
cargs = args[1:]
srcdir = self.environment.get_source_dir()
builddir = self.environment.get_build_dir()
m = 'must be a string, or the output of find_program(), files(), or ' \
'configure_file(); not {!r}'
m = 'must be a string, or the output of find_program(), files() '\
'or configure_file(), or a compiler object; not {!r}'
if isinstance(cmd, ExternalProgramHolder):
cmd = cmd.held_object
elif isinstance(cmd, CompilerHolder):
cmd = cmd.compiler.get_exelist()[0]
prog = ExternalProgram(cmd, silent=True)
if not prog.found():
raise InterpreterException('Program {!r} not found '
'or not executable'.format(cmd))
cmd = prog
else:
if isinstance(cmd, mesonlib.File):
cmd = cmd.absolute_path(srcdir, builddir)

@ -1850,6 +1850,14 @@ int main(int argc, char **argv) {
self.init(testdir, ['--cross-file=' + name], inprocess=True)
self.wipe()
def test_compiler_run_command(self):
'''
The test checks that the compiler object can be passed to
run_command().
'''
testdir = os.path.join(self.unit_test_dir, '23 compiler run_command')
self.init(testdir)
class FailureTests(BasePlatformTests):
'''

@ -0,0 +1,10 @@
project('compiler_object_in_run_command', 'c')
cc = meson.get_compiler('c')
# This test only checks that the compiler object can be passed to
# run_command(). If the compiler has been launched, it is expected
# to output something either to stdout or to stderr.
result = run_command(cc, '--version')
if result.stdout() == '' and result.stderr() == ''
error('No output in stdout and stderr. Did the compiler run at all?')
endif
Loading…
Cancel
Save