Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OSX: changing path of .framework

Tags:

xcode

macos

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.

like image 975
psychotik Avatar asked Aug 20 '09 06:08

psychotik


People also ask

Where is PATH variable stored in Mac?

The default PATH and MANPATH values are in /etc/paths and /etc/manpaths . And also the path-helper reads files in the etc/paths.

What is Path Mac?

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.


1 Answers

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.

like image 61
wadesworld Avatar answered Oct 03 '22 15:10

wadesworld