From 4b95dd3a6d1a08e22a144f3336f44e0d2c92bd75 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sun, 17 Mar 2019 20:39:44 +0200 Subject: [PATCH 1/9] Add test script to generate a static library with a custom target. --- docs/markdown/Reference-manual.md | 1 + mesonbuild/backend/backends.py | 6 +++ .../common/216 link custom/custom_stlib.py | 38 +++++++++++++++++++ test cases/common/216 link custom/meson.build | 20 ++++++++++ 4 files changed, 65 insertions(+) create mode 100755 test cases/common/216 link custom/custom_stlib.py create mode 100644 test cases/common/216 link custom/meson.build 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 From 93df9530c820402d553d3db2b1b3a93ba13161fb Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sun, 17 Mar 2019 21:31:02 +0200 Subject: [PATCH 2/9] Make custom lib script work with MSVC. --- .../common/216 link custom/custom_stlib.py | 48 +++++++++++++++---- test cases/common/216 link custom/meson.build | 4 +- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/test cases/common/216 link custom/custom_stlib.py b/test cases/common/216 link custom/custom_stlib.py index 776dfbfe2..925d997f4 100755 --- a/test cases/common/216 link custom/custom_stlib.py +++ b/test cases/common/216 link custom/custom_stlib.py @@ -8,8 +8,6 @@ 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() { @@ -17,12 +15,8 @@ void flob() { } ''' -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) +def generate_lib_gnulike(outfile, c_file, private_dir, compiler_array): + static_linker = 'ar' o_file = c_file.with_suffix('.o') compile_cmd = compiler_array + ['-c', '-g', '-O2', '-o', o_file, c_file] subprocess.check_call(compile_cmd) @@ -31,8 +25,42 @@ def generate_lib(outfile, private_dir, compiler_array): out_file.unlink() link_cmd = [static_linker, 'csrD', outfile, o_file] subprocess.check_call(link_cmd) + return 0 + + +def generate_lib_msvc(outfile, c_file, private_dir, compiler_array): + static_linker = 'lib' + o_file = c_file.with_suffix('.obj') + compile_cmd = compiler_array + ['/MDd', + '/nologo', + '/ZI', + '/Ob0', + '/Od', + '/c', + '/Fo' + str(o_file), + str(c_file)] + subprocess.check_call(compile_cmd) + out_file = pathlib.Path(outfile) + if out_file.exists(): + out_file.unlink() + link_cmd = [static_linker, + '/nologo', + '/OUT:' + str(outfile), + str(o_file)] + subprocess.check_call(link_cmd) + return 0 + +def generate_lib(outfile, private_dir, compiler_array): + private_dir = pathlib.Path(private_dir) + if not private_dir.exists(): + private_dir.mkdir() + c_file = private_dir / 'flob.c' + c_file.write_text(contents) + for i in compiler_array: + if i.endswith('cl') or i.endswith('cl.exe'): + return generate_lib_msvc(outfile, c_file, private_dir, compiler_array) + return generate_lib_gnulike(outfile, c_file, private_dir, compiler_array) if __name__ == '__main__': options = parser.parse_args() - generate_lib(options.o, options.private_dir, options.cmparr) - sys.exit(1) + sys.exit(generate_lib(options.o, options.private_dir, options.cmparr)) diff --git a/test cases/common/216 link custom/meson.build b/test cases/common/216 link custom/meson.build index 3dc11ecc7..dc013541f 100644 --- a/test cases/common/216 link custom/meson.build +++ b/test cases/common/216 link custom/meson.build @@ -4,7 +4,8 @@ project('linkcustom', 'c') # 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.') +assert(not meson.is_cross_build(), + 'MESON_SKIP_TEST cross checking not implemented.') cc = meson.get_compiler('c') genprog = find_program('custom_stlib.py') @@ -17,4 +18,3 @@ clib = custom_target('linkcustom', #exe = executable('prog', 'prog.c', link_with: clib) #test('linkcustom', exe) - \ No newline at end of file From e81f48db1600056942e30e2567af73d6d7678188 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sun, 17 Mar 2019 22:34:19 +0200 Subject: [PATCH 3/9] Can link against custom targets. Closes #4908. --- mesonbuild/backend/backends.py | 4 ++++ mesonbuild/build.py | 19 ++++++++++++++++++- test cases/common/216 link custom/meson.build | 9 +++++++-- test cases/common/216 link custom/prog.c | 6 ++++++ 4 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 test cases/common/216 link custom/prog.c diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index be181a831..b62438eb0 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -211,6 +211,10 @@ class Backend: return os.path.join(self.get_target_dir(target), link_lib) elif isinstance(target, build.StaticLibrary): return os.path.join(self.get_target_dir(target), target.get_filename()) + elif isinstance(target, build.CustomTarget): + if not target.is_linkable_target(): + raise MesonException('Tried to link against custom target "%s", which is not linkable.' % target.name) + return os.path.join(self.get_target_dir(target), target.get_filename()) elif isinstance(target, build.Executable): if target.import_filename: return os.path.join(self.get_target_dir(target), target.get_import_filename()) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 20f0cdb28..eb8e60c89 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -567,6 +567,8 @@ class BuildTarget(Target): if self.link_targets or self.link_whole_targets: extra = set() for t in itertools.chain(self.link_targets, self.link_whole_targets): + if isinstance(t, CustomTarget): + continue # We can't know anything about these. for name, compiler in t.compilers.items(): if name in clink_langs: extra.add((name, compiler)) @@ -1062,7 +1064,7 @@ You probably should put it in link_with instead.''') msg = "Can't link non-PIC static library {!r} into shared library {!r}. ".format(t.name, self.name) msg += "Use the 'pic' option to static_library to build with PIC." raise InvalidArguments(msg) - if self.is_cross != t.is_cross: + if not isinstance(t, CustomTarget) and self.is_cross != t.is_cross: raise InvalidArguments('Tried to mix cross built and native libraries in target {!r}'.format(self.name)) self.link_targets.append(t) @@ -1149,6 +1151,8 @@ You probably should put it in link_with instead.''') # Check if any of the internal libraries this target links to were # written in this language for link_target in itertools.chain(self.link_targets, self.link_whole_targets): + if isinstance(link_target, CustomTarget): + continue for language in link_target.compilers: if language not in langs: langs.append(language) @@ -2090,6 +2094,19 @@ class CustomTarget(Target): raise InvalidArguments('Substitution in depfile for custom_target that does not have an input file.') return self.depfile + def is_linkable_target(self): + if len(self.outputs) != 1: + return False + suf = os.path.splitext(self.outputs[0])[-1] + if suf == '.a' or suf == '.dll' or suf == '.lib' or suf == '.so': + return True + + def get_link_dep_subdirs(self): + return OrderedSet() + + def get_all_link_deps(self): + return [] + def type_suffix(self): return "@cus" diff --git a/test cases/common/216 link custom/meson.build b/test cases/common/216 link custom/meson.build index dc013541f..a1923b928 100644 --- a/test cases/common/216 link custom/meson.build +++ b/test cases/common/216 link custom/meson.build @@ -16,5 +16,10 @@ clib = custom_target('linkcustom', '-o', '@OUTPUT@', '--private-dir', '@PRIVATE_DIR@'] + cc.cmd_array()) -#exe = executable('prog', 'prog.c', link_with: clib) -#test('linkcustom', exe) +exe = executable('prog', 'prog.c', link_with: clib) +test('linkcustom', exe) + +d = declare_dependency(link_with: clib) + +exe2 = executable('prog2', 'prog.c', dependencies: d) +test('linkcustom2', exe2) diff --git a/test cases/common/216 link custom/prog.c b/test cases/common/216 link custom/prog.c new file mode 100644 index 000000000..eaede6d07 --- /dev/null +++ b/test cases/common/216 link custom/prog.c @@ -0,0 +1,6 @@ +void flob(); + +int main(int argc, char **argv) { + flob(); + return 0; +} From 95f5a72f625358544f7a37782e7c94266a2867d4 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sun, 17 Mar 2019 23:34:52 +0200 Subject: [PATCH 4/9] Delete failing test that checks for custom target linking. --- .../failing/89 link_with custom target/demo.c | 5 ---- .../failing/89 link_with custom target/foo.c | 3 --- .../lib_generator.py | 24 ------------------- .../89 link_with custom target/meson.build | 23 ------------------ 4 files changed, 55 deletions(-) delete mode 100644 test cases/failing/89 link_with custom target/demo.c delete mode 100644 test cases/failing/89 link_with custom target/foo.c delete mode 100755 test cases/failing/89 link_with custom target/lib_generator.py delete mode 100644 test cases/failing/89 link_with custom target/meson.build diff --git a/test cases/failing/89 link_with custom target/demo.c b/test cases/failing/89 link_with custom target/demo.c deleted file mode 100644 index b6feacaef..000000000 --- a/test cases/failing/89 link_with custom target/demo.c +++ /dev/null @@ -1,5 +0,0 @@ -int func_in_foo(); - -int main(int argc, char **argv) { - return func_in_foo(); -} diff --git a/test cases/failing/89 link_with custom target/foo.c b/test cases/failing/89 link_with custom target/foo.c deleted file mode 100644 index 2c714223d..000000000 --- a/test cases/failing/89 link_with custom target/foo.c +++ /dev/null @@ -1,3 +0,0 @@ -int func_in_foo() { - return 0; -} diff --git a/test cases/failing/89 link_with custom target/lib_generator.py b/test cases/failing/89 link_with custom target/lib_generator.py deleted file mode 100755 index 98ed5a820..000000000 --- a/test cases/failing/89 link_with custom target/lib_generator.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python3 - -# Mimic a binary that generates a static library - -import os -import subprocess -import sys - -if __name__ == '__main__': - if len(sys.argv) != 4: - print(sys.argv[0], 'compiler input_file output_file') - sys.exit(1) - compiler = sys.argv[1] - ifile = sys.argv[2] - ofile = sys.argv[3] - tmp = ifile + '.o' - if compiler.endswith('cl'): - subprocess.check_call([compiler, '/nologo', '/MDd', '/Fo' + tmp, '/c', ifile]) - subprocess.check_call(['lib', '/nologo', '/OUT:' + ofile, tmp]) - else: - subprocess.check_call([compiler, '-c', ifile, '-o', tmp]) - subprocess.check_call(['ar', 'csr', ofile, tmp]) - -os.unlink(tmp) diff --git a/test cases/failing/89 link_with custom target/meson.build b/test cases/failing/89 link_with custom target/meson.build deleted file mode 100644 index 6977ca1b7..000000000 --- a/test cases/failing/89 link_with custom target/meson.build +++ /dev/null @@ -1,23 +0,0 @@ -project('link_with custom target', ['c']) - -# -# libraries created by a custom_target currently can be used in sources: (see -# common/100 manygen/ for an example of that), but not in link_with: -# - -lib_generator = find_program('lib_generator.py') - -cc = meson.get_compiler('c').cmd_array().get(-1) - -libfoo_target = custom_target( - 'libfoo', - input: ['foo.c'], - output: ['libfoo.a'], - command: [lib_generator, cc, '@INPUT@', '@OUTPUT@'] -) - -libfoo = declare_dependency( - link_with: libfoo_target, -) - -executable('demo', ['demo.c'], dependencies: [libfoo]) From 19eb0e762a81fa4cd411d9bee1ed0809f52f4716 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Tue, 19 Mar 2019 00:26:43 +0200 Subject: [PATCH 5/9] Win fixes. --- mesonbuild/build.py | 3 +++ test cases/common/216 link custom/custom_stlib.py | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index eb8e60c89..4052beb4c 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -2101,6 +2101,9 @@ class CustomTarget(Target): if suf == '.a' or suf == '.dll' or suf == '.lib' or suf == '.so': return True + def get_link_deps_mapping(self, prefix, environment): + return {} + def get_link_dep_subdirs(self): return OrderedSet() diff --git a/test cases/common/216 link custom/custom_stlib.py b/test cases/common/216 link custom/custom_stlib.py index 925d997f4..37cf29812 100755 --- a/test cases/common/216 link custom/custom_stlib.py +++ b/test cases/common/216 link custom/custom_stlib.py @@ -18,12 +18,12 @@ void flob() { def generate_lib_gnulike(outfile, c_file, private_dir, compiler_array): static_linker = 'ar' o_file = c_file.with_suffix('.o') - compile_cmd = compiler_array + ['-c', '-g', '-O2', '-o', o_file, c_file] + compile_cmd = compiler_array + ['-c', '-g', '-O2', '-o', str(o_file), str(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] + link_cmd = [static_linker, 'csrD', outfile, str(o_file)] subprocess.check_call(link_cmd) return 0 From 6ee2796879c49a1a338e7dbf4ddab59c140ccf14 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Tue, 19 Mar 2019 20:51:06 +0200 Subject: [PATCH 6/9] THANK YOU STEVE JOBS FOR YOUR GREAT MODERN TOOLCHAIN! --- test cases/common/216 link custom/custom_stlib.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test cases/common/216 link custom/custom_stlib.py b/test cases/common/216 link custom/custom_stlib.py index 37cf29812..7311c4c62 100755 --- a/test cases/common/216 link custom/custom_stlib.py +++ b/test cases/common/216 link custom/custom_stlib.py @@ -23,7 +23,7 @@ def generate_lib_gnulike(outfile, c_file, private_dir, compiler_array): out_file = pathlib.Path(outfile) if out_file.exists(): out_file.unlink() - link_cmd = [static_linker, 'csrD', outfile, str(o_file)] + link_cmd = [static_linker, 'csr', outfile, str(o_file)] subprocess.check_call(link_cmd) return 0 From fd624a848e4f77b60c5859363e3c22052e779d3b Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Tue, 19 Mar 2019 21:04:56 +0200 Subject: [PATCH 7/9] Fix codegen with clang-cl. --- test cases/common/216 link custom/custom_stlib.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/test cases/common/216 link custom/custom_stlib.py b/test cases/common/216 link custom/custom_stlib.py index 7311c4c62..80334edc0 100755 --- a/test cases/common/216 link custom/custom_stlib.py +++ b/test cases/common/216 link custom/custom_stlib.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -import os, sys, subprocess, argparse, pathlib +import shutil, sys, subprocess, argparse, pathlib parser = argparse.ArgumentParser() @@ -16,7 +16,14 @@ void flob() { ''' def generate_lib_gnulike(outfile, c_file, private_dir, compiler_array): - static_linker = 'ar' + if shutil.which('ar'): + static_linker = 'ar' + elif shutil.which('llvm-ar'): + static_linker = 'llvm-ar' + elif shutil.which('gcc-ar'): + static_linker = 'gcc-ar' + else: + sys.exit('Could not detect a static linker.') o_file = c_file.with_suffix('.o') compile_cmd = compiler_array + ['-c', '-g', '-O2', '-o', str(o_file), str(c_file)] subprocess.check_call(compile_cmd) @@ -57,7 +64,7 @@ def generate_lib(outfile, private_dir, compiler_array): c_file = private_dir / 'flob.c' c_file.write_text(contents) for i in compiler_array: - if i.endswith('cl') or i.endswith('cl.exe'): + if (i.endswith('cl') or i.endswith('cl.exe')) and 'clang-cl' not in i: return generate_lib_msvc(outfile, c_file, private_dir, compiler_array) return generate_lib_gnulike(outfile, c_file, private_dir, compiler_array) From 3196e4e141029aae0b800e7c39f6b3ed31d1cc02 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Thu, 28 Mar 2019 22:56:37 +0200 Subject: [PATCH 8/9] Support link_whole with custom targets. --- mesonbuild/build.py | 9 +++++++-- test cases/common/216 link custom/meson.build | 10 ++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 4052beb4c..13a57e7e3 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1070,13 +1070,18 @@ You probably should put it in link_with instead.''') def link_whole(self, target): for t in listify(target, unholder=True): - if not isinstance(t, StaticLibrary): + if isinstance(t, CustomTarget): + if not t.is_linkable_target(): + raise InvalidArguments('Custom target {!r} is not linkable.'.format(t)) + if not t.get_filename().endswith('.a'): + raise InvalidArguments('Can only link_whole custom targets that are .a archives.') + elif not isinstance(t, StaticLibrary): raise InvalidArguments('{!r} is not a static library.'.format(t)) if isinstance(self, SharedLibrary) and not t.pic: msg = "Can't link non-PIC static library {!r} into shared library {!r}. ".format(t.name, self.name) msg += "Use the 'pic' option to static_library to build with PIC." raise InvalidArguments(msg) - if self.is_cross != t.is_cross: + if not isinstance(t, CustomTarget) and self.is_cross != t.is_cross: raise InvalidArguments('Tried to mix cross built and native libraries in target {!r}'.format(self.name)) self.link_whole_targets.append(t) diff --git a/test cases/common/216 link custom/meson.build b/test cases/common/216 link custom/meson.build index a1923b928..5af27cd39 100644 --- a/test cases/common/216 link custom/meson.build +++ b/test cases/common/216 link custom/meson.build @@ -23,3 +23,13 @@ d = declare_dependency(link_with: clib) exe2 = executable('prog2', 'prog.c', dependencies: d) test('linkcustom2', exe2) + +# Link whole tests + +exe3 = executable('prog3', 'prog.c', link_whole: clib) +test('linkwhole', exe) + +d2 = declare_dependency(link_whole: clib) + +exe4 = executable('prog4', 'prog.c', dependencies: d2) +test('linkwhole2', exe2) From 2259db2683d9e60c727ce847d1da7a759b190006 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Thu, 28 Mar 2019 23:11:30 +0200 Subject: [PATCH 9/9] Add documentation. --- docs/markdown/Reference-manual.md | 13 ++++++++++--- docs/markdown/snippets/linkcustom.md | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 docs/markdown/snippets/linkcustom.md diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md index 1c81a9dc4..a7f0506ae 100644 --- a/docs/markdown/Reference-manual.md +++ b/docs/markdown/Reference-manual.md @@ -519,11 +519,18 @@ be passed to [shared and static libraries](#library). when this file changes. - `link_whole` links all contents of the given static libraries whether they are used by not, equivalent to the - `-Wl,--whole-archive` argument flag of GCC, available since - 0.40.0. As of 0.41.0 if passed a list that list will be flattened. + `-Wl,--whole-archive` argument flag of GCC, available since 0.40.0. + As of 0.41.0 if passed a list that list will be flattened. Starting + from version 0.51.0 this argument also accepts outputs produced by + custom targets. The user must ensure that the output is a library in + the correct format. - `link_with`, one or more shared or static libraries (built by this project) that this target should be linked with, If passed a list - this list will be flattened as of 0.41.0. + this list will be flattened as of 0.41.0. Starting with version + 0.51.0, the arguments can also be custom targets. In this case Meson + will assume that merely adding the output file in the linker command + line is sufficient to make linking work. If this is not sufficient, + then the build system writer must write all other steps manually. - `export_dynamic` when set to true causes the target's symbols to be dynamically exported, allowing modules built using the [`shared_module`](#shared_module) function to refer to functions, diff --git a/docs/markdown/snippets/linkcustom.md b/docs/markdown/snippets/linkcustom.md new file mode 100644 index 000000000..d6ee8018a --- /dev/null +++ b/docs/markdown/snippets/linkcustom.md @@ -0,0 +1,16 @@ +## Can link against custom targets + +The output of `custom_target` can be used in `link_with` and +`link_whole` keyword arguments. This is useful for integrating custom +code generator steps, but note that there are many limitations: + + - Meson can not know about link dependencies of the custom target. If + the target requires further link libraries, you need to add them manually + + - The user is responsible for ensuring that the code produced by + different toolchains are compatible. + + - The custom target can only have one output file. + + - The output file must have the correct file name extension. +