2

I'm new to cmake, and could't figure out how to achieve this after a few days.

I'm trying to build a C++ project that depends on OpenCV using cmake, but I want cmake to clone and install it like this. I found a project's CMakeFile that I'm using as reference to accomplish this.So I have this:

main.cpp:

#include <iostream>
#include <opencv2/opencv.hpp>


int main() {
    std::cout << "OpenCV Version: " + cv::getVersionString() << std::endl;
    return 0;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.12)
project(cv_playground)
set(CMAKE_CXX_STANDARD 14)

find_package(Git REQUIRED)

include(ExternalProject)

# OpenCV
set(OPENCV_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/opencv)
ExternalProject_Add(opencv
        GIT_REPOSITORY https://github.com/opencv/opencv
        GIT_TAG 68942affdbc4677aa845bc4307d4752182324a0e # 4.0.0-alpha
        SOURCE_DIR opencv
        BINARY_DIR opencv-build
        CMAKE_ARGS
          -DCMAKE_INSTALL_PREFIX=${OPENCV_INSTALL_LOCATION}
        )
include_directories(${OPENCV_INSTALL_LOCATION}/include/opencv4)
link_directories(${OPENCV_INSTALL_LOCATION}/lib)

add_executable(cv_playground main.cpp)
add_dependencies(cv_playground opencv)
target_link_libraries(cv_playground opencv_core opencv_dnn opencv_features2d opencv_flann opencv_highgui opencv_imgcodecs)

But when building the project I get a lot of undefined references (pthread, gz, dlopen/dlclose, itt_domain_create_ptr, etc)

I would like to know how to fix those undef refs, I already installed pthread, zlib, etc but I don't know how to make cmake to use them. I tried to add them in the target_link_libraries for example but still gives me the same errors:

CMakeLists.txt (note the CMAKE_DL_LIBS in target_link_libraries):

cmake_minimum_required(VERSION 3.12)
project(cv_playground)
set(CMAKE_CXX_STANDARD 14)
set(THREADS_PREFER_PTHREAD_FLAG ON)

find_package(Threads REQUIRED)
find_package(Git REQUIRED)

include(ExternalProject)

# OpenCV
set(OPENCV_INSTALL_LOCATION ${CMAKE_BINARY_DIR}/opencv)
ExternalProject_Add(opencv
        GIT_REPOSITORY https://github.com/opencv/opencv
        GIT_TAG 68942affdbc4677aa845bc4307d4752182324a0e # 4.0.0-alpha
        SOURCE_DIR opencv
        BINARY_DIR opencv-build
        CMAKE_ARGS
          -DWITH_OPENGL=OFF
          -DCMAKE_INSTALL_PREFIX=${OPENCV_INSTALL_LOCATION}
        )
include_directories(${OPENCV_INSTALL_LOCATION}/include/opencv4)
link_directories(${OPENCV_INSTALL_LOCATION}/lib)

add_executable(cv_playground main.cpp)
add_dependencies(cv_playground opencv)
target_link_libraries(cv_playground Threads::Threads ${CMAKE_DL_LIBS} opencv_core opencv_dnn opencv_features2d opencv_flann opencv_highgui opencv_imgcodecs)

Error message (still get undefined reference to dlopen, dlclose, ...)

[ 90%] Linking CXX executable cv_playground
/home/syonekura/CLionProjects/cv_playground/cmake-build-debug/opencv/lib/libopencv_core.a(system.cpp.o): In function `cv::TLSData<cv::(anonymous namespace)::ThreadID>::createDataInstance() const':
system.cpp:(.text._ZNK2cv7TLSDataINS_12_GLOBAL__N_18ThreadIDEE18createDataInstanceEv+0x37): undefined reference to `__itt_thread_set_name_ptr__3_0'
/home/syonekura/CLionProjects/cv_playground/cmake-build-debug/opencv/lib/libopencv_core.a(opencl_core.cpp.o): In function `GetHandle(char const*)':
opencl_core.cpp:(.text._ZL9GetHandlePKc+0x7): undefined reference to `dlopen'
opencl_core.cpp:(.text._ZL9GetHandlePKc+0x1e): undefined reference to `dlsym'
opencl_core.cpp:(.text._ZL9GetHandlePKc+0x53): undefined reference to `dlclose'
/home/syonekura/CLionProjects/cv_playground/cmake-build-debug/opencv/lib/libopencv_core.a(opencl_core.cpp.o): In function `opencl_check_fn(int)':
opencl_core.cpp:(.text._ZL15opencl_check_fni+0x3f): undefined reference to `dlsym'
  • 1
    `I tried to add them in the target_link_libraries for example but still gives me the same errors.` - Add that attempt into your question post. And post **exact** error message (which includes filenames). – Tsyvarev Sep 30 '18 at 17:57
  • @Tsyvarev added the attempt and an extract of the error message (the original it's quite long but it's basically the same error message for different functions) – Sebastian Yonekura Baeza Sep 30 '18 at 19:23
  • As you can see from the error messages, the errors are caused by `opencv` library. For resolve them properly, you need to place needed libraries **after** the `opencv` one. But your code exposes opposite case. See that answer for more info: https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix/24675715. – Tsyvarev Sep 30 '18 at 23:19
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Tsyvarev Sep 30 '18 at 23:20

1 Answers1

1

So I've had quite a few issues with this myself. Cmake should essentially be used just to build the OpenCV library. Provided you're using an ubuntu machine you want to do this:

# Update and upgrade packages
sudo apt-get -y update
sudo apt-get -y upgrade

# Remove any existing versions of x264
sudo apt-get remove x264 libx264-dev

# Install OS Libraries

# Install Dependencies
sudo apt-get -y install build-essential checkinstall cmake pkg-config yasm gfortran git
sudo apt-get -y install libjpeg8-dev libjasper-dev libpng12-dev
# Used for Ubuntu 16.04
sudo apt-get -y install libtiff5-dev
sudo apt-get -y install libavcodec-dev libavformat-dev libswscale-dev libdc1394-22-dev
sudo apt-get -y install libxine2-dev libv4l-dev
sudo apt-get -y install libgstreamer0.10-dev libgstreamer-plugins-base0.10-dev
sudo apt-get -y install libqt4-dev libgtk2.0-dev libtbb-dev
sudo apt-get -y install libatlas-base-dev
sudo apt-get -y install libfaac-dev libmp3lame-dev libtheora-dev
sudo apt-get -y install libvorbis-dev libxvidcore-dev
sudo apt-get -y install libopencore-amrnb-dev libopencore-amrwb-dev
sudo apt-get -y install x264 v4l-utils

# Install Optional Dependencies
sudo apt-get -y install libprotobuf-dev protobuf-compiler
sudo apt-get -y install libgoogle-glog-dev libgflags-dev
sudo apt-get -y install libgphoto2-dev libeigen3-dev libhdf5-dev doxygen

# Download OpenCV from Github
git clone https://github.com/opencv/opencv.git
cd opencv
git checkout 3.3.0
cd ..

# Download opencv_contrib from Github
git clone https://github.com/opencv/opencv_contrib.git
cd opencv_contrib
git checkout 3.3.0
cd ..

# Compile and Install OpenCV with contrib
# Create build directory inside opencv directory
cd opencv
mkdir build
cd build

# Run CMake with the following options
cmake -D CMAKE_BUILD_TYPE=RELEASE \
      -D CMAKE_INSTALL_PREFIX=/usr/local \
      -D INSTALL_C_EXAMPLES=ON \
      -D INSTALL_PYTHON_EXAMPLES=ON \
      -D WITH_TBB=ON \
      -D WITH_V4L=ON \
      -D WITH_QT=ON \
      -D WITH_OPENGL=ON \
      -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules \
      -D BUILD_EXAMPLES=ON ..

# Compile and Install
make -j4
sudo make install
sudo sh -c 'echo "/usr/local/lib" >> /etc/ld.so.conf.d/opencv.conf'
sudo ldconfig

You can cherry pick the parts that are most relevant, but essentially what this entails is making the OpenCV library available to your project. You can then either use a make file to make your project, or you can run a command as so:

c++ pkg-config --cflags opencv filename.cpp pkg-config --libs opencv -o filename

This creates an executable called filename

Philip Bal
  • 23
  • 9