Search code examples
xcodemacosopenglhomebrewfreetype

how to make Xcode project with homebrew libraries portable?


I have installed FreeType on my mac using Brew. The code on my mac works fine, but when I try to run the project on other mac I get the below mentioned linking error.

dyld: Library not loaded: /usr/local/opt/freetype/lib/libfreetype.6.dylib
Referenced from: /Users/ashutosh/Library/Developer/Xcode/DerivedData/InstrumentChamp- 
etytleaabhxmokadgrjzbgtmwxfl/Build/Products/Debug/instrumentchamp.app/Contents/MacOS/instrumentchamp
Reason: image not found (lldb) 

All the library directories and include directories of Freetype are included in project's '$SRCROOT/' directory when I try to run the code on other mac.

The path you see in the linking error for library is where brew had installed freetype in the mac where I created this project.

/usr/local/opt/freetype/lib/libfreetype.6.dylib

I have copied all the lib/ include/ directories that were needed to my project's home folder.
And I have set the library and include paths in Xcode.

What is it that I am missing here? What else do I have to do to make my code portable on any other Mac. I got the project to run on other mac by installing Brew, but I want to do it without the need to install brew.

PS: I had to install freetype using brew, as I couldn't compile the .dylib for freetype for 32bit processor, a 64bit copy of .dylib was giving me error such as 'wrong architecture!'


Solution

  • The basic idea I was getting at in my comments is that OS X is pretty stupid about where it searches for libraries, it will use the same absolute path used during compilation to resolve them at run-time.

    Usually when you want to deploy/distribute your application to a different machine from the one that built it, you will include your libraries with the install package/bundle. But you probably want them to use a path relative to your application at run-time, thus install_name_tool -change allows you to replace the nasty absolute path with something relative.

    Hope this makes sense, Apple makes it really easy to use system-wide frameworks on OS X, custom libraries not so much. If you compile using a system-wide framework, /System/Library/Frameworks/... is universally available on all OS X installs (given the same target release version).


    To solve your problem, I would do the following:

    install_name_tool -change /usr/local/opt/freetype/lib/libfreetype.6.dylib @executable_path/lib/libfreetype.6.dylib <executable_name_here>

    Then it will stop looking for libfreetype.6.dylib in the location it was when you compiled the software, and instead search for it relative to your executable's location at run-time (in this case, in the sub-directory lib/).