OpenCV 3.3.1 is breaking builds in Kinetic

Apologies in advance for not asking this on ROS Answers, but it’s been unusable all day and this is a somewhat pressing question.

After upgrading my Ubuntu Xenial / ROS Kinetic over the weekend, I noticed that the latest release included OpenCV 3.3.1, and now none of my packages that use OpenCV will build. I’m having this issue on my workstation, but I’ve also reproduced the exact issue in a Docker container based on ros:kinetic.

Whenever I build a component that adds ${OpenCV_LIBRARIES} to its target_link_libraries macro, the build fails saying there is “no rule to make target ‘opencv_core-NOTFOUND’”. For example, if I clone and build swri_geometry_util, also modifying it to print out the contents of catkin_LIBRARIES and OpenCV_LIBRARIES just before the error happens, I get this:

Starting  >>> swri_geometry_util                                                                                                                                                                                                            
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Warnings   << swri_geometry_util:cmake /workspace/logs/swri_geometry_util/build.cmake.000.log                                                                                                                                               
catkin_LIBRARIES: /opt/ros/kinetic/lib/libcv_bridge.so;/opt/ros/kinetic/lib/libopencv_core3.so.3.3.1;/opt/ros/kinetic/lib/libopencv_imgproc3.so.3.3.1;/opt/ros/kinetic/lib/libopencv_imgcodecs3.so.3.3.1;/opt/ros/kinetic/lib/libtf.so;/opt/ros/kinetic/lib/libtf2_ros.so;/opt/ros/kinetic/lib/libactionlib.so;/opt/ros/kinetic/lib/libmessage_filters.so;/opt/ros/kinetic/lib/libroscpp.so;/usr/lib/x86_64-linux-gnu/libboost_signals.so;/usr/lib/x86_64-linux-gnu/libboost_filesystem.so;/opt/ros/kinetic/lib/libxmlrpcpp.so;/opt/ros/kinetic/lib/libtf2.so;/opt/ros/kinetic/lib/libroscpp_serialization.so;/opt/ros/kinetic/lib/librosconsole.so;/opt/ros/kinetic/lib/librosconsole_log4cxx.so;/opt/ros/kinetic/lib/librosconsole_backend_interface.so;/usr/lib/x86_64-linux-gnu/liblog4cxx.so;/usr/lib/x86_64-linux-gnu/libboost_regex.so;/opt/ros/kinetic/lib/librostime.so;/opt/ros/kinetic/lib/libcpp_common.so;/usr/lib/x86_64-linux-gnu/libboost_system.so;/usr/lib/x86_64-linux-gnu/libboost_thread.so;/usr/lib/x86_64-linux-gnu/libboost_chrono.so;/usr/lib/x86_64-linux-gnu/libboost_date_time.so;/usr/lib/x86_64-linux-gnu/libboost_atomic.so;/usr/lib/x86_64-linux-gnu/libpthread.so;/usr/lib/x86_64-linux-gnu/libconsole_bridge.so
OpenCV_LIBRARIRES: opencv_core
cd /workspace/build/swri_geometry_util; catkin build --get-env swri_geometry_util | catkin env -si  /usr/bin/cmake /workspace/src/marti_common/swri_geometry_util --no-warn-unused-cli -DCATKIN_DEVEL_PREFIX=/workspace/devel/.private/swri_geometry_util -DCMAKE_INSTALL_PREFIX=/opt/rtk/kinetic -DCMAKE_BUILD_TYPE=RelWithDebInfo; cd -
............................................................................................................................................................................................................................................
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
Errors     << swri_geometry_util:make /workspace/logs/swri_geometry_util/build.make.000.log                                                                                                                                                 
make[2]: *** No rule to make target 'opencv_core-NOTFOUND', needed by '/workspace/devel/.private/swri_geometry_util/lib/libswri_geometry_util.so'.  Stop.
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [CMakeFiles/swri_geometry_util.dir/all] Error 2
make: *** [all] Error 2
cd /workspace/build/swri_geometry_util; catkin build --get-env swri_geometry_util | catkin env -si  /usr/bin/make --jobserver-fds=6,7 -j; cd -
............................................................................................................................................................................................................................................
Failed     << swri_geometry_util:make              [ Exited with code 2 ]                                                                                                                                                                   
Failed    <<< swri_geometry_util                   [ 9.4 seconds ]

My CMAKE_PREFIX_PATH and LD_LIBRARY_PATH are set appropriately, and the opencv libs exist in /opt/ros/kinetic/lib/ . If I manually downgrade to the 3.2.0 version of OpenCV, it works fine without any other changes. I’ve tested this with a handful of different packages on both my workstation and in a Docker container, and it’s the same behavior everywhere.

If I hand-edit /opt/ros/kinetic/share/OpenCV-3.3.1/OpenCVConfig.cmake to make it return absolute paths to libraries instead of just library names, it works fine. I wouldn’t think I should need to do that, and it worked fine with 3.2.0.

Am I missing something? Did the way OpenCV should be included change in 3.3.1?

On a related note, OpenCV 3.3 seems to have broken some other things, too. See https://github.com/opencv/opencv_contrib/issues/1376 for an example. I’m surprised that a major package that breaks backward compatibility was allowed to be released into Kinetic at this point.

Take a look at https://github.com/ros-perception/vision_opencv/issues/192

But you need this now in your CMakeLists.txt:

find_package(OpenCV REQUIRED)
...
target_link_libraries(
  ...
  ${OpenCV_LIBRARIES}

I don’t think that’s my issue, unfortunately. swri_geometry_util's CMakeLists.txt has the following:

find_package(OpenCV REQUIRED core)
...
include_directories(include ${catkin_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ${GEOS_INCLUDE_DIRS} ${EIGEN3_INCLUDE_DIRS})
...
target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ${GEOS_LIBRARIES})

However, I still get a build failure about “No rule to make target ‘opencv_core-NOTFOUND’”. Here’s an example Dockerfile that demonstrates the issue: https://pastebin.com/yN9f4i6v

I am getting a very similar error after upgrading apt packages today:

make[2]: *** No rule to make target 'opencv_calib3d-NOTFOUND'

In my CMakeLists.txt I already have the lines recommended by @lucasw.

Testing with your docker image, I noticed that you have OpenCV inside your catkin_packages DEPENDS entry which means that you already have the OpenCV libraries in your link flags crom the {catkin_LIBRARIES}` element. And I successfully tested that the package compiles and links by removing the `{OpenCV_LIBRARIES}` from your link command.

[100%] Linking CXX shared library /workspace/devel/.private/swri_geometry_util/lib/libswri_geometry_util.so
/usr/bin/cmake -E cmake_link_script CMakeFiles/swri_geometry_util.dir/link.txt --verbose=1
/usr/bin/c++ -fPIC -O2 -g -DNDEBUG -shared -Wl,-soname,libswri_geometry_util.so -o /workspace/devel/.private/swri_geometry_util/lib/libswri_geometry_util.so CMakeFiles/swri_geometry_util.dir/src/cubic_spline.cpp.o CMakeFiles/swri_geometry_util.dir/src/geometry_util.cpp.o CMakeFiles/swri_geometry_util.dir/src/intersection.cpp.o CMakeFiles/swri_geometry_util.dir/src/polygon.cpp.o /opt/ros/kinetic/lib/libcv_bridge.so /opt/ros/kinetic/lib/libopencv_core3.so.3.3.1 /opt/ros/kinetic/lib/libopencv_imgproc3.so.3.3.1 /opt/ros/kinetic/lib/libopencv_imgcodecs3.so.3.3.1 /opt/ros/kinetic/lib/libtf.so /opt/ros/kinetic/lib/libtf2_ros.so /opt/ros/kinetic/lib/libactionlib.so /opt/ros/kinetic/lib/libmessage_filters.so /opt/ros/kinetic/lib/libroscpp.so -lboost_signals -lboost_filesystem /opt/ros/kinetic/lib/libxmlrpcpp.so /opt/ros/kinetic/lib/libtf2.so /opt/ros/kinetic/lib/libroscpp_serialization.so /opt/ros/kinetic/lib/librosconsole.so /opt/ros/kinetic/lib/librosconsole_log4cxx.so /opt/ros/kinetic/lib/librosconsole_backend_interface.so -llog4cxx -lboost_regex /opt/ros/kinetic/lib/librostime.so /opt/ros/kinetic/lib/libcpp_common.so -lboost_system -lboost_thread -lboost_chrono -lboost_date_time -lboost_atomic -lpthread -lconsole_bridge -Wl,-rpath,/opt/ros/kinetic/lib:
make[2]: Leaving directory ‘/workspace/build/swri_geometry_util’
[100%] Built target swri_geometry_util

The above solution isn’t a full fix, but will at least get you going.

calib3d is the first of the OpenCV libraries exported if you don’t filter for just the core component like in the above example.

I’ve created a ticket here Lets follow up in the ticket.