aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild
diff options
context:
space:
mode:
Diffstat (limited to 'mesonbuild')
-rw-r--r--mesonbuild/backend/ninjabackend.py21
-rw-r--r--mesonbuild/build.py22
-rw-r--r--mesonbuild/compilers/compilers.py2
-rw-r--r--mesonbuild/compilers/mixins/gnu.py3
4 files changed, 46 insertions, 2 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index c3c5705..f34849d 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -840,7 +840,11 @@ int dummy;
for src in self.generate_unity_files(target, unity_src):
obj_list.append(self.generate_single_compile(target, src, True, unity_deps + header_deps))
linker, stdlib_args = self.determine_linker_and_stdlib_args(target)
- elem = self.generate_link(target, outname, obj_list, linker, pch_objects, stdlib_args=stdlib_args)
+ if isinstance(target, build.StaticLibrary) and target.prelink:
+ final_obj_list = self.generate_prelink(target, obj_list)
+ else:
+ final_obj_list = obj_list
+ elem = self.generate_link(target, outname, final_obj_list, linker, pch_objects, stdlib_args=stdlib_args)
self.generate_shlib_aliases(target, self.get_target_dir(target))
self.add_build(elem)
@@ -2683,6 +2687,21 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
return guessed_dependencies + absolute_libs
+ def generate_prelink(self, target, obj_list):
+ assert(isinstance(target, build.StaticLibrary))
+ prelink_name = os.path.join(self.get_target_private_dir(target), target.name + '-prelink.o')
+ elem = NinjaBuildElement(self.all_outputs, [prelink_name], 'CUSTOM_COMMAND', obj_list)
+
+ prelinker = target.get_prelinker()
+ cmd = prelinker.exelist[:]
+ cmd += prelinker.get_prelink_args(prelink_name, obj_list)
+
+ cmd = self.replace_paths(target, cmd)
+ elem.add_item('COMMAND', cmd)
+ elem.add_item('description', 'Prelinking {}.'.format(prelink_name))
+ self.add_build(elem)
+ return [prelink_name]
+
def generate_link(self, target, outname, obj_list, linker, extra_args=None, stdlib_args=None):
extra_args = extra_args if extra_args is not None else []
stdlib_args = stdlib_args if stdlib_args is not None else []
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 36d4e19..5b7a679 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -102,7 +102,7 @@ known_build_target_kwargs = (
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'}
+known_stlib_kwargs = known_build_target_kwargs | {'pic', 'prelink'}
known_jar_kwargs = known_exe_kwargs | {'main_class'}
@lru_cache(maxsize=None)
@@ -1280,6 +1280,23 @@ You probably should put it in link_with instead.''')
return langs
+ def get_prelinker(self):
+ all_compilers = self.environment.coredata.compilers[self.for_machine]
+ if self.link_language:
+ comp = all_compilers[self.link_language]
+ return comp
+ for l in clink_langs:
+ if l in self.compilers:
+ try:
+ prelinker = all_compilers[l]
+ except KeyError:
+ raise MesonException(
+ 'Could not get a prelinker linker for build target {!r}. '
+ 'Requires a compiler for language "{}", but that is not '
+ 'a project language.'.format(self.name, l))
+ return prelinker
+ raise MesonException('Could not determine prelinker for {!r}.'.format(self.name))
+
def get_clink_dynamic_linker_and_stdlibs(self):
'''
We use the order of languages in `clink_langs` to determine which
@@ -1674,6 +1691,9 @@ class StaticLibrary(BuildTarget):
self.suffix = 'a'
self.filename = self.prefix + self.name + '.' + self.suffix
self.outputs = [self.filename]
+ self.prelink = kwargs.get('prelink', False)
+ if not isinstance(self.prelink, bool):
+ raise InvalidArguments('Prelink keyword argument must be a boolean.')
def get_link_deps_mapping(self, prefix, environment):
return {}
diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py
index 81d48d2..7d1d427 100644
--- a/mesonbuild/compilers/compilers.py
+++ b/mesonbuild/compilers/compilers.py
@@ -1205,6 +1205,8 @@ class Compiler(metaclass=abc.ABCMeta):
# TODO: using a TypeDict here would improve this
raise EnvironmentError('{} does not implement get_feature_args'.format(self.id))
+ def get_prelink_args(self, prelink_name, obj_list):
+ raise EnvironmentException('{} does not know how to do prelinking.'.format(self.id))
def get_args_from_envvars(lang: str,
for_machine: MachineChoice,
diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py
index 5771ad8..d3fa77d 100644
--- a/mesonbuild/compilers/mixins/gnu.py
+++ b/mesonbuild/compilers/mixins/gnu.py
@@ -396,3 +396,6 @@ class GnuCompiler(GnuLikeCompiler):
# GCC only warns about unknown or ignored attributes, so force an
# error.
return ['-Werror=attributes']
+
+ def get_prelink_args(self, prelink_name, obj_list):
+ return ['-r', '-o', prelink_name] + obj_list