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.
libpkgconf.4.0.0.dylib
./.libs
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?
libtool
@midipix I believe Darwin requires -Wl,-install_name,libfoo.@MAJOR_VERSION@.dylib where MAJOR_VERSION is a number of course while linux uses -soname.
-Wl,-install_name,libfoo.@MAJOR_VERSION@.dylib
MAJOR_VERSION
-soname
@midipix Just in you case you don't already know, on Darwin -no-undefined should set -Wl,-undefined,error.
-no-undefined
-Wl,-undefined,error
Thanks @RJVB and @orbea! The above info surely will make fixing easy. To be continued ...
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).
-install_name
.lib
--no-undefined
@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.
make install-shared
almost, almost there ...
Can you attach the full build report, starting with ./configure? That'll help speed things up:-)
Here you go:
<img alt="pkgconf-build.txt" src="/cross/slibtool/issue/raw/files/2476e2c1b32d1c3de96d6262c5f08d7b5b64b615b636bbf1a3e3be25c84da48e-pkgconf-build.txt" />
Here's the libtool script too; it seems likely that it'll have the additional arguments to set the compatibility and current version values.
<img alt="libtool" src="/cross/slibtool/issue/raw/files/101260b3f72084b466d5ede915ed3f8cdd425017d0b0427bd35a719809d1aa04-libtool" />
Fixed in commit 816e280 :=)
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 ;)
-Wl,--no-undefined
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 :=)
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 ...
host = "x86_64-apple-darwin13.4.0"
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.
.libs/libpkgconf.4.dylib
-install_name /opt/local/lib/libpkgconf.4.dylib -compatibility_version 5 -current_version 5.0
(There's also a -Wl,-single_module of which I'm not certain if it's required.)
-Wl,-single_module
Guilty as charged. Fixed in commit 36d22a5.
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:
<img alt="darwin_dylib_linkcmd.diff" src="/cross/slibtool/issue/raw/files/3dfdb1195766421edb6ed373cd4f2ff4ee5fd4dc9215024773aceba079fc0803-darwin_dylib_linkcmd.diff" />
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...
datarootdir
According to this old comment libtool did n+1 so that is presumably where the '5' comes from.
n+1
https://github.com/mesonbuild/meson/issues/1451#issuecomment-284845913=
Which can be seen in /usr/bin/libtool:
/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 ;;
For reference this is what cmake seems to do:
https://github.com/Kitware/CMake/blob/cc58d743884066d477b3aafc6c4ccb6a6046bca0/Modules/Platform/Darwin.cmake#L54-L56
https://github.com/Kitware/CMake/blob/cc58d743884066d477b3aafc6c4ccb6a6046bca0/Modules/Platform/Darwin.cmake#L80-L81
https://github.com/Kitware/CMake/blob/cc58d743884066d477b3aafc6c4ccb6a6046bca0/Modules/Platform/Darwin.cmake#L97-L98
https://github.com/Kitware/CMake/blob/cc58d743884066d477b3aafc6c4ccb6a6046bca0/Source/cmGlobalXCodeGenerator.cxx#L3038-L3067
I think the verdict is that GNU libtool does -compatibility_version $(($current + 1)) and -current_version $(($current + 1)).$revision.
-compatibility_version $(($current + 1))
-current_version $(($current + 1)).$revision
While cmake gives them both $major.$minor.$patch as long as the value is at least 1.0.0.
$major.$minor.$patch
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?
.cmake
-Wl,
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.
rlibtool
slibtool
cmake
meson
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.
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 ...
Log in to comment on this ticket.