#c #opencv #cmake
#c #opencv #cmake
Вопрос:
Я пытаюсь включить opencv в свой проект на c . Я хочу, чтобы CMake справился с этим за меня.
В настоящее время я нахожусь на том этапе, когда мне нужно включить opencv с тегом: #include <opencv2/opencv.hpp>
Однако файлы в каталоге _deps / opencv-src выдают следующую ошибку:
Scanning dependencies of target VisionC
Building CXX object CMakeFiles/VisionC.dir/main.cpp.o
In file included from /Users/koen/Vakken/MotionVision/VisionC/main.cpp:2:
/Users/koen/Vakken/MotionVision/VisionC/cmake-build-debug/_deps/opencv-src/include/opencv2/opencv.hpp:48:10: fatal error: 'opencv2/opencv_modules.hpp' file not found
#include "opencv2/opencv_modules.hpp"
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Похоже, что файлы не могут содержать свои собственные заголовки
Мой файл CMakeLists по-прежнему довольно прост:
cmake_minimum_required(VERSION 3.17)
project(VisionC)
set(CMAKE_CXX_STANDARD 20)
include(FetchContent)
FetchContent_Declare(
opencv
GIT_REPOSITORY https://github.com/opencv/opencv.git
GIT_TAG 4.4.0
)
FetchContent_GetProperties(opencv)
if (NOT opencv_POPULATED)
FetchContent_Populate(opencv)
add_subdirectory(${opencv_SOURCE_DIR} ${opencv_BINARY_DIR})
include_directories(${opencv_SOURCE_DIR}/include) # "/include" should be deleted somehow...
endif ()
FetchContent_MakeAvailable(opencv)
add_executable(VisionC main.cpp)
target_link_libraries(VisionC opencv_lib)
Я думаю, что «/ include» в строке include_directories намекает на то, что библиотека включена в каталог с «высоким» или около того… Я не уверен, как мне следует это изменить. Если я удалю эту строку, я должен включить opencv, например #include <include/opencv2/opencv.hpp>
Ответ №1:
Я нашел решение, теперь это мои cmakelists:
cmake_minimum_required(VERSION 3.17)
project(VisionC)
set(CMAKE_CXX_STANDARD 20)
# Fetch from git
include(FetchContent)
FetchContent_Declare(
opencv
GIT_REPOSITORY https://github.com/opencv/opencv.git
GIT_TAG 4.4.0
)
FetchContent_GetProperties(opencv)
if (NOT opencv_POPULATED)
FetchContent_Populate(opencv)
endif ()
FetchContent_MakeAvailable(opencv)
# Find on pc
set(OpenCV_DIR ${CMAKE_CURRENT_BINARY_DIR})
include_directories(${OpenCV_INCLUDE_DIRS})
find_package(OpenCV REQUIRED)
# Link
add_executable(VisionC main.cpp)
target_link_libraries(VisionC ${OpenCV_LIBS})
Комментарии:
1. Поскольку
FetchContent_MakeAvailable(opencv)
вы следуете каноническому шаблону, вы можете удалитьFetchContent_GetProperties
/FetchContent_Populate
, т.е. Все делается с помощьюFetchContent_MakeAvailable
… ссылка: cmake.org/cmake/help/latest/module /…2. вы правы, я
include_directories(${OpenCV_INCLUDE_DIRS})
тоже так думаю3. Я пытался сделать то же самое, что и вы, но у меня есть список ошибок, подобных следующему:
Target "opencv_core" INTERFACE_INCLUDE_DIRECTORIES property contains path: "~/CLionProjects/vision/cmake-build-debug" which is prefixed in the build directory.
Вы знаете, почему?4. Честно говоря, это было для школьного проекта. Я только что запустил его. Прошу прощения. Возможно, вы могли бы просто изменить значение INTERFACE_INCLUDE_DIRECTORIES, чтобы исключить этот путь и посмотреть, что произойдет. Честно говоря, если бы вы могли это исправить, я думаю, что многие люди были бы очень счастливы в будущем!
5. кажется, сборка происходит очень медленно
Ответ №2:
Решение, предоставленное @Typhaon, вообще не является решением, потому что оно использует find_package наряду с fetchContent и использует только результат find_package, игнорируя извлеченное содержимое. Другими словами, если вы удалите обычаи fetchContent, это будет работать. Если кому-то интересно, какова правильная интеграция OpenCV с find_package, взгляните на пример, предоставленный OpenCV https://github.com/opencv/opencv/blob/4.x/samples/cpp/example_cmake/CMakeLists.txt .
Итак, как насчет fetch_content или даже использования add_subdriectory? Такое использование в настоящее время не поддерживается https://github.com/opencv/opencv/issues/20548
Но в настоящее время я нашел обходной путь, который работает для меня с текущей версией. Итак, проблема в том, что целевые объекты модулей OpenCV не включают в себя заголовок include dir, поэтому, когда вы пытаетесь связать с ними, вы можете, но вам также необходимо указать каталог включения вручную. В настоящее время существуют переменные OPENCV_MODULE_opencv_{module_name}_LOCATION, которые указывают на исходный каталог модуля, и их можно использовать для получения каталога include . Например
target_include_directories(my_target PRIVATE
${OPENCV_MODULE_opencv_core_LOCATION}/include
${OPENCV_MODULE_opencv_highgui_LOCATION}/include
)
target_link_libraries(my_target opencv_core opencv_highgui)
После этого возникает ошибка, подобная этой
52 | #include "opencv2/opencv_modules.hpp"
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
И это потому, что по какой-то причине opencv_modules.hpp генерируется в корне каталога сборки. Но, к счастью, есть переменная, которая указывает на этот каталог OPENCV_CONFIG_FILE_INCLUDE_DIR . Итак, окончательный файл списка CMake выглядит следующим образом
cmake_minimum_required(VERSION 3.23)
project(my_project)
set(CMAKE_CXX_STANDARD 20)
include(FetchContent)
FetchContent_Declare(
opencv
GIT_REPOSITORY https://github.com/opencv/opencv.git
GIT_TAG 4.6.0
GIT_SHALLOW TRUE
GIT_PROGRESS TRUE
)
FetchContent_MakeAvailable(opencv)
add_executable(my_target main.cpp)
target_include_directories(my_target PRIVATE
${OPENCV_CONFIG_FILE_INCLUDE_DIR}
${OPENCV_MODULE_opencv_core_LOCATION}/include
${OPENCV_MODULE_opencv_highgui_LOCATION}/include
)
target_link_libraries(my_target opencv_core opencv_highgui)
Недостатком этого обходного пути является то, что упомянутые переменные могут меняться с выпусками, и в настоящее время это работает для 4.6.0.