build: dependencies should come after link_with on link command

This fixes regression caused by
3162b901ca
that changes the order in which libraries are put on the link command.

In addition, that commit was wrong because libraries from dependencies
were processed before process_compiler() is called, which that commit
wanted to avoid.
pull/11960/head
Xavier Claessens 1 year ago committed by Jussi Pakkanen
parent cd63853ad2
commit 1fef03c0f0
  1. 19
      mesonbuild/build.py
  2. 11
      test cases/unit/113 complex link cases/meson.build
  3. 1
      unittests/linuxliketests.py

@ -755,8 +755,19 @@ class BuildTarget(Target):
self.process_objectlist(objects) self.process_objectlist(objects)
self.process_kwargs(kwargs) self.process_kwargs(kwargs)
self.missing_languages = self.process_compilers() self.missing_languages = self.process_compilers()
self.link(extract_as_list(kwargs, 'link_with'))
self.link_whole(extract_as_list(kwargs, 'link_whole')) # self.link_targets and self.link_whole_targets contains libraries from
# dependencies (see add_deps()). They have not been processed yet because
# we have to call process_compilers() first and we need to process libraries
# from link_with and link_whole first.
# See https://github.com/mesonbuild/meson/pull/11957#issuecomment-1629243208.
link_targets = extract_as_list(kwargs, 'link_with') + self.link_targets
link_whole_targets = extract_as_list(kwargs, 'link_whole') + self.link_whole_targets
self.link_targets.clear()
self.link_whole_targets.clear()
self.link(link_targets)
self.link_whole(link_whole_targets)
if not any([self.sources, self.generated, self.objects, self.link_whole_targets, self.structured_sources, if not any([self.sources, self.generated, self.objects, self.link_whole_targets, self.structured_sources,
kwargs.pop('_allow_no_sources', False)]): kwargs.pop('_allow_no_sources', False)]):
mlog.warning(f'Build target {name} has no sources. ' mlog.warning(f'Build target {name} has no sources. '
@ -1337,8 +1348,8 @@ class BuildTarget(Target):
self.extra_files.extend(f for f in dep.extra_files if f not in self.extra_files) self.extra_files.extend(f for f in dep.extra_files if f not in self.extra_files)
self.add_include_dirs(dep.include_directories, dep.get_include_type()) self.add_include_dirs(dep.include_directories, dep.get_include_type())
self.objects.extend(dep.objects) self.objects.extend(dep.objects)
self.link(dep.libraries) self.link_targets.extend(dep.libraries)
self.link_whole(dep.whole_libraries) self.link_whole_targets.extend(dep.whole_libraries)
if dep.get_compile_args() or dep.get_link_args(): if dep.get_compile_args() or dep.get_link_args():
# Those parts that are external. # Those parts that are external.
extpart = dependencies.InternalDependency('undefined', extpart = dependencies.InternalDependency('undefined',

@ -47,3 +47,14 @@ s1 = static_library('t7-s1', 's1.c')
s2 = static_library('t7-s2', 's2.c') s2 = static_library('t7-s2', 's2.c')
s3 = static_library('t7-s3', 's3.c', link_with: [s1, s2], install: true) s3 = static_library('t7-s3', 's3.c', link_with: [s1, s2], install: true)
e = executable('t7-e1', 'main.c', link_with: s3) e = executable('t7-e1', 'main.c', link_with: s3)
# Regression test: s3 should come last in the linker command. This seems to be
# required for at least backward compatibility reasons:
# https://github.com/mesonbuild/meson/pull/11957#issuecomment-1629243208
s1 = static_library('t8-s1', 's1.c')
s2 = static_library('t8-s2', 's2.c')
s3 = static_library('t8-s3', 's3.c')
e = executable('t8-e1', 'main.c',
link_with: [s1, s2],
dependencies: declare_dependency(link_with: s3),
)

@ -1846,3 +1846,4 @@ class LinuxlikeTests(BasePlatformTests):
self.assertIn('build t5-e1: c_LINKER t5-e1.p/main.c.o | libt5-s1.so.p/libt5-s1.so.symbols libt5-s3.a\n', content) self.assertIn('build t5-e1: c_LINKER t5-e1.p/main.c.o | libt5-s1.so.p/libt5-s1.so.symbols libt5-s3.a\n', content)
self.assertIn('build t6-e1: c_LINKER t6-e1.p/main.c.o | libt6-s2.a libt6-s3.a\n', content) self.assertIn('build t6-e1: c_LINKER t6-e1.p/main.c.o | libt6-s2.a libt6-s3.a\n', content)
self.assertIn('build t7-e1: c_LINKER t7-e1.p/main.c.o | libt7-s3.a\n', content) self.assertIn('build t7-e1: c_LINKER t7-e1.p/main.c.o | libt7-s3.a\n', content)
self.assertIn('build t8-e1: c_LINKER t8-e1.p/main.c.o | libt8-s1.a libt8-s2.a libt8-s3.a\n', content)

Loading…
Cancel
Save