How do I reference a dylib? - c++

I have an application written in platform-independent C++ which has been primarily developed on Windows. I'm now trying to get it up and running on a Mac but I seem to be lost in how to link to the Mac version of a third-party library I'm using. I added the library's include and lib folders to header and library search paths respectively and it compiles/links but upon running dies with the following:
dyld: Library not loaded: #executable_path/../Frameworks/libsfml-system-d.2.dylib
Referenced from: /Users/jdoe/Library/Developer/Xcode/DerivedData/Foobar-fonhiddwdwvgqygcegiffqkontxi/Build/Products/Debug/Foobar.app/Contents/MacOS/Foobar
Reason: image not found
I can get it to run by putting the dylibs in /usr/lib but I don't think this is a good idea for distribution. How can I include the dylib inside my app bundle?

Add a copy-files build phase that copies the dylib into the Frameworks folder inside the app bundle. (When you Get Info on a copy files build phase, Frameworks is one of the destination choices.)

Related

dyld: Library not loaded: libNiTE2.dylib....Reason: image not found

The library I am trying to use is NiTE2, I have successfully include & linked OPENNI2 and the libfreenect driver. Here is the error message:
dyld: Library not loaded: libNiTE2.dylib
Referenced from: /Users/yangwang/Documents/cinder_projects/basic/xcode/build/Debug/basic.app/Contents/MacOS/basic
Reason: image not found
NOTE:
There are quite a few similar questions regarding the same error messages. but none of them helped my case.
A few things I already tried but not working:
I have tried adding the dylib file into Embedded Binaries like this one suggested: dyld: Library not loaded, Reason: image not found
I also made sure I have included the correct search path for the lib, and properly set it up in Library Search Path, like this one suggested:
Eclipse on Mac dyld: Library not loaded: Image not found
All openni2 and libfreenect related dylibs are being found with no problem.
Here are images of my settings:
project hierarchy view
library search path
XCode v: 9.3.1
Mac os v: 10.13.4
----UPDATE-----
I added some Copy Files settings into Build Phase, screenshot here, including everything inside my include and lib folder. This didn't solve my problem ( yet ). Then, after build, I went myapp.app/Contents/MacOS and used ./myapp to run the build. And it magically runs and found all libraries! I don't quite understand why though, hope someone can explain.
libNite2.dylib is linked from the same folder as the basic executable.
You could use #executable_path, to point to the dylib: this way, double clicking on the file should work.
It might be possible to change it using installname_tool:
cd /Users/yangwang/Documents/cinder_projects/basic/xcode/build/Debug/basic.app/Contents/MacOS/
then
install_name_tool -change libNiTE2.dylib #executable_path/libNiTE2.dylib basic.
Fingers crossed this will work when you double click the .app file.
You may want to add this as an extra step in Xcode post compile to avoid having to type this every time you change something in code. Something along these lines: bare in mind the screenshot is actually from an OpenFrameworks, not Cinder project, but you should have a similar view in XCode (some variables might be different).
Another side note: based on your screenshot it looks like OpenNI is linked against from /usr/local/opt/openni2(guessing Homebrew symlink). This will work on your machine, but not on another mac unless you install OpenNI2 via homebrew on it as well (otherwise, if the OpenNI libs are copied to the executable you can consider setting executable relative paths for these too).

Xcode 8 - Link dylib relative to executable runtime path

I have a fairly large project in Xcode 8.2, which consists of one big dynamic library libarc.dylib and several other executable targets. One of these targets runs the unit and integration tests on my library.
I have set the Xcode build location to be relative to my project directory, instead of the default Xcode derived data location.
Building and running my project's targets works fine from within Xcode, but when I run my tests executable, from the build product directory, via terminal, I get the following error.
dyld: Library not loaded: /usr/local/lib/libarc.dylib
Referenced from: /Users/<username>/programming/<project>/Build/Products/Debug/.Tests
Reason: image not found
[1] 44968 abort ./Tests
So obviously the dynamic library is not loading. Upon checking the local/lib path, I notice that my library is not installed.
Running otool -L Tests gives me
/usr/local/lib/libarc.dylib (compatibility version 1.0.0, current version 1.0.0)
This library is project-specific, and I would like to load it from my project Build location. Preferably, at some stage, everything will be bundled into an .app.
How can I set the dylib loading path, for the Tests target, to point to the libarc.dylib in its run path?
I have found some information, that suggests Embedding Binaries into my target, but as of Xcode 8.2, I can not find this section under the General tab, for my target.
Beyond just converting my library to a static library, what other options do I have? I don't think its appropriate to have the library installed system wide in the release. Would a static library be more appropriate, given my requirements. I'll also add, the library consists of a game engine, so performance is key.
As a final note, many of the engine core systems are implemented as singletons.

Using Ogre library locally for a project

what I would like to do is to have an application (I am currently working off the sample framework app) and include any ogre library files with it, as opposed to have it installed for the whole system. This way I can easily port the application onto other computers once built.
I am on Mac OS 10.9. I built Ogre by first running the CMake app to configure the Xcode project, then opening the created Xcode project and building the Install and SampleBrowser congifurations. A directory sdk/lib was created in the Ogre directory. This contains directories debug, OGRE and pkgconfig. The OGRE directory has all the samples .dylib files. What I do not see is the main ogre library file.
The contents of the file lib/pkgconfig/Ogre.pc suggest that there should be a library file called OgreMain in the lib directory:
Libs: -L${libdir} -lOgreMain -lpthread
As far as I understand it, I need this library file to be a part of my project. I could then link the sdk/include for all the Ogre's header files. I am confused about how to make this work. Could anyone please help?
Sounds like this is Ogre 1.8. In that case the libraries and frameworks need to be installed in your application bundle. Inside MyApp.app/Contents you will need folders named Components, Plugins and Frameworks. Ogre.framework goes in frameworks, component dylibs go into Components, plugin dylibs go in Plugins.
I actually found a great tutorial that worked straight away for me here: http://will.thimbleby.net/ogre3d-tutorial/
This is for Ogre 1.8, the only difference when using Ogre1.9 is that you don't use RenderSystem_GL.dylib but RenderSystem_GL.framework (found at the same place as Ogre.framework) and you deal with it in the same manner in terms of your project setup as with Ogre.framework.

How do I build and use a dynamic library on Mac OS X?

I have a very simple question that I've been trying to figure out for the last 6 hours or so. I want to simply build a dynamic library on Mac OS X, and then build an application using that library. I've created the .dylib and compiled the test application with it, but when I run the application I get:
Joes-Mac-Pro:Desktop Joe$ ./test
dyld: Library not loaded: ./lib/simple_library.dylib
Referenced from: /Users/Joe/Desktop/./test
Reason: image not found
Trace/BPT trap: 5
I've tried making a lib folder in the executable directory and putting the dylib inside, same error. I've tried putting the dylib in the executable path itself, same error. I've tried using install_name_tool to change the path to the dylib in the executable, nothing changes, same error. I've tried building the test application with -headerpad_max_install_names and then using install_name_tool to change the path. Still nothing changes. Same error.
Is what I'm trying to do not possible with the Mac operating system? I'm new to this platform, and am used to things like this working without a hitch on Windows and GNU/Linux. Also, I'm trying to do all this with the command line. I would very much prefer to avoid XCode.
Edit: Oops, I derped. Turns out I made a typo in my install_name_tool arguments. It's working fine now.
install_name_tool is the right tool.
Try otool your_binary to see which dylib are missing.
Also be sure your binary and the linked library are build for the same architectures.
You'll need to ensure that DYLD_LIBRARY_PATH includes the directory where your library resides.
DYLD_LIBRARY_PATH
This is a colon separated list of directories that contain libraries. The dynamic linker searches these directo-
ries before it searches the default locations for libraries. It allows you to test new versions of existing
libraries.
For each library that a program uses, the dynamic linker looks for it in each directory in DYLD_LIBRARY_PATH in
turn. If it still can't find the library, it then searches DYLD_FALLBACK_FRAMEWORK_PATH and DYLD_FALL-
BACK_LIBRARY_PATH in turn.
Use the -L option to otool(1). to discover the frameworks and shared libraries that the executable is linked
against.
The various details of dynamic linking are documented in the dyld man page.

How can I get Xcode to link and debug an app with Boost Filesystem?

TL;DR
Objective-C app linked with static library that dynamic links Boost Filesystem. App can be run from output directory using Terminal, but trying to run from Xcode debugger or Finder gives error dyld: Library not loaded: libboost_filesystem.dylib <snip> Reason: image not found.
Problem
In my Xcode project I have a structure that looks like this:
MainProject (Objective-C)
- static_lib_that_uses_filesystem (C++)
To get everything to link, I added libboost_system and libboost_filesystem dylibs to the "Link Binary with Libraries" build phase in MainProject.
When I try to run the app from either Xcode or Finder I get:
sharedlibrary apply-load-rules all
warning: Unable to read symbols for libboost_filesystem.dylib (file not found).
warning: Unable to read symbols from "libboost_filesystem.dylib" (not yet mapped into memory).
warning: Unable to read symbols for libboost_system.dylib (file not found).
warning: Unable to read symbols from "libboost_system.dylib" (not yet mapped into memory).
[Switching to process 43957 thread 0x0]
dyld: Library not loaded: libboost_filesystem.dylib
Referenced from: /Users/ssteele/Library/Developer/Xcode/DerivedData/MainProject-dqrhyuarllykslftblocjdzxlran/Build/Products/Debug/MainProject.app/Contents/MacOS/MainProject
Reason: image not found
I added a build stage to copy the dylibs to the Frameworks directory in the bundle, this doesn't help. I changed this to copy them to the Executables directory which also didn't help.
Having them in the Executables directory does allow me to run the app from Terminal.
How can I get the app to find the dylibs when run from Finder/Xcode?
Background Info
I'm using Xcode 4.2 on Lion and currently targeting Lion only. I built my shared libraries for filesystem like this:
./b2 threading=multi macosx-version=10.7 --with-filesystem stage
This creates libboost_system.dylib, libboost_filesystem.dylib, and also .a equivalents in the stage/lib directory, I'm referencing them in the project directly from there.
Dynamic libs (dylibs) on OSX bake in the path that they should be loaded from. For example...
/usr/lib/some_awesome.dylib.
When you link to a dylib, the linker embeds this path in your executable as the place to look for it at runtime. This is fine and easy with installed libs, but for relative path linking it's more complicated.
When you build the boost libs, they just get their names embedded rather than a full or relative path (i.e. libboost_system.dylib rather than /usr/lib/libboost_filesystem.dylib). You should be able to change this with the dll-path option, but that seems broken currently.
To fix your problem you either need to get the correct path relative to your application embedded (e.g. #executable_path/libwhatever.dylib) into the dylibs somehow, which would probably require the bjam dll-path option to work, or instead you can fix your executable to look in a different location.
To do this, use something like the following as a script step in your build:
install_name_tool -change libboost_filesystem.dylib #executable_path/libboost_filesystem.dylib$BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH
Note that if you have multiple dylibs that reference each other with broken paths, you'll need to fix the paths between them too, e.g.
install_name_tool -change libboost_system.dylib #executable_path/libboost_system.dylib$BUILT_PRODUCTS_DIR/$EXECUTABLE_FOLDER_PATH/libboost_filesystem.dylib
The following is a good article on this: Creating working dylibs
The issue is that boost needs to be installed e.g. b2 ..... install. This copies the libraries and headers into /usr/local/lib and /usr/local/include.
OSX dynamic libraries only run from the directory that they are built for.
You can change the install directory by using the -prefix argument to boost build. However the libraries would still need to be in the same directory for all users.
There should be a way of building boost as a framework and/or embedding #executable_path in the library.
An alternative is to use boost's static libraries - build the static only or delete the dynamic ones, Xcode looks for dynamic before static. If using static then the path to the libraries does not matter at run time as all the code is now in the executable.
I think you need to add the path to the directory where you saved libboost_filesystem.a in the "library search paths"
Click on your project profile -> build settings -> expand "Search path" -> "library search paths"