Skip to content

macOS dylib minor version numbers differ between cmake and autotools builds #622

@ryandesign

Description

@ryandesign

When building hidapi 0.14.0 on macOS, the dynamic library's minor version information is different depending on whether cmake or autotools was used for the build.

With autotools:

% otool -L /opt/local/lib/libhidapi.dylib | head -n2
/opt/local/lib/libhidapi.dylib:
	/opt/local/lib/libhidapi.0.dylib (compatibility version 1.0.0, current version 1.0.0)

With cmake:

% otool -L /opt/local/lib/libhidapi.dylib | head -n2
/opt/local/lib/libhidapi.dylib:
	/opt/local/lib/libhidapi.0.dylib (compatibility version 0.0.0, current version 0.14.0)

With autotools the library's major version is 0 and its minor version is 1.0.0 (compatible back to minor version 1.0.0) whereas with cmake the library's major version is still 0 but its minor version has regressed to 0.14.0 (compatible back to minor version 0.0.0).

This is bad because the major and minor library version that was available at compile time is baked into each binary that uses the library. For example, here's a program that was built with hidapi-compiled-with-autotools:

% otool -L /opt/local/bin/mspdebug | head -n2
/opt/local/bin/mspdebug:
	/opt/local/lib/libhidapi.0.dylib (compatibility version 1.0.0, current version 1.0.0)

If I then replace libhidapi with one compiled with cmake, the program will not run*:

% mspdebug
dyld: Library not loaded: /opt/local/lib/libhidapi.0.dylib
  Referenced from: /opt/local/bin/mspdebug
  Reason: Incompatible library version: mspdebug requires version 1.0.0 or later, but libhidapi.0.dylib provides version 0.0.0
zsh: abort      mspdebug

This means that if a user wants to switch from hidapi compiled with autotools to hidapi compiled with cmake, they have to recompile all their software that links with libhidapi. This is a barrier to getting people to switch from autotools to cmake, as I believe you want us to do.

You have to be very careful to match your previous library version numbering scheme when switching to a different build system. libtool has a very special way of defining library versions that you have to follow. What's not explained there, because I guess they considered it an implementation detail that you didn't need to know about if you never stopped using libtool, is that library minor versions on macOS are 1.0.0 higher than on other operating systems because when Mac OS X was first introduced it could not handle library minor versions less than 1.0.0 but there was existing Unix software using libtool that specified library versions less than 1.0.0. macOS has been able to handle library minor versions less than 1.0.0 for a long time now but of course libtool can never remove that workaround or else projects' library minor versions would decrease when they updated libtool.

*What I did not realize until I researched it for this bug report is that Apple removed these library version checks completely in macOS 12, and in macOS 10.14(?) through macOS 11, it only runs the checks if the library was built for a macOS version earlier than 10.14. But since I'm sure you want your software to work on the widest range of systems possible, you should continue to follow the original spirit of the library minor version numbers by never letting them decrease (for any given major library version number; when the major library version number increases, of course the library minor version number can reset).

Metadata

Metadata

Assignees

No one assigned

    Labels

    build system/CIAnything related to building the project or running on CImacOSRelated to macOS backend

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions