diff options
author | Aditya Kamath <118170220+KamathForAIX@users.noreply.github.com> | 2023-06-28 00:32:32 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-27 22:02:32 +0300 |
commit | 8946bc05f7f9cdd16dce3613c481a66f7835fc7f (patch) | |
tree | ca5b43bcab5a14d45f317cae2a15fd8426aec60f | |
parent | 78b8d447eea08445c9708bc0e3ba3c886717f6cd (diff) | |
download | meson-8946bc05f7f9cdd16dce3613c481a66f7835fc7f.zip meson-8946bc05f7f9cdd16dce3613c481a66f7835fc7f.tar.gz meson-8946bc05f7f9cdd16dce3613c481a66f7835fc7f.tar.bz2 |
Archive shared library in AIX (#11850)
* Archive shared library in AIX
This code change to ensure we archive shared libraries in AIX.
The things we do are:
Archive shared library
Install archived shared library
Build all must build the archived shared library
blibpath must have the archived shared library dependency.
* Archive shared library in AIX.
Made changes as per the review comments given in the first
PR request.
They are:-
Use self.environment.machines[t.for_machine].is_aix()
Remove trial spaces
Use of val instead of internal
Changed comments wherever requested
* Space after octothorpe
* Fixed failed test case causing build break during install section
* Moved AIX specific code to AIXDynamicLinker from backend
* Fix indentation, trailing spaces, add type annotations and Linux/macOS build break
* Remove some more trailing space issues
* Fixed the wrong return type in linkers
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 22 | ||||
-rw-r--r-- | mesonbuild/compilers/compilers.py | 6 | ||||
-rw-r--r-- | mesonbuild/envconfig.py | 6 | ||||
-rw-r--r-- | mesonbuild/linkers/linkers.py | 24 | ||||
-rw-r--r-- | mesonbuild/minstall.py | 9 |
5 files changed, 66 insertions, 1 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index b36e125..29cc8c6 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1034,6 +1034,11 @@ class NinjaBackend(backends.Backend): elem = self.generate_link(target, outname, final_obj_list, linker, pch_objects, stdlib_args=stdlib_args) self.generate_dependency_scan_target(target, compiled_sources, source2object, generated_source_files, fortran_order_deps) self.add_build(elem) + #In AIX, we archive shared libraries. If the instance is a shared library, we add a command to archive the shared library + #object and create the build element. + if isinstance(target, build.SharedLibrary) and self.environment.machines[target.for_machine].is_aix(): + elem = NinjaBuildElement(self.all_outputs, linker.get_archive_name(outname), 'AIX_LINKER', [outname]) + self.add_build(elem) def should_use_dyndeps_for_target(self, target: 'build.BuildTarget') -> bool: if mesonlib.version_compare(self.ninja_version, '<1.10.0'): @@ -2306,6 +2311,13 @@ class NinjaBackend(backends.Backend): options = self._rsp_options(compiler) self.add_rule(NinjaRule(rule, command, args, description, **options, extra=pool)) + if self.environment.machines[for_machine].is_aix(): + rule = 'AIX_LINKER{}'.format(self.get_rule_suffix(for_machine)) + description = 'Archiving AIX shared library' + cmdlist = compiler.get_command_to_archive_shlib() + args = [] + options = {} + self.add_rule(NinjaRule(rule, cmdlist, args, description, **options, extra=None)) args = self.environment.get_build_command() + \ ['--internal', @@ -3378,6 +3390,11 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) else: dependencies = target.get_dependencies() internal = self.build_target_link_arguments(linker, dependencies) + #In AIX since shared libraries are archived the dependencies must + #depend on .a file with the .so and not directly on the .so file. + if self.environment.machines[target.for_machine].is_aix(): + for i, val in enumerate(internal): + internal[i] = linker.get_archive_name(val) commands += internal # Only non-static built targets need link args and link dependencies if not isinstance(target, build.StaticLibrary): @@ -3581,6 +3598,11 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) for t in deps.values(): # Add the first output of each target to the 'all' target so that # they are all built + #Add archive file if shared library in AIX for build all. + if isinstance(t, build.SharedLibrary): + if self.environment.machines[t.for_machine].is_aix(): + linker, stdlib_args = self.determine_linker_and_stdlib_args(t) + t.get_outputs()[0] = linker.get_archive_name(t.get_outputs()[0]) targetlist.append(os.path.join(self.get_target_dir(t), t.get_outputs()[0])) elem = NinjaBuildElement(self.all_outputs, targ, 'phony', targetlist) diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 3fd5896..b8f5132 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -938,6 +938,12 @@ class Compiler(HoldableObject, metaclass=abc.ABCMeta): return self.linker.build_rpath_args( env, build_dir, from_dir, rpath_paths, build_rpath, install_rpath) + def get_archive_name(self, filename: str) -> str: + return self.linker.get_archive_name(filename) + + def get_command_to_archive_shlib(self) -> T.List[str]: + return self.linker.get_command_to_archive_shlib() + def thread_flags(self, env: 'Environment') -> T.List[str]: return [] diff --git a/mesonbuild/envconfig.py b/mesonbuild/envconfig.py index 1bf6ab9..24c1855 100644 --- a/mesonbuild/envconfig.py +++ b/mesonbuild/envconfig.py @@ -357,6 +357,12 @@ class MachineInfo(HoldableObject): """ return self.system == 'gnu' + def is_aix(self) -> bool: + """ + Machine is aix? + """ + return self.system == 'aix' + def is_irix(self) -> bool: """Machine is IRIX?""" return self.system.startswith('irix') diff --git a/mesonbuild/linkers/linkers.py b/mesonbuild/linkers/linkers.py index d7868f2..edd4085 100644 --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py @@ -16,6 +16,7 @@ from __future__ import annotations import abc import os import typing as T +import re from .base import ArLikeLinker, RSPFileSyntax from .. import mesonlib @@ -541,6 +542,14 @@ class DynamicLinker(metaclass=abc.ABCMeta): suffix: str, soversion: str, darwin_versions: T.Tuple[str, str]) -> T.List[str]: return [] + def get_archive_name(self, filename: str) -> str: + #Only used by AIX. + return str() + + def get_command_to_archive_shlib(self) -> T.List[str]: + #Only used by AIX. + return [] + class PosixDynamicLinkerMixin: @@ -1440,6 +1449,21 @@ class AIXDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker): def get_allow_undefined_args(self) -> T.List[str]: return self._apply_prefix(['-berok']) + def get_archive_name(self, filename: str) -> str: + # In AIX we allow the shared library name to have the lt_version and so_version. + # But the archive name must just be .a . + # For Example shared object can have the name libgio.so.0.7200.1 but the archive + # must have the name libgio.a having libgio.a (libgio.so.0.7200.1) in the + # archive. This regular expression is to do the same. + filename = re.sub('[.][a]([.]?([0-9]+))*([.]?([a-z]+))*', '.a', filename.replace('.so', '.a')) + return filename + + def get_command_to_archive_shlib(self) -> T.List[str]: + # Archive shared library object and remove the shared library object, + # since it already exists in the archive. + command = ['ar', '-q', '-v', '$out', '$in', '&&', 'rm', '-f', '$in'] + return command + def get_link_whole_for(self, args: T.List[str]) -> T.List[str]: # AIX's linker always links the whole archive: "The ld command # processes all input files in the same manner, whether they are diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py index ec01fe7..4900691 100644 --- a/mesonbuild/minstall.py +++ b/mesonbuild/minstall.py @@ -23,11 +23,12 @@ import shutil import subprocess import sys import typing as T +import re from . import build, coredata, environment from .backend.backends import InstallData from .mesonlib import (MesonException, Popen_safe, RealPathAction, is_windows, - setup_vsenv, pickle_load, is_osx, OptionKey) + is_aix, setup_vsenv, pickle_load, is_osx, OptionKey) from .scripts import depfixer, destdir_join from .scripts.meson_exe import run_exe try: @@ -709,6 +710,12 @@ class Installer: def install_targets(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix: str) -> None: for t in d.targets: + # In AIX, we archive our shared libraries. When we install any package in AIX we need to + # install the archive in which the shared library exists. The below code does the same. + # We change the .so files having lt_version or so_version to archive file install. + if is_aix(): + if '.so' in t.fname: + t.fname = re.sub('[.][a]([.]?([0-9]+))*([.]?([a-z]+))*', '.a', t.fname.replace('.so', '.a')) if not self.should_install(t): continue if not os.path.exists(t.fname): |