Merge pull request #6838 from dcbaker/link-language-in-libraries

Link language in libraries
pull/7074/head
Jussi Pakkanen 5 years ago committed by GitHub
commit f8a04f0f76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      docs/markdown/Reference-manual.md
  2. 8
      docs/markdown/snippets/link_language_all_targets.md
  3. 15
      mesonbuild/build.py
  4. 16
      run_unittests.py
  5. 5
      test cases/common/232 link language/c_linkage.cpp
  6. 10
      test cases/common/232 link language/c_linkage.h
  7. 5
      test cases/common/232 link language/lib.cpp
  8. 5
      test cases/common/232 link language/main.c
  9. 18
      test cases/common/232 link language/meson.build

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

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

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

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

@ -0,0 +1,5 @@
extern "C" {
int makeInt(void) {
return 0;
}
}

@ -0,0 +1,10 @@
#ifdef __cplusplus
extern "C" {
#endif
int makeInt(void);
#ifdef __cplusplus
}
#endif

@ -0,0 +1,5 @@
extern "C" {
int makeInt(void) {
return 1;
}
}

@ -0,0 +1,5 @@
#include "c_linkage.h"
int main(void) {
return makeInt();
}

@ -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)
Loading…
Cancel
Save