I'm compiling my program using Bazel, and I have a dependency on Intel TBB. Intel TBB only provide dynamic libraries (no static) for good reasons (if you are curious: ctrl+f static here).
In my bazel WORKSPACE I defined that rule :
new_local_repository(
name = "inteltbb",
path = "./third_party/intel_tbb",
build_file = "./third_party/inteltbb.BUILD",
)
and in my "inteltbb.BUILD" I have:
cc_library(
name = "dynamic_lib",
srcs = ["build/macos_intel64_clang_cc8.1.0_os10.12.5_debug/libtbb_debug.dylib"],
hdrs = glob(["include/**/*.h"]),
visibility = ["//visibility:public"],
strip_include_prefix = "include/"
)
Then in my final program (under the cc_binary rule) I have:
deps = [
"@inteltbb//:dynamic_lib", [...]
It compile properly, find the headers successfully but at runtime it crashes saying:
____Running command line: bazel-bin/build-game
dyld: Library not loaded: @rpath/libtbb_debug.dylib
Referenced from: /private/var/tmp/_bazel_dmabin/526b91f44cfc47d856222c6b20765cc8/execroot/__main__/bazel-out/darwin_x86_64-fastbuild/bin/build-game
Reason: image not found
I check under the "bazel-bin" folder (where the executable is symlink for runtime execution: bazel-bin/build-game.runfiles/main/) and I do have:
- the symlink for the executable (build-game)
- a folder called (brace yourself):
_solib_darwin_x86_64/_U@inteltbb_S_S_Cdynamic_Ulib___Uexternal_Sinteltbb_Sbuild_Smacos_Uintel64_U clang_Ucc8.1.0_Uos10.12.5_Udebugthat contain mylibtbb_debug.dylibfor intel tbb.
Also when I run: otool -l build-game | grep LC_RPATH -A2 the result is:
cmd LC_RPATH
cmdsize 152
path $ORIGIN/_solib_darwin_x86_64/_U@inteltbb_S_S_Cdynamic_Ulib___Uexternal_Sinteltbb_Sbuild_Smacos_Uintel64_Uclang_Ucc8.1.0_Uos10.12.5_Udebug (offset 12)
I don't understand why my executable doesn't find my dylib. I can't find anything wrong about the otool output but I'm not a mac expert (at all). Any idea is welcome.
[edit] If I edit the executable using otool to replace the path to the dylib like that:
@executable_path/_solib_darwin_x86_64/_U@inteltbb_S_S_Cdynamic_Ulib___Uexternal_Sinteltbb_Slib/libtbb_debug.dylib
Then it works fine. I doesn't feel right that bazel force me to do that at every compilation :/
[edit 2] A few people asked me the line I used to modify the path of the lib in the executable. First run:
otool -L build-game
To spot the path of the lib you want to change. In my case it was: @rpath/libtbb_debug.dylib. After that run:
install_name_tool -change @rpath/libtbb_debug.dylib @executable_path/_solib_darwin_x86_64/_U@inteltbb_S_S_Cdynamic_Ulib___Uexternal_Sinteltbb_Slib/libtbb_debug.dylib build-game
to change the path. Note that you can use @executable_path to make it relative to the binary path or you can put an absolute path, up to you.