AIX: Implement shared_target = "aix-solib" support
authorJohn Kohl <john.kohl@hcl.com>
Fri, 21 Jul 2023 14:31:34 +0000 (10:31 -0400)
committerTomas Mraz <tomas@openssl.org>
Mon, 5 Feb 2024 09:10:25 +0000 (10:10 +0100)
This builds shared libraries as libxxx.so, libxxx.so.ver and static
libraries as libxxx.a.  For shlib_variant builds, it builds libxxx.so,
libxxxvariant.so.ver, and libxxxx.a.  libxxx.so is a linker import
library that directs the linker to embed a run-time dependency
reference to libxxxvariant.so.ver.  Only libxxxvariant.so.ver is needed
at runtime.

Fixes #21518

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21540)

Configurations/10-main.conf
Configurations/platform/AIX.pm
Configurations/platform/Unix.pm
Configurations/unix-Makefile.tmpl
util/mkdef.pl

index 2a047caa7d4a46673f7cf5934e36c1af0ed79e33..c9db9aac28ebdaebeb8ad77768db1ac10a7245c6 100644 (file)
@@ -1407,6 +1407,19 @@ my %targets = (
         AR               => add("-X32"),
         RANLIB           => add("-X32"),
     },
+    # shared_target of "aix-solib" builds shared libraries packaged
+    # without archives.  This improves the behavior of inter-library
+    # references (libssl depending on libcrypto) when building with
+    # shlib_variant.
+    # You'll get:  libxxx.so (import library, used when linking applications)
+    #              libxxx.so.ver (shared object)
+    #              libxxx.a (static library archive)
+    # and for runtime, you only need libxxx.so.ver.  libxxx.so and libxxx.a
+    # can be installed along with include files to make an SDK
+    "aix-cc-solib" => {
+        inherit_from     => [ "aix-cc" ],
+        shared_target    => "aix-solib",
+    },
     "aix64-cc" => {
         inherit_from     => [ "aix-common" ],
         CC               => "cc",
@@ -1425,6 +1438,10 @@ my %targets = (
         AR               => add("-X64"),
         RANLIB           => add("-X64"),
     },
+    "aix64-cc-solib" => {
+        inherit_from     => [ "aix64-cc" ],
+        shared_target    => "aix-solib",
+    },
 
 # SIEMENS BS2000/OSD: an EBCDIC-based mainframe
     "BS2000-OSD" => {
index c6c1437f962a6459732d28125a0ffc0b32be33b6..709242712de0074f55d58e59db7b8514e885e447 100644 (file)
@@ -13,12 +13,16 @@ require platform::Unix;
 use configdata;
 
 sub dsoext              { '.so' }
-sub shlibextsimple      { '.a' }
+sub shlibextsimple      { return '.so' if $target{shared_target} eq "aix-solib";
+                         '.a'}
 
 # In shared mode, the default static library names clashes with the final
 # "simple" full shared library name, so we add '_a' to the basename of the
-# static libraries in that case.
+# static libraries in that case, unless in solib mode (using only .so
+# files for shared libraries, and not packaging them inside archives)
 sub staticname {
+    return platform::Unix->staticname($_[1]) if $target{shared_target} eq "aix-solib";
+
     # Non-installed libraries are *always* static, and their names remain
     # the same, except for the mandatory extension
     my $in_libname = platform::BASE->staticname($_[1]);
@@ -27,3 +31,17 @@ sub staticname {
 
     return platform::BASE->staticname($_[1]) . ($disabled{shared} ? '' : '_a');
 }
+
+# In solib mode, we do not install the simple symlink (we install the import
+# library).  In regular mode, we install the symlink.
+sub sharedlib_simple {
+    return undef if $target{shared_target} eq "aix-solib";
+    return platform::Unix->sharedlib_simple($_[1], $_[0]->shlibextsimple());
+}
+
+# In solib mode, we install the import library.  In regular mode, we have
+# no import library.
+sub sharedlib_import {
+    return platform::Unix->sharedlib_simple($_[1]) if $target{shared_target} eq "aix-solib";
+    return undef;
+}
index 8db0ed912e3a2f56443c4870d92ca2f03544a90f..6746af8c71ecb66522dde5c34e15bada17b0be92 100644 (file)
@@ -73,7 +73,9 @@ sub sharedlib_simple {
     my $name = $_[0]->sharedname($_[1]);
     my $simplename = $_[0]->sharedname_simple($_[1]);
     my $ext = $_[0]->shlibext();
-    my $simpleext = $_[0]->shlibextsimple();
+    # Allow override of the extension passed in as parameter
+    my $simpleext = $_[2];
+    $simpleext = $_[0]->shlibextsimple() unless defined $simpleext;
 
     return undef unless defined $simplename && defined $name;
     return undef if ($name eq $simplename && $ext eq $simpleext);
index f7e55b3abea4ad6818fc115d5713f52192ee4cef..25c713e952c48a0923710208ec3ab478e1ba5f9f 100644 (file)
      sub windowsdll { $config{target} =~ /^(?:Cygwin|mingw)/ }
 
      # Shared AIX support is special. We put libcrypto[64].so.ver into
-     # libcrypto.a and use libcrypto_a.a as static one.
-     sub sharedaix  { !$disabled{shared} && $config{target} =~ /^aix/ }
+     # libcrypto.a and use libcrypto_a.a as static one, unless using
+     # shared_target style aix-solib.  In that mode, create
+     # libcrypto.so as a link-import library that inserts runtime
+     # dependencies on libcrypto.so.ver, and the static library is
+     # named libcrypto.a.
+     sub sharedaix  { !$disabled{shared} && $target{shared_target} =~ /^aix(?!-solib$)/ }
+     sub sharedaix_solib  { !$disabled{shared} && $target{shared_target} =~ /^aix-solib$/ }
 
      our $sover_dirname = platform->shlib_version_as_filename();
 
@@ -760,12 +765,12 @@ install_dev: install_runtime_libs
                fn1=`basename "$$s1"`; \
                fn2=`basename "$$s2"`; \
                fn3=`basename "$$s3"`; \
-               : {- output_off(); output_on() unless windowsdll() or sharedaix(); "" -}; \
+               : {- output_off(); output_on() unless windowsdll() or sharedaix() or sharedaix_solib(); "" -}; \
                if [ "$$fn2" != "" ]; then \
                        $(ECHO) "link $(DESTDIR)$(libdir)/$$fn2 -> $(DESTDIR)$(libdir)/$$fn1"; \
                        ln -sf $$fn1 "$(DESTDIR)$(libdir)/$$fn2"; \
                fi; \
-               : {- output_off() unless windowsdll() or sharedaix(); output_on() if windowsdll(); "" -}; \
+               : {- output_off() unless windowsdll() or sharedaix() or sharedaix_solib(); output_on() if windowsdll() or sharedaix_solib(); "" -}; \
                if [ "$$fn3" != "" ]; then \
                        $(ECHO) "install $$s3 -> $(DESTDIR)$(libdir)/$$fn3"; \
                        cp $$s3 "$(DESTDIR)$(libdir)/$$fn3.new"; \
@@ -773,7 +778,7 @@ install_dev: install_runtime_libs
                        mv -f "$(DESTDIR)$(libdir)/$$fn3.new" \
                              "$(DESTDIR)$(libdir)/$$fn3"; \
                fi; \
-               : {- output_off() if windowsdll(); output_on() if sharedaix(); "" -}; \
+               : {- output_off() if windowsdll() or sharedaix_solib(); output_on() if sharedaix(); "" -}; \
                a="$(DESTDIR)$(libdir)/$$fn2"; \
                $(ECHO) "install $$s1 -> $$a"; \
                if [ -f $$a ]; then ( trap "rm -rf /tmp/ar.$$$$" INT 0; \
@@ -1790,6 +1795,8 @@ EOF
       # libraries for DLLs are a thing.  On platforms that have this mechanism,
       # $import has the name of this import library.  On platforms that don't
       # have this mechanism, $import will be |undef|.
+      # It's also used on AIX in solib mode, which creates import libraries
+      # for the shared libraries.
       my $import = platform->sharedlib_import($args{lib});
       # $simple is for platforms where full shared library names include the
       # shared library version, and there's a simpler name that doesn't include
@@ -1850,9 +1857,18 @@ EOF
           }
       }
       if (defined $import) {
+          if (sharedaix_solib()) {
+              $recipe .= <<"EOF";
+$import: $full $defs[0]
+       rm -f $import && \\
+       echo \\#!$full > $import && \\
+        cat $defs[0] >>$import
+EOF
+          } else {
       $recipe .= <<"EOF";
 $import: $full
 EOF
+          }
       }
       $recipe .= <<"EOF";
 $full: $fulldeps
index 88784504c09d36cf34b1a3a74989fee1a899d515..04b2545c59833399d53cdf5e6ac18ed1c787cc81 100755 (executable)
@@ -117,6 +117,7 @@ my %OS_data = (
     aix         => { writer     => \&writer_aix,
                      sort       => sorter_unix(),
                      platforms  => { UNIX                       => 1 } },
+    "aix-solib" => 'aix',       # alias
     VMS         => { writer     => \&writer_VMS,
                      sort       => OpenSSL::Ordinals::by_number(),
                      platforms  => { VMS                        => 1 } },