Xcode 4 adding dylib - objective-c

I am trying to create and then add the dylib to a project.
I created it by using the "Cocoa-Library" template and setting the type to "Dynamic" (not sure if it should be dynamic or static...). Then I created a simple obj-c class called Test and wrote a method in it that prints out something to console.
I compiled and used the generated .dylib file and put it in another project. Now whenever I try to use it, I get this message on runtime"
dyld: Library not loaded: /usr/local/lib/TESTLib.dylib
Referenced from: /Users/***/Library/Developer/Xcode/DerivedData/TestingDYLIB-axmoocnxbwznoyerfogosumqufxc/Build/Products/Debug/TestingDYLIB.app/Contents/MacOS/TestingDYLIB
Reason: image not found
I also created a Copy File phase and set the destination to "Frameworks". I still get the same error.
What am I doing wrong?

The issue is not where Xcode is looking for the library at compile time, which is what Simon Whitaker's answer addresses.
The issue is that the application which uses the dylib cannot find it at runtime. When an application is built that uses a dynamic library, it copies the install_name of the dylib into the output binary.
Creating a copy files phase and copying the dylib to the Frameworks subdirectory of the app's bundle is the right thing do do.
However, you need to do an additional step. You need to compile the dynamic library with an install_name appropriate for a bundle app. By default, a dynamic library is created with an install_name of /usr/local/lib. The app can't find your library there because it doesn't exist. Even if you put the library there, your users certainly won't have it, so that would be the wrong solution.
The right solution is bundling the library with the app. To set the install name for the dynamic library, go into the dynamic library project and set the "Dynamic Library Install Name" option to: #executable_path/../Frameworks/libmydynamiclibrary.dylib

Xcode is looking in /usr/local/lib/ for the library. If the library is in another location, add that location to your Library Search Paths:
Select project file in Xcode 4
Select the target, then click the Build Settings tab
Make sure All is selected in the filter bar (not Basic)
Scroll down to the Search Paths section and you'll find Library Search Paths in there

Related

Cocoa Screensaver plugin with bundled custom frameworks

My app is partitioned into a number of frameworks.
Each framework has its Installation Directory set to #executable_path/../Frameworks, is linked and copied to the main executables Frameworks folder. All is working great.
Now some of the same frameworks are used in a separate screen saver executable.
The frameworks are linked, copied, present in the actual binary -
yet the screensaver module will fail to load with the following error:
Error loading /Users/someuser/Library/Screen Savers/MyScreenSaver.saver/Contents/MacOS/MyScreenSaver: dlopen(/Users/someuser/Library/Screen Savers/MyScreenSaver.saver/Contents/MacOS/MyScreenSaver, 265): Library not loaded: #executable_path/../Frameworks/BusinessBase.framework/Versions/A/BusinessBase
Referenced from: /Users/someuser/Library/Screen Savers/MyScreenSaver.saver/Contents/MacOS/MyScreenSaver
Reason: image not found
Looks like the screen saver (loaded as a plugin) cannot find the frameworks referenced by itself.
I've tried setting the screen savers Framework Search Path to both #loader_path/../Frameworks and #executable_path/../Frameworks.
No luck.
Any ideas what else to try..?
FWIW I've managed to fix this issue with some install_name_tool magic in a post build script:
The key was to change executable_path to loader_path and use the correct relative paths for the binary calling the respective framework.
For a screensaver plugin, #executable_path is the path to the ScreenSaverEngine executable that's loading your screensaver, or to System Preferences if it's running as a preview. It is not the path to your screensaver module! For that, you will need to use #loader_path.

How to use dylib file in application?

I have created lib.dylib dynamic library. I want to use that library in my application.
What are the Build setting and build phase settings are required?
Steps to use the library in objective-c.
so there are 2 ways...
1) if the Dyld is available at link time, then you just link against it. (in Xcode you add it to the link build phase of the target you are building.)
if using a framework: The headers will end up in the header search path so you can #import <framework/header.h> them.
2) if it isn't then you will need to open the dynamic library with dlopen, then you read in each function directly... this is much more of a specialty task, like dealing with a plug-in architecture.
there are some tricky thinks if you are supplying the dynamic lib then there are issues with the library install path being relative to the executable... but you will just have to tackle them if you hit them (start by googling #rpath)

How to add framework to xcode

I am new to Xcode and want to add and use framework which I have taken from internet but
when I add it to my products folder by right clicking on products and using add new files it
runs fine and when i use my project's project.app file on my mac or on any other mac it
gives me dyld error that the bundle image not find. And when I use bundle image in my
framework folder its give me ld error that bundle not found help please.
ld: framework not found SMS-Bundled
Command /Developer/usr/bin/clang failed with exit code 1
*updated
when i add my framework to framework folder now its giving me error at run time...
dyld: Library not loaded: #executable_path/../Frameworks/SMS-Bundled.framework/Versions/A/SMS-Bundled
Referenced from: /Users/usman/Library/Developer/Xcode/DerivedData/Serial_Tools-detoutxzbnjrngcuulrbgcasxmjs/Build/Products/Debug/Serial Tools.app/Contents/MacOS/Serial Tools
Reason: image not found
(In Finder)
Go to the folder where your custom framework is. copy the framework. Now go to your project's folder. Create a new folder called Frameworks, paste the custom framework inside this folder.
(In Xcode)
Drag the custom folder FROM finder to the Frameworks folder on the project explorer (where all the rest of the frameworks are)
Now select your project, go to Build Settings, scroll down to "Framework Search Paths" field, double click the value to open it, press the + to add a new path, write ./Frameworks as the new path.
From now on if you want to add other private/custom frameworks all you have to do is copy them into the created frameworks folder, and simply drag and drop it into the xcode frameworks folder. (You must drag it from the project framework folder in finder to the framework folder in xcode).
PD: You don't necessarily have to name this folder frameworks, it can be whatever, just make sure to change the Framework Search Paths accordingly.
In your project build setting, under "framework search paths" mention the path of the framework.
This will resolve your issue.

Is there any way to change the dynamic library search path in Xcode

Below is my scenario,
In my Application i had to make use of libopus library , i downloaded and install, compile --> install procedure is normal as its for any other open source library,
I linked libopus.a with my application, the way i did is , by default it will get installed in /usr/local/lib, so i drag from there and add it to my application,
Worked fine and no error on my machine,
On Another machine, i was expecting it to be run smoothly as i included this library statically, but its throwing error as
dyld: Library not loaded: /usr/local/lib/libopus.0.dylib
so i concluded, libopus.a somehow including libopus.0.dylib also dynamically,
Now i am able ot add a copy phase in my build setting , so it will get copied in ../Framework folder
if i do otool -L libpus.a then it shows following result
otool -L /usr/local/lib/libopus.a
Archive : /usr/local/lib/libopus.a
/usr/local/lib/libopus.a(bands.o):
/usr/local/lib/libopus.a(celt.o):
/usr/local/lib/libopus.a(cwrs.o):
/usr/local/lib/libopus.a(entcode.o):
/usr/local/lib/libopus.a(entdec.o):
/usr/local/lib/libopus.a(entenc.o):
/usr/local/lib/libopus.a(repacketizer.o):
It doesn't show as its depend upon the dylib library
Now my Question is
How to tell Application to look into this path first
I tried following option,
install_name_tool but it seems it will work on other machine , so the user need to run this script NOT DEVELOPER,
trying to set the some option in the xcode to set the RUNTIME Search path to locate that particular dylib but not getting succeed so far
install_name_tool is run by the developer during the build process, not by the user.
If you're building the library, you should use libtool(1) with the option -install_name #rpath; otherwise, you can use install_name_tool(1) with -id #rpath to do the same thing on the dylib. Then, when you're building your application, set the "Runpath search paths" to the path where you will install the library.
Apple has some good documentation on this in their Mach-O Programming Topics and Dynamic Library Programming Topics.

How to embed app with log4cocoa?

I'm having some trouble to embed my application with the log4cocoa framework.I've embed frameworks in my application before with no trouble, but I cannot fix this one.
First of all, this is my system out:
dyld: Library not loaded: #loader_path/Frameworks/Log4Cocoa.framework/Versions/A/Log4Cocoa
Referenced from: /Users/leandro/Documents/Projects/MLoggerApplication/build/Debug/MLoggerApplication.app/Contents/MacOS/MLoggerApplication
Reason: image not found
Well, I think done all necessary steps to get a framework working fine including the copy files phase and changed the installation directory over the build options to #executable_path/../Frameworks .
I hope problem clear enough to receive your help.
Thanks in advance.
Looks like your framework isn't being copied into your target. If a framework isn't part of the system (ie, you have to distribute it with your app), you need to not only link your executable against the framework but to copy it into your app's ./Frameworks folder.
To do this, add a Copy Files build phase, select "Frameworks" as the build phase's destination, then drag the framework (from your Frameworks folder in your Xcode project) under that Copy Files build phase you just created. If you already have a Copy Files build phase for Frameworks, then just use it instead of creating a new one.
Firstly, i mean, Joshua Nozzi is completely right about how is to embed an app with a framework!
But log4cocoa as a little different and could only realize that because it is an opensource code able for download at http://sourceforge.net/projects/log4cocoa/.
The framework could be used with this configuration by adding a "Copy Files build phase, but instead "Frameworks", select "Products Directory" as the build phase's destination, then drag the framework to that "Copy Files build phase.
The difference among this, and the other frameworks relies in this build variable: installation directory.It has as default value: "/Frameworks .
This variable can be accessed by right clicking on the log4cocoa(first item in the targets list), then select "Get Info" and finally "build".
To use it as "normal" framework rebuild it after you have edited the "installation directory" value to "#executable_path/../Frameworks" or if you are going to embed a framework with it, you would prefer "#loader_path/../Frameworks"