Search code examples
c++opencvcmakeconan

OpenCV library not found - cmake with conan


I have a conanfile describing what I want to include (in this case, mainly the OpenCV part), and a corresponding cmakelists going with it. When running conan install and then cmake, it works, but during compilation the OpenCV libraries could not be included. The same code works on windows, so I wonder if I forgot some setting or so.

The include files appear to be found, but when it comes to linking:

`undefined reference to `cv::imshow(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cv::_InputArray const&)''

Conanfile.py:

from conans import ConanFile, CMake
from conans import tools
from conans.tools import os_info, SystemPackageTool
import os, sys
import sysconfig
from io import StringIO


class PadConan(ConanFile):
    name = "AmbuScan"
    version = "0.1.0"

    description = "AmbuScan for pad localization"
    url = ""
    license = "GPL"

    short_paths = True
    settings = "os", "compiler", "build_type", "arch"
    generators = "cmake"

    ubitrack_version = "1.3.0"

    requires = (
        "opencv/4.3.0@conan/stable",
        "kinect-azure-sensor-sdk/1.4.1@camposs/stable",
        "zlib/1.2.11@camposs/stable",
        )

    # all sources are deployed with the package
    exports_sources = "include/*", "src/*", "CMakeLists.txt"

    def system_requirements(self):
        pass

    def configure(self):
        self.options['opencv'].contrib = False
        self.options['opencv'].cuda = False

    def imports(self):
        self.copy(src="bin", pattern="*.dll", dst="./bin")     # Copies all dll files from packages bin folder to my "bin" folder
        self.copy(src="", pattern="**.dll", dst="./bin", keep_path=False)     # Copies all dll files from packages bin folder to my "bin" folder
        self.copy(src="lib", pattern="*.lib", dst="./lib")     # Copies all lib files from packages lib folder to my "lib" folder
        self.copy(src="bin", pattern="*", dst="./bin")         # Copies all applications
        self.copy(src="bin", pattern="*.dll", dst="./bin")     # Copies all dll files from packages bin folder to my "bin" folder
        self.copy(src="lib", pattern="*.dylib*", dst="./lib")  # Copies all dylib files from packages lib folder to my "lib" folder
        self.copy(src="lib", pattern="*.so*", dst="./lib")     # Copies all so files from packages lib folder to my "lib" folder
        self.copy(src="lib", pattern="*.a", dst="./lib")       # Copies all static libraries from packages lib folder to my "lib" folder
        
    def _configure_cmake(self):
        cmake = CMake(self)
        cmake.verbose = True

        def add_cmake_option(option, value):
            var_name = "{}".format(option).upper()
            value_str = "{}".format(value)
            var_value = "ON" if value_str == 'True' else "OFF" if value_str == 'False' else value_str
            cmake.definitions[var_name] = var_value

        for option, value in self.options.items():
            add_cmake_option(option, value)

        cmake.configure()
        return cmake

    def build(self):
        cmake = self._configure_cmake()
        cmake.build()

    def package(self):
        cmake = self._configure_cmake()
        cmake.install()

CMakelists.txt:

cmake_minimum_required(VERSION 3.18)
project(PadLocalizer C CXX)

if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/conanbuildinfo_multi.cmake)
    include(${CMAKE_CURRENT_BINARY_DIR}/conanbuildinfo_multi.cmake)
    conan_set_find_paths()
elseif(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/conanbuildinfo.cmake)
    include(${CMAKE_CURRENT_BINARY_DIR}/conanbuildinfo.cmake)
else()
    message(WARNING "The file conanbuildinfo.cmake doesn't exist, you have to run conan install first")
endif()

conan_basic_setup(TARGETS)

include(GNUInstallDirs)

if(UNIX)
    if(APPLE)
        MESSAGE(STATUS "Building for Macos.")
        set(PAD_TARGET_APPLE 1)
    endif()
    MESSAGE(STATUS "Building for Unix.")
    set(PAD_TARGET_UNIX 1)
elseif(WIN32)
    MESSAGE(STATUS "Building for Windows.")
    set(PAD_TARGET_WINDOWS 1)
endif()

if (MSVC)
    # per default disable extended aligned storage for now on msvc
    add_definitions(-D_DISABLE_EXTENDED_ALIGNED_STORAGE -DHAVE_SNPRINTF)
endif()

set(PAD_HEADERS
        "include/runtime.h"
        )

set(PAD_HEADERS_CAPTURE
        "include/azure_camera.h"
        )

set(PAD_SOURCES
        src/main.cpp
        )

set(PAD_SOURCES_CAPTURE
        src/azure_camera.cpp
        )

source_group(pad\\include FILES ${PAD_HEADERS})
source_group(pad\\include\\capture FILES ${PAD_HEADERS_CAPTURE})
source_group(pad\\src FILES ${PAD_SOURCES})
source_group(pad\\src\\capture FILES ${PAD_SOURCES_CAPTURE})

add_executable(pad
        ${PAD_SOURCES}
        ${PAD_HEADERS}
        ${PAD_SOURCES_CAPTURE}
        ${PAD_HEADERS_CAPTURE}
        )

set_target_properties(pad PROPERTIES CXX_STANDARD 17)
set_target_properties(pad PROPERTIES LINKER_LANGUAGE CXX)
set_property(TARGET pad PROPERTY POSITION_INDEPENDENT_CODE ON)

target_link_libraries(pad PUBLIC
        CONAN_PKG::opencv
        CONAN_PKG::eigen
        CONAN_PKG::kinect-azure-sensor-sdk
        )

target_include_directories(pad PUBLIC
        $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>/include
        $<INSTALL_INTERFACE:include>
        PRIVATE
        ${PROJECT_BINARY_DIR}/include
        ${PROJECT_BINARY_DIR}/src
        ${PROJECT_SOURCE_DIR}/src
        ${CMAKE_BINARY_DIR}/include
        )

# need to review these settings if they are still appropriate
MESSAGE(STATUS "Building for ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION}")
if(WIN32)
    set_target_properties(pad PROPERTIES COMPILE_FLAGS "/EHsc /c /W3 /GR /wd4355 /wd4996 /wd4251 /wd4275 /wd4819 /wd4290")
    set_target_properties(pad PROPERTIES LINK_FLAGS "/SUBSYSTEM:CONSOLE")
    set_target_properties(pad PROPERTIES COMPILE_DEFINITIONS "WIN32" "_MBCS" "BOOST_SPIRIT_USE_OLD_NAMESPACE")
    set_target_properties(pad PROPERTIES LINK_FLAGS_DEBUG "/NODEFAULTLIB:libc.lib /NODEFAULTLIB:libcmt.lib /NODEFAULTLIB:msvcrt.lib /NODEFAULTLIB:libcd.lib /NODEFAULTLIB:libcmtd.lib")

    ## Check for Windows Version ##
    if( ${CMAKE_SYSTEM_VERSION} EQUAL 6.1 ) # Windows 7
        MESSAGE(STATUS "Setting minimum Windows version to Win7 WINVER=0x0601")
        set_target_properties(pad PROPERTIES COMPILE_DEFINITIONS WINVER=0x0601)
    elseif( ${CMAKE_SYSTEM_VERSION} EQUAL 6.2 ) # Windows 8
        MESSAGE(STATUS "Setting minimum Windows version to Win8 WINVER=0x0602")
        set_target_properties(pad PROPERTIES COMPILE_DEFINITIONS WINVER=0x0602)
    elseif( ${CMAKE_SYSTEM_VERSION} EQUAL 6.3 ) # Windows 8.1
        MESSAGE(STATUS "Setting minimum Windows version to Win8.1 WINVER=0x0603")
        set_target_properties(pad PROPERTIES COMPILE_DEFINITIONS WINVER=0x0603)
    elseif( ${CMAKE_SYSTEM_VERSION} EQUAL 10.0 ) # Windows 10
        MESSAGE(STATUS "Setting minimum Windows version to Win8.1 WINVER=0x0603")
        set_target_properties(pad PROPERTIES COMPILE_DEFINITIONS WINVER=0x0603)
    else() # Some other Windows
        MESSAGE(STATUS "Setting minimum Windows version to Vista WINVER=0x0600")
        set_target_properties(pad PROPERTIES COMPILE_DEFINITIONS WINVER=0x0600)
    endif()
endif(WIN32)

install(TARGETS pad EXPORT padConfig
        ARCHIVE  DESTINATION ${CMAKE_INSTALL_LIBDIR}
        LIBRARY  DESTINATION ${CMAKE_INSTALL_LIBDIR}
        RUNTIME  DESTINATION ${CMAKE_INSTALL_BINDIR})  # This is for Windows

# This makes the project importable from the install directory
# Put config file in per-project dir (name MUST match), can also
# just go into 'cmake'.
install(EXPORT padConfig DESTINATION share/pad/cmake)

# This makes the project importable from the build directory
export(TARGETS pad FILE padConfig.cmake)

Solution

  • Which OS and compiler do you use? What are your conan settings? Type:

    conan profile show default
    

    If "default" is your default profile of course.

    If you use compiler gcc > 5, please make sure you use the c++11 ABI:

    conan profile update settings.compiler.libcxx=libstdc++11 default