ar linker: generate thin archives for uninstalled static libraries

Since they will never be used outside of the build directory, they do
not need to literally contain the .o files, and references will be
sufficient.

This covers a major use of object libraries, which is that the static
library would potentially take up a lot of space by including another
copy of every .o file.

Fixes #9292
Fixes #8057
Fixes #2129
pull/9294/head
Eli Schwartz 3 years ago
parent 253ff71e6b
commit 0a3a9fa0c3
No known key found for this signature in database
GPG Key ID: CEB167EFB5722BD6
  1. 11
      docs/markdown/snippets/uninstalled_static_linker.md
  2. 2
      mesonbuild/backend/ninjabackend.py
  3. 27
      mesonbuild/linkers/linkers.py
  4. 2
      unittests/allplatformstests.py

@ -0,0 +1,11 @@
## More efficient static linking of uninstalled libraries
A somewhat common use case of [[static_library]] is to create uninstalled
internal convenience libraries which are solely meant to be linked to other
targets. Some build systems call these "object libraries". Meson's
implementation does always create a static archive.
This will now check to see if the static linker supports "thin archives"
(archives which do not contain the actual object code, only references to their
location on disk) and if so, use them to minimize space usage and speed up
linking.

@ -2790,7 +2790,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
if target.import_filename:
commands += linker.gen_import_library_args(self.get_import_filename(target))
elif isinstance(target, build.StaticLibrary):
commands += linker.get_std_link_args()
commands += linker.get_std_link_args(not target.should_install())
else:
raise RuntimeError('Unknown build target type.')
return commands

@ -59,7 +59,7 @@ class StaticLinker:
def get_exelist(self) -> T.List[str]:
return self.exelist.copy()
def get_std_link_args(self) -> T.List[str]:
def get_std_link_args(self, is_thin: bool) -> T.List[str]:
return []
def get_buildtype_linker_args(self, buildtype: str) -> T.List[str]:
@ -176,7 +176,7 @@ class ArLikeLinker(StaticLinker):
# in fact, only the 'ar' id can
return False
def get_std_link_args(self) -> T.List[str]:
def get_std_link_args(self, is_thin: bool) -> T.List[str]:
return self.std_args
def get_output_args(self, target: str) -> T.List[str]:
@ -193,17 +193,28 @@ class ArLinker(ArLikeLinker):
super().__init__(exelist)
stdo = mesonlib.Popen_safe(self.exelist + ['-h'])[1]
# Enable deterministic builds if they are available.
stdargs = 'csr'
thinargs = ''
if '[D]' in stdo:
self.std_args = ['csrD']
else:
self.std_args = ['csrD']
stdargs += 'D'
if '[T]' in stdo:
thinargs = 'T'
self.std_args = [stdargs]
self.std_thin_args = [stdargs + thinargs]
self.can_rsp = '@<' in stdo
def can_linker_accept_rsp(self) -> bool:
return self.can_rsp
def get_std_link_args(self, is_thin: bool) -> T.List[str]:
# FIXME: osx ld rejects this: "file built for unknown-unsupported file format"
if is_thin and not mesonlib.is_osx():
return self.std_thin_args
else:
return self.std_args
class ArmarLinker(ArLikeLinker): # lgtm [py/missing-call-to-init]
class ArmarLinker(ArLikeLinker):
id = 'armar'
@ -214,7 +225,7 @@ class DLinker(StaticLinker):
self.arch = arch
self.__rsp_syntax = rsp_syntax
def get_std_link_args(self) -> T.List[str]:
def get_std_link_args(self, is_thin: bool) -> T.List[str]:
return ['-lib']
def get_output_args(self, target: str) -> T.List[str]:
@ -1114,7 +1125,7 @@ class PGIStaticLinker(StaticLinker):
self.id = 'ar'
self.std_args = ['-r']
def get_std_link_args(self) -> T.List[str]:
def get_std_link_args(self, is_thin: bool) -> T.List[str]:
return self.std_args
def get_output_args(self, target: str) -> T.List[str]:

@ -1447,7 +1447,7 @@ class AllPlatformTests(BasePlatformTests):
link_cmd = ['ar', 'csr', outfile, objectfile]
link_cmd = linker.get_exelist()
link_cmd += linker.get_always_args()
link_cmd += linker.get_std_link_args()
link_cmd += linker.get_std_link_args(False)
link_cmd += linker.get_output_args(outfile)
link_cmd += [objectfile]
self.pbcompile(compiler, source, objectfile, extra_args=extra_args)

Loading…
Cancel
Save