macOS: NAMELINK variants of shared library break Xcode import
CMake generates 3 output files for a shared library on macOS:
- The main library
library.MAJOR.MINOR.PATCH.dylib
- A major compatibility version symlink
library.MAJOR.dylib
- An unversioned symlink
library.dylib
Usually the variant with the entire semver in its filename is the "actual" file, whereas the other two variants are symlinks.
From my observation the canonical way to generate these is to have both symlinks point directly to the actual dynamic library:
9,0M Okt 15 21:29 libavcodec.59.37.100.dylib
26 Okt 15 21:29 libavcodec.59.dylib -> libavcodec.59.37.100.dylib
26 Okt 15 21:29 libavcodec.dylib -> libavcodec.59.37.100.dylib
CMake however generates a "chain" of symlinks:
90K Nov 17 21:44 libjansson.4.14.0.dylib
23 Nov 17 21:44 libjansson.4.dylib -> libjansson.4.14.0.dylib
18 Nov 17 21:44 libjansson.dylib -> libjansson.4.dylib
In my tests this trips up Xcode when specifying libraries to be copied into an app bundle's "Frameworks" directory (via the XCODE_EMBED_FRAMEWORKS
target property), which uses an internal copy tool to move the files into the bundle, but doesn't resolve entire symlink chains.
In the above example, the CMake finder looks for a library called "libjansson", finds the symlink and keeps that as the LIBRARY_LOCATION
target property. clang
's linker doesn't seem to have any issue resolving this chain, but when composing the app bundle, Xcode will fail when it tries to codesign copied frameworks/libraries as the first symlink level was resolved, but instead libjansson.4.dylib
was copied which is just a symlink.
From what I could tell, the correct way to generate these libraries is to have the compatibility versions link to the actual library file and not generate a symlink chain, which would also fix the issue with Xcode.