diff --git a/srcpkgs/meson/patches/fix-static-linking.patch b/srcpkgs/meson/patches/fix-static-linking.patch new file mode 100644 index 00000000000..faf6eb27328 --- /dev/null +++ b/srcpkgs/meson/patches/fix-static-linking.patch @@ -0,0 +1,142 @@ +From 2d370c24ec83de889c83511c4a32e52e75a38aca Mon Sep 17 00:00:00 2001 +From: Nirbheek Chauhan +Date: Wed, 25 Jul 2018 12:59:41 +0530 +Subject: [PATCH] Fix linking of shared/static libs with static libs + +This commit contains the following fixes: + +1. When a shared library A does `link_with:` to static library B, the + parts of B used by A will be added to A, and so we don't need to + return B in A.get_dependencies() for targets that link to A. This + already is the behaviour when a shared library A does `link_whole:` + on B. + +2. In situation (1), when generating a pkg-config file for A, we must + also not add B to Libs.private for A. This already is the behaviour + when a shared library A does `link_whole:` on B. + +3. When a static library A does `link_whole:` to static library B, we + must add the objects in B to A. + +4. When a static library A does `link_with:` to static library B, and + B is not installed (which makes it an internal static library), we + must add the objects in B to A, otherwise nothing can use A. + +5. In situation (4), when generating a pkg-config file for A, we must + also not add B to Libs.private for A. + +All these situations are tested by the unit test added in this commit. + +--- mesonbuild/backend/ninjabackend.py ++++ mesonbuild/backend/ninjabackend.py +@@ -2412,7 +2412,7 @@ def generate_link(self, target, outfile, outname, obj_list, linker, extra_args=[ + # line where the static library is used. + dependencies = [] + else: +- dependencies = target.get_dependencies() ++ dependencies = target.get_dependencies(link_whole=True) + internal = self.build_target_link_arguments(linker, dependencies) + commands += internal + # Only non-static built targets need link args and link dependencies +--- mesonbuild/backend/vs2010backend.py ++++ mesonbuild/backend/vs2010backend.py +@@ -1032,7 +1032,7 @@ def gen_vcxproj(self, target, ofname, guid): + (additional_libpaths, additional_links, extra_link_args) = self.split_link_args(extra_link_args.to_native()) + + # Add more libraries to be linked if needed +- for t in target.get_dependencies(): ++ for t in target.get_dependencies(link_whole=True): + lobj = self.build.targets[t.get_id()] + linkname = os.path.join(down, self.get_target_filename_for_linking(lobj)) + if t in target.link_whole_targets: +--- mesonbuild/build.py ++++ mesonbuild/build.py +@@ -856,22 +856,43 @@ def get_outputs(self): + def get_extra_args(self, language): + return self.extra_args.get(language, []) + +- def get_dependencies(self, exclude=None, internal=True): ++ def is_internal(self): ++ if isinstance(self, StaticLibrary) and not self.need_install: ++ return True ++ return False ++ ++ def get_dependencies(self, exclude=None, internal=True, link_whole=False): + transitive_deps = [] + if exclude is None: + exclude = [] +- if internal: +- link_targets = itertools.chain(self.link_targets, self.link_whole_targets) +- else: +- # We don't want the 'internal' libraries when generating the +- # `Libs:` and `Libs.private:` lists in pkg-config files. +- link_targets = self.link_targets +- for t in link_targets: ++ for t in self.link_targets: + if t in transitive_deps or t in exclude: + continue ++ # When we don't want internal libraries, f.ex. when we're ++ # generating the list of private installed libraries for use in ++ # a pkg-config file, don't include static libraries that aren't ++ # installed because those get directly included in the static ++ # or shared library already. See: self.link() ++ if not internal and t.is_internal(): ++ continue + transitive_deps.append(t) + if isinstance(t, StaticLibrary): +- transitive_deps += t.get_dependencies(transitive_deps + exclude, internal) ++ transitive_deps += t.get_dependencies(transitive_deps + exclude, ++ internal, link_whole) ++ for t in self.link_whole_targets: ++ if t in transitive_deps or t in exclude: ++ continue ++ if not internal and t.is_internal(): ++ continue ++ # self.link_whole_targets are not included by default here because ++ # the objects from those will already be in the library. They are ++ # only needed while generating backend (ninja) target dependencies. ++ if link_whole: ++ transitive_deps.append(t) ++ # However, the transitive dependencies are still needed ++ if isinstance(t, StaticLibrary): ++ transitive_deps += t.get_dependencies(transitive_deps + exclude, ++ internal, link_whole) + return transitive_deps + + def get_source_subdir(self): +@@ -958,7 +979,17 @@ def link(self, target): + raise InvalidArguments(msg) + if 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) ++ # When linking to a static library that's not installed, we ++ # transparently add that target's objects to ourselves. ++ # Static libraries that are installed will either be linked through ++ # self.link_targets or using the pkg-config file. ++ if isinstance(self, StaticLibrary) and isinstance(t, StaticLibrary) and not t.need_install: ++ self.objects.append(t.extract_all_objects()) ++ # Add internal and external deps ++ self.external_deps += t.external_deps ++ self.link_targets += t.link_targets ++ else: ++ self.link_targets.append(t) + + def link_whole(self, target): + for t in listify(target, unholder=True): +@@ -970,7 +1001,15 @@ def link_whole(self, target): + raise InvalidArguments(msg) + if 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) ++ # When we're a static library and we link_whole: to another static ++ # library, we need to add that target's objects to ourselves. ++ if isinstance(self, StaticLibrary): ++ self.objects.append(t.extract_all_objects()) ++ # Add internal and external deps ++ self.external_deps += t.external_deps ++ self.link_targets += t.link_targets ++ else: ++ self.link_whole_targets.append(t) + + def add_pch(self, language, pchlist): + if not pchlist: diff --git a/srcpkgs/meson/template b/srcpkgs/meson/template index 8b6b47d187d..ce401a40214 100644 --- a/srcpkgs/meson/template +++ b/srcpkgs/meson/template @@ -1,7 +1,7 @@ # Template file for 'meson' pkgname=meson version=0.47.2 -revision=2 +revision=3 noarch=yes build_style=python3-module pycompile_module="mesonbuild"