Boost library static linking on Xcode 4 - xcode

I am using the Boost library on OS X using Xcode. Boost was installed on my system using macports. I have successfully built my app by adding the 3 boost libraries I need (for example, libboost_thread-mt.a) to that Targets 'Link Binary With Libraries' list. However I need to link these libraries statically so that the app will run on other computers without the boost library needing to be installed.
How do I do this exactly? Through my numerous google searches I'm finding I might need to add '-static' - where do I add this in Xcode?

If you've linked with a .a library, then you have already linked statically. You never need to ship .a libraries. They're just bundles of objects.
EDIT: Your error strongly suggests that you're linking the dylib rather than the .a. If you have libfoo.dylib and libfoo.a in your library path, even if you say "link libfoo.a" in Xcode, and even if libfoo.a is earlier in the search path, it will still link libfoo.dylib. This is because Xcode's linking is totally broken and passes -lfoo to the linker (you should never use -l for something you built and have the exact path to). I always recommend linking libraries you built in LDFLAGS in an xcconfig file rather than using the build pane. You pass the exact path you want rather than using -l. See Abandoning the Build Panel for more of my thoughts on xcconfig. It's out of date now, since it was written for Xcode3, but the basics still apply.
Using the build pane, you can also pass the entire path to the library in "Other Linker Flags." But this still has all the problems of the build pane.
The quicker (but less robust) solution is sometimes to add -Wl,-search_paths_first to the "Other Linker Flags." This changes the behavior so that each library path is searched for both .dylib and .a before going on (the default behavior is to search everywhere for .dylib and only then search for .a). So if your .a is in a different directory from your .dylib, and that directory is earlier in the search path, this will work.
This question finally got me to open a radar on this, which I should have done years ago. I recommend that others open duplicates.

Related

How can I tell why my program requires a specific shared library?

I'm working on an OS X application using a third-party framework. This framework is distributed both as shared objects and static objects. For my purposes, I want to use the static objects because I can't rely on the presence of the library on other systems.
However, when I build the application with Xcode, something decides it needs the shared objects, and when I run it, dyld tells me off before I even get to my program:
dyld: Library not loaded: /usr/local/lib/libshared.dylib
  Referenced from: /Users/me/Library/Developer/Xcode/snip/Application.app/Contents/MacOS/Application
  Reason: image not found
I ran otool -L on the executable, and sure enough, it tried to link against the shared objects (which aren't even installed on my system). However, when I ran it on the thirty-some .a files that I link against, none of them indicated any dependency on them.
Apple's ld -v is just a tad verbose: it displays the library search paths but doesn't produce any other kind of useful output.
How can I find what tried to link against the shared objects?
otool -L does list the libraries against which any object links.
This specific instance was caused by an Xcode bug (known as rdar://2725744 to the ones blessed with Apple bug database access, and not fixed as of Xcode 6.1.1) where if you try to link against a .a static library with Xcode but there's a .dylib (or .so) dynamic library with the same name in the same directory, the linker will pick the dynamic one.
When you instruct Xcode to link against a static library (say /some/path/to/my/libFooBar.a), it adds -L/some/path/to/my -lFooBar to the linker invocation. However, with it, ld first searches for a dynamic library called libFooBar.dylib, and it will fall back to the static library only if it can't find the dynamic one.
If you added the framework is listed in the "Build Phases" of "Link Binary with Libraries" and it has the setting of "Required" that could explain why the launch fails.
Try changing the setting to "Optional". Then if nothing uses the framework, it should launch fine. (If something tries to use the framework, but fails to check for it first, it might crash.)

firebreath mac osx, bundle - link binary with libraries disable

I working with Firebreath 1.7, MacOSX 10.8.3, Xcode 4.6.3.
I want add boost::chrono as static library to my plugin.
After running prepmac.sh i have my_plugin bundle target. I choose my_plugin target in project/targets tab and don't see option "Link binary With Libraries".
How i can add boost::chrono library to my_plugin by another method?
Changing things manually there is not the correct way to do it; you should never change the project files without changing the cmake files, because eventually you'll need to rerun the prep script.
First of all, are you using system boost? boost::chrono is not part of the boost that firebreath includes, which is a subset of the boost features to keep size down for those who don't want to deal with it. If you are using part firebreath boost and part your own, you could have problems.
If you've configured system boost correctly, you should be able to just add this to the end of your PluginConfig.cmake file and rerun the prep script:
add_boost_library(chrono)
Barring that, you could also just do it using cmake directly, which would mean adding a target_link_libraries command to your CMakeLists.txt or Mac/projectDef.cmake file at the end, something like:
target_link_libraries(${PROJECT_NAME} boost_chrono)
(you'd need to find out for sure what the library name is; you might even need to use find_library to locate it).

Compile with GCC and relocate the linked libraries

I have my soft.c and I compile it successfully and link it against /usr/lib/myLib.so.
Everything it's ok except for the fact that it's not what I'm looking for, i would like to manage the final path considered for the linking, in other words i want GCC to consider the library /usr/lib/myLib.so but I also want the final linking to be a relative path, kinda like ../myLib.so.
The usual scenario is
./soft linked to -> /usr/lib/myLib.so
I want
./soft linked to -> ../myLib.so
Obiviously I also need GCC to manage any cross referenced library, for example if /usr/lib/myLib.so is linked to other libs i want all the libraries involved to be relocated in the relative path so ../myLib.so can fully work from a relative path .
How to achieve that ?
Thanks.
You could include run-time search path information in the binaries, using the -rpath option to the linker (passed to gcc as -Wl,-rpath,.
Note that this is generally frowned upon by distribution maintainers, as there should be a single system-wide library search path so conflicts are caught early.

RPATH must exist at compile time

Please forgive me if I'm missing something obvious here. I'm developing some applications for another platform, and all of my proprietary libraries are installed to /app/lib. To facilitate this, I specify a runtime library path for each of my binaries as "/app/lib". This works fine; however, it requires that the path "/app/lib" exist in my build environment when linking (even though that directory is empty). I'm using NetBeans, which might be complicating matters, but I can see "-Wl, -rpath /app/lib" being passed to gcc.
I'd like to avoid the need to create an empty "/app/lib" in my build environment, but I don't want to change the file structure on my target platform. If I delete /app/lib from the build environment, I get an error when building that it can't be found. Is there a way to specify a runtime search path without the need for it to exist at link time?
I think the option you are looking for is -Wl,-rpath-link,/path/to/libraries. You need to use both options at once.
The linker will then use -rpath-link to find the libraries at link-time, but it'll encode the -rpath value into the binary for use at run time.
The syntax should be "-Wl,-rpath -Wl,/app/lib" ("-Wl,-rpath,/app/lib" works too). This is a bug in NetBeans. The reason why it's not more critical (and why I didn't notice this before) is that link-time search paths appear to carry over into runtime. Because NetBeans isn't placing a comma between -rpath and /app/lib, /app/lib is being interpreted as a link-time search path. As a result, my dependent libraries are still found at run-time in the appropriate location, but because it's a link-time dependency, the linking fails because /app/lib doesn't exist.

How to distribute a Mac OS X with dependent libraries?

I have a program (specifically my entry for the SO DevDays Countdown app challenge) which relies on several dynamic libraries, namely libSDL, libSDL_ttf, and others. I have these libraries installed under /opt/local/lib via MacPorts, and many people won't have these installed (and some might have them installed, but not at that location).
How do I distribute my program so that people without these libraries installed can run it out-of-the-box? Obviously I'll have to distribute the various .dylib files, but doing this is insufficient. The dynamic loader still looks for the libraries installed at the locations I have them installed at. Is there a way to tell the dynamic loader to look in the current directory of the executable, like what Windows does with DLLs? People shouldn't have to modify any environment variables (e.g. DYLD_LIBRARY_PATH), since again I want this to work out-of-the-box.
The basic approach to this is to ship them in the .app bundle. You'll then modify the location the linker looks for shared libraries to include this.
The steps are:
Create a new copy files build phase to your target that copies those files into the Frameworks directory of the .app bundle.
Edit the build configuration setting "Runpath Search Paths" to include #executable_path/../Frameworks
If you build your executable with these changes and then look, you should find that the dylibs exist in the Foo.app/Contents/Framework directory and running otool -L Foo.app/Contents/MacOS/Foo should yield and entry prefixed by #rpath for those dylibs.
From this Cocoabuilder post:
In general, #loader_path is preferred over #executable_path, as it
allows embedded frameworks to work in both an executable and a bundle,
plugin, or sub-framework. The only downside is that #loader_path
requires 10.4 or newer. If you're on 10.5 or newer, #rpath is even
better than #loader_path.
As you mentioned you're not using Xcode, so it's a bit difficult. Here are options in my order of preference:
Switch to Xcode. Use frameworks. The SDL libraries are available as frameworks already, and I've seen more than a couple commercial games with a libsdl.framework inside the app bundle.
Use frameworks, but keep your Makefiles. Download the framework versions of your SDL libraries (or build them yourself), and link with them with the -framework linker flag. Distribute the frameworks with your app or don't, and tell your users to put them in either ~/Library/Frameworks or in /Library/Frameworks. I wouldn't bother with an installer for this.
Statically link against SDL. In the Makefile, you'll have to list the path of the static libraries rather than use the -l flag, e.g., you run "ld blah blah /opt/local/lib/libsdl.a". There is no way that I know to tell -l to prefer static over shared libraries, and believe me, I've looked.
Statically link the libraries.

Resources