aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Reference-manual.md3
-rw-r--r--docs/markdown/snippets/gendeps.md16
-rw-r--r--mesonbuild/backend/ninjabackend.py1
-rw-r--r--mesonbuild/build.py7
-rw-r--r--mesonbuild/interpreter.py7
-rwxr-xr-xtest cases/common/27 pipeline/depends/copyrunner.py7
-rw-r--r--test cases/common/27 pipeline/depends/filecopier.c22
-rw-r--r--test cases/common/27 pipeline/depends/libsrc.c.in3
-rw-r--r--test cases/common/27 pipeline/depends/meson.build11
-rw-r--r--test cases/common/27 pipeline/depends/prog.c5
-rw-r--r--test cases/common/27 pipeline/meson.build2
11 files changed, 83 insertions, 1 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 01fa3c3..2fc3d6a 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -714,6 +714,9 @@ following:
- `arguments` a list of template strings that will be the command line
arguments passed to the executable
+- `depends` is an array of build targets that must be built before this
+ generator can be run. This is used if you have a generator that calls
+ a second executable that is built in this project. Available since 0.51.0
- `depfile` is a template string pointing to a dependency file that a
generator can write listing all the additional files this target
depends on, for example a C compiler would list all the header files
diff --git a/docs/markdown/snippets/gendeps.md b/docs/markdown/snippets/gendeps.md
new file mode 100644
index 0000000..e724994
--- /dev/null
+++ b/docs/markdown/snippets/gendeps.md
@@ -0,0 +1,16 @@
+## Generators have a new `depends` keyword argument
+
+Generators can now specify extra dependencies with the `depends`
+keyword argument. It matches the behaviour of the same argument in
+other functions and specifies that the given targets must be built
+before the generator can be run. This is used in cases such as this
+one where you need to tell a generator to indirectly invoke a
+different program.
+
+```meson
+exe = executable(...)
+cg = generator(program_runner,
+ output: ['@BASENAME@.c'],
+ arguments: ['--use-tool=' + exe.full_path(), '@INPUT@', '@OUTPUT@'],
+ depends: exe)
+```
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index b897180..591b2f4 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1800,6 +1800,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
cmd = cmdlist
elem = NinjaBuildElement(self.all_outputs, outfiles, rulename, infilename)
+ elem.add_dep([self.get_target_filename(x) for x in generator.depends])
if generator.depfile is not None:
elem.add_item('DEPFILE', depfile)
if len(extra_dependencies) > 0:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index d51e2e3..65b2c20 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -1273,6 +1273,7 @@ class Generator:
self.exe = exe
self.depfile = None
self.capture = False
+ self.depends = []
self.process_kwargs(kwargs)
def __repr__(self):
@@ -1321,6 +1322,12 @@ class Generator:
if not isinstance(capture, bool):
raise InvalidArguments('Capture must be boolean.')
self.capture = capture
+ if 'depends' in kwargs:
+ depends = listify(kwargs['depends'], unholder=True)
+ for d in depends:
+ if not isinstance(d, BuildTarget):
+ raise InvalidArguments('Depends entries must be build targets.')
+ self.depends.append(d)
def get_base_outnames(self, inname):
plainname = os.path.basename(inname)
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 678560f..cb3aa8a 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -1983,7 +1983,12 @@ permitted_kwargs = {'add_global_arguments': {'language', 'native'},
},
'executable': build.known_exe_kwargs,
'find_program': {'required', 'native'},
- 'generator': {'arguments', 'output', 'depfile', 'capture', 'preserve_path_from'},
+ 'generator': {'arguments',
+ 'output',
+ 'depends',
+ 'depfile',
+ 'capture',
+ 'preserve_path_from'},
'include_directories': {'is_system'},
'install_data': {'install_dir', 'install_mode', 'rename', 'sources'},
'install_headers': {'install_dir', 'install_mode', 'subdir'},
diff --git a/test cases/common/27 pipeline/depends/copyrunner.py b/test cases/common/27 pipeline/depends/copyrunner.py
new file mode 100755
index 0000000..0ef6a6d
--- /dev/null
+++ b/test cases/common/27 pipeline/depends/copyrunner.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python3
+
+import sys, subprocess
+
+prog, infile, outfile = sys.argv[1:]
+
+subprocess.check_call([prog, infile, outfile])
diff --git a/test cases/common/27 pipeline/depends/filecopier.c b/test cases/common/27 pipeline/depends/filecopier.c
new file mode 100644
index 0000000..9001cf3
--- /dev/null
+++ b/test cases/common/27 pipeline/depends/filecopier.c
@@ -0,0 +1,22 @@
+#include<stdio.h>
+#include<assert.h>
+
+#define BUFSIZE 1024
+
+int main(int argc, char **argv) {
+ char buffer[BUFSIZE];
+ size_t num_read;
+ size_t num_written;
+ FILE *fin = fopen(argv[1], "rb");
+ FILE *fout;
+ assert(fin);
+ num_read = fread(buffer, 1, BUFSIZE, fin);
+ assert(num_read > 0);
+ fclose(fin);
+ fout = fopen(argv[2], "wb");
+ assert(fout);
+ num_written = fwrite(buffer, 1, num_read, fout);
+ assert(num_written == num_read);
+ fclose(fout);
+ return 0;
+}
diff --git a/test cases/common/27 pipeline/depends/libsrc.c.in b/test cases/common/27 pipeline/depends/libsrc.c.in
new file mode 100644
index 0000000..652f4eb
--- /dev/null
+++ b/test cases/common/27 pipeline/depends/libsrc.c.in
@@ -0,0 +1,3 @@
+int func() {
+ return 42;
+}
diff --git a/test cases/common/27 pipeline/depends/meson.build b/test cases/common/27 pipeline/depends/meson.build
new file mode 100644
index 0000000..5111fee
--- /dev/null
+++ b/test cases/common/27 pipeline/depends/meson.build
@@ -0,0 +1,11 @@
+runner = find_program('copyrunner.py')
+
+copier = executable('copier', 'filecopier.c', native: true)
+
+cg = generator(runner,
+ output: ['@BASENAME@.c'],
+ arguments: [copier.full_path(), '@INPUT@', '@OUTPUT@'],
+ depends: copier)
+
+test('generatordep',
+ executable('gd', 'prog.c', cg.process('libsrc.c.in')))
diff --git a/test cases/common/27 pipeline/depends/prog.c b/test cases/common/27 pipeline/depends/prog.c
new file mode 100644
index 0000000..f4a7dd3
--- /dev/null
+++ b/test cases/common/27 pipeline/depends/prog.c
@@ -0,0 +1,5 @@
+int func();
+
+int main(int argc, char **argv) {
+ return func() != 42;
+}
diff --git a/test cases/common/27 pipeline/meson.build b/test cases/common/27 pipeline/meson.build
index bbb49d6..e12cb7b 100644
--- a/test cases/common/27 pipeline/meson.build
+++ b/test cases/common/27 pipeline/meson.build
@@ -19,3 +19,5 @@ test('pipelined', e2)
# This is in a subdirectory to make sure
# we write proper subdir paths to output.
subdir('src')
+
+subdir('depends')