PDA

View Full Version : Statically linking with a UNIX lib (FreeType)




Thomas Harte
Mar 10, 2008, 02:20 PM
Hi,

I'm quite an idiot when it comes to anything involving UNIX or the commandline, and I'm having a problem I can't seem to get past.

I'm using FreeType in a project of mine. I'd like to build my project and distribute it to other people.

I downloaded and built FreeType using this:

./configure CFLAGS="-arch i386 -arch ppc -mmacosx-version-min=10.4" --enable-shared=no --enable-static=yes
make
sudo make install

I then added libfreetype.a to the "Linked Frameworks" section of my Xcode project.

My project builds and runs perfectly on my machine. But when I try to run it on another machine that has not had FreeType downloaded and installed, I get the error (on the console):

Dyld Error Message:
Library not loaded: /usr/local/lib/libfreetype.6.dylib
Referenced from: /Users/nialgiacomelli/Downloads/FreescapeGL.app/Contents/MacOS/FreescapeGL
Reason: image not found

Which, apart from anything else apparently means that "--enable-shared=no --enable-static=yes" does not, as I would expect, build only a static linking version of FreeType, and/or adding libfreetype.a to Xcode causes it to also find and link with libfreetype.6.dylib.

I also have a Framework of FreeType that I obtained from the internet. It seems not to be embeddable, i.e. if I link against it and then even if I embed it into my application, then my application does not run on another Mac that does not have FreeType.framework in ~/Library/Frameworks or /Library/Frameworks.

I figure this is probably a point of general application, so: what are the general case instructions for building and installing a UNIX-style library, so that I can statically link it into my projects and then distribute them to end-users such that they are able to use them without downloading and installing the support libraries for themselves?



yeroen
Mar 10, 2008, 02:43 PM
Where was libfreetype.a installed on your system? Was it also installed in /usr/local/lib?

This Technical Q&A note from Apple provides a discussion on static linking:

http://developer.apple.com/qa/qa2006/qa1393.html

Hope that helps.

Thomas Harte
Mar 10, 2008, 03:23 PM
Hmmm, having tried that, FreeType seems to be simply refusing not to build at least something into a dynamic library. Making sure that the compiler can find the .a but can't find the .dylib generates:

"_FT_New_Face", referenced from:
CFont::Open(char const*)in EBGFFont.o
"_FT_Init_FreeType", referenced from:
__EBGF_SetupFontLibrary() in EBGFFont.o
"_FT_Get_Char_Index", referenced from:
CFont::GetWidth(char const*, ...)in EBGFFont.o
CFont::GetWidth(char const*, ...)in EBGFFont.o
CFont::Print(char const*, ...)in EBGFFont.o
CFont::Print(char const*, ...)in EBGFFont.o
"_FT_Set_Char_Size", referenced from:
CFont::Open(char const*)in EBGFFont.o
"_FT_Outline_Decompose", referenced from:
CFont::GetChar(int) in EBGFFont.o
"_FT_Load_Char", referenced from:
CFont::GetChar(int) in EBGFFont.o
"_FT_Get_Kerning", referenced from:
CFont::GetWidth(char const*, ...)in EBGFFont.o
CFont::Print(char const*, ...)in EBGFFont.o
"_FT_Done_FreeType", referenced from:
__EBGF_FreeFontLibrary() in EBGFFont.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

Anyone have any comment on that? And a question related to another possible solution to my problems: is there any way to take a framework that is not embeddable and make it embeddable without rebuilding from source?

yeroen
Mar 10, 2008, 04:06 PM
To answer your question, you can't force it by attempting to statically link a dynamic library. They're different formats.

Can you post your build settings?

On the command line, you'd simply pass libfreetype.a to gcc as follows:

gcc MyProgram MyProgram.o libfreetype.a

So wherever you list your object files in Xcode is where you need to put the path to libfreetype.a.

Thomas Harte
Mar 11, 2008, 05:01 AM
To answer your question, you can't force it by attempting to statically link a dynamic library. They're different formats.
Right, but as I understand it, Frameworks are dynamic libraries that you have Xcode copy into your application bundle they're in no way statically linked. The only difference between embeddable Frameworks and non-embeddable ones is that they're linked such that the application looks in its own Frameworks folder before looking in /Library/Frameworks and ~/Library/Frameworks.

To be honest, I have no idea why non-embeddable frameworks even exist.
Can you post your build settings?
My build settings for FreeType are as listed above. I'm using Xcode for my own project. As I said, I built a version of FreeType with static linking enabled and shared linking disabled, and added the .a to the "linked frameworks" of my project. Nevertheless, FreeType produces a .a and a .dylib, and Xcode links such that it needs to be able to find the .dylib, even with the settings from the Apple article linked above applied.

Deleting the .dylib even implies that the .a doesn't contain enough information to link with on its own.

I also have a separate Framework of FreeType, downloaded prebuilt from the internet. Putting that in /Library/Frameworks and adding it to the "linked frameworks" of my project also produces an application that works on my machine, but that one fails if used on machines without the FreeType framework preinstalled into /Library/Frameworks even if the framework is also embedded into my application.

When I get back to my development machine, I'll grab screenshots and videos if necessary. If there are any specific textual fields that would be relevant, or if there is a way to make Xcode show what GCC commands it is invoking then I'll get them too.
On the command line, you'd simply pass libfreetype.a to gcc as follows:

gcc MyProgram MyProgram.o libfreetype.a

So wherever you list your object files in Xcode is where you need to put the path to libfreetype.a.
Xcode can find libfreetype.a, and if I link against it then I get a working application. It just seems to insist on also requiring the dylib to be present, in as much as FreeType builds a dylib even though I tell it not to, and Xcode links against it even though I don't tell it anything about the existence of a dylib.