1

I have written a program that crucially depends on OpenCV. I have compiled OpenCV from the latest stable version and would now like to distribute this program, to ensure that people do not need to compile OpenCV by themselves. The program itself is compiled using g++.

I tried a number of things to resolve this issue:

  1. compiling OpenCV as static libraries works, but I cannot statically link my program to these libraries as some libraries in OS X cannot be statically linked; I found this information here: Mixed static and dynamic link on Mac OS

  2. I tried to move to XCode, where I used it as a command line project. I set the search path as well as the installation location to @rpath and added a build phase to copy the files to Executables. I verified with otool whether the compiled file has the correct links but it still fails on a clean machine (one that does not have the OpenCV libraries) with a "Library not found @rpath/libopencv..." error. (Yes, all macs use Lion, so @rpath should work). This answer was found here: Xcode keeps searching dylib at wrong path

the result I get from runnig otool -L on both the compiled file and the library is @rpath/libopencv_core.2.4.dylib (compatibility version 2.4.0, current version 2.4.0) /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)

So ... what am I doing wrong? And how can I distribute these libraries together with my program?

Community
  • 1
  • 1
kvaruni
  • 832
  • 1
  • 10
  • 20

2 Answers2

2

You should use Frameworks (SO question on frameworks). Combine all the stuff your app uses in one folder and then link to the framework in your XCode project.

Community
  • 1
  • 1
Viktor Latypov
  • 14,289
  • 3
  • 40
  • 55
  • This does not appear to be an answer. This is a command line utility that will, mainly, be used from the command line. As such, it is also very easy to compile on other platforms such as *nix or Windows. I would agree with you if this was a full-fledged app but, well, it isn't one, just a simple command line tool. – kvaruni May 30 '12 at 13:55
  • Not much to argue. Standard "dll hell". – Viktor Latypov May 30 '12 at 19:46
1

I've had to do that recently to run JavaCV in an applet. This command should get the job done:

BADPATH=/opt/local/lib  # in the case of MacPorts, change as necessary
for f in libopencv*2.4.dylib; do install_name_tool $f -id @rpath/$f \
    -add_rpath /opt/local/lib/ -add_rpath /usr/local/lib/ -add_rpath @loader_path/. \
    -change $BADPATH/libopencv_core.2.4.dylib @rpath/libopencv_core.2.4.dylib \
    -change $BADPATH/libopencv_calib3d.2.4.dylib @rpath/libopencv_calib3d.2.4.dylib \
    -change $BADPATH/libopencv_features2d.2.4.dylib @rpath/libopencv_features2d.2.4.dylib \
    -change $BADPATH/libopencv_flann.2.4.dylib @rpath/libopencv_flann.2.4.dylib \
    -change $BADPATH/libopencv_gpu.2.4.dylib @rpath/libopencv_gpu.2.4.dylib \
    -change $BADPATH/libopencv_highgui.2.4.dylib @rpath/libopencv_highgui.2.4.dylib \
    -change $BADPATH/libopencv_imgproc.2.4.dylib @rpath/libopencv_imgproc.2.4.dylib \
    -change $BADPATH/libopencv_legacy.2.4.dylib @rpath/libopencv_legacy.2.4.dylib \
    -change $BADPATH/libopencv_ml.2.4.dylib @rpath/libopencv_ml.2.4.dylib \
    -change $BADPATH/libopencv_nonfree.2.4.dylib @rpath/libopencv_nonfree.2.4.dylib \
    -change $BADPATH/libopencv_objdetect.2.4.dylib @rpath/libopencv_objdetect.2.4.dylib \
    -change $BADPATH/libopencv_photo.2.4.dylib @rpath/libopencv_photo.2.4.dylib \
    -change $BADPATH/libopencv_video.2.4.dylib @rpath/libopencv_video.2.4.dylib; done

And relink your software with those and the desired "-rpath" option.

Samuel Audet
  • 4,964
  • 1
  • 26
  • 33
  • This is basically what XCode does. Nevertheless, I tried those commands to manually set the library links. Yet I still end up with an "@rpath/libopencv_core.2.4.0.dylib not loaded" error. So clearly it is looking for it in @rpath, but somehow it still fails to find these library files. Thanks though! – kvaruni May 30 '12 at 14:39
  • What "-rpath" do you use when linking your application? – Samuel Audet May 31 '12 at 04:07
  • Strange... It works here. Check out [the FaceApplet demo](http://code.google.com/p/javacv/wiki/HowToMakeAnApplet). – Samuel Audet May 31 '12 at 07:01
  • I am also surprised that it doesn't work, but I already tested it on two different machines to ensure that it is not some other problem. Thanks for the link, I will look into it later today. – kvaruni May 31 '12 at 07:23
  • And forgot to mention, but you can unzip the JAR file and inspect the `.dylibs` files with `otool -L` or whatever to figure out how they differ... – Samuel Audet May 31 '12 at 09:59
  • How exactly do you change the software to the desired rpaths? Just as a verification, since I cannot see any difference between the dylibs in the jar file and my own dylibs. – kvaruni May 31 '12 at 13:08
  • Just like you, I relink with `-rpath @loader_path/.` as shown here http://code.google.com/p/javacpp/source/browse/javacpp/src/main/resources/com/googlecode/javacpp/properties/macosx-x86_64.properties#8 – Samuel Audet Jun 01 '12 at 01:57
  • With a lot of help from Samuel, the problem is finally resolved! To fully work, the script required me to change "for f in libopencv*2.4.dylib" to "for f in libopencv*". Also, and this was quite surprising, having multiple -add_rpath commands in a single statement resulting in a "load command" error when checking the dylib with otool -L. You can avoid these problems by adding the rpaths one by one, which gives no errors _but also doesn't work_; for some reason, which as of yet is not known, only the dylibs _with_ the error work perfectly. So ignore the error and be happy! – kvaruni Jun 09 '12 at 07:15