4

I have a project that includes a prebuilt version of opencv in a subdirectory. For example:

MyProject
* CMakeLists.txt
* src
* third_party
** CMakeLists.txt
** opencv
**** include
**** lib

I would like to link against the version of opencv located in the third_party directory. My question is, how do I inform CMake to link to the prebuilt dylib files in lib, and include the headers in the relevant opencv directory?

cmake_minimum_required(VERSION 2.8.9)
project (myproject)

include_directories(${CMAKE_SOURCE_DIR}/third_party/opencv/include)
link_directories(${CMAKE_SOURCE_DIR}/third_party/opencv/lib)

file(GLOB SOURCES "*.cpp")

add_executable(myproject ${SOURCES})
target_link_libraries(myproject opencv_calib3d opencv_contrib opencv_core opencv_highgui opencv_features2d opencv_highgui opencv_imgproc)
MM.
  • 4,224
  • 5
  • 37
  • 74
  • If you use `find_package(OpenCV)`, then `set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/third_party/opencv)` before it. Alternatively you can use direct paths: `include_directories(${CMAKE_SOURCE_DIR}/third_party/opencv/include)` and corresponded `link_directories(${CMAKE_SOURCE_DIR}/third_party/opencv/lib)` call. What is the problem with these standard commands? – Tsyvarev Oct 06 '15 at 22:15
  • @Tsyvarev I have taken your suggestions and applied them (see ammended question description). Unfortunately I still get a linker error (ld: symbol(s) not found for architecture x86_64) – MM. Oct 06 '15 at 22:40
  • Plesase, add linker's error message into your question. Do you have another OpenCV library, installed into default path? It looks strange that linker has found library files, but hasn't found symbols in it. – Tsyvarev Oct 07 '15 at 06:54
  • The error message is simply a symbols not found message, indicating that I am not linking to the library – MM. Oct 09 '15 at 18:41
  • "Symbol(s) not found" message indicates that all requested (in `target_link_libraries()`) **libraries are found**, but **none of them defines given symbol**. BTW, this error can be resulted from incorrect symbol name, used by the code. – Tsyvarev Oct 09 '15 at 18:51
  • My apologies, the error I actually get is `ld: library not found for -l` – MM. Oct 09 '15 at 19:56
  • Does this library file exist under `${CMAKE_SOURCE_DIR}/third_party/opencv/lib`? (BTW, what's a reason to hide actual name of the **free** library?? Knowing this name sometimes may help in resolving resason of the problem.) – Tsyvarev Oct 09 '15 at 20:01
  • No reason for hiding the name other than to avoid enumerating all of the libraries. One example is libflann.dylib. In this example my cmake file would contain: `link_directories(${CMAKE_SOURCE_DIR}/third_party/prebuilt/libs) target_link_libraries(myproject flann)`. The error is `ld: library not found for -lflann` – MM. Oct 09 '15 at 20:09
  • How `flann` library is related with openCV? – Tsyvarev Oct 09 '15 at 20:59

1 Answers1

8

I've given your example a try with CMake 3.3.2 on OS X 10.11 having XCode 7.0.1.

Using the link_directories() and target_link_libraries() approach suggested by @Tsyvarev seems to work without raising any linker warnings or errors (it finds the .dylib libraries I placed in the third_party directory).

Just a view hints, that hopefully could get you a start why it's not working on your Mac.

  • With your code I get the following command line linker file (inside CMake's binary output directory):

    CMakeFiles/myproject.dir/src/link.txt

    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++    
    -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk 
    -Wl,-search_paths_first 
    -Wl,-headerpad_max_install_names  
    CMakeFiles/myproject.dir/src/main.cpp.o  -o myproject  
    -L[...CMAKE_SOURCE_DIR...]/third_party/opencv/lib  
    -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_highgui -lopencv_features2d -lopencv_highgui -lopencv_imgproc -lopencv_features2d -lopencv_imgproc 
    -Wl,-rpath,[...CMAKE_SOURCE_DIR...]/third_party/opencv/lib 
    
  • You can try to give full library paths, because those are additionally checked by CMake itself and it gets more obvious what I link against. Here is a modified version of your example:

    CMakeLists.txt

    cmake_minimum_required(VERSION 2.8.9)
    project (myproject)
    
    include_directories(${CMAKE_SOURCE_DIR}/third_party/opencv/include)
    
    file(GLOB SOURCES "src/*.cpp")
    file(GLOB LIBRARIES "third_party/opencv/lib/*.dylib")
    message("LIBRARIES = ${LIBRARIES}")
    
    add_executable(myproject ${SOURCES})
    target_link_libraries(myproject ${LIBRARIES})  
    

    With this CMake just adds fully qualified paths (relative to my binary output directory) into the linker file. The -L and -l options are gone and you get "lines" like:

    ../third_party/opencv/lib/libopencv_calib3d.dylib 
    

Additional Q/A References

Community
  • 1
  • 1
Florian
  • 39,996
  • 9
  • 133
  • 149