Search code examples
c++opencvcmaketarget

Using OpenCV's CMake module targets instead of including all libraries directly?


Problem: I have a project which uses OpenCV. I'm able to switch to what ever the latest version is if need be. My project uses CMake. I currently integrate opencv like so:

# OPENCV package
find_package(OpenCV)
add_library(opencv INTERFACE)
target_include_directories(opencv
        INTERFACE
        ${OpenCV_INCLUDE_DIRS})
target_link_libraries(opencv
        INTERFACE
        ${OpenCV_LIBS})

add_executable(opencv_example example.cpp)

target_link_libraries(opencv_example 
    PRIVATE 
        opencv
)

I cannot find examples of OpenCV using explicit module dependency targets. In order to not cruff up global includes unessessarily or leave naked variables laying around. I create an interface target for OpenCV and use this interface target instead of doing what OpenCV CMake example recommends:

# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)

# Declare the executable target built from your sources
add_executable(opencv_example example.cpp)

# Link your application with OpenCV libraries
target_link_libraries(opencv_example ${OpenCV_LIBS})

My question is it possible to just use OpenCV's module targets instead of having to bringing the whole kitchen sink along?

example (see module list here):

...

add_executable(opencv_example example.cpp)

target_link_libraries(opencv_example 
    PRIVATE
        opencv::core 
        opencv::video
        opencv::imgproc
)

thus I only get dependencies required for the modules I actually use. I looked through the OpenCV repository, but it is full of custom cmake macros and functions and It is difficult to see where a target is declared, let alone if it can be accessed from find_package.


Solution

  • While opencv::module doesn't work, if you use find_package, starting from at most OpenCV3.2 (it may have been available before) you can use targets like opencv_module for example with:

    find_package(OpenCV REQUIRED COMPONENTS core imgproc video)
    
    add_executable(opencv_example example.cpp)
    
    target_link_libraries(opencv_example 
        PRIVATE
            opencv_core 
            opencv_video
            opencv_imgproc
    )
    

    I found out these targets were exported here:https://github.com/opencv/opencv/issues/8028#issuecomment-273419374