0

I am trying to import OpenCV into my CMakeLists.txt file. Here's the code I'm using:

find_package(OpenCV 3 REQUIRED) add_library(opencv SHARED IMPORTED) set_target_properties(opencv PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${OpenCV_INCLUDE_DIRS}" IMPORTED_LOCATION "${OpenCV_LIBS}") 

Later in the cmake file, I create a target that links to opencv, like so:

add_executable(sample "src/sample.cpp") target_link_libraries(sample opencv) 

However, this fails to build. I happen to be using Ninja, but it fails with Make too.

Here is the error I am getting when I try to build with Ninja:

ninja: error: stat(opencv_viz;opencv_videostab;opencv_videoio;opencv_video;opencv_superres;opencv_stitching;opencv_shape;opencv_photo;opencv_objdetect;opencv_ml;opencv_imgproc;opencv_imgcodecs;opencv_highgui;opencv_flann;opencv_features2d;opencv_cudev;opencv_cudawarping;opencv_cudastereo;opencv_cudaoptflow;opencv_cudaobjdetect;opencv_cudalegacy;opencv_cudaimgproc;opencv_cudafilters;opencv_cudafeatures2d;opencv_cudacodec;opencv_cudabgsegm;opencv_cudaarithm;opencv_core;opencv_calib3d): File name too long 

Clearly the value of ${OpenCV_LIBS} is a list of values, and that list is getting passed as one long string instead of being split up and linked as individual args to the compiler.

I have verified that other libraries fail too if the IMPORTED_LOCATION is a list of values (separated by semi-colon) instead of just being a single path to a library.

What am I doing wrong?

1
  • I am using cmake version 3.5.2 FYI Commented Feb 11, 2017 at 17:43

2 Answers 2

1

The problem is that a shared imported library will be looking for one file to link against.

To solve your problem, I would use an interface library instead and set its dependencies:

find_package(OpenCV 3 REQUIRED) add_library(opencv INTERFACE ) target_include_directories(opencv INTERFACE "${OpenCV_INCLUDE_DIRS}") target_link_libraries(opencv INTERFACE "${OpenCV_LIBS}") 

The target_include_directories may even not be necessary depending on your CMake version.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you thank you! Just wondering, is there a reason not to always just to use an interface library? Or is it better to use set_target_properties() when there is just one file for the library?
Phrased another way: is there any value by using add_library(opencv INTERFACE IMPORTED) instead of just add_library(opencv INTERFACE)? Apparently you can't use target_link_libraries or target_include_directories if the library was marked IMPORTED.
I am not sure... However, in the normal case I wouldn't go all the way to define a custom target "opencv", but I would call directly target_link_libraries(sample ${OpenCV_LIBRARIES}).
1

oLen's answer will work, but then you lose the ability to mark the library as IMPORTED.

A better way to accomplish what I was trying to do it to set the INTERFACE_LINK_LIBRARIES property. The library should also be an INTERFACE library instead of SHARED.

So the cmake config to import the target becomes:

find_package(OpenCV 3 REQUIRED) add_library(opencv INTERFACE IMPORTED) set_target_properties(opencv PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${OpenCV_INCLUDE_DIRS}" INTERFACE_LINK_LIBRARIES "${OpenCV_LIBS}") 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.