I am debugging a problem where I am trying to link against a dylib
, and set the program's rpath to a directory containing the library.
I have narrowed this to the following MWE:
> ls deps/include/spinnaker/
AVIRecorder.h Camera.h CameraPtr.h Exception.h …bunch of headers
> ls deps/lib/libSpinnaker.dylib*
deps/lib/libSpinnaker.dylib deps/lib/libSpinnaker.dylib.1.24.0.60
> cat test.cpp
#include <cstddef>
#include <Event.h> // for CameraList
#include <CameraList.h> // for CameraList
#include <CameraPtr.h> // for CameraPtr
#include <ImagePtr.h> // for ImagePtr
#include <SystemPtr.h> // for SystemPtr
int main()
{
const auto system_ptr = Spinnaker::System::GetInstance();
}
I compile this with
clang++ -std=c++14 -o wat -I deps/include/spinnaker/ -L deps/lib/ -lSpinnaker -Wl,-rpath,./deps/lib test.cpp
And thus libSpinnaker
gets referenced as shown by
[…]
Load command 9
cmd LC_UUID
cmdsize 24
uuid B4498482-D872-3270-AC47-102914DDBCBE
Load command 10
cmd LC_BUILD_VERSION
cmdsize 32
platform 1
minos 10.15
sdk 10.15.6
ntools 1
tool 3
version 609.8
Load command 11
cmd LC_SOURCE_VERSION
cmdsize 16
version 0.0
Load command 12
cmd LC_MAIN
cmdsize 24
entryoff 16224
stacksize 0
Load command 13
cmd LC_LOAD_DYLIB
cmdsize 56
name libSpinnaker.dylib.1.24.0.60 (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 0.0.0
compatibility version 0.0.0
Load command 14
cmd LC_LOAD_DYLIB
cmdsize 48
name /usr/lib/libc++.1.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 902.1.0
compatibility version 1.0.0
Load command 15
cmd LC_LOAD_DYLIB
cmdsize 56
name /usr/lib/libSystem.B.dylib (offset 24)
time stamp 2 Thu Jan 1 01:00:02 1970
current version 1281.100.1
compatibility version 1.0.0
Load command 16
cmd LC_RPATH
cmdsize 24
path ./deps/lib (offset 12)
Load command 17
cmd LC_FUNCTION_STARTS
cmdsize 16
dataoff 49312
datasize 8
Load command 18
cmd LC_DATA_IN_CODE
cmdsize 16
dataoff 49320
datasize 0
So the LC_RPATH
is included, the library is present at the specified path, but still I get
dyld: Library not loaded: libSpinnaker.dylib.1.24.0.60
Referenced from: <binary-path>
Reason: image not found
Abort trap: 6
when running it.
Now my observation is that @rpath
is missing before the reference to libSpinnaker
in the otool
output – for other libraries its always there when I look at my larger cmake-based project. I would expect the line
name @rpath/libSpinnaker.dylib.1.24.0.60 (offset 24)
instead of what i am seeing.
I can set DYLD_LIBRARY_PATH
and that'll work, but I want to bake this into the binary with the rpath mechanism.
Question: Is the fact that @rpath
is missing here indicative of a problem? And if so, how can I get it added with the compiler or CMake? If this is not the problem, what is it?
install_name_tool -id @rpath/libSpinnaker.dylib.1.24.0.60 deps/lib/libSpinnaker.dylib.1.24.0.60
install_name_tool -change libSpinnaker.dylib.1.24.0.60 @rpath/libSpinnaker.dylib.1.24.0.60 wat
You noticed that the @rpath
was missing from the installed name of the library. install_name_tool
is the command which allows you to change the installed pathnames, add or remove @rpaths, etc. Because of the modifications, install_name_tool
should be used before codesign
. Apple documentation has an example of how to setup this type of relative structure.