XCode -- how to link in a library statically?
-
I would like to link libcurl.a statically into a framework
(CURLhandle). And not the system provided one, but one I built that I
know is the right version for my app to run. How can I specify a
static library that is in /usr/local/lib inside of XCode? I tried
various "gcc" type thing in the "other linker flags" of the targets
build prefs but it couldn't find it when linking.
Thanks
Chad -
On Nov 17, 2003, at 8:34 PM, Chad Leigh -- ObjectWerks Inc. wrote:> I would like to link libcurl.a statically into a framework
> (CURLhandle). And not the system provided one, but one I built that I
> know is the right version for my app to run. How can I specify a
> static library that is in /usr/local/lib inside of XCode? I tried
> various "gcc" type thing in the "other linker flags" of the targets
> build prefs but it couldn't find it when linking.
You should be able to just drag the file from the Finder into "Linked
Frameworks." Xcode is smart enough to statically link such things
automatically.
However, if it's in /usr/local/lib, I assume you want it to actually
reside in the Framework bundle at runtime (so that the user doesn't
have to install the library)? Here's what I did for my framework:
1. In the Finder, copy the libcurl.a file to your project directory
2. Drag the file from the project directory to "Linked Frameworks" in
the Xcode window
3. Choose "relative to enclosing group" (the default should be fine)
If you want the library bundled in the framework, you'll also have to
add a copy phase (Project > New Build Phase > Copy Files Phase). The
new copy phase should be visible when you click the triangle next to
your active target. Drag the file from the Frameworks group to the copy
phase, then open the inspector and choose "Frameworks" as the
destination.
If you want a working example, download the DataCrux source from
http://treehouseideas.com/datacrux/.
This caused me a few problems initially, so let me know if you can't
get it working. More here too:
http://cocoadev.com/index.pl?LinkingToExternalLibraries
- Scott
--
Tree House Ideas
http://treehouseideas.com/ -
On Nov 17, 2003, at 9:55 PM, Scott Stevenson wrote:>
> On Nov 17, 2003, at 8:34 PM, Chad Leigh -- ObjectWerks Inc. wrote:
>
>> I would like to link libcurl.a statically into a framework
>> (CURLhandle). And not the system provided one, but one I built that
>> I know is the right version for my app to run. How can I specify a
>> static library that is in /usr/local/lib inside of XCode? I tried
>> various "gcc" type thing in the "other linker flags" of the targets
>> build prefs but it couldn't find it when linking.
>
> You should be able to just drag the file from the Finder into "Linked
> Frameworks." Xcode is smart enough to statically link such things
> automatically.
>
> However, if it's in /usr/local/lib, I assume you want it to actually
> reside in the Framework bundle at runtime (so that the user doesn't
> have to install the library)? Here's what I did for my framework:
Thanks Scott. However, this second thing confuses me. If it is linked
in statically, the built framework no longer needs to reference it, so
it doesn't matter if the library is in the framework bundle, or even on
the machine!?!?!?! Is that not so? Is that not what a "static link"
is all about? Including all the code (runtime code) needed for the
app/library to resolve?
Thanks
Chad -
On Nov 17, 2003, at 9:55 PM, Scott Stevenson wrote:> If you want the library bundled in the framework, you'll also have to
> add a copy phase (Project > New Build Phase > Copy Files Phase). The
> new copy phase should be visible when you click the triangle next to
> your active target. Drag the file from the Frameworks group to the
> copy phase, then open the inspector and choose "Frameworks" as the
> destination.
Ok, ignoring the previous libcurl thing. This is a question I think
related to the above but I am not sure if it is the same.
I have two targets currently. Say A, my app, and B, a framework. I
have A depending on B. But A's code references B and I want to know
how to make B, the framework, get copied somewhere inside the project
so that A's code can reference it somehow without having to get inside
the build directories. I tried adding a Copy phase to the build for
the framework B, and dragging the framework product (ie the framework)
into the copy phase and setting a target of "Frameworks" but this
causes the Framework build to fail (with no error messages at all
including the newly found build log in the bottom pane of the build
details :-). I looked at the cocadev link below but that is a
different issue and it is also different from including the library as
originally discussed. Am I really do a "deployment" of the Framework?
Thanks for any insight
Chad>
> If you want a working example, download the DataCrux source from
> http://treehouseideas.com/datacrux/.
>
> This caused me a few problems initially, so let me know if you can't
> get it working. More here too:
> http://cocoadev.com/index.pl?LinkingToExternalLibraries
>
> - Scott
>
> --
> Tree House Ideas
> http://treehouseideas.com/
>
> _______________________________________________
> MacOSX-dev mailing list
> <MacOSX-dev...>
> http://www.omnigroup.com/mailman/listinfo/macosx-dev -
On Nov 17, 2003, at 10:18 PM, Chad Leigh -- ObjectWerks Inc. wrote:> I tried adding a Copy phase to the build for the framework B, and
> dragging the framework product (ie the framework) into the copy phase
> and setting a target of "Frameworks" but this causes the Framework
> build to fail
I don't have the same setup as you, but I believe you need to add a
copy phase to target "A" (your app), not the framework. You want to
copy the built product of "B" to the Frameworks destination of A.
Also, open the target inspector for the app and add the framework as a
direct dependency. I believe this will make sure they are built in the
right order. Do a 'clean all' before you try to compile again, just to
make sure everything is correctly lined up.> Am I really do a "deployment" of the Framework?
This is an interesting question. It's possible ZeroLink may cause
problems here (I don't know for sure), so if it doesn't work as
describe above, try switching to the deployment build style for both
targets, clean all, then recompile.
- Scott
--
Tree House Ideas
http://treehouseideas.com/ -
On Nov 17, 2003, at 9:37 PM, Chad Leigh -- ObjectWerks Inc. wrote:> Thanks Scott. However, this second thing confuses me. If it is
> linked in statically, the built framework no longer needs to reference
> it, so it doesn't matter if the library is in the framework bundle, or
> even on the machine!?!?!?!
Yeah, I believe you're right. I had some problems with this in the
pre-release of Xcode, but I just tested with the current version and it
appears static linking does work as expected. So you can ignore the bit
about the copy phase.
- Scott
--
Tree House Ideas
http://treehouseideas.com/ -
On Nov 18, 2003, at 1:24 AM, Scott Stevenson wrote:>
> On Nov 17, 2003, at 10:18 PM, Chad Leigh -- ObjectWerks Inc. wrote:
>
>> I tried adding a Copy phase to the build for the framework B, and
>> dragging the framework product (ie the framework) into the copy phase
>> and setting a target of "Frameworks" but this causes the Framework
>> build to fail
>
> I don't have the same setup as you, but I believe you need to add a
> copy phase to target "A" (your app), not the framework. You want to
> copy the built product of "B" to the Frameworks destination of A.
>
> Also, open the target inspector for the app and add the framework as a
> direct dependency. I believe this will make sure they are built in the
> right order. Do a 'clean all' before you try to compile again, just to
> make sure everything is correctly lined up.
I will try this. The framework is already a dependency of the app.
What I have setup now is a copy phase in the framework with a "Product
Directory" as the destination with a subpath of ".." . Doing this
sticks the framework in the root of the project, which allows the App
to easily find it and its headers, with the framework being a direct
dependency of the App. While this "works", it probably is not the way
you are supposed to do it :-) I will give your way a shot.
I am also trying to figure out how to get some Omni frameworks in my
app (pre built) so that they get put in the final .app for
distribution. For now I have them added (with copy) into the main App
target Linked Frameworks.
I think I need a copy phase to copy all these frameworks into the build
results? (into the .app)? In project builder I don't remember how I
did it but it worked :-)
I started from scratch and re-added all my source and stuff in order to
get a native build that was untainted by any project builder stuff. I
know there is that "upgraded" bit but I wanted to make sure it was
untainted so I re-added in all my source tonight and now am trying to
get it all to work. It looks like my nibs got screwed up somehow as
well with Panther...
Chad -
On Nov 18, 2003, at 12:53 AM, Chad Leigh -- ObjectWerks Inc. wrote:> I am also trying to figure out how to get some Omni frameworks in my
> app (pre built) so that they get put in the final .app for
> distribution. For now I have them added (with copy) into the main App
> target Linked Frameworks.
>
> I think I need a copy phase to copy all these frameworks into the
> build results? (into the .app)?
Yup.
- Scott
--
Tree House Ideas
http://treehouseideas.com/ -
>> Also, open the target inspector for the app and add the framework as
>> a direct dependency. I believe this will make sure they are built in
>> the right order. Do a 'clean all' before you try to compile again,
>> just to make sure everything is correctly lined up.
>
> I will try this. The framework is already a dependency of the app.
>
Yes, it's mildly irritating that even though Xcode allows a unbuilt,
internal framework or library to be added as a dependent framework of
your application (under the application target's Frameworks and
Libraries), you still have to add it to the application target info as
a "direct dependency" -- Xcode should have done it automatically but
doesn't.
Cheers, Glen Low
---
pixelglow software | simply brilliant stuff
www.pixelglow.com -
On Nov 18, 2003, at 5:36 PM, Glen Low wrote:>>> Also, open the target inspector for the app and add the framework as
>>> a direct dependency. I believe this will make sure they are built in
>>> the right order. Do a 'clean all' before you try to compile again,
>>> just to make sure everything is correctly lined up.
>>
>> I will try this. The framework is already a dependency of the app.
>>
>
> Yes, it's mildly irritating that even though Xcode allows a unbuilt,
> internal framework or library to be added as a dependent framework of
> your application (under the application target's Frameworks and
> Libraries), you still have to add it to the application target info as
> a "direct dependency" -- Xcode should have done it automatically but
> doesn't.
>
That is a matter of build order dependency versus "I use this"
dependency. Not much different than ordering your make file
appropriately and sticking in the right gcc -L and -l flags and stuff
like that...
The really frustrating thing is that you seem to need to set up a
manual copy phase to actually include the internal framework or library
or whatever in the finished app bundle.
best
Chad -
I'm trying the same thing - I've built a newer version of the libxml
static library and installed it in /usr/local/. I dragged my new
/usr/local/include/libxml folder to my project, and changed my code's
#includes from <libxml/something.h> to "something.h". It builds without
error, but when I run I get a (zero)link unknown symbol error:
ZeroLink: unknown symbol '_htmlParseDoc'
I've gotten different symbols to appear depending on my souce. If I
don't call any library functions, I can refer to a #define in the new
library headers and run without error, so I wonder if the previous
version's bins (or dylibs or whatever they are) are still being
referred to.
Since the library headers themselves are full of "<libxml/something.h>"
includes, I added a symlink in /usr/include to point to the new libxml
folder. This eliminated build errors (but not the link problem). By the
way, a symlink in the same place was also necessary just to build
against the original OS X-supplied libxml library in /usr/include/.
I think I don't quite have it. Any suggestions?
Thanks,
Paul Collins
Gracion Software
On Nov 17, 2003, at 9:37 PM, Chad Leigh -- ObjectWerks Inc. wrote:> On Nov 17, 2003, at 9:55 PM, Scott Stevenson wrote:
>
>>
>> On Nov 17, 2003, at 8:34 PM, Chad Leigh -- ObjectWerks Inc. wrote:
>>
>>> I would like to link libcurl.a statically into a framework
>>> (CURLhandle). And not the system provided one, but one I built that
>>> I know is the right version for my app to run. How can I specify a
>>> static library that is in /usr/local/lib inside of XCode? I tried
>>> various "gcc" type thing in the "other linker flags" of the targets
>>> build prefs but it couldn't find it when linking.
>>
>> You should be able to just drag the file from the Finder into "Linked
>> Frameworks." Xcode is smart enough to statically link such things
>> automatically.
>> -
On Nov 21, 2003, at 12:26 PM, Paul Collins wrote:> I'm trying the same thing - I've built a newer version of the libxml
> static library and installed it in /usr/local/. I dragged my new
> /usr/local/include/libxml folder to my project, and changed my code's
> #includes from <libxml/something.h> to "something.h". It builds
> without error, but when I run I get a (zero)link unknown symbol error:
Are the libraries listed under the target's 'Frameworks & Libraries'
build phase?
- Scott
--
Tree House Ideas
http://treehouseideas.com/ -
On Nov 21, 2003, at 1:26 PM, Paul Collins wrote:> I'm trying the same thing - I've built a newer version of the libxml
> static library and installed it in /usr/local/. I dragged my new
> /usr/local/include/libxml folder to my project, and changed my code's
> #includes from <libxml/something.h> to "something.h". It builds
> without error, but when I run I get a (zero)link unknown symbol error:
>
> ZeroLink: unknown symbol '_htmlParseDoc'
Grab the actual .a file from /usr/local or whereever it is and add it
to the Linked Frameworks bit...
Chad -
Success. Actually, my Target didn't HAVE a 'Frameworks & Libraries'
build phase. Targets I add to an existing Project only have Header and
Sources. So I made a new Project - the built-in target had all the
phases. At first, got this error:
ZeroLink: unknown symbol '_gzopen'
But then I turned ZeroLink off and it worked.
Thanks guys!
Paul
On Nov 21, 2003, at 1:15 PM, Scott Stevenson wrote:> On Nov 21, 2003, at 12:26 PM, Paul Collins wrote:
>> I'm trying the same thing - I've built a newer version of the libxml
>> static library and installed it in /usr/local/. I dragged my new
>> /usr/local/include/libxml folder to my project, and changed my code's
>> #includes from <libxml/something.h> to "something.h". It builds
>> without error, but when I run I get a (zero)link unknown symbol
>> error:
>
> Are the libraries listed under the target's 'Frameworks & Libraries'
> build phase?
>
> - Scott


