diff options
| author | Aditya Vidyadhar Kamath <Aditya.Kamath1@ibm.com> | 2023-10-10 08:13:14 -0500 |
|---|---|---|
| committer | Eli Schwartz <eschwartz93@gmail.com> | 2023-10-31 19:18:17 -0400 |
| commit | f4d19db25e3183833a5e2d77ef5ab40b9b523144 (patch) | |
| tree | 0669d882c388e8a0a256402dc4b4519a37ec3a45 | |
| parent | ce691f8c98aeb72a246c4d6e9d60ed9ec88a6afd (diff) | |
| download | meson-f4d19db25e3183833a5e2d77ef5ab40b9b523144.tar.gz | |
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 #12219
| -rw-r--r-- | mesonbuild/backend/backends.py | 3 | ||||
| -rw-r--r-- | mesonbuild/backend/ninjabackend.py | 12 | ||||
| -rw-r--r-- | mesonbuild/build.py | 6 | ||||
| -rw-r--r-- | mesonbuild/minstall.py | 3 |
4 files changed, 15 insertions, 9 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index dd9e6ee6c..8cf738dbf 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -355,6 +355,9 @@ class Backend: # 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 0c984eadf..0c126006c 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1060,8 +1060,9 @@ class NinjaBackend(backends.Backend): #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'): @@ -3457,11 +3458,6 @@ 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): @@ -3667,7 +3663,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) # 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 isinstance(t, build.SharedLibrary) and t.aix_so_archive: 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]) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 4fc409a8d..8ae54754b 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -2171,6 +2171,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, @@ -2436,6 +2439,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 bf6f7a120..297afb4e2 100644 --- a/mesonbuild/minstall.py +++ b/mesonbuild/minstall.py @@ -722,8 +722,9 @@ class Installer: # 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 |
