CMakefile find_package小结

本文详细介绍了如何从源码编译OpenCV及其额外模块,并提供了配置CMakeLists.txt文件的具体步骤来确保正确链接OpenCV库。此外,还分享了一些实用的小技巧,帮助解决编译过程中可能遇到的问题。

下载了最新的opencv源码和opencv extra modules 源码,编译

mkdir build; cd build; cmake .. 
make
sudo make install

install后是将需要的头文件和库文件拷贝到/usr目录下,有时是/usr/local目录下。具体如何区分还待进一步分析

然后编译opencv extra modules中的样例代码。

cmake_minimum_required(VERSION 2.8)

SET(CMAKE_MODULE_PATH
${CMAKE_INSTALL_PREFIX}/lib/cmake/ )
SET(CMAKE_CXX_FLAGS "-std=c++0x")

find_package(aruco REQUIRED )
# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED)

# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")

# Add OpenCV headers location to your include paths
#MESSAGE(STATUS "Head files Directory: ${PROJECT_SOURCE_DIR}/include")
#declaration the include files directories
include_directories(${OpenCV_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/include)

#MESSAGE(STATUS "Lib Directory: ${PROJECT_SOURCE_DIR}/lib")
# declaration the lib directories
link_directories(${PROJET_SOURCE_DIR}/lib)

include_directories(${PROJET_SOURCE_DIR}/include)

add_executable(aruco_simple aruco_simple.cpp)
target_link_libraries(aruco_simple ${aruco_LIBS} ${OpenCV_LIBS})

小技巧:
1. find_package 就是在系统环境变量指定的目录中寻找******Config.cmake和*****Config-version.cmake文件,通常在ubuntu下使用apt-get install 命令会自动在相应目录下生成这个文件。如果是手动编译源代码的话,在执行make install后也会在相应目录下生成该两个文件。如果有些package找不到,那就手动搜索这两个文件,如果找到了,那就是目录没有添加到系统变量中。
2.

message(STATUS "libraries: ${OpenCV_LIBS} message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}") 

上面输出的信息非常有用,可以查看编译中真正用到的库和头文件是哪些。有可能系统中有opencv2.14和opencv3共存的情况,名字相同的头文件在不同的目录下。这时需要你仔细分辨。
3. 如果Config.cmake指的不是用到的版本,例如安装了ros-indigo-opencv ,就生成/opt/ros/indigo/share/OpenCV-3.1.0-dev/OpenCVConfig.cmake文件,这个opencv的版本非常低,不适合,但ros其它节点用到了这个库,在编译以前的代码时需要该文件。这样下载了opencv的最新的代码,编译,make install,再编译sample时就不应该使用find_package,而是在CMakefile中直接将所需的头文件路径和库加进去,例如

include_directories(/usr/local/include)
target_link_libraries(aruco_simple /usr/local/lib/libopencv_aruco.so /usr/local/lib/libopencv_core.so /usr/local/lib/libopencv_video.so /usr/local/lib/libopencv_videoio.so /usr/local/lib/libopencv_highgui.so)

这样系统中就有了opencv的两个版本
4. 还有就是

SET(CMAKE_CXX_FLAGS "-std=c++0x")
SET(CMAKE_CXX_FLAGS "-std=c++11")

增加编译时的标志
或者某些环境变量缺失时,可以直接用SET增加,例如经常莫名奇妙就走丢的Eigen3

#Add Eigen3 headers location to your include paths
SET( EIGEN3_INCLUDE_DIR "/usr/local/include/eigen" )
Errors << mav_system_msgs:cmake /home/liu/catkin_ws/logs/mav_system_msgs/build.cmake.001.log CMake Warning (dev) at CMakeLists.txt:2 (project): Policy CMP0048 is not set: project() command manages VERSION variables. Run "cmake --help-policy CMP0048" for policy details. Use the cmake_policy command to set the policy and suppress this warning. The following variable(s) would be set to empty: CMAKE_PROJECT_VERSION CMAKE_PROJECT_VERSION_MAJOR CMAKE_PROJECT_VERSION_MINOR CMAKE_PROJECT_VERSION_PATCH This warning is for project developers. Use -Wno-dev to suppress it. ImportError: "from catkin_pkg.package import parse_package" failed: No module named 'catkin_pkg' Make sure that you have installed "catkin_pkg", it is up to date and on the PYTHONPATH. CMake Error at /opt/ros/noetic/share/catkin/cmake/safe_execute_process.cmake:11 (message): execute_process(/home/liu/miniconda3/bin/python3 "/opt/ros/noetic/share/catkin/cmake/parse_package_xml.py" "/opt/ros/noetic/share/catkin/cmake/../package.xml" "/home/liu/catkin_ws/build/mav_system_msgs/catkin/catkin_generated/version/package.cmake") returned error code 1 Call Stack (most recent call first): /opt/ros/noetic/share/catkin/cmake/catkin_package_xml.cmake:74 (safe_execute_process) /opt/ros/noetic/share/catkin/cmake/all.cmake:168 (_catkin_package_xml) /opt/ros/noetic/share/catkin/cmake/catkinConfig.cmake:20 (include) CMakeLists.txt:4 (find_package) cd /home/liu/catkin_ws/build/mav_system_msgs; catkin build --get-env mav_system_msgs | catkin env -si /usr/bin/cmake /home/liu/catkin_ws/src/mav_comm/mav_system_msgs --no-warn-unused-cli -DCATKIN_DEVEL_PREFIX=/home/liu/catkin_ws/devel -DCMAKE_INSTALL_PREFIX=/home/liu/catkin_ws/install -DCMAKE_BUILD_TYPE=Release; cd -
07-19
### `set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)` 该命令将 `CMAKE_FIND_ROOT_PATH_MODE_PROGRAM` 设置为 `NEVER`。`CMAKE_FIND_ROOT_PATH_MODE_PROGRAM` 用于控制在使用 `find_program` 命令查找程序时,是否限制在 `CMAKE_FIND_ROOT_PATH` 指定的路径中查找。设置为 `NEVER` 意味着在查找程序时,不会受 `CMAKE_FIND_ROOT_PATH` 的限制,会在系统默认的搜索路径中查找程序。使用场景通常是在交叉编译时,主机系统上的程序(如编译器、链接器等)可能不在 `CMAKE_FIND_ROOT_PATH` 中,需要在主机系统的默认路径中查找这些程序。例如,在使用交叉编译工具链时,需要使用主机系统上的 `make` 程序来构建项目,就可以通过该设置让 CMake 在主机系统默认路径中找到 `make` 程序。 ### `set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)` 此命令把 `CMAKE_FIND_ROOT_PATH_MODE_LIBRARY` 设置为 `ONLY`。`CMAKE_FIND_ROOT_PATH_MODE_LIBRARY` 控制 `find_library` 命令查找库文件时的搜索路径规则。设置为 `ONLY` 表示 `find_library` 只会在 `CMAKE_FIND_ROOT_PATH` 指定的路径中查找库文件,不论是否传入了路径,也不论是否设置了 `CMAKE_PREFIX_PATH`。使用场景是在交叉编译时,确保只使用目标系统的库文件,避免使用主机系统的库文件,从而保证编译出的程序能在目标系统上正常运行。例如,在为 `aarch64 - linux - gnu` 架构进行交叉编译时,需要使用该架构对应的库文件,将该模式设置为 `ONLY` 可以确保只从 `CMAKE_FIND_ROOT_PATH` 中查找合适的库文件 [^1]。 ### `set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)` 该设置将 `CMAKE_FIND_ROOT_PATH_MODE_INCLUDE` 设为 `ONLY`。`CMAKE_FIND_ROOT_PATH_MODE_INCLUDE` 用于控制 `find_path` 命令查找头文件时的搜索路径规则。设置为 `ONLY` 意味着 `find_path` 只会在 `CMAKE_FIND_ROOT_PATH` 指定的路径中查找头文件。使用场景和 `CMAKE_FIND_ROOT_PATH_MODE_LIBRARY` 类似,在交叉编译时,确保只使用目标系统的头文件,避免使用主机系统的头文件,保证编译的正确性。例如,在交叉编译时,需要使用目标架构对应的头文件来编译程序,将该模式设置为 `ONLY` 可以确保只从 `CMAKE_FIND_ROOT_PATH` 中查找合适的头文件 [^1]。 ### `set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)` 把 `CMAKE_FIND_ROOT_PATH_MODE_PACKAGE` 设置为 `ONLY`。`CMAKE_FIND_ROOT_PATH_MODE_PACKAGE` 控制 `find_package` 命令查找 CMake 包时的搜索路径规则。设置为 `ONLY` 表示 `find_package` 只会在 `CMAKE_FIND_ROOT_PATH` 指定的路径中查找 CMake 包。使用场景是在交叉编译时,确保只使用目标系统的 CMake 包,避免使用主机系统的包,保证项目依赖的正确性。例如,在交叉编译项目中依赖某个特定架构的 CMake 包,通过该设置可以确保只从 `CMAKE_FIND_ROOT_PATH` 中查找该包。 ### `set(CMAKE_FIND_ROOT_PATH "/usr/${target_arch}")` 此命令将 `CMAKE_FIND_ROOT_PATH` 设置为 `/usr/${target_arch}`。`CMAKE_FIND_ROOT_PATH` 是一个重要的 CMake 变量,它指定了在查找程序、库文件、头文件和 CMake 包时的根路径。当 `CMAKE_FIND_ROOT_PATH_MODE_*` 系列变量设置为 `ONLY` 或 `BOTH` 时,CMake 会在 `CMAKE_FIND_ROOT_PATH` 指定的路径中进行查找。使用场景是在交叉编译时,指定目标系统的根路径,让 CMake 知道在哪里查找目标系统的程序、库文件、头文件和 CMake 包。例如,在为 `aarch64 - linux - gnu` 架构进行交叉编译时,将 `target_arch` 设置为 `aarch64 - linux - gnu`,则 `CMAKE_FIND_ROOT_PATH` 会被设置为 `/usr/aarch64 - linux - gnu`,CMake 会在该路径下查找目标系统的相关文件。 以下是一个简单的 CMake 示例,展示这些设置的使用: ```cmake set(target_arch aarch64-linux-gnu) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH "/usr/${target_arch}") project(MyCrossCompileProject) add_executable(my_app main.cpp) find_library(SOME_LIB some_library) if(SOME_LIB) target_link_libraries(my_app ${SOME_LIB}) endif() ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值