Skip to content

Commit bc8a7e1

Browse files
KamathForAIXrgommers
authored andcommitted
Use target.aix_so_archive to decide to archive shared library in AIX
Previously, AIX support was updated to archive shared libraries per AIX platform conventions, which expect .a files that contain .so files. This is usually correct, but an edge case occurs for loadable plugins, e.g. what meson creates for `shared_module()`. A notable example is python extensions (SciPy, for example). These should *not* be archived, because the .so file itself needs to be loaded as a plugin. For example, SciPy fails to import in the python interpreter. Handle this by differentiating between plugins and regular libraries, and only archiving when safe to do so. Fixes mesonbuild#12219 (cherry picked from commit f4d19db)
1 parent ea58090 commit bc8a7e1

File tree

4 files changed

+15
-9
lines changed

4 files changed

+15
-9
lines changed

mesonbuild/backend/backends.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,9 @@ def get_target_filename_for_linking(self, target: T.Union[build.Target, build.Cu
339339
# On all other platforms, we link to the library directly.
340340
if isinstance(target, build.SharedLibrary):
341341
link_lib = target.get_import_filename() or target.get_filename()
342+
# In AIX, if we archive .so, the blibpath must link to archived shared library otherwise to the .so file.
343+
if mesonlib.is_aix() and target.aix_so_archive:
344+
link_lib = re.sub('[.][a]([.]?([0-9]+))*([.]?([a-z]+))*', '.a', link_lib.replace('.so', '.a'))
342345
return os.path.join(self.get_target_dir(target), link_lib)
343346
elif isinstance(target, build.StaticLibrary):
344347
return os.path.join(self.get_target_dir(target), target.get_filename())

mesonbuild/backend/ninjabackend.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,8 +1054,9 @@ def generate_target(self, target):
10541054
#In AIX, we archive shared libraries. If the instance is a shared library, we add a command to archive the shared library
10551055
#object and create the build element.
10561056
if isinstance(target, build.SharedLibrary) and self.environment.machines[target.for_machine].is_aix():
1057-
elem = NinjaBuildElement(self.all_outputs, linker.get_archive_name(outname), 'AIX_LINKER', [outname])
1058-
self.add_build(elem)
1057+
if target.aix_so_archive:
1058+
elem = NinjaBuildElement(self.all_outputs, linker.get_archive_name(outname), 'AIX_LINKER', [outname])
1059+
self.add_build(elem)
10591060

10601061
def should_use_dyndeps_for_target(self, target: 'build.BuildTarget') -> bool:
10611062
if mesonlib.version_compare(self.ninja_version, '<1.10.0'):
@@ -3505,11 +3506,6 @@ def generate_link(self, target: build.BuildTarget, outname, obj_list, linker: T.
35053506
else:
35063507
dependencies = target.get_dependencies()
35073508
internal = self.build_target_link_arguments(linker, dependencies)
3508-
#In AIX since shared libraries are archived the dependencies must
3509-
#depend on .a file with the .so and not directly on the .so file.
3510-
if self.environment.machines[target.for_machine].is_aix():
3511-
for i, val in enumerate(internal):
3512-
internal[i] = linker.get_archive_name(val)
35133509
commands += internal
35143510
# Only non-static built targets need link args and link dependencies
35153511
if not isinstance(target, build.StaticLibrary):
@@ -3714,7 +3710,7 @@ def generate_ending(self):
37143710
# Add the first output of each target to the 'all' target so that
37153711
# they are all built
37163712
#Add archive file if shared library in AIX for build all.
3717-
if isinstance(t, build.SharedLibrary):
3713+
if isinstance(t, build.SharedLibrary) and t.aix_so_archive:
37183714
if self.environment.machines[t.for_machine].is_aix():
37193715
linker, stdlib_args = self.determine_linker_and_stdlib_args(t)
37203716
t.get_outputs()[0] = linker.get_archive_name(t.get_outputs()[0])

mesonbuild/build.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2148,6 +2148,9 @@ class SharedLibrary(BuildTarget):
21482148

21492149
typename = 'shared library'
21502150

2151+
# Used by AIX to decide whether to archive shared library or not.
2152+
aix_so_archive = True
2153+
21512154
def __init__(
21522155
self,
21532156
name: str,
@@ -2495,6 +2498,9 @@ class SharedModule(SharedLibrary):
24952498

24962499
typename = 'shared module'
24972500

2501+
# Used by AIX to not archive shared library for dlopen mechanism
2502+
aix_so_archive = False
2503+
24982504
def __init__(
24992505
self,
25002506
name: str,

mesonbuild/minstall.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,8 +713,9 @@ def install_targets(self, d: InstallData, dm: DirMaker, destdir: str, fullprefix
713713
# In AIX, we archive our shared libraries. When we install any package in AIX we need to
714714
# install the archive in which the shared library exists. The below code does the same.
715715
# We change the .so files having lt_version or so_version to archive file install.
716+
# If .so does not exist then it means it is in the archive. Otherwise it is a .so that exists.
716717
if is_aix():
717-
if '.so' in t.fname:
718+
if not os.path.exists(t.fname) and '.so' in t.fname:
718719
t.fname = re.sub('[.][a]([.]?([0-9]+))*([.]?([a-z]+))*', '.a', t.fname.replace('.so', '.a'))
719720
if not self.should_install(t):
720721
continue

0 commit comments

Comments
 (0)