Adding a 3rd party C++ library to ObjectiveC project

  • I'd like to use an open source 3rd party C++ library in my Objective C project, but I have no idea how to do this.  I pulled the library from github, and it contains the source,  docs, and a bunch of cmake files. There is no compiled library and the docs are very scarce.

    Any suggestions how I can add and use this in my project?  Can I even use C++ within my ObjectiveC project?

    Thanks,

    - Koen.
  • On Jun 7, 2013, at 8:42 AM, Koen van der Drift <koenvanderdrift...> wrote:

    > I'd like to use an open source 3rd party C++ library in my Objective C project, but I have no idea how to do this.  I pulled the library from github, and it contains the source,  docs, and a bunch of cmake files. There is no compiled library and the docs are very scarce.

    It’s probably easiest to just use the supplied makefile/scripts to build the library, rather than trying to get Xcode to build it. As long as the build process outputs a library of some sort (.dylib or .a) you can add that file to your Xcode project.

    > Any suggestions how I can add and use this in my project?  Can I even use C++ within my ObjectiveC project?

    Sure. If you want to call C++ APIs (or include any headers that have C++ syntax) from Objective-C code, change the suffix of that source file from “.m” to “.mm” to enable Objective-C++. The compiler will then recognize both Objective-C and C++ syntax.

    I recommend making an Objective-C wrapper around the C++ API. Then the only .mm files you need are for the ones that implement that wrapper. The rest of your app can just use the Objective-C API and not have to worry about C++.

    —Jens
  • On Jun 7, 2013, at 12:45 PM, Jens Alfke <jens...> wrote:

    > It’s probably easiest to just use the supplied makefile/scripts to build the library, rather than trying to get Xcode to build it. As long as the build process outputs a library of some sort (.dylib or .a) you can add that file to your Xcode project.

    Yep, I just finished doing that :)  It took a while, I needed Boost as a dependency, and used MacPorts to install that from the terminal. After that was done, I could build my library. So I now have a .a file in /usr/local/lib/ and a bunch of .hpp files in /usr/local/include/  Do I need all of these in Xcode?

    > I recommend making an Objective-C wrapper around the C++ API. Then the only .mm files you need are for the ones that implement that wrapper. The rest of your app can just use the Objective-C API and not have to worry about C++.

    The library is just used with one of my ObjC files, so I'll start with renaming that to .mm. If that doesn't work, I'll look into the wrapper as you suggested.

    Thanks,

    - Koen.
  • On Jun 7, 2013, at 8:42 AM, Koen van der Drift <koenvanderdrift...> wrote:

    > I'd like to use an open source 3rd party C++ library in my Objective C project, but I have no idea how to do this.  I pulled the library from github, and it contains the source,  docs, and a bunch of cmake files. There is no compiled library and the docs are very scarce.
    >
    > Any suggestions how I can add and use this in my project?  Can I even use C++ within my ObjectiveC project?

    The short answer is "Yes, you can use C++ libraries with your Cocoa apps."

    The long answer is, well, a bit longer.

    (1) You have to build the C++ library first. That is sometimes tricky, especially for many open source projects. Once that is done, you are probably two thirds of the way there.

    (2) In your Xcode project, you need to set your target to (a) locate the relevant header files and (b) link against the relevant library (standard stuff).

    (3) You need to turn your Objective C source code files that reference any of the C++ objects to Objective-C++ code (basically change the file from a ".m" file to a ".mm" file).

    In general, I find I don't include C++ objects in my Objective C objects but instead include pointers to them. Then in the -init method (or appropriate place) I allocate the C++ object. This need may have changed over the years, but it has been what I've been using for several years.

    Todd
  • Installing and building without errors has just finished.  Now the fun part start, how to even use it.

    - Koen.

    On Jun 7, 2013, at 1:08 PM, Todd Heberlein <todd_heberlein...> wrote:

    >
    > On Jun 7, 2013, at 8:42 AM, Koen van der Drift <koenvanderdrift...> wrote:
    >
    >> I'd like to use an open source 3rd party C++ library in my Objective C project, but I have no idea how to do this.  I pulled the library from github, and it contains the source,  docs, and a bunch of cmake files. There is no compiled library and the docs are very scarce.
    >>
    >> Any suggestions how I can add and use this in my project?  Can I even use C++ within my ObjectiveC project?
    >
    > The short answer is "Yes, you can use C++ libraries with your Cocoa apps."
    >
    > The long answer is, well, a bit longer.
    >
    > (1) You have to build the C++ library first. That is sometimes tricky, especially for many open source projects. Once that is done, you are probably two thirds of the way there.
    >
    > (2) In your Xcode project, you need to set your target to (a) locate the relevant header files and (b) link against the relevant library (standard stuff).
    >
    > (3) You need to turn your Objective C source code files that reference any of the C++ objects to Objective-C++ code (basically change the file from a ".m" file to a ".mm" file).
    >
    > In general, I find I don't include C++ objects in my Objective C objects but instead include pointers to them. Then in the -init method (or appropriate place) I allocate the C++ object. This need may have changed over the years, but it has been what I've been using for several years.
    >
    > Todd
    >
  • On Jun 7, 2013, at 10:01 AM, Koen van der Drift <koenvanderdrift...> wrote:

    > Yep, I just finished doing that :)  It took a while, I needed Boost as a dependency, and used MacPorts to install that from the terminal. After that was done, I could build my library. So I now have a .a file in /usr/local/lib/ and a bunch of .hpp files in /usr/local/include/  Do I need all of these in Xcode?

    Use the + button in the libraries list in the target viewer to add the library. It’ll show up in the list since it’s in a known location.
    You can just include the headers with #include <headername.hpp> since they’re in the standard system includes directory. No need to add them to your project.

    > The library is just used with one of my ObjC files, so I'll start with renaming that to .mm. If that doesn't work, I'll look into the wrapper as you suggested.

    Cool. The usual problem people run into is C++ syntax leaking into source files not being compiled with Objective-C++. A common mistake is to add “#include <blah.hpp>” in the header file of an Obj-C class — when that header gets #imported from a .m (not .mm) file, the parser isn’t expecting C++ syntax and will barf. The barfage may happen way down in some C++ standard library header and be very confusing if you don’t realize what’s going on.

    —Jens
  • On Jun 7, 2013, at 11:13 AM, Koen van der Drift <koenvanderdrift...> wrote:

    > Installing and building without errors has just finished.  Now the fun part start, how to even use it.

    My motto: “It linked — ship it!”

    —Jens
  • On Jun 7, 2013, at 11:08 AM, Todd Heberlein wrote:

    > In general, I find I don't include C++ objects in my Objective C objects but instead include pointers to them. Then in the -init method (or appropriate place) I allocate the C++ object. This need may have changed over the years, but it has been what I've been using for several years.

    FYI, the option to call default constructors of C++ objects embedded in Objective-C objects has been around since 10.3 ;-)

    --
    Scott Ribe
    <scott_ribe...>
    http://www.elevated-dev.com/
    (303) 722-0567 voice
  • On Jun 7, 2013, at 2:15 PM, Jens Alfke <jens...> wrote:

    > Use the + button in the libraries list in the target viewer to add the library. It’ll show up in the list since it’s in a known location.

    Hmm, I cheered too soon. The library (installed in /usr/local/lib) does not show up in that list.  That directory is added to my Framework and Library Search Paths in the Build Settings.  Can I just drag the library into my project instead from that location?

    - Koen.
  • On Jun 7, 2013, at 11:27 AM, Koen van der Drift <koenvanderdrift...> wrote:

    > Hmm, I cheered too soon. The library (installed in /usr/local/lib) does not show up in that list.  That directory is added to my Framework and Library Search Paths in the Build Settings.  Can I just drag the library into my project instead from that location?

    One other possible gotcha is whether it is a static or dynamic library. If it is a dynamic library you have to take some extra steps to embed the library into your app bundle. Otherwise, the app will build and run fine on your development machine, but then fail when you move it to another machine without the library installed.

    On Jun 7, 2013, at 11:25 AM, Scott Ribe <scott_ribe...> wrote:

    > FYI, the option to call default constructors of C++ objects embedded in Objective-C objects has been around since 10.3 ;-)

    I'm clearly ready for the Coders Retirement Center :), so I'll defer to others on how to get that library into your project.

    In an old man's voice: In my day sonny, I used to add the path to the "Build Settings" "Library Search Path" and add -llibname to "Other Linker Flags".

    Todd
  • On Jun 7, 2013, at 3:29 PM, Todd Heberlein <todd_heberlein...> wrote:

    > One other possible gotcha is whether it is a static or dynamic library. If it is a dynamic library you have to take some extra steps to embed the library into your app bundle. Otherwise, the app will build and run fine on your development machine, but then fail when you move it to another machine without the library installed.

    It's a static library (.a), and I don't expect any upstream updates soon.  Oh, did I mention this is for an iOS project, that might bring some more fun with it ;-)

    - Koen.
  • On Jun 7, 2013, at 11:27 AM, Koen van der Drift <koenvanderdrift...> wrote:

    > Hmm, I cheered too soon. The library (installed in /usr/local/lib) does not show up in that list.  That directory is added to my Framework and Library Search Paths in the Build Settings.  Can I just drag the library into my project instead from that location?

    Yeah. My mistake — /usr/local/lib isn’t one of the places Xcode’s UI looks for libraries.

    —Jens
  • On Jun 7, 2013, at 3:33 PM, Koen van der Drift <koenvanderdrift...> wrote:

    > It's a static library (.a), and I don't expect any upstream updates soon.  Oh, did I mention this is for an iOS project, that might bring some more fun with it ;-)

    So this turns out to be some kind of a hassle. Since the Simulator and the iPhone have two different architectures, I need to have two copies of the library available. Can I just create both, and add them to Xcode with a different name for each architecture?  Maybe I should create a framework for the library instead, so I don't have to change the whole time?

    Other than that, it's really awesome. Once I figured out how to correctly compile the library with cmake, and change the C++  std lib to the GNU version, it was pretty straight forward.

    - Koen.
  • On Fri, Jun 7, 2013 at 11:14 PM, Koen van der Drift
    <koenvanderdrift...> wrote:
    >
    > On Jun 7, 2013, at 3:33 PM, Koen van der Drift <koenvanderdrift...> wrote:
    >
    >> It's a static library (.a), and I don't expect any upstream updates soon.  Oh, did I mention this is for an iOS project, that might bring some more fun with it ;-)
    >
    > So this turns out to be some kind of a hassle. Since the Simulator and the iPhone have two different architectures, I need to have two copies of the library available. Can I just create both, and add them to Xcode with a different name for each architecture?  Maybe I should create a framework for the library instead, so I don't have to change the whole time?
    >
    http://stackoverflow.com/questions/1211854/xcode-conditional-build-settings
    -based-on-architecture-device-arm-vs-simulat


    Jeff
  • What I ended up doing in the end was just copy the source and header files from the 3rd party library into my project, without creating a library. I spent hours searching and reading info on how to create a static library inside and outside Xcode, but I never could get it to work for both architectures.

    Oh well, it was a nice exercise. The sun is shining, time to go outside.

    - Koen.

    On Jun 7, 2013, at 11:19 PM, Jeffrey Walton <noloader...> wrote:

    > On Fri, Jun 7, 2013 at 11:14 PM, Koen van der Drift
    > <koenvanderdrift...> wrote:
    >>
    >> On Jun 7, 2013, at 3:33 PM, Koen van der Drift <koenvanderdrift...> wrote:
    >>
    >>> It's a static library (.a), and I don't expect any upstream updates soon.  Oh, did I mention this is for an iOS project, that might bring some more fun with it ;-)
    >>
    >> So this turns out to be some kind of a hassle. Since the Simulator and the iPhone have two different architectures, I need to have two copies of the library available. Can I just create both, and add them to Xcode with a different name for each architecture?  Maybe I should create a framework for the library instead, so I don't have to change the whole time?
    >>
    > http://stackoverflow.com/questions/1211854/xcode-conditional-build-settings
    -based-on-architecture-device-arm-vs-simulat

    >
    > Jeff
  • On Jun 7, 2013, at 8:14 PM, Koen van der Drift <koenvanderdrift...> wrote:

    > So this turns out to be some kind of a hassle. Since the Simulator and the iPhone have two different architectures, I need to have two copies of the library available. Can I just create both, and add them to Xcode with a different name for each architecture?

    You can use the lipo tool to combine the libraries for each architecture into a single fat library.

    —Jens
  • On Jun 8, 2013, at 3:07 PM, Jens Alfke <jens...> wrote:

    > You can use the lipo tool to combine the libraries for each architecture into a single fat library.

    I played around with that too, but then got errors such as: "lipo: can't open input file: armv7"

    - Koen.
  • On Sat, Jun 8, 2013 at 2:57 PM, Koen van der Drift
    <koenvanderdrift...> wrote:
    > What I ended up doing in the end was just copy the source and header files from the 3rd party library into my project, without creating a library. I spent hours searching and reading info on how to create a static library inside and outside Xcode, but I never could get it to work for both architectures.
    >
    Yeah, I've hit the same wall in the past. There's not much information
    on porting a third party library to a Framework. Apple has information
    on creating frameworks, but nothing for Makefile project -> Framework.
    Stack overflow had no answers either (when I searched in the past).

    Now I build the third party library using SDKROOT (the Makefiles have
    to be made aware), and then install them in /usr/local. My installs
    look similar to:

        /usr/local/openssl/iphoneos-armv6
        /usr/local/openssl/iphoneos-armv7
        /usr/local/openssl/iphoneos-armv7s
        /usr/local/openssl/iphone-simulator
        /usr/local/openssl/macosx-i386
        /usr/local/openssl/macosx-x86_64

    I then use paths and conditional build settings to include the proper library.

    Jeff

    > On Jun 7, 2013, at 11:19 PM, Jeffrey Walton <noloader...> wrote:
    >
    >> On Fri, Jun 7, 2013 at 11:14 PM, Koen van der Drift
    >> <koenvanderdrift...> wrote:
    >>>
    >>> On Jun 7, 2013, at 3:33 PM, Koen van der Drift <koenvanderdrift...> wrote:
    >>>
    >>>> It's a static library (.a), and I don't expect any upstream updates soon.  Oh, did I mention this is for an iOS project, that might bring some more fun with it ;-)
    >>>
    >>> So this turns out to be some kind of a hassle. Since the Simulator and the iPhone have two different architectures, I need to have two copies of the library available. Can I just create both, and add them to Xcode with a different name for each architecture?  Maybe I should create a framework for the library instead, so I don't have to change the whole time?
    >>>
    >> http://stackoverflow.com/questions/1211854/xcode-conditional-build-settings
    -based-on-architecture-device-arm-vs-simulat

  • I finally figured out why I couldn't get it to work.

    The library i am trying to add to my project comes with CMAKE build files. In order to have it build for iOS, I found a toolchain file, that can be used to add specifics (patch the makefile) for a specific build environment. I used this to set it either for the device or the simulator architecture.  However, when playing around with lipo, I noticed that the architecture for both is actually x86_64, so the toolchain file was never used, or at least the architecture info was not used. This also explains that I could only build and run my project with the static library in the simulator and was getting all sorts of errors and warnings when trying to run it on a device.

    So, next is to figure out how to fix this and tickle CMAKE so that the libraries are actually build for the correct architectures.  I know this is outside the scope of this mailing list, but if anyone has some experience with this, feel free to contact me off-list.

    - Koen.

    On Jun 8, 2013, at 3:22 PM, Jeffrey Walton <noloader...> wrote:

    > On Sat, Jun 8, 2013 at 2:57 PM, Koen van der Drift
    > <koenvanderdrift...> wrote:
    >> What I ended up doing in the end was just copy the source and header files from the 3rd party library into my project, without creating a library. I spent hours searching and reading info on how to create a static library inside and outside Xcode, but I never could get it to work for both architectures.
    >>
    > Yeah, I've hit the same wall in the past. There's not much information
    > on porting a third party library to a Framework. Apple has information
    > on creating frameworks, but nothing for Makefile project -> Framework.
    > Stack overflow had no answers either (when I searched in the past).
    >
    > Now I build the third party library using SDKROOT (the Makefiles have
    > to be made aware), and then install them in /usr/local. My installs
    > look similar to:
    >
    > /usr/local/openssl/iphoneos-armv6
    > /usr/local/openssl/iphoneos-armv7
    > /usr/local/openssl/iphoneos-armv7s
    > /usr/local/openssl/iphone-simulator
    > /usr/local/openssl/macosx-i386
    > /usr/local/openssl/macosx-x86_64
    >
    > I then use paths and conditional build settings to include the proper library.
    >
    > Jeff
    >
    >> On Jun 7, 2013, at 11:19 PM, Jeffrey Walton <noloader...> wrote:
    >>
    >>> On Fri, Jun 7, 2013 at 11:14 PM, Koen van der Drift
    >>> <koenvanderdrift...> wrote:
    >>>>
    >>>> On Jun 7, 2013, at 3:33 PM, Koen van der Drift <koenvanderdrift...> wrote:
    >>>>
    >>>>> It's a static library (.a), and I don't expect any upstream updates soon.  Oh, did I mention this is for an iOS project, that might bring some more fun with it ;-)
    >>>>
    >>>> So this turns out to be some kind of a hassle. Since the Simulator and the iPhone have two different architectures, I need to have two copies of the library available. Can I just create both, and add them to Xcode with a different name for each architecture?  Maybe I should create a framework for the library instead, so I don't have to change the whole time?
    >>>>
    >>> http://stackoverflow.com/questions/1211854/xcode-conditional-build-settings
    -based-on-architecture-device-arm-vs-simulat

  • On Jun 8, 2013, at 12:22 PM, Jeffrey Walton <noloader...> wrote:

    > Yeah, I've hit the same wall in the past. There's not much information
    > on porting a third party library to a Framework.

    A framework is just a special directory structure. Static frameworks for iOS are especially simple; they just look like
    Foo.framework
      Foo
      Headers
      foo.h
    where the file Foo.framework/Foo is the just library with the “.a” suffix removed.

    —Jens
  • I was finally able to create three different static libraries (the armv7s was missing) with this helpful tool: https://code.google.com/p/ios-cmake/

    Made one fat library, added it to my project, and the devices and simulators all work.

    - Koen.

    On Jun 8, 2013, at 7:26 PM, Jens Alfke <jens...> wrote:

    >
    > On Jun 8, 2013, at 12:22 PM, Jeffrey Walton <noloader...> wrote:
    >
    >> Yeah, I've hit the same wall in the past. There's not much information
    >> on porting a third party library to a Framework.
    >
    > A framework is just a special directory structure. Static frameworks for iOS are especially simple; they just look like
    > Foo.framework
    > Foo
    > Headers
    > foo.h
    > where the file Foo.framework/Foo is the just library with the “.a” suffix removed.
    >
    > —Jens
previous month june 2013 next month
MTWTFSS
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Go to today