#59 Shared libraries created on Mac lack version info and have the wrong ID
Opened 9 months ago by RJVB. Modified 9 months ago

Shared libraries on Mac have 2 versions stored inside: a current version and a compatibility (aka ABI) version. This information is stored in dependents linked against those libraries, and the loader will refuse to load a dependent if a dependency is replaced with one having a lower compatibility version.
Also, each shared library has a so-called id, and under normal linking conditions this information is also stored in the dependents to allow to find/load the intended copy of the dependency.

From a fresh rlibtool-based build of pkgconf and comparing with the installed version:

> otool -L {pkgconf-mp9-work/destroot,}/opt/local/lib/libpkgconf.dylib
pkgconf-mp9-work/destroot/opt/local/lib/libpkgconf.dylib:
        .libs/libpkgconf.4.0.0.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
/opt/local/lib/libpkgconf.dylib:
        /opt/local/lib/libpkgconf.4.dylib (compatibility version 5.0.0, current version 5.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

You'll note that the freshly built library has 0.0.0 for both versions, which means any dependent that has been linked against the installed version will fail to load after installing that new version.

In addition, any dependent linked against the new version will expect libpkgconf.4.0.0.dylib in ./.libs, probably meaning a .libs subdirectory of the directory where the dependent lives. And it would fail to load after a pkgconf upgrade replaced libpkgconf.4.0.0.dylib with say libpkgconf.4.0.1.dylib.


My last 2 reported issues are real blockers, which is sad because it seemed like rlibtool became ready for prime time and it can really help speeding builds up on Mac.

That should still be the case if rlibtool could be configured to delegate static and shared library generation to the project's libtool script if it exists, as a more or less temporary workaround for projects that "don't build yet". Does that option already exist or how hard would it be to implement?

@midipix I believe Darwin requires -Wl,-install_name,libfoo.@MAJOR_VERSION@.dylib where MAJOR_VERSION is a number of course while linux uses -soname.

@midipix Just in you case you don't already know, on Darwin -no-undefined should set -Wl,-undefined,error.

Thanks @RJVB and @orbea! The above info surely will make fixing easy. To be continued ...

@midipix I believe Darwin requires -Wl,-install_name,libfoo.@MAJOR_VERSION@.dylib where MAJOR_VERSION is a number of course while linux uses -soname.

Yes. -install_name should take care of setting the proper ID in the library, but with libtool's approach it may be necessary to change this during the install phase when the dylibs are moved from their .lib directory to the ultimate install location. I admit I didn't look at the -install_name arguments emitted, just at the final results.
I wasn't aware there's an Apple version of --no-undefined (but I think it's the default behaviour).

@RJVB I am not sure if this helps, but a lot of these were tested for the GNU Makefile in this gambatte fork.

https://gitlab.com/jgemu/gambatte/-/blob/5fe2c023bde87706ffa5b6dcb1e5c3d981fef99f/mk/jg.mk#L32-60

Using the git version and building using make install-shared should install Darwin libraries with correct library name and version? This is what I am using for reference.

My last 2 reported issues are real blockers, which is sad because it seemed like rlibtool became ready for prime time and it can really help speeding builds up on Mac.

almost, almost there ...

From a fresh rlibtool-based build of pkgconf and comparing with the installed version:

Can you attach the full build report, starting with ./configure? That'll help speed things up:-)

Here's the libtool script too; it seems likely that it'll have the additional arguments to set the compatibility and current version values.

libtool

@midipix Just in you case you don't already know, on Darwin -no-undefined should set -Wl,-undefined,error.

Fixed in commit 816e280 :=)

@midipix I believe Darwin requires -Wl,-install_name,libfoo.@MAJOR_VERSION@.dylib where MAJOR_VERSION is a number of course while linux uses -soname.

I believe commit 5d0af4b covers everything in terms of -soname vs. -install_name, but perhaps more string transformations are needed.

I believe commit 5d0af4b covers everything in terms of -soname vs. -install_name, but perhaps more string transformations are needed.

I'll need to test on my Mac, but out of curiosity: why do you do the platform testing at runtime? I suppose in case of cross-compiling, but would that be done using tools from the host platform configure to generate Mach-O binaries but still requiring the native commandline options?

And I think #816e280 missed the -Wl,--no-undefined in src/logic/linkcmd/slbt_linkcmd_executable.c ;)

I believe commit 5d0af4b covers everything in terms of -soname vs. -install_name, but perhaps more string transformations are needed.

I'll need to test on my Mac, but out of curiosity: why do you do the platform testing at runtime? I suppose in case of cross-compiling, but would that be done using tools from the host platform configure to generate Mach-O binaries but still requiring the native commandline options?

Cross-compilation indeed :=)

And I think #816e280 missed the -Wl,--no-undefined in src/logic/linkcmd/slbt_linkcmd_executable.c ;)

Thanks for the catch! Now fixed in commit d2d5afe.

What I didn't catch is that host = "x86_64-apple-darwin13.4.0" and that you probably meant to check host.flavor ...

EDIT:
with that suggested change the build now completes, but sadly you didn't address the other, trickier problems covered by this ticket:

> otool -Lj
 {pkgconf-mp9-work/destroot,}/opt/local/lib/libpkgconf.dylib
pkgconf-mp9-work/destroot/opt/local/lib/libpkgconf.dylib:
        .libs/libpkgconf.4.0.0.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
/opt/local/lib/libpkgconf.dylib:
        /opt/local/lib/libpkgconf.4.dylib (compatibility version 5.0.0, current version 5.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

Looking at what I think is the libtool invocation to create libpkconf:

> (cd  pkgconf-mp9-work/pkgconf-pkgconf-1.9.0 ;  /opt/local/bin/rlibtool --tag=CC --mode=link ccache /opt/local/bin/clang-mp-9.0 -DPERSONALITY_PATH=\"/opt/local/share/pkgconfig/personality.d:/opt/local/etc/pkgconfig/personality.d\" -DPKG_DEFAULT_PATH=\"/opt/local/lib/pkgconfig:/opt/local/share/pkgconfig\" -DSYSTEM_INCLUDEDIR=\"/opt/local/include\" -DSYSTEM_LIBDIR=\"/opt/local/lib\" -Os -flto=thin -arch x86_64 -Wall -Wextra -Wformat=2 -std=gnu99 -no-undefined -version-info 4:0:0 -export-symbols-regex '^pkgconf_' -Wl,-headerpad_max_install_names -Os -flto=thin -arch x86_64 -o libpkgconf.la -rpath /opt/local/lib libpkgconf/audit.lo libpkgconf/cache.lo libpkgconf/client.lo libpkgconf/pkg.lo libpkgconf/bsdstubs.lo libpkgconf/fragment.lo libpkgconf/argvsplit.lo libpkgconf/fileio.lo libpkgconf/tuple.lo libpkgconf/dependency.lo libpkgconf/queue.lo libpkgconf/path.lo libpkgconf/personality.lo libpkgconf/parser.lo -v )
rlibtool: lconf: {.name="libtool"}.
rlibtool: fdcwd: {.fdcwd=AT_FDCWD, .realpath="/Volumes/VMs/MPbuild/_Volumes_Debian_MP9_site-ports_devel_pkgconf/pkgconf/work/pkgconf-pkgconf-1.9.0"}.
rlibtool: lconf: fstatat(AT_FDCWD,".",...) = 0 {.st_dev = 4311744520, .st_ino = 6313673}.
rlibtool: lconf: openat(AT_FDCWD,"libtool",O_RDONLY,0) = 3.
rlibtool: lconf: found "/Volumes/VMs/MPbuild/_Volumes_Debian_MP9_site-ports_devel_pkgconf/pkgconf/work/pkgconf-pkgconf-1.9.0/libtool".
rlibtool: link: ln -s libpkgconf.dylib.def .libs/libpkgconf.dylib.def.darwin
rlibtool: link: ln -s libpkgconf.dylib.def.darwin .libs/libpkgconf.dylib.def.host
rlibtool: link: /opt/local/bin/llvm-ar-mp-9.0 -crs .libs/libpkgconf.a libpkgconf/.libs/audit.o libpkgconf/.libs/cache.o libpkgconf/.libs/client.o libpkgconf/.libs/pkg.o libpkgconf/.libs/bsdstubs.o libpkgconf/.libs/fragment.o libpkgconf/.libs/argvsplit.o libpkgconf/.libs/fileio.o libpkgconf/.libs/tuple.o libpkgconf/.libs/dependency.o libpkgconf/.libs/queue.o libpkgconf/.libs/path.o libpkgconf/.libs/personality.o libpkgconf/.libs/parser.o
rlibtool: link: ln -s libpkgconf.la .libs/libpkgconf.la.shrext.dylib
rlibtool: link: ln -s libpkgconf.la.shrext.dylib .libs/libpkgconf.la.shrext
rlibtool: link: ccache /opt/local/bin/clang-mp-9.0 libpkgconf/.libs/audit.o libpkgconf/.libs/cache.o libpkgconf/.libs/client.o libpkgconf/.libs/pkg.o libpkgconf/.libs/bsdstubs.o libpkgconf/.libs/fragment.o libpkgconf/.libs/argvsplit.o libpkgconf/.libs/fileio.o libpkgconf/.libs/tuple.o libpkgconf/.libs/dependency.o libpkgconf/.libs/queue.o libpkgconf/.libs/path.o libpkgconf/.libs/personality.o libpkgconf/.libs/parser.o -DPERSONALITY_PATH="/opt/local/share/pkgconfig/personality.d:/opt/local/etc/pkgconfig/personality.d" -DPKG_DEFAULT_PATH="/opt/local/lib/pkgconfig:/opt/local/share/pkgconfig" -DSYSTEM_INCLUDEDIR="/opt/local/include" -DSYSTEM_LIBDIR="/opt/local/lib" -Os -flto=thin -arch x86_64 -Wall -Wextra -Wformat=2 -std=gnu99 -Wl,-headerpad_max_install_names -Os -flto=thin -arch x86_64 -v -shared -fPIC -Wl,-undefined,error -o .libs/libpkgconf.4.0.0.dylib
# Executing "/Users/bertin/script/ccache /opt/local/bin/clang-mp-9.0 libpkgconf/.libs/audit.o libpkgconf/.libs/cache.o libpkgconf/.libs/client.o libpkgconf/.libs/pkg.o libpkgconf/.libs/bsdstubs.o libpkgconf/.libs/fragment.o libpkgconf/.libs/argvsplit.o libpkgconf/.libs/fileio.o libpkgconf/.libs/tuple.o libpkgconf/.libs/dependency.o libpkgconf/.libs/queue.o libpkgconf/.libs/path.o libpkgconf/.libs/personality.o libpkgconf/.libs/parser.o -DPERSONALITY_PATH="/opt/local/share/pkgconfig/personality.d:/opt/local/etc/pkgconfig/personality.d" -DPKG_DEFAULT_PATH="/opt/local/lib/pkgconfig:/opt/local/share/pkgconfig" -DSYSTEM_INCLUDEDIR="/opt/local/include" -DSYSTEM_LIBDIR="/opt/local/lib" -Os -flto=thin -arch x86_64 -Wall -Wextra -Wformat=2 -std=gnu99 -Wl,-headerpad_max_install_names -Os -flto=thin -arch x86_64 -v -shared -fPIC -Wl,-undefined,error -o .libs/libpkgconf.4.0.0.dylib" in "/Volumes/VMs/MPbuild/_Volumes_Debian_MP9_site-ports_devel_pkgconf/pkgconf/work/pkgconf-pkgconf-1.9.0"
clang version 9.0.1 
Target: x86_64-apple-darwin13.4.0
Thread model: posix
InstalledDir: /opt/local/libexec/llvm-9.0/bin
 "/opt/local/libexec/llvm-9.0/bin/ld" -demangle -lto_library /Volumes/Debian/MP9/libexec/llvm-9.0/lib/libLTO.dylib -dynamic -dylib -arch x86_64 -macosx_version_min 10.9.0 -o .libs/libpkgconf.4.0.0.dylib libpkgconf/.libs/audit.o libpkgconf/.libs/cache.o libpkgconf/.libs/client.o libpkgconf/.libs/pkg.o libpkgconf/.libs/bsdstubs.o libpkgconf/.libs/fragment.o libpkgconf/.libs/argvsplit.o libpkgconf/.libs/fileio.o libpkgconf/.libs/tuple.o libpkgconf/.libs/dependency.o libpkgconf/.libs/queue.o libpkgconf/.libs/path.o libpkgconf/.libs/personality.o libpkgconf/.libs/parser.o -headerpad_max_install_names -undefined error -lSystem /Volumes/Debian/MP9/libexec/llvm-9.0/lib/clang/9.0.1/lib/darwin/libclang_rt.osx.a
rlibtool: link: ln -s libpkgconf.4.0.0.dylib .libs/libpkgconf.4.dylib
rlibtool: link: ln -s libpkgconf.4.0.0.dylib .libs/libpkgconf.dylib
rlibtool: link: ln -s /dev/null .libs/libpkgconf.dylib.def
rlibtool: link: ln -s ../libpkgconf.la .libs/libpkgconf.la
rlibtool: link: ln -s ../libpkgconf.la .libs/libpkgconf.lai

While after a build using the project's libtool script:

> ( cd pkgconf-mp9-work/pkgconf-pkgconf-1.9.0 ; ./libtool --tag=CC --mode=link ccache /opt/local/bin/clang-mp-9.0 -DPERSONALITY_PATH=\"/opt/local/share/pkgconfig/personality.d:/opt/local/etc/pkgconfig/personality.d\" -DPKG_DEFAULT_PATH=\"/opt/local/lib/pkgconfig:/opt/local/share/pkgconfig\" -DSYSTEM_INCLUDEDIR=\"/opt/local/include\" -DSYSTEM_LIBDIR=\"/opt/local/lib\" -Os -flto=thin -arch x86_64 -Wall -Wextra -Wformat=2 -std=gnu99 -no-undefined -version-info 4:0:0 -export-symbols-regex '^pkgconf_' -Wl,-headerpad_max_install_names -Os -flto=thin -arch x86_64 -o libpkgconf.la -rpath /opt/local/lib libpkgconf/audit.lo libpkgconf/cache.lo libpkgconf/client.lo libpkgconf/pkg.lo libpkgconf/bsdstubs.lo libpkgconf/fragment.lo libpkgconf/argvsplit.lo libpkgconf/fileio.lo libpkgconf/tuple.lo libpkgconf/dependency.lo libpkgconf/queue.lo libpkgconf/path.lo libpkgconf/personality.lo libpkgconf/parser.lo -v )
libtool: link: rm -fr  .libs/libpkgconf.4.dylib .libs/libpkgconf.4.dylib.dSYM .libs/libpkgconf.a .libs/libpkgconf.dylib .libs/libpkgconf.exp .libs/libpkgconf.la .libs/libpkgconf.lai
libtool: link: /opt/local/bin/llvm-nm-mp-9.0  libpkgconf/.libs/audit.o libpkgconf/.libs/cache.o libpkgconf/.libs/client.o libpkgconf/.libs/pkg.o libpkgconf/.libs/bsdstubs.o libpkgconf/.libs/fragment.o libpkgconf/.libs/argvsplit.o libpkgconf/.libs/fileio.o libpkgconf/.libs/tuple.o libpkgconf/.libs/dependency.o libpkgconf/.libs/queue.o libpkgconf/.libs/path.o libpkgconf/.libs/personality.o libpkgconf/.libs/parser.o   | sed -n -e 's/^.*[       ]\([BCDEGRST][BCDEGRST]*\)[     ][      ]*_\([_A-Za-z][_A-Za-z0-9]*\)$/\1 _\2 \2/p' | sed '/ __gnu_lto/d' | /opt/local/bin/gsed 's/.* //' | sort | uniq > .libs/libpkgconf.exp
libtool: link: /opt/local/bin/grep -E -e "^pkgconf_" ".libs/libpkgconf.exp" > ".libs/libpkgconf.expT"
libtool: link: mv -f ".libs/libpkgconf.expT" ".libs/libpkgconf.exp"
libtool: link: sed 's|^|_|' < .libs/libpkgconf.exp > .libs/libpkgconf-symbols.expsym
libtool: link: ccache /opt/local/bin/clang-mp-9.0 -dynamiclib  -o .libs/libpkgconf.4.dylib  libpkgconf/.libs/audit.o libpkgconf/.libs/cache.o libpkgconf/.libs/client.o libpkgconf/.libs/pkg.o libpkgconf/.libs/bsdstubs.o libpkgconf/.libs/fragment.o libpkgconf/.libs/argvsplit.o libpkgconf/.libs/fileio.o libpkgconf/.libs/tuple.o libpkgconf/.libs/dependency.o libpkgconf/.libs/queue.o libpkgconf/.libs/path.o libpkgconf/.libs/personality.o libpkgconf/.libs/parser.o    -Os -flto=thin -arch x86_64 -Wl,-headerpad_max_install_names -Os -flto=thin -arch x86_64   -install_name  /opt/local/lib/libpkgconf.4.dylib -compatibility_version 5 -current_version 5.0 -Wl,-single_module -Wl,-exported_symbols_list,.libs/libpkgconf-symbols.expsym
# Executing "/Users/bertin/script/ccache /opt/local/bin/clang-mp-9.0 -dynamiclib -o .libs/libpkgconf.4.dylib libpkgconf/.libs/audit.o libpkgconf/.libs/cache.o libpkgconf/.libs/client.o libpkgconf/.libs/pkg.o libpkgconf/.libs/bsdstubs.o libpkgconf/.libs/fragment.o libpkgconf/.libs/argvsplit.o libpkgconf/.libs/fileio.o libpkgconf/.libs/tuple.o libpkgconf/.libs/dependency.o libpkgconf/.libs/queue.o libpkgconf/.libs/path.o libpkgconf/.libs/personality.o libpkgconf/.libs/parser.o -Os -flto=thin -arch x86_64 -Wl,-headerpad_max_install_names -Os -flto=thin -arch x86_64 -install_name /opt/local/lib/libpkgconf.4.dylib -compatibility_version 5 -current_version 5.0 -Wl,-single_module -Wl,-exported_symbols_list,.libs/libpkgconf-symbols.expsym" in "/Volumes/VMs/MPbuild/_Volumes_Debian_MP9_site-ports_devel_pkgconf/pkgconf/work/pkgconf-pkgconf-1.9.0"
libtool: link: dsymutil .libs/libpkgconf.4.dylib || :
warning: no debug symbols in executable (-arch x86_64)
libtool: link: (cd ".libs" && rm -f "libpkgconf.dylib" && ln -s "libpkgconf.4.dylib" "libpkgconf.dylib")
libtool: link: /opt/local/bin/llvm-ar-mp-9.0 cru .libs/libpkgconf.a  libpkgconf/audit.o libpkgconf/cache.o libpkgconf/client.o libpkgconf/pkg.o libpkgconf/bsdstubs.o libpkgconf/fragment.o libpkgconf/argvsplit.o libpkgconf/fileio.o libpkgconf/tuple.o libpkgconf/dependency.o libpkgconf/queue.o libpkgconf/path.o libpkgconf/personality.o libpkgconf/parser.o
libtool: link: /bin/echo .libs/libpkgconf.a
.libs/libpkgconf.a
libtool: link: ( cd ".libs" && rm -f "libpkgconf.la" && ln -s "../libpkgconf.la" "libpkgconf.la" )

Note how the output file is .libs/libpkgconf.4.dylib, and the -install_name /opt/local/lib/libpkgconf.4.dylib -compatibility_version 5 -current_version 5.0 which take care of setting the ID and versions.

(There's also a -Wl,-single_module of which I'm not certain if it's required.)

What I didn't catch is that host = "x86_64-apple-darwin13.4.0" and that you probably meant to check host.flavor ...

Guilty as charged. Fixed in commit 36d22a5.

EDIT:
with that suggested change the build now completes, but sadly you didn't address the other, trickier problems covered by this ticket:

We aim for commits to be as limited in scope as possible ... and when a single issue entails multiple points then several commits are to be expected:-)

And here's the difference:

From rlibtool's to libtool's link command, if I read the diff correctly?

And here's the difference:

From rlibtool's to libtool's link command, if I read the diff correctly?

Yes; what I do not understand is why both -soname and -install_name are missing from the rlibtool command. Following commits 5d0af4b and 36d22a5, that seems odd.

Another oddity:

-version-info 4:0:0

Is all I can see in the [r]libtool invocation in terms of version information, yet libtool passes the following:

-compatibility_version 5 -current_version 5.0

Where is the '5' coming from? Can you see in gnu libtool where the math is taking place?

These are documented in the Darwin LD(1) man page.

     -compatibility_version number
         Specifies the compatibility version number of the library.  When a library is loaded by dyld, the compatibility version is
         checked and if the program's version is greater that the library's version, it is an error.  The format of number is X[.Y[.Z]]
         where X must be a positive non-zero number less than or equal to 65535, and .Y and .Z are optional and if present must be non-
         negative numbers less than or equal to 255.  If the compatibility version number is not specified, it has a value of 0 and no
         checking is done when the library is used.  This option is also called -dylib_compatibility_version for compatibility.

     -current_version number
         Specifies the current version number of the library. The current version of the library can be obtained programmatically by the
         user of the library so it can determine exactly which version of the library it is using.  The format of number is X[.Y[.Z]]
         where X must be a positive non-zero number less than or equal to 65535, and .Y and .Z are optional and if present must be non-
         negative numbers less than or equal to 255.  If the version number is not specified, it has a value of 0.  This option is also
         called -dylib_current_version for compatibility.

https://www.unix.com/man-page/osx/1/ld/

But I am not sure where the '5' is coming from either.

Another oddity:
Where is the '5' coming from? Can you see in gnu libtool where the math is taking place?

I've given up trying to figure out GNU/libtool's version logic a long time ago.
A long-standing problem (on Mac) with code that migrates from autoconf to, say, Meson is that all libraries get the embedded versioning that's equal to the one in the filename ... and that dependents all have to be rebuilt even if there's no ABI change at all. And whatever reason GNU had to "be smart" with the version numbers it wasn't so important that it was carried over to the Meson build system.

And whatever reason GNU had to "be smart" with the version numbers it wasn't so important that it was carried over to the Meson build system.

We should find out if GNU had good reasons or not, Meson also failed to carry over basic things like datarootdir...

According to this old comment libtool did n+1 so that is presumably where the '5' comes from.

https://github.com/mesonbuild/meson/issues/1451#issuecomment-284845913=

Which can be seen in /usr/bin/libtool:

        darwin)
          # Like Linux, but with the current version available in
          # verstring for coding it into the library header
          func_arith $current - $age
          major=.$func_arith_result
          versuffix=$major.$age.$revision
          # Darwin ld doesn't like 0 for these options...
          func_arith $current + 1
          minor_current=$func_arith_result
          xlcverstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
          verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
          # On Darwin other compilers
          case $CC in
              nagfor*)
                  verstring="$wl-compatibility_version $wl$minor_current $wl-current_version $wl$minor_current.$revision"
                  ;;
              *)
                  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
                  ;;
          esac
          ;;

And for -install_name /usr/bin/libtool shows:

                case $host in
                *-*-darwin*)
                  depdepl=
                  eval deplibrary_names=`$SED -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
                  if test -n "$deplibrary_names"; then
                    for tmp in $deplibrary_names; do
                      depdepl=$tmp
                    done
                    if test -f "$absdir/$objdir/$depdepl"; then
                      depdepl=$absdir/$objdir/$depdepl
                      darwin_install_name=`$OTOOL -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
                      if test -z "$darwin_install_name"; then
                          darwin_install_name=`$OTOOL64 -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
                      fi
                      func_append compiler_flags " $wl-dylib_file $wl$darwin_install_name:$depdepl"
                      func_append linker_flags " -dylib_file $darwin_install_name:$depdepl"
                      path=
                    fi
                  fi
                  ;;

I think the verdict is that GNU libtool does -compatibility_version $(($current + 1)) and -current_version $(($current + 1)).$revision.

While cmake gives them both $major.$minor.$patch as long as the value is at least 1.0.0.

Looking at the various .cmake files it seems some environment may require -Wl, while others do not. I am not sure if there are any that break if -Wl, is used?

I think the verdict is that GNU libtool does -compatibility_version $(($current + 1)) and -current_version $(($current + 1)).$revision.

While cmake gives them both $major.$minor.$patch as long as the value is at least 1.0.0.

I think it's obvious that rlibtool should do with libtool does, for the reasons explained above. I'm not really up to speed with the intentions for slibtool; it could be preferable to do what cmake (and meson) do, if slibtool is not supposed to give the same build results as libtool.

Looking at the various .cmake files it seems some environment may require -Wl, while others do not. I am not sure if there are any that break if -Wl, is used?

Are you certain that this doesn't depend on which driver is used, i.e. whether clang is being invoked, or ld directly? The latter surely wouldn't like seeing -Wl,.

I think it's obvious that rlibtool should do with libtool does

Agreed.

Are you certain that this doesn't depend on which driver is used, i.e. whether clang is being invoked, or ld directly? The latter surely wouldn't like seeing -Wl,.

Not sure:

$ grep -r -- -compatibility_version 
Modules/Platform/Apple-Absoft-Fortran.cmake:set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
Modules/Platform/Apple-GNU-Fortran.cmake:set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
Modules/Platform/Apple-Intel-Fortran.cmake:set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
Modules/Platform/Apple-IntelLLVM-Fortran.cmake:set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
Modules/Platform/Apple-NAG-Fortran.cmake:set(CMAKE_Fortran_OSX_COMPATIBILITY_VERSION_FLAG "-Wl,-compatibility_version -Wl,")
Modules/Platform/Apple-PGI.cmake:  set(CMAKE_${lang}_OSX_COMPATIBILITY_VERSION_FLAG "-Wl,-compatibility_version,")
Modules/Platform/Darwin.cmake:  set(CMAKE_${lang}_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ")
$ grep -r -- -current_version 
Modules/Platform/Apple-Absoft-Fortran.cmake:set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-current_version ")
Modules/Platform/Apple-GNU-Fortran.cmake:set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-current_version ")
Modules/Platform/Apple-Intel-Fortran.cmake:set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-current_version ")
Modules/Platform/Apple-IntelLLVM-Fortran.cmake:set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-current_version ")
Modules/Platform/Apple-NAG-Fortran.cmake:set(CMAKE_Fortran_OSX_CURRENT_VERSION_FLAG "-Wl,-current_version -Wl,")
Modules/Platform/Apple-PGI.cmake:  set(CMAKE_${lang}_OSX_CURRENT_VERSION_FLAG "-Wl,-current_version,")
Modules/Platform/Darwin.cmake:  set(CMAKE_${lang}_OSX_CURRENT_VERSION_FLAG "-current_version ")
$ grep -r -- -install_name 
Modules/CMakeSwiftInformation.cmake:  set(CMAKE_SHARED_LIBRARY_SONAME_Swift_FLAG "-Xlinker -install_name -Xlinker ")
Modules/Platform/Apple-NAG-Fortran.cmake:set(CMAKE_SHARED_LIBRARY_SONAME_Fortran_FLAG "-Wl,-install_name -Wl,")
Modules/Platform/Apple-PGI.cmake:  set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-install_name")
Modules/Platform/Apple-XL-C.cmake:set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-Wl,-install_name")
Modules/Platform/Apple-XL-CXX.cmake:set(CMAKE_SHARED_LIBRARY_SONAME_CXX_FLAG "-Wl,-install_name")
Modules/Platform/Darwin.cmake:set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name")
Source/cmGlobalXCodeGenerator.cxx:      extraLinkOptions += " -install_name ";

I think it's obvious that rlibtool should do with libtool does

Agreed.

Indeed:-)

Since there are only a few switches left and they're all related, for now I'd like to get darwin support completed via a single commit. I'll post a patch in the next couple of days for @RJVB to test ...

Login to comment on this ticket.

Metadata
Attachments 3
Attached 9 months ago View Comment
Attached 9 months ago View Comment
Attached 9 months ago View Comment