Generators can have extra target dependencies. Closes #4131.

pull/5412/head
Jussi Pakkanen 5 years ago
parent 60e1676651
commit 79d530e325
  1. 3
      docs/markdown/Reference-manual.md
  2. 16
      docs/markdown/snippets/gendeps.md
  3. 1
      mesonbuild/backend/ninjabackend.py
  4. 7
      mesonbuild/build.py
  5. 7
      mesonbuild/interpreter.py
  6. 7
      test cases/common/27 pipeline/depends/copyrunner.py
  7. 22
      test cases/common/27 pipeline/depends/filecopier.c
  8. 3
      test cases/common/27 pipeline/depends/libsrc.c.in
  9. 11
      test cases/common/27 pipeline/depends/meson.build
  10. 5
      test cases/common/27 pipeline/depends/prog.c
  11. 2
      test cases/common/27 pipeline/meson.build

@ -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

@ -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)
```

@ -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:

@ -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)

@ -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'},

@ -0,0 +1,7 @@
#!/usr/bin/env python3
import sys, subprocess
prog, infile, outfile = sys.argv[1:]
subprocess.check_call([prog, infile, outfile])

@ -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;
}

@ -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')))

@ -0,0 +1,5 @@
int func();
int main(int argc, char **argv) {
return func() != 42;
}

@ -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')

Loading…
Cancel
Save