diff options
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 21 | ||||
-rw-r--r-- | mesonbuild/build.py | 22 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 2 | ||||
-rw-r--r-- | mesonbuild/compilers/mixins/gnu.py | 3 |
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 |