alexgolec
alexgolec

Reputation: 28262

Dynamic libraries passed to the linker as absolute paths being loaded by relative path?

I'm attempting to build and run a project I'm working on. I go ahead and build and everything's wonderful, no errors of any sort. Then when I try to run an executable, I get an error message that some of the dynamic library dependencies could not be found:

dyld: Library not loaded: libgpr.dylib
  Referenced from: ./test-exec
  Reason: image not found
Trace/BPT trap: 5

Interesting. What does otool -l report?

... snip ...
Load command 11
       cmd LC_MAIN
   cmdsize 24
  entryoff 1247184
 stacksize 0
Load command 12
          cmd LC_LOAD_DYLIB
      cmdsize 104
         name /abs/path/to/libprotobuf.10.dylib (offset 24) <--- The same path as passed to the linker
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 11.0.0
compatibility version 11.0.0
Load command 13
          cmd LC_LOAD_DYLIB
      cmdsize 40
         name libgpr.dylib (offset 24)     <--- Note the local path
   time stamp 2 Wed Dec 31 19:00:02 1969
      current version 0.0.0
compatibility version 0.0.0

What gives? My build invocation is (after some cleanup), as emitted by CMake:

Compile (newlines for readability)

cd /path/to/project && /path/to/c++ 
   -Wno-inconsistent-missing-override -g -fPIE 
-I/path/to/project -I/googletest/headers 
-I/googlemock/headers 
-I/path/to/project/usr/include 
-I/include 
-I/path/to/jni/Contents/Home/include
-I/path/to/jni/Home/include/darwin
-std=gnu++11 -o test-exec.o -c
/path/to/project/test-exec.cc

Link:

cd /path/to/project && /usr/local/Cellar/cmake/3.2.2/bin/cmake -E cmake_link_script CMakeFiles/test-exec.dir/link.txt --verbose=1
/path/to/c++   
-Wno-inconsistent-missing-override -g 
-Wl,-search_paths_first
-Wl,-headerpad_max_install_names  
test-exec.o  -o test-exec
/path/to/libprotobuf.dylib 
/path/to/libgpr.dylib
/path/to/libgrpc.dylib
/path/to/libgrpc++.dylib
../../dep1.a
../../dep2.a
/path/to/libgmock.a
/path/to/libgmock_main.a 
/path/to/libgtest_main.a

As far as I can tell, both libprotobuf.dylib and libgpr.dylib are being passed in as absolute paths during the link stage. How come libprotobuf.dylib gets loaded by absolute path and not libgpr.dylib?

For what it's worth, setting DYLD_LIBRARY_PATH makes it work, but I don't want to have to set it or export it. I've set up my repo to build all dependencies and place them into a specific directory, it should be just clone-and-build.

My compiler version is:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ --version
Apple LLVM version 7.0.0 (clang-700.0.72)
Target: x86_64-apple-darwin14.5.0
Thread model: posix

Upvotes: 4

Views: 1366

Answers (1)

z2oh
z2oh

Reputation: 93

I ran into this problem recently. Using install_name_tool after building the dylib fixed the problem; however, the version of clang I'm using accepts an -install_name parameter which lets me rename the dylib I'm building (I used -install_name @rpath/<name>.dylib). otool -D <name>.dylib confirmed the corrected name. Once the main program was linked against this newly built dylib, otool -l <exe> showed the correctly updated path (@rpath/<name>.dylib in my case), and the dylib was correctly found at runtime.

Upvotes: 1

Related Questions