Skip to content

macOS: dylib compatibility/current version inconsistency between CMake and Autotools #55

@AmirIHz

Description

@AmirIHz

compatibility version and current version of the Mach-O shared library libexpat.dylib built using the Autoconf build system are different from compatibility version and current version of the dylib built using the CMake build system (on macOS).

configure + make link the dylib with -compatibility_version 8 -current_version 8.3 (see gist)
After make install:

$ otool -L /usr/local/lib/libexpat.dylib
/usr/local/lib/libexpat.dylib:
	/usr/local/lib/libexpat.1.dylib (compatibility version 8.0.0, current version 8.3.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.60.2)

CMake + make link the dylib with -compatibility_version 1.0.0 -current_version 1.6.3 (see gist)
After make install:

$ otool -L /usr/local/lib/libexpat.dylib
/usr/local/lib/libexpat.dylib:
	libexpat.1.dylib (compatibility version 1.0.0, current version 1.6.3)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.50.2)

Version number 1.6.3 is part of the dylib filename in either case: libexpat.1.6.3.dylib (both libexpat.dylib and libexpat.1.dylib are symbolic links pointing to libexpat.1.6.3.dylib)

Any binary that depends on the expat library will fail (crash) if they were linked against the dylib that was built using the "configure way", e.g. tar (bsdtar), which I compiled myself:

dyld: Library not loaded: /usr/local/lib/libexpat.1.dylib
  Referenced from: /usr/local/bin/tar
  Reason: Incompatible library version: tar requires version 8.0.0 or later, but libexpat.1.dylib provides version 1.0.0
[1]    45316 abort      tar --version

In CMakeLists.txt:

set(LIBCURRENT 7)   # sync
set(LIBREVISION 3)  # with
set(LIBAGE 6)       # configure.ac!
math(EXPR LIBCURRENT_MINUS_AGE "${LIBCURRENT} - ${LIBAGE}")

if(NOT WIN32)
    set_property(TARGET expat PROPERTY VERSION ${LIBCURRENT_MINUS_AGE}.${LIBAGE}.${LIBREVISION})
    set_property(TARGET expat PROPERTY SOVERSION ${LIBCURRENT_MINUS_AGE})
    set_property(TARGET expat PROPERTY NO_SONAME ${NO_SONAME})
endif(NOT WIN32)

So... ${LIBCURRENT_MINUS_AGE}.${LIBAGE}.${LIBREVISION})1.6.3

In configure.ac:

dnl
dnl Increment LIBREVISION if source code has changed at all
dnl
dnl If the API has changed, increment LIBCURRENT and set LIBREVISION to 0
dnl
dnl If the API changes compatibly (i.e. simply adding a new function
dnl without changing or removing earlier interfaces), then increment LIBAGE.
dnl 
dnl If the API changes incompatibly set LIBAGE back to 0
dnl

LIBCURRENT=7   # sync
LIBREVISION=3  # with
LIBAGE=6       # CMakeLists.txt!

Somewhere in the process this apparently ends up as 8.3.0?...

Incidentally, I used the tarball from downloads.sourceforge.net, so there was already a configure. Cloning this git repository and running buildconf.sh first didn't change anything to the end result.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions