macosgmpdylibrpath

Compiled libgmp has itself in its own prefix path as dependency


I have managed to compile a fat library of GMP for MacOS, arm64 and x86_64. However, if I get the output of "otool -L" right, then this library has its own installation path listed as its dependency (additional info: libgmp does not exist in /usr/local/lib/):

~/projectDir/justATest$ otool -L ../lib_mac/libgmp.10.dylib 
../lib_mac/libgmp.10.dylib:
    /usr/local/lib/libgmp.10.dylib (compatibility version 16.0.0, current version 16.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.100.5)

I can compile and link a minimal test application with this library, but when I start the application, the library is expected in /usr/local/lib:

~/projectDir/justATest/build$ ./example 
dyld: Library not loaded: /usr/local/lib/libgmp.10.dylib
  Referenced from: /Users/geom/projectDir/justATest/build/./example
  Reason: image not found
Abort trap: 6

~/projectDir/justATest/build$ otool -L example 
example:
    /usr/local/lib/libgmp.10.dylib (compatibility version 16.0.0, current version 16.0.0)
    /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 905.6.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.100.5)
geom@hexmac:~/projectDir/justATest/build$ 

This is unexpected because CMake has found my libgmp.10.dylib and used it for compilation. The used CMakeLists for this minimal example is

cmake_minimum_required(VERSION 3.5)
project(testing)
set(CMAKE_MACOSX_RPATH 1)

link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../lib_mac/)
add_executable(example main.cpp )

MESSAGE(${CMAKE_CURRENT_SOURCE_DIR}/../lib_mac/)
TARGET_LINK_LIBRARIES(example gmp.10 )

I'm not sure if the RPath-Setting above is correct, but with a classic Makefile and rpath I got the same behavior. Thus I believe that the reason is really this path in the libgmp.10.dylib that I have compiled. To test the libgmp compilation I have unpacked a fresh gmp-6.3.0 directory and used these lines for creating only an x86_64 binary:

export CFLAGS=" -O2 -fno-stack-check --target=x86_64-apple-darwin13.0.0"
./configure --enable-fat --build=x86_64-apple-darwin --host=x86_64-apple-darwin13.0.0
make -j 4

but with the same behavior.

geom@hexmac:~/gmpTest/gmp-6.3.0$ otool -L .libs/libgmp.10.dylib 
.libs/libgmp.10.dylib:
    /usr/local/lib/libgmp.10.dylib (compatibility version 16.0.0, current version 16.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.100.5)

I wonder if this path in the library is the problem or if my rpath usage is wrong? Any hints are appreciated.

EDIT: Thanks to the helpful answer from Siguza below, I was able to solve the problem. The solution was to specify the rpath tag during compilation of the gmp library. After he mentioned LC_ID_DYLIB I found also this article discussing the peculiarities of the MacOS linker:

https://forums.developer.apple.com/forums/thread/736719


Solution

  • What you're seeing in otool -L is almost certainly LC_ID_DYLIB, not LC_LOAD_DYLIB (check otool -l to confirm). So this is all fine.

    Instead, the issue you're seeing comes from the fact that your library has an install name at which it can't be found. If you want to use rpath, then the install name of the library needs to be something like @rpath/libgmp.10.dylib or @rpath/lib/libgmp.10.dylib, depending on your expected folder structure.

    So you can either have it build with the correct install name by passing the appropriate linker flags to configure:

    LDFLAGS='-Wl,-install_name,@rpath/libgmp.10.dylib' 
    

    or you can fix it up manually with

    install_name_tool -id @rpath/libgmp.10.dylib libgmp.10.dylib
    

    in which case you'll have to manually re-sign afterwards, and you'll probably have to extract and then bundle it up again with lipo.