diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index 7668fa061..1c81a9dc4 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -334,6 +334,7 @@ the following special string substitutions: - `@DEPFILE@` the full path to the dependency file passed to `depfile` - `@PLAINNAME@`: the input filename, without a path - `@BASENAME@`: the input filename, with extension removed +- `@PRIVATE_DIR@`: path to a directory where the custom target must store all its intermediate files, available since 0.50.1 The `depfile` keyword argument also accepts the `@BASENAME@` and `@PLAINNAME@` substitutions. *(since 0.47)* diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 4d35d223d..be181a831 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -964,6 +964,12 @@ class Backend: raise MesonException(msg) dfilename = os.path.join(outdir, target.depfile) i = i.replace('@DEPFILE@', dfilename) + elif '@PRIVATE_DIR@' in i: + if target.absolute_paths: + pdir = self.get_target_private_dir_abs(target) + else: + pdir = self.get_target_private_dir(target) + i = i.replace('@PRIVATE_DIR@', pdir) elif '@PRIVATE_OUTDIR_' in i: match = re.search(r'@PRIVATE_OUTDIR_(ABS_)?([^/\s*]*)@', i) if not match: diff --git a/test cases/common/216 link custom/custom_stlib.py b/test cases/common/216 link custom/custom_stlib.py new file mode 100755 index 000000000..776dfbfe2 --- /dev/null +++ b/test cases/common/216 link custom/custom_stlib.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python3 + +import os, sys, subprocess, argparse, pathlib + +parser = argparse.ArgumentParser() + +parser.add_argument('--private-dir', required=True) +parser.add_argument('-o', required=True) +parser.add_argument('cmparr', nargs='+') + +static_linker = 'ar' + +contents = '''#include + +void flob() { + printf("Now flobbing.\\n"); +} +''' + +def generate_lib(outfile, private_dir, compiler_array): + outdir = pathlib.Path(private_dir) + if not outdir.exists(): + outdir.mkdir() + c_file = outdir / 'flob.c' + c_file.write_text(contents) + o_file = c_file.with_suffix('.o') + compile_cmd = compiler_array + ['-c', '-g', '-O2', '-o', o_file, c_file] + subprocess.check_call(compile_cmd) + out_file = pathlib.Path(outfile) + if out_file.exists(): + out_file.unlink() + link_cmd = [static_linker, 'csrD', outfile, o_file] + subprocess.check_call(link_cmd) + +if __name__ == '__main__': + options = parser.parse_args() + generate_lib(options.o, options.private_dir, options.cmparr) + sys.exit(1) diff --git a/test cases/common/216 link custom/meson.build b/test cases/common/216 link custom/meson.build new file mode 100644 index 000000000..3dc11ecc7 --- /dev/null +++ b/test cases/common/216 link custom/meson.build @@ -0,0 +1,20 @@ +project('linkcustom', 'c') + +# This would require passing the static linker to the build script or having +# it detect it by itself. I'm too lazy to implement it now and it is not +# really needed for testing that custom targets work. It is the responsibility +# of the custom target to produce things in the correct format. +assert(not meson.is_cross(), 'MESON_SKIP_TEST cross checking not implemented.') + +cc = meson.get_compiler('c') +genprog = find_program('custom_stlib.py') + +clib = custom_target('linkcustom', + output: 'libflob.a', + command: [genprog, + '-o', '@OUTPUT@', + '--private-dir', '@PRIVATE_DIR@'] + cc.cmd_array()) + +#exe = executable('prog', 'prog.c', link_with: clib) +#test('linkcustom', exe) + \ No newline at end of file