CmakeLists所遇命令用法总结

本文详细讲解了CMake中的option命令、MESSAGE输出提示、add_definitions功能,以及find_package的配置与使用,涉及编译开关、输出控制、库查找和链接等关键知识点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 option命令:

形式:option(<variable> "<help_text>" [value])

简介:cmake中option起到编译开关的作用,CMakeLists.txt中option以前的语句,变量按未定义处理,option之后的语句,变量才被定义。另外,注意,option命令定义的变量不影响c或c++源码中#ifdef或者#ifndef逻辑判断

2 MESSAGE("text"):

在make的时候向控制台输出的提示信息命令语句

3 add_definitions的用法

功能描述:其功能与C/C++中的#define一样

实例如下:

源文件main.cpp

#include <iostream>
int main()
{
#ifdef TEST_IT_CMAKE
	std::cout<<"in ifdef"<<std::endl;
#endif
	std::cout<<"not in ifdef"<<std::endl;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(optiontest)

add_executable(optiontest main.cpp)
option(TEST_IT_CMAKE "test" ON)
message(${TEST_IT_CMAKE})
if(TEST_IT_CMAKE)
	message("itis" ${TEST_IT_CMAKE})
	add_definitions(-DTEST_IT_CMAKE)
endif()

运行编译

// 第一种编译运行方法
mkdir build&& cd build
cmake ../ -DTEST_IT_CMAKE=OFF
make
./optiontest

// 第二种编译运行方法
mkdir build&& cd build
cmake ../ -DTEST_IT_CMAKE=ON
make
./optiontest

分析运行输出结果,就可以明白该指令的用法。

4 编译选项设置

两种设置方式

(1)通过add_compile_options命令

        add_compile_options命令添加的编译选项是针对所有编译器的(包括c和c++编译器)

#判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持
if(CMAKE_COMPILER_IS_GNUCXX)
    add_compile_options(-std=c++11)
    message(STATUS "optional:-std=c++11")   
endif(CMAKE_COMPILER_IS_GNUCXX)

(2)通过set命令修改CMAKE_CXX_FLAGSCMAKE_C_FLAGS

        set命令设置CMAKE_C_FLAGSCMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器

#判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持
if(CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
    message(STATUS "optional:-std=c++11")   
endif(CMAKE_COMPILER_IS_GNUCXX)

 5 list的用法总结

list(LENGTH <list><output variable>)
list(GET <list> <elementindex> [<element index> ...]<output variable>)
list(APPEND <list><element> [<element> ...])
list(FIND <list> <value><output variable>)
list(INSERT <list><element_index> <element> [<element> ...])
list(REMOVE_ITEM <list> <value>[<value> ...])
list(REMOVE_AT <list><index> [<index> ...])
list(REMOVE_DUPLICATES <list>)
list(REVERSE <list>)
list(SORT <list>)

LENGTH            返回list的长度

GET              返回list中index的element到value中

APPEND            添加新element到list中

FIND             返回list中element的index,没有找到返回-1

INSERT           将新element插入到list中index的位置

REMOVE_ITEM      从list中删除某个element

REMOVE_AT       从list中删除指定index的element

REMOVE_DUPLICATES       从list中删除重复的element

REVERSE         将list的内容反转

SORT           将list按字母顺序排序

 6 cmake中find_package用法

参考如下链接find_package原理简介以及使用说明

cmake本身不提供任何关于搜索库的便捷方法,也不会对库本身的环境变量进行设置。它仅仅是按照优先级顺序在指定的搜索路径进行查找Findxxx.cmake文件和xxxConfig.cmake文件(其中xxx代表库的名字,特别注意的是有大小写之分),这两个文件大体上是没有区别的,cmake能够找到这两个文件中的任何一个,我们都能成功使用该库,也就是我们可以用库的内置好了Cmake变量。包含了库的头文件和库文件的路径信息,虽然库的作者一般会提供这两个文件,但是也会遇到安装完毕后找不到的情况。当我们在cmake..命令之后,Cmake 会读取执行CMakeLists.txt中的代码,当执行find_package()这条命令后,Cmake 就会从某些路径中找这Findxxx.cmake文件或者xxxConfig.cmake文件,Cmake找到任意一个之后就会执行这个文件,然后这个文件执行后就会设置好一些Cmake变量。比如下面的变量(NAME表示库的名字 比如可以用Opencv 代表Opencv库):

<NAME>_FOUND
<NAME>_INCLUDE_DIRS or <NAME>_INCLUDES
<NAME>_LIBRARIES or <NAME>_LIBRARIES or <NAME>_LIBS
<NAME>_DEFINITIONS

一般常用的就是xxx_FOUNDxxx_INCLUDE_DIRSxxx_LIBS,分别代表是否找到库的标志、库的头文件路径、库文件路径。find_package()有两种模式:Module模式Config模式,分别对应上面的Findxxx.cmake 和xxxConfig.cmake两个文件。cmake默认优先Module模式,而Config模式是备选项

Module模式(仅仅查找Findxxx.cmake文件):

Cmake会优先搜索CMAKE_MODULE_PATH指定的路径,如果在CMakeLists.txt中没有设置CMAKE_MODULE_PATH为存储Findxxx.cmake的路径,也就是说没有下面的指令:
set(CMAKE_MODULE_PATH "Findxxx.cmake文件所在的路径")

那么Cmake不会搜索CMAKE_MODULE_PATH指定的路径,此时Cmake会搜索第二优先级的路径,也就是<CMAKE_ROOT>/share/cmake-x.y/Mdodules (注意:x.y表示版本号。我的是3.10)。其中CMAKE_ROOT是你在安装Cmake的时候的系统路径,因为我并没有指定安装路径,所以是系统默认的路径,在我的系统中(ubuntu16.04)系统的默认路径是/usr/loacl,如果你在安装的过程中使用了
cmake -DCMAKE_INSTALL_PREFIX=自己dir路径 ,那么此时CMAKE_ROOT就代表那个你写入的路径 。刚刚说道第一优先级的路径搜索没有找到Findxxx.cmake文件,就会到第二优先级的路径下搜索。如果Cmake在两个路径下都没有找到Findxxx.cmake文件。那么Cmake就会进入Config模式。

Config模式(仅仅查找xxxConfig.cmake文件):

Cmake会优先搜索xxx_DIR 指定的路径。如果在CMakeLists.txt中没有设置这个cmake变量。也就是说没有下面的指令:
set(xxx_DIR "xxxConfig.cmkae文件所在的路径")

那么Cmake就不会搜索xxx_DIR指定的路径,此时Cmake 就会自动到第二优先级的路径下搜索,也就是/usr/local/lib/cmake/xxx/中的xxxConfig.cmake文件。

查看find_package()的结果

find_package(but_velodyne REQUIRED)
if (but_velodyne_FOUND)
  MESSAGE (STATUS "@@@@@@dern: ${ButVELODYNE_DEFINITIONS}")
  MESSAGE (STATUS "@@@@@@dern: ${ButVELODYNE_INCLUDE_DIRS}")
  MESSAGE (STATUS "@@@@@@dern: ${ButVELODYNE_LIBRARY_DIRS}")
else()
  MESSAGE (STATUS "@@@@@@dern: but_velodyne not found")
endif(but_velodyne_FOUND)

7 include_directions和find_package

参考链接:include_directories与find_package的联系与区别

include_directories

是用来提供找头文件路径的,打个比方,我现在想要#include"cv.h",但是这个cv.h的路径是/usr/local/include/opencv,那么我总不能在主函数头前写
#include “/usr/local/include/opencv/cv.h”吧,这个时候就用到include_directories了,它提供了一个搜索头文件暂时的根目录,即你可以在cmakelists中写上
include_directories(/usr/local/include)来让库文件搜索以/usr/local/include为基础,即在main函数前写上#include “opencv/cv.h"即可

find_package():可参考6

也就是只要找到了*.CMAKE,我们就能够给上图底部的几个变量赋路径

最后,记得将找到的库连接到我们的可执行文件上

target_link_libraries( imageBasics ${OpenCV_LIBS} )

图像增强代码的CMakeLists.txt

cmake_minimum_required( VERSION 2.8 )//版本要求

project( imageBasics )//工程名

set( CMAKE_CXX_FLAGS "-std=c++11" )//添加c++ 11标准支持

find_package( OpenCV 3 REQUIRED )//寻找OpenCV.CMakeLists,以此找到包,并赋值各库相关变量

include_directories( ${OpenCV_INCLUDE_DIRS} )//OpenCV_INCLUDE_DIRS是关于find_package的变量,
                                             //包含了一个路径,这样可以在代码中的#include做根目录
include_directories(/usr/local/include)//同上,找根目录

add_executable( imageBasics test_transform2.cpp )//添加对主函数的可执行文件

target_link_libraries( imageBasics ${OpenCV_LIBS} )//链接OpenCV库,OpenCV_LIBS为代表库可执行文件的变量
                                                   //$为取出变量中的值

在有的时候会出现find_package找不到 __Config.cmake, _-config.cmake
的情况,解决办法非常简单,因为这两个文件都是包含了package所需的所有路径变量,非常重要,没有它们find_package不会起效果,所以直接去根目录下搜到这两个文件,路径复制后,直接设置,如
$set(OpenCV_DIR /opt/ros/kinetic/share/OpenCV-3.3.1-dev)
_DIR其实就是这两个文件所存在的位置,设置好后直接就得到所有路径变量了

还有就是find_package请和include_directories(${OpenCV_INCLUDE_DIRS}) target_link_libraries( test ${OpenCV_LIBS})配合食用,三步走

find_package(OpenCV 3.3.1 REQUIRED)中间写版本可以在多个版本包共存的条件下拿到自己想要的包的Config.cmake文件的路径

cmake_minimum_required(VERSION 3.0.2) project(handmsg) ## Compile as C++11, supported in ROS Kinetic and newer # add_compile_options(-std=c++11) ## Find catkin macros and libraries ## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) ## is used, also find other catkin packages find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation ) ## System dependencies are found with CMake's conventions # find_package(Boost REQUIRED COMPONENTS system) ## Uncomment this if the package has a setup.py. This macro ensures ## modules and global scripts declared therein get installed ## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html # catkin_python_setup() ################################################ ## Declare ROS messages, services and actions ## ################################################ ## To declare and build messages, services or actions from within this ## package, follow these steps: ## * Let MSG_DEP_SET be the set of packages whose message types you use in ## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...). ## * In the file package.xml: ## * add a build_depend tag for "message_generation" ## * add a build_depend and a exec_depend tag for each package in MSG_DEP_SET ## * If MSG_DEP_SET isn't empty the following dependency has been pulled in ## but can be declared for certainty nonetheless: ## * add a exec_depend tag for "message_runtime" ## * In this file (CMakeLists.txt): ## * add "message_generation" and every package in MSG_DEP_SET to ## find_package(catkin REQUIRED COMPONENTS ...) ## * add "message_runtime" and every package in MSG_DEP_SET to ## catkin_package(CATKIN_DEPENDS ...) ## * uncomment the add_*_files sections below as needed ## and list every .msg/.srv/.action file to be processed ## * uncomment the generate_messages entry below ## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...) ## Generate messages in the 'msg' folder add_message_files( FILES handstatus.msg handtarget.msg igh.msg tactile.msg HandPlanPoint.msg handPosCaliData.msg ) ## Generate services in the 'srv' folder # add_service_files( # FILES # Service1.srv # Service2.srv # ) ## Generate actions in the 'action' folder # add_action_files( # FILES # Action1.action # Action2.action # ) ## Generate added messages and services with any dependencies listed here generate_messages( DEPENDENCIES std_msgs ) ################################################ ## Declare ROS dynamic reconfigure parameters ## ################################################ ## To declare and build dynamic reconfigure parameters within this ## package, follow these steps: ## * In the file package.xml: ## * add a build_depend and a exec_depend tag for "dynamic_reconfigure" ## * In this file (CMakeLists.txt): ## * add "dynamic_reconfigure" to ## find_package(catkin REQUIRED COMPONENTS ...) ## * uncomment the "generate_dynamic_reconfigure_options" section below ## and list every .cfg file to be processed ## Generate dynamic reconfigure parameters in the 'cfg' folder # generate_dynamic_reconfigure_options( # cfg/DynReconf1.cfg # cfg/DynReconf2.cfg # ) ################################### ## catkin specific configuration ## ################################### ## The catkin_package macro generates cmake config files for your package ## Declare things to be passed to dependent projects ## INCLUDE_DIRS: uncomment this if your package contains header files ## LIBRARIES: libraries you create in this project that dependent projects also need ## CATKIN_DEPENDS: catkin_packages dependent projects also need ## DEPENDS: system dependencies of this project that dependent projects also need catkin_package( # INCLUDE_DIRS include # LIBRARIES handmsg # CATKIN_DEPENDS roscpp rospy std_msgs # DEPENDS system_lib ) ########### ## Build ## ########### ## Specify additional locations of header files ## Your package locations should be listed before other locations include_directories( # include ${catkin_INCLUDE_DIRS} ) ## Declare a C++ library # add_library(${PROJECT_NAME} # src/${PROJECT_NAME}/handmsg.cpp # ) ## Add cmake target dependencies of the library ## as an example, code may need to be generated before libraries ## either from message generation or dynamic reconfigure # add_dependencies(${PROJECT_NAME} ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) ## Declare a C++ executable ## With catkin_make all packages are built within a single CMake context ## The recommended prefix ensures that target names across packages don't collide # add_executable(${PROJECT_NAME}_node src/handmsg_node.cpp) ## Rename C++ executable without prefix ## The above recommended prefix causes long target names, the following renames the ## target back to the shorter version for ease of user use ## e.g. "rosrun someones_pkg node" instead of "rosrun someones_pkg someones_pkg_node" # set_target_properties(${PROJECT_NAME}_node PROPERTIES OUTPUT_NAME node PREFIX "") ## Add cmake target dependencies of the executable ## same as for the library above # add_dependencies(${PROJECT_NAME}_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) ## Specify libraries to link a library or executable target against # target_link_libraries(${PROJECT_NAME}_node # ${catkin_LIBRARIES} # ) ############# ## Install ## ############# # all install targets should use catkin DESTINATION variables # See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html ## Mark executable scripts (Python etc.) for installation ## in contrast to setup.py, you can choose the destination # catkin_install_python(PROGRAMS # scripts/my_python_script # DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} # ) ## Mark executables for installation ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_executables.html # install(TARGETS ${PROJECT_NAME}_node # RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} # ) ## Mark libraries for installation ## See http://docs.ros.org/melodic/api/catkin/html/howto/format1/building_libraries.html # install(TARGETS ${PROJECT_NAME} # ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} # LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} # RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION} # ) ## Mark cpp header files for installation # install(DIRECTORY include/${PROJECT_NAME}/ # DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION} # FILES_MATCHING PATTERN "*.h" # PATTERN ".svn" EXCLUDE # ) ## Mark other files for installation (e.g. launch and bag files, etc.) # install(FILES # # myfile1 # # myfile2 # DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION} # ) ############# ## Testing ## ############# ## Add gtest based cpp test target and link libraries # catkin_add_gtest(${PROJECT_NAME}-test test/test_handmsg.cpp) # if(TARGET ${PROJECT_NAME}-test) # target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME}) # endif() ## Add folders to be run by python nosetests # catkin_add_nosetests(test)
最新发布
07-12
-- Found Protobuf: /usr/lib/aarch64-linux-gnu/libprotobuf.a;-lpthread (found version "3.0.0") Generated: /home/songzhiyi/onnx-rel-1.13.0/.setuptools-cmake-build/onnx/onnx-ml.proto Generated: /home/songzhiyi/onnx-rel-1.13.0/.setuptools-cmake-build/onnx/onnx-operators-ml.proto Generated: /home/songzhiyi/onnx-rel-1.13.0/.setuptools-cmake-build/onnx/onnx-data.proto -- Could NOT find pybind11 (missing: pybind11_DIR) CMake Error at CMakeLists.txt:463 (message): cannot find pybind -- Configuring incomplete, errors occurred! See also "/home/songzhiyi/onnx-rel-1.13.0/.setuptools-cmake-build/CMakeFiles/CMakeOutput.log". See also "/home/songzhiyi/onnx-rel-1.13.0/.setuptools-cmake-build/CMakeFiles/CMakeError.log". Traceback (most recent call last): File "setup.py", line 381, in <module> "backend-test-tools = onnx.backend.test.cmd_tools:main", File "/home/songzhiyi/.local/lib/python3.6/site-packages/setuptools/__init__.py", line 153, in setup return distutils.core.setup(**attrs) File "/usr/lib/python3.6/distutils/core.py", line 148, in setup dist.run_commands() File "/usr/lib/python3.6/distutils/dist.py", line 955, in run_commands self.run_command(cmd) File "/usr/lib/python3.6/distutils/dist.py", line 974, in run_command cmd_obj.run() File "/usr/lib/python3.6/distutils/command/build.py", line 135, in run self.run_command(cmd_name) File "/usr/lib/python3.6/distutils/cmd.py", line 313, in run_command self.distribution.run_command(command) File "/usr/lib/python3.6/distutils/dist.py", line 974, in run_command cmd_obj.run() File "setup.py", line 233, in run self.run_command("cmake_build") File "/usr/lib/python3.6/distutils/cmd.py", line 313, in run_command self.distribution.run_command(command) File "/usr/lib/python3.6/distutils/dist.py", line 974, in run_command cmd_obj.run() File "setup.py", line 219, in run subprocess.check_call(cmake_args) File "/usr/lib/python3.6/subprocess.py", line 311, in check_call raise CalledProcessError(retcode, cmd) subprocess.CalledProcessError: Command '['/usr/bin/cmake', '-DPYTHON_INCLUDE_DIR=/usr/include/python3.6m', '-DPYTHON_EXECUTABLE=/usr/bin/python3.6', '-DBUILD_ONNX_PYTHON=ON', '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON', '-DONNX_NAMESPACE=onnx', '-DPY_EXT_SUFFIX=.cpython-36m-aarch64-linux-gnu.so', '-DCMAKE_BUILD_TYPE=Release', '-DONNX_ML=1', '/home/songzhiyi/onnx-rel-1.13.0']' returned non-zero exit status 1.
07-01
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值