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