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?

Community
  • 1
  • 1
mythbu
  • 786
  • 1
  • 7
  • 20

1 Answers1

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.

Community
  • 1
  • 1
DarkDust
  • 90,870
  • 19
  • 190
  • 224