Search code examples
c++macosqtopencvmacdeployqt

qt5 deployment with opencv, how to fix the lib install paths?


A similar problem have been partially addressed here dyld: Library not loaded: lib/libopencv_core.3.0.dylib Reason: image not found that lead to a solution there that do not work for me.

I use Qt 5, with openCV 3 with Mac OS X 10.10.5. When I use macdeployqt, this process does not have the proper paths for the openCV .dylib files. It complains with:

ERROR: no file at "/lib/libopencv_core.3.0.dylib"
ERROR: no file at "/lib/libopencv_highgui.3.0.dylib"
ERROR: no file at "/lib/libopencv_imgproc.3.0.dylib"

which relates to wrong file paths, given as relative but interpreted as absolute, according to:

$ otool -L myApp.app/Contents/MacOS/myApp 
myApp.app/Contents/MacOS/myApp:

(...)

    lib/libopencv_core.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
    lib/libopencv_highgui.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
    lib/libopencv_imgproc.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)

(...)

And of course, the app crash when it runs in a different computer, complaining about the missing libraries above.

How can I fix this given that the solution mentioned above did not work? Or how can I "better" apply the solution above in this case? (I may not have adapted them properly).

I tried 3 different installation of opencv 3: CMake, homebrew, and macports. The problem remained identical.


Solution

  • A kind soul at work helped me to better understand how I could adapt the above solutions that use the install_name_tool. Because the above solutions did not work apply to my case, here is a script with comments that describe each step in detail. This script assumes that you have used macdeployedqt already, and that you got a .app file. This fix works with opencv 3 when linking the opencv_core, opencv_highgui, and opencv_imgproc libraries. For your own case, you need to change the LIB_DIR and APP_DIR to (resp.) the directory where your opencv library files (.dylib) are, and the path to your .app package (here my app is called Qtfits_openmp). Of course, there could be a more compact script to make out of this, but I hope the detailed steps will help anyone to adapt to his/her own case.

    #! /bin/bash
    
    LIB_DIR=~/Dev/opencv3_tbb_opencl/lib
    APP_DIR=~/Dev/build-Qtfits_openmp-clang_omp-Release/Qtfits_openmp.app
    # This script supposes here that you are in the parent directory of the app.
    
    # check to what libs your app is "explicitly" linked to with otool -L $APP_DIR/Contents/MacOS/Qtfits_openmp
    # If originally linking with LIBS += -lopencv_core -lopencv_highgui -lopencv_imgproc, you'd need to copy them in the .app with their dependencies.
    # However, opencv has the path of symbolic links, ending with 3.0. , so we need to copy the actual files, i.e., with the whole version number 3.0.0. 
    cp $LIB_DIR/libopencv_core.3.0.0.dylib $APP_DIR/Contents/Frameworks/libopencv_core.3.0.0.dylib
    cp $LIB_DIR/libopencv_highgui.3.0.0.dylib $APP_DIR/Contents/Frameworks/libopencv_highgui.3.0.0.dylib
    cp $LIB_DIR/libopencv_imgproc.3.0.0.dylib $APP_DIR/Contents/Frameworks/libopencv_imgproc.3.0.0.dylib
    # Extra dependencies exist: otool -L libopencv_* will show you all the dependencies that you need to copy.
    # Here we will also need to add imgcodecs and videoio to the .app
    cp $LIB_DIR/libopencv_imgcodecs.3.0.0.dylib $APP_DIR/Contents/Frameworks/libopencv_imgcodecs.3.0.0.dylib
    cp $LIB_DIR/libopencv_videoio.3.0.0.dylib $APP_DIR/Contents/Frameworks/libopencv_videoio.3.0.0.dylib
    
    
    # With otool -L $APP_DIR/Contents/MacOS/yourApp , look at the .lib files with a wrong path. With the following result:
    #   lib/libopencv_core.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
    #   lib/libopencv_highgui.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
    #   lib/libopencv_imgproc.3.0.dylib (compatibility version 3.0.0, current version 3.0.0)
    
    # we need to fix the 3 libraries core, highgui and imgproc which are given here with an incorrect relative path. 
    # Note that again, opencv kept the basename of the symbolic links (ending with 3.0.dylib), not the basename of the actual files (ending with 3.0.0.dylib)
    # So we have to keep things consistent with what we did above. 
    
    install_name_tool -change lib/libopencv_core.3.0.dylib @executable_path/../Frameworks/libopencv_core.3.0.0.dylib $APP_DIR/Contents/MacOS/Qtfits_openmp
    install_name_tool -change lib/libopencv_highgui.3.0.dylib @executable_path/../Frameworks/libopencv_highgui.3.0.0.dylib $APP_DIR/Contents/MacOS/Qtfits_openmp
    install_name_tool -change lib/libopencv_imgproc.3.0.dylib @executable_path/../Frameworks/libopencv_imgproc.3.0.0.dylib $APP_DIR/Contents/MacOS/Qtfits_openmp
    
    # Now we need to fix the path to all the dependencies of each library file.
    cd $APP_DIR/Contents/Frameworks
    
    # Change the IDs
    for i in libopencv*.dylib; do install_name_tool -id @executable_path/../Frameworks/$i $i; done
    
    # Again, with otool -L libopencv_* , you will see that you need to change their paths so that your copied libraries are pointed to within the app.
    # for each opencv lib that is not properly referenced, change it from the absolute or wrong-relative path to @executable_path/../Frameworks/
    
    # fix libopencv_highgui
    install_name_tool -change $LIB_DIR/libopencv_imgcodecs.3.0.dylib @executable_path/../Frameworks/libopencv_imgcodecs.3.0.0.dylib libopencv_highgui.3.0.0.dylib
    install_name_tool -change $LIB_DIR/libopencv_core.3.0.dylib @executable_path/../Frameworks/libopencv_core.3.0.0.dylib libopencv_highgui.3.0.0.dylib
    install_name_tool -change $LIB_DIR/libopencv_imgproc.3.0.dylib @executable_path/../Frameworks/libopencv_imgproc.3.0.0.dylib libopencv_highgui.3.0.0.dylib
    install_name_tool -change $LIB_DIR/libopencv_videoio.3.0.dylib @executable_path/../Frameworks/libopencv_videoio.3.0.0.dylib libopencv_highgui.3.0.0.dylib
    
    # fix libopencv_imgproc 
    install_name_tool -change $LIB_DIR/libopencv_core.3.0.dylib @executable_path/../Frameworks/libopencv_core.3.0.0.dylib libopencv_imgproc.3.0.0.dylib
    
    # fix libopencv_videoi
    install_name_tool -change $LIB_DIR/libopencv_imgcodecs.3.0.dylib @executable_path/../Frameworks/libopencv_imgcodecs.3.0.0.dylib libopencv_videoio.3.0.0.dylib
    install_name_tool -change $LIB_DIR/libopencv_imgproc.3.0.dylib @executable_path/../Frameworks/libopencv_imgproc.3.0.0.dylib libopencv_videoio.3.0.0.dylib
    install_name_tool -change $LIB_DIR/libopencv_core.3.0.dylib @executable_path/../Frameworks/libopencv_core.3.0.0.dylib libopencv_videoio.3.0.0.dylib
    
    # fix libopencv_imgcodecs
    install_name_tool -change $LIB_DIR/libopencv_imgproc.3.0.dylib @executable_path/../Frameworks/libopencv_imgproc.3.0.0.dylib libopencv_imgcodecs.3.0.0.dylib
    install_name_tool -change $LIB_DIR/libopencv_core.3.0.dylib @executable_path/../Frameworks/libopencv_core.3.0.0.dylib libopencv_imgcodecs.3.0.0.dylib