aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2020-05-02 01:57:09 +0300
committerGitHub <noreply@github.com>2020-05-02 01:57:09 +0300
commitf8a04f0f76a09e875a2a2235facf9f58bb5031b5 (patch)
treec64779d76cba72fde7848616fd816a9998b90e31
parent30c4a7744f00c0393e4f261a6337d65b4c4d469d (diff)
parent1bfeaadd6d1dc87532a1c0ad4be615eb34044495 (diff)
downloadmeson-f8a04f0f76a09e875a2a2235facf9f58bb5031b5.zip
meson-f8a04f0f76a09e875a2a2235facf9f58bb5031b5.tar.gz
meson-f8a04f0f76a09e875a2a2235facf9f58bb5031b5.tar.bz2
Merge pull request #6838 from dcbaker/link-language-in-libraries
Link language in libraries
-rw-r--r--docs/markdown/Reference-manual.md8
-rw-r--r--docs/markdown/snippets/link_language_all_targets.md8
-rw-r--r--mesonbuild/build.py15
-rwxr-xr-xrun_unittests.py16
-rw-r--r--test cases/common/232 link language/c_linkage.cpp5
-rw-r--r--test cases/common/232 link language/c_linkage.h10
-rw-r--r--test cases/common/232 link language/lib.cpp5
-rw-r--r--test cases/common/232 link language/main.c5
-rw-r--r--test cases/common/232 link language/meson.build18
9 files changed, 82 insertions, 8 deletions
diff --git a/docs/markdown/Reference-manual.md b/docs/markdown/Reference-manual.md
index 963af9d..5c5f56a 100644
--- a/docs/markdown/Reference-manual.md
+++ b/docs/markdown/Reference-manual.md
@@ -600,8 +600,12 @@ be passed to [shared and static libraries](#library).
depends on such as a symbol visibility map. The purpose is to
automatically trigger a re-link (but not a re-compile) of the target
when this file changes.
-- `link_language` since 0.51.0 makes the linker for this target
- be for the specified language. This is helpful for multi-language targets.
+- `link_language` since 0.51.0 (broken until 0.55.0) makes the linker for this
+ target be for the specified language. It is generally unnecessary to set
+ this, as meson will detect the right linker to use in most cases. There are
+ only two cases where this is needed. One, your main function in an
+ executable is not in the language meson picked, or second you want to force
+ a library to use only one ABI.
- `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.
diff --git a/docs/markdown/snippets/link_language_all_targets.md b/docs/markdown/snippets/link_language_all_targets.md
new file mode 100644
index 0000000..9019d50
--- /dev/null
+++ b/docs/markdown/snippets/link_language_all_targets.md
@@ -0,0 +1,8 @@
+## link_language argument added to all targets
+
+Previously the `link_language` argument was only supposed to be allowed in
+executables, because the linker used needs to be the linker for the language
+that implements the main function. Unfortunately it didn't work in that case,
+and, even worse, if it had been implemented properly it would have worked for
+*all* targets. In 0.55.0 this restriction has been removed, and the bug fixed.
+It now is valid for `executable` and all derivative of `library`.
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index c200261..aff1d5f 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -82,6 +82,7 @@ buildtarget_kwargs = set([
'override_options',
'sources',
'gnu_symbol_visibility',
+ 'link_language',
])
known_build_target_kwargs = (
@@ -92,7 +93,7 @@ known_build_target_kwargs = (
rust_kwargs |
cs_kwargs)
-known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'link_language', 'pie'}
+known_exe_kwargs = known_build_target_kwargs | {'implib', 'export_dynamic', 'pie'}
known_shlib_kwargs = known_build_target_kwargs | {'version', 'soversion', 'vs_module_defs', 'darwin_versions'}
known_shmod_kwargs = known_build_target_kwargs | {'vs_module_defs'}
known_stlib_kwargs = known_build_target_kwargs | {'pic'}
@@ -1217,11 +1218,7 @@ You probably should put it in link_with instead.''')
See: https://github.com/mesonbuild/meson/issues/1653
'''
- langs = []
-
- # User specified link_language of target (for multi-language targets)
- if self.link_language:
- return [self.link_language]
+ langs = [] # type: T.List[str]
# Check if any of the external libraries were written in this language
for dep in self.external_deps:
@@ -1253,6 +1250,12 @@ You probably should put it in link_with instead.''')
# Populate list of all compilers, not just those being used to compile
# sources in this target
all_compilers = self.environment.coredata.compilers[self.for_machine]
+
+ # If the user set the link_language, just return that.
+ if self.link_language:
+ comp = all_compilers[self.link_language]
+ return comp, comp.language_stdlib_only_link_flags()
+
# Languages used by dependencies
dep_langs = self.get_langs_used_by_deps()
# Pick a compiler based on the language priority-order
diff --git a/run_unittests.py b/run_unittests.py
index da898a3..c77c9c0 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -4641,6 +4641,22 @@ recommended as it is not supported on some platforms''')
def test_junit_valid_exitcode(self):
self._test_junit('44 test args')
+ def test_link_language_linker(self):
+ # TODO: there should be some way to query how we're linking things
+ # without resorting to reading the ninja.build file
+ if self.backend is not Backend.ninja:
+ raise unittest.SkipTest('This test reads the ninja file')
+
+ testdir = os.path.join(self.common_test_dir, '232 link language')
+ self.init(testdir)
+
+ build_ninja = os.path.join(self.builddir, 'build.ninja')
+ with open(build_ninja, 'r', encoding='utf-8') as f:
+ contents = f.read()
+
+ self.assertRegex(contents, r'build main(\.exe)?.*: c_LINKER')
+ self.assertRegex(contents, r'build (lib|cyg)?mylib.*: c_LINKER')
+
class FailureTests(BasePlatformTests):
'''
diff --git a/test cases/common/232 link language/c_linkage.cpp b/test cases/common/232 link language/c_linkage.cpp
new file mode 100644
index 0000000..dc006b9
--- /dev/null
+++ b/test cases/common/232 link language/c_linkage.cpp
@@ -0,0 +1,5 @@
+extern "C" {
+ int makeInt(void) {
+ return 0;
+ }
+}
diff --git a/test cases/common/232 link language/c_linkage.h b/test cases/common/232 link language/c_linkage.h
new file mode 100644
index 0000000..1609f47
--- /dev/null
+++ b/test cases/common/232 link language/c_linkage.h
@@ -0,0 +1,10 @@
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int makeInt(void);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/test cases/common/232 link language/lib.cpp b/test cases/common/232 link language/lib.cpp
new file mode 100644
index 0000000..ab43828
--- /dev/null
+++ b/test cases/common/232 link language/lib.cpp
@@ -0,0 +1,5 @@
+extern "C" {
+ int makeInt(void) {
+ return 1;
+ }
+}
diff --git a/test cases/common/232 link language/main.c b/test cases/common/232 link language/main.c
new file mode 100644
index 0000000..5a167e7
--- /dev/null
+++ b/test cases/common/232 link language/main.c
@@ -0,0 +1,5 @@
+#include "c_linkage.h"
+
+int main(void) {
+ return makeInt();
+}
diff --git a/test cases/common/232 link language/meson.build b/test cases/common/232 link language/meson.build
new file mode 100644
index 0000000..f9af6cd
--- /dev/null
+++ b/test cases/common/232 link language/meson.build
@@ -0,0 +1,18 @@
+project(
+ 'link_language',
+ ['c', 'cpp'],
+)
+
+exe = executable(
+ 'main',
+ ['main.c', 'c_linkage.cpp'],
+ link_language : 'c',
+)
+
+lib = library(
+ 'mylib',
+ ['lib.cpp'],
+ link_language : 'c',
+)
+
+test('main', exe)