My Mac OS application links with a non-system-provided framework Foo.framework. I added a reference to the framework in XCode and the app builds fine. I also have a rule which copies the framework into the output Frameworks folder (MyApp.app/Contents/Frameworks). However, at runtime the binary is looking for the framework in ~/Library/Frameworks and the app fails to load.
otool -l MyApp.app also tells me that it's looking for the framework in /Users//Library/Frameworks.
Can someone explain why this happens, and what the right way to make the app look in the application bundle's Frameworks folder is?
My hacky workaround is to include a custom script to change the path in the mach-o binary using install_name_tool, but I'm sure there is a clean way of doing this.
The default PATH and MANPATH values are in /etc/paths and /etc/manpaths . And also the path-helper reads files in the etc/paths.
PATH is a system-level variable that holds a list of directories. When you enter a command in the terminal, it's shorthand for a program with the same name. The system looks in each of the PATH directories for the program corresponding to the command. When it finds a matching program, it runs it.
You're on the right track.
It happens because on OS X an "install_name"
is recorded in the library when it's created. That install_name is then copied to any application which links with it.
The "best" way to solve the problem is to modify the source of the framework so that the -install_name
linkder flag is set when the framework is built.
However, that's often not possible, either because you don't have the source, or the framework has a huge mess of autoconf stuff that makes it near impossible. In that case, use install_name_tool with the -id flag to change the recorded install_name
in the library.
So, with all that said, what do you change it to?
@executable_path/../Frameworks/Foo.framework/Foo (or whatever the name is)
So, from the directory containing Foo.framework:
install_name_tool -id @executable_path/../Frameworks/Foo.framework/Foo Foo.framework/Foo
At runtime, the loader will resolve @executable_path to the path to the application's executable. Obviously you also need to setup a Copy Files build phase to copy the framework into the Framework folder of the application bundle.
You can also use install_name_tool
with the -change flag to change the install_name of a library after it's already been linked into the application, but that's obviously suboptimal. Fix it before linking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With