diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index dd9e6ee6cf28..8cf738dbf436 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -355,6 +355,9 @@ def get_target_filename_for_linking(self, target: T.Union[build.Target, build.Cu # On all other platforms, we link to the library directly. if isinstance(target, build.SharedLibrary): link_lib = target.get_import_filename() or target.get_filename() + # In AIX, if we archive .so, the blibpath must link to archived shared library otherwise to the .so file. + if mesonlib.is_aix() and target.aix_so_archive: + link_lib = re.sub('[.][a]([.]?([0-9]+))*([.]?([a-z]+))*', '.a', link_lib.replace('.so', '.a')) return os.path.join(self.get_target_dir(target), link_lib) elif isinstance(target, build.StaticLibrary): return os.path.join(self.get_target_dir(target), target.get_filename()) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 3375b699e97d..186809e87e74 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1058,8 +1058,9 @@ def generate_target(self, target): #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) + if target.aix_so_archive: + 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'): @@ -2381,13 +2382,13 @@ def generate_dynamic_link_rules(self): 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)) + 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', @@ -3489,11 +3490,6 @@ def generate_link(self, target: build.BuildTarget, outname, obj_list, linker: T. 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): @@ -3699,8 +3695,8 @@ def generate_ending(self) -> None: # 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(): + if self.environment.machines[t.for_machine].is_aix(): + if isinstance(t, build.SharedLibrary) and t.aix_so_archive: 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])) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index ac2993fec487..c40febcef50e 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -2176,6 +2176,9 @@ class SharedLibrary(BuildTarget): typename = 'shared library' + # Used by AIX to decide whether to archive shared library or not. + aix_so_archive = True + def __init__( self, name: str, @@ -2441,6 +2444,9 @@ class SharedModule(SharedLibrary): typename = 'shared module' + # Used by AIX to not archive shared library for dlopen mechanism + aix_so_archive = False + def __init__( self, name: str, diff --git a/mesonbuild/minstall.py b/mesonbuild/minstall.py index 5f8629b7fe47..e1ba6505fd50 100644 --- a/mesonbuild/minstall.py +++ b/mesonbuild/minstall.py @@ -720,8 +720,9 @@ def install_targets(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix # 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 .so does not exist then it means it is in the archive. Otherwise it is a .so that exists. if is_aix(): - if '.so' in t.fname: + if not os.path.exists(t.fname) and '.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