2

I've written a little C program which uses libusb. Now I want to distribute this program to "normal" (not dev) Mac OS X computers. But when I ported the compiled file to a test machine I got the following error:

dyld: Library not loaded: /opt/local/lib/libusb-0.1.4.dylib
  Referenced from: /Users/kitty/myprogram
  Reason: image not found
Trace/BPT trap: 5

When I copy the files (works only with all the files)

/opt/local/lib/libusb-0.1.4.dylib   /opt/local/lib/libusb-1.0.a     
/opt/local/lib/libusb.a
/opt/local/lib/libusb-1.0.0.dylib   /opt/local/lib/libusb-1.0.dylib     
/opt/local/lib/libusb.dylib

from my machine to the target machine the program works flawlessly.

But I really want to create or compile everything into a single executable. How is this possible?

Using -static while compiling does not work since not all libraries can be compiled into the final app statically (see this SO question here).

So how can I make a single neat little application file?

1 Answer 1

2

You can convert a static library to a dynamic library, but I'm not aware of a way to do the reverse as you want it.

If you're building an app with a bundle, you need to put the library you want to distribute inside your bundle, in the Frameworks directory, and link against that.

If you are not building a bundle-based app, just a single binary, you may need to provide instructions for your users on how to install the library on their system (e.g. via Homebrew).

Here's how you do it for bundle-based apps:

Apple has a document about run-path dependent libraries but doesn't actually explain how to set this up for a newbie.

Here's how it should work:

  • Add the libusb.dylib you want to use to your project.
  • It should automatically get added to your "Link Binary with Libraries" phase in your project's "Build Phases". If not, add it here.
  • Add a new "Copy Files" build phase.
    • In the "Destination" drop-down box, select "Frameworks". This is the Frameworks directory in your app's final bundle.
    • Then press the "+" icon in that copy build phase and add your library.
  • If you had any manual linking options like -L/usr/local/lib and -lusb, remove them.
  • Clean and build.

When you now look into your app bundle, you'll see that the library is copied to <bundle_path>/Contents/Frameworks/. You can now start the app from wherever you want, the dynamic link loader knows it needs to look at <path_to_binary>/../Frameworks/ to find your library.

But: you may need to rebuild your libusb to have the install_name set to @rpath/../Frameworks/libusb.dylib or use the install_name_tool CLI tool fix that path for your copy of libusb.dylib that you added to your project.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.