Proper way to link against libraries with dependencies? - xcode

I'm working on a fairly simple OS X app that uses a couple third-party libraries (SoX and TwoLAME) to do some audio converting. TwoLAME relies on libsndfile, and SoX relies on sndfile plus a number of other libraries.
For development, I simply installed the two libraries with Homebrew, which took care of the dependencies, and then linked right to them (ie in /usr/local/Cellar/...). Now that I'm ready to deploy, I need to figure out a way to get everything packaged up.
I know frameworks are a bit ambiguous in Cocoa (fake ones, dynamic ones, etc), but it seems like ideally I would end up with some frameworks of one kind or another that I can drop into the project and everything would work.
I've read through a lot of different docs and tutorials about frameworks, and tried a number of approaches, but I seem to be missing some core concept for getting this all to work together.
I have been able to make frameworks from the libraries that sort of work, in the sense that I compile from source, take the static (.a) library and put it in a "fake" framework with the headers, and the app will run with those. Those static libraries are still referencing the dependencies on my local path, though. So, eg, if I uninstall Lame from Homebrew, the SoX static library in my framework will fail.
I'm really struggling to figure out what the best way cleanly get all these libraries and their dependencies into this app. The tutorials I've seen about building dynamic Cocoa libraries from scratch have been very hard to do with the source code for these pre-existing libraries. The other option I have considered it build dylibs and then use install_name_tool to change paths to be relative just ship everything with the app and try to match everything up.
There's got to be some better way that I'm just missing, and would really appreciate any help.

Related

Embed libraries into package

I have a Cocoa application that uses OpenCV, TBB, boost and some other libraries which are installed in my system. How do I create a package that has all this inside so that customer doesn't have to install anything besides just copy/paste my package?
At the building stage they are referenced via .dylib .
Is it possible?
Where I choose in xCode Product\Archive it will only export the app itself.
well, after a lot of reading I could not find an easy solution. Maybe is there, but I didn't have more time to search for it.
So instead I wrote a small application in C++ that uses otool and install_name_tool utilities to analyze needed required libraries and copy them into the bundle. Is located here https://github.com/integral-llc/libb . Keep in mind, it was made for personal use, but can be easily changed for anything else.
It worked perfectly for my case. It found all needed dependencies for OpenCV, boost, TBB.
if you have better tools or ideas to improve current one, you are more than welcome to say.

Can I use OpenFrameworks on OS X without having to use XCode?

I can't stand XCode, but really love OpenFrameworks, and I know it works on Linux+Win32 so I don't see why it should be XCode dependent. If I need to have XCode installed that's fine, I just don't want to use it at all.
Xcode internally uses gcc/llvm. in fact from the command line you can cd into a directory that contains an openFrameworks project and just type xcodebuild. but this won't allow you to edit the project file and add new source code, etc.
the Linux makefiles could be adapted to work on OSX as well. they already contain a lot of the information necessary about finding the correct source files, library paths etc. however Linux allows us to install many more components as shared system libraries, while on OSX we link most of the libs statically, so a number of extra library paths would need to be added. probably the biggest gotcha is that everything has to be compiled 32 bit, which means passing -arch i386 everywhere, so you can't just install dependant libs using Homebrew or MacPorts. we are in the process of transitioning to 64 bit but there are still some QuickTime calls that require us to stick with 32 bit, mainly around accessing legacy video capture devices that a lot of us still use for computer vision.
like #cdelacroix points out, we only maintain Xcode project files on OSX. this is mainly due to the lack of a decent alternative. there is a version of Code::Blocks for OSX but it is not very well supported, has some issues with native gui rendering and tends to lag behind the other platforms. Xcode is also the easiest way to install a toolchain on OSX so for most users installing Xcode is necessary.
if you do get a makefile based build system working, and would be interested in maintaining it medium to long term, please consider contributing it to the GitHub repository, it would be gladly accepted.
As of March 2013, openFrameworks has official makefile support for compiling the library itself. However, at the time of this writing, the changes haven't yet been merged into the stable release. You'll need to clone the Git repository and switch to the development branch.
git clone https://github.com/openframeworks/openFrameworks
cd openFrameworks && git checkout develop
cd libs/openFrameworksCompiled/project
make
As far as I can tell, we still need to use the unofficial solutions for compiling apps against the library.
You need Xcode, or at least a set of compilers (more information is available here), but otherwise, no, you can edit/work with the code in whatever editor or environment you want.
Here's a link to a makefile which will compile an OpenFrameworks application on OsX:
https://gist.github.com/labe-me/1190981
Place the makefile in the apps' directory and run make. Tested on OsX 10.6, but haven't tried with addons yet.
As #mipadi said, there is no requirement to actually use Xcode, you can do pretty much everything you do in Xcode with make or cake or any of your build system of choice. All you have to do is find the right set of command line options to pass to the usual tools (compiler, linker, strip, etc.), and sometimes the easier way is to... look in the Xcode build window how it is doing stuff (expand the lines with the small button on the right of each line).
For example you can link with your framework of choice with ld -framework Framework -FPathToFramework foo.o or your dynamic library with ld -lLib -LPathToDylib foo.o. You might have to learn about #rpath, #loader_path and install_name_tool to ship a self-contained packaged application.
As for OpenFrameworks, the "requirement" for Xcode is that the authors decided to maintain only Xcode project files. I just looked at how they do it, they ship source code and Xcode project files that build static libraries, so it will be even more simple for you (although you will need to link the library dependencies by hand). You will have to choose between compiling everything from source in your build system (if you want more customization power without touching Xcode), or just produce the 2 static libraries (openFrameworks.a and openFrameworksDebug.a) with Xcode once, then use them in your build system (recommended until you really need continuous customization).

Including a framework without embedding it in the app bundle

I'm still not 100% sure with the framework linking process, but from what I've seen here before nobody has asked a similar question, perhaps because this could be a silly question, but I'll give it a go anyway.
In my current X-Code project, I'm using a custom framework, say example.framework. At the moment, as far as I'm aware of, in order for the program to function with the framework, I need to have it either in /Library/Frameworks, or I need to have it copied into the bundle resources in the build phase.
Would anybody know about adding a framework to a project in a way that it gets compiled into the executable, so I don't have to include the raw framework with the app? I'd rather not share the whole framework...
Thank you in advance! Any suggestions are also welcome!
A Mac OS X framework is basically a shared library, meaning it's a separate binary.
Basically, when your main executable is launched, the OS will load the framework/dylib into memory, and map the symbols, so your main executable can access them.
Note that a framework/dylib (bundled into the application or not), does not need to contain the header files, as those are only needed at compilation time.
With Xcode, you can actually decide whether or not to include the header files, when you are copying the framework to its installation directory (see your build phases).
If you don't copy header files, people won't be able to use your framework/dylib (unless they reverse-engineer it, of course).
If you still think a framework is not suitable for your needs, you may want to create a static library instead.
A static library is a separate object file (usually .a) that is «included» with your final binary, at link time.
This way, you only have a single binary file, containing the code from the library and from your project.

Why would I want to use a static library?

I understand for non-iOS targets, using shared libraries can lead to lower memory usage, and also that some companies distribute a library and headers (like Superpin) and a static library allows them to not distribute the source of their product. But outside of those, what are the reasons you'd want to use a static library? I use git for all of my projects, and I usually add external libraries (open source ones) as a submodule. This means they take up disk space locally, but they do not clutter up the repo. Also since iOS doesn't support shared libraries, the benefits of building libraries to promote code reuse seems diminished.
Basically, is there any reason outside of selling closed source libraries that it makes sense to build/use static libraries for iOS?
organization, reuse, and easy integration into other programs.
if you have a library which is used by multiple apps or targets multiple platforms, then you will have to maintain the build for each app. with a library, you let the library maintainer set up the build correctly, then you just link to the result (if it's developed internally, then you'll want to add it as a dependency too).
it's like DRY, but for projects.
libraries become more useful as projects become more complex. you should try to identify what programs (functions, class hierarchies, etc) are reusable outside of your app's context, and put it in a library for easy reuse - like pattern recognition.
once your codebase has hundreds or thousands of files, you will want to minimize what you use, and you will not want to maintain the dependencies manually for each project.
Also since iOS doesn't support shared
libraries, the benefits of building
libraries to promote code reuse seems
diminished.
There's no reason you can't build your own static library to use across multiple projects.
Other than for that purpose and the ones you mentioned I don't think there's much else.
Static libraries allow you to have truly standalone executables. Since all library code is actually, physically present in the executable, you don't have to worry about the exec failing to run because there's a too-old version of some library, or a too-new one, or it's completely missing, etc. And you don't have to worry about your app suddenly breaking because some library got replaced. It cuts down on dependencies and lets your app be more encapsulated.

creating a .dll on a mac: .dylib or framework?

I need to create a Mac version of our libraries for one of our customers. I am not so familiar with dynamic libraries on Mac, but from what I understand, I have 2 options: .dylib or frameworks. What would be the best option? Why?
Few related questions:
If I understand correctly, .dylib have to be installed in one of the stnadard UNIX directories such as /usr/lib, etc. Hence using a .dylib should make my customer's installer much more complex, since they'll probably need to request permission to write something in a system folder?
Can frameworks be private and embedded within my customer's bundle? So no one else can see/use them?
Any constructive criticisms/comments/ideas more than welcome. Thanks in advance.
Alex
.dylib is similar to .so on Linux.
Frameworks are basically just the OSX way of distributing libraries and headers together. They are the Application Bundle equivalent for library distribution.
With either method if you want to ensure other people don't use them you should be using static libraries (.a files) and getting your customer to statically link them into their application.
Otherwise there isn't really much difference between Frameworks and .dylib except the prior is nicer for OSX developers.
Either can be embedded inside a customers Application bundle, otool/install_name_tool handle them both fine.

Resources