CMakeLists写法总结

本文介绍了CMakeLists的常见写法,包括设置最低版本、项目名称、查找外部库、设置源文件路径等,并以OpenCV为例说明如何配置库。

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

个人最近学习了一些关于常见的CMakeLists的一些写法格式,分享给大家。

    CMAKE_MINIMUM_REQUIRED(VERSION xxx) 该项表示要求CMAKE的最低版本号.

    PROJECT(aim1) 此项表示所建立的工程名称 aim1;

    FIND_PACKAGE(xxx)该命令首先会在模块路径中寻找 Find<name>.cmake,这是查找库的一个典型方式。具体查找路径依次为CMake: 变量${CMAKE_MODULE_PATH}中的所有目录。如果没有查询到,随后会查看它自己的模块目录 /share/cmake-x.y/Modules/ ;

     如果没找到这样的文件,find_package()会在~/.cmake/packages//usr/local/share/中的各个包目录中查找,寻找<库名字的大写>Config.cmake 或者 <库名字的小写>-config.cmake (比如FIND_PACKAGE(Opencv REQUIRED),它会查找/usr/local/share/OpenCV中的OpenCVConfig.cmakeopencv-config.cmake)。个人认为这是CMake内置的快速查找方法

   SET( SRC_DIR_PATH src ),SET命令是用来设置变量,换句话说就是给变量赋值,例如本条命令表示SRC_DIR_PATH=src,注意这里的src代表Cmakelists的相对路径,即目录内的src文件夹,。SRC_DIR_PATH表示源文件目录路径。

    FILE(GLOB_RECURSE SOURCE_FILES "src/*.cpp"),FILE文件命令具体包括许多,在这里使用GLOB_RECURSE 代表把该目录(src下)的所有源文件都赋予变量SOURCE_FILES。

   INCLUDE_DIRECTORIES(xxx/include),INCLUDE就像源文件内的include一样,用来设置头文件。这里是用来设置头文件的搜索目录。告诉CMake,编译的时候去哪里找头文件。

   LINK_DIRECTORIES(xxx/lib),LINK就是链接的意思,lib是库,该命令就是要链接库,设置动态链接库的目录,例如链接caffe,可以表示为LINK_DIRECTORIES(/home/usr/caffe/build/lib)。既然已经设置好了链接库的目录,那么具体需要链接哪些库,需要通过下面的操作完成。

   SET( LIB_PROJECT caffe glog boost_system protobuf boost_thread gflags ),该命令是在设置链接库文件的名称。

   随后,需要在ADD_EXECUTABLE()命令后写出TARGET_LINK_LIBRARIES(aim1 ${LIB_PROJECT}),要链接的动态库, 参数指明库的名字即可,比如libcaffe.so,这里是需要加上lib前缀和.so后缀的,或者以变量的形式表示。而上条设置名称时,不需要这些前后缀。

   ADD_EXECUTABLE(TARGET ${PUBLIC_SRC_FILE} ${SRC_DIR_PATH}/detect_read_video_mixture.cpp ),生成可执行文件,需要将生成的名称和TARGET_LINK_LIBRARIES必须保持一致。

message( STATUS "hello world"),message命令就是向终端窗口发送消息,例如本条命令就是发送hello world。

 

 

CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
# 指定工程名称
PROJECT(abc)
set(CMAKE_CXX_FLAGS "-std=c++11")

# 导入OpenCV库
FIND_PACKAGE( OpenCV REQUIRED )

# 设置源文件
SET( SRC_DIR_PATH src )
FILE(GLOB_RECURSE SOURCE_FILES "src/*.cpp")

# 设置头文件搜索目录
SET( CAFFE_ROOT /home/kevin/SSD/caffe)
SET( CUDA_HOME /usr/local/cuda-8.0 )
INCLUDE_DIRECTORIES(${CAFFE_ROOT}/include/ ./include/ ${CAFFE_ROOT}/.build_release/src/ ${CUDA_HOME}/include/ )

# 设置动态库链接目录
LINK_DIRECTORIES( ${CAFFE_ROOT}/build/lib/ ${CUDA_HOME}/lib64/)

# 设置要链接的库文件
SET( LIB_PROJECT caffe glog boost_system protobuf boost_thread gflags)

# 指定执行文件输出目录
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
# 生成可执行文件,即程序
ADD_EXECUTABLE( abc ${PUBLIC_SRC_FILE} ${SRC_DIR_PATH}/test.cpp  )

# 要链接的动态库, 参数指明库的名字即可,比如libxxxx1.so, 指明是xxxx1即可!!!
TARGET_LINK_LIBRARIES( abc ${LIB_PROJECT} ${OpenCV_LIBS} )

 

<think>我们正在解决CMake项目中头文件找不到的问题(no such file or directory)。根据用户提供的引用和问题,我们将重点放在如何配置CMakeLists.txt文件上。 引用分析: [^1]:展示了如何用configure_file生成配置文件,但这不是解决头文件路径的关键。 [^2]:重点在于在CMakeLists.txt中配置头文件路径,特别是使用`include_directories`来包含catkin和生成的头文件路径(如devel/include)。这提示我们需要使用`include_directories`或类似命令来添加头文件搜索路径。 [^3]:虽然讲的是Clion中工作目录的问题,但提醒我们路径设置的重要性,以及相对路径和绝对路径的使用。 [^4]:展示了在ESP32项目中,通过添加组件(COMPONENT_REQUIRES)来解决头文件找不到的问题。这类似于在CMake中添加依赖的库或组件。 因此,解决方案将围绕CMakeLists.txt中的以下关键点: 1. 使用`include_directories`或`target_include_directories`添加头文件路径。 2. 使用`add_subdirectory`或`find_package`来引入依赖的库(如果头文件在外部库中)。 3. 对于自动生成的头文件(如通过protobuf、ROS消息生成等),需要包含生成目录(如${CATKIN_DEVEL_PREFIX}/include或${CMAKE_BINARY_DIR}/generated/include)。 4. 对于组件化的项目(如ESP-IDF),需要在组件依赖中声明。 具体步骤: 步骤1:使用`include_directories`(全局)或`target_include_directories`(针对特定目标)添加头文件路径。 示例: ```cmake # 添加全局头文件搜索路径(所有目标都会使用) include_directories( ${PROJECT_SOURCE_DIR}/include # 项目自己的头文件目录 ${CMAKE_BINARY_DIR}/generated # 如果有自动生成的头文件 /path/to/external/include # 外部库的头文件路径 ) ``` 或者更推荐的方式(针对特定目标,避免污染全局): ```cmake # 在创建目标(如可执行文件或库)后,使用target_include_directories add_executable(my_target main.cpp) target_include_directories(my_target PRIVATE ${PROJECT_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/generated ) ``` 步骤2:如果头文件属于其他库(如第三方库),需要先通过`find_package`或`find_library`找到库,然后链接并包含头文件。 例如,使用find_package找到OpenCV: ```cmake find_package(OpenCV REQUIRED) # 然后包含头文件路径和链接库 target_include_directories(my_target PRIVATE ${OpenCV_INCLUDE_DIRS}) target_link_libraries(my_target ${OpenCV_LIBS}) ``` 步骤3:对于自动生成的头文件(如通过ROS的add_message_files生成的msg头文件),需要确保包含生成目录。在ROS中,通常包含${catkin_INCLUDE_DIRS}和${CATKIN_DEVEL_PREFIX}/include(如引用[2]所示)。 示例(ROS): ```cmake include_directories( ${catkin_INCLUDE_DIRS} ${CATKIN_DEVEL_PREFIX}/include ) ``` 步骤4:在类似ESP32的组件化项目中,需要在组件的CMakeLists.txt中声明依赖的组件(如引用[4]所示)。 示例(ESP-IDF): ```cmake set(COMPONENT_REQUIRES adf_utils # 添加头文件所在的组件 ... # 其他组件 ) ``` 步骤5:确保路径正确,避免空格和特殊字符。如果路径包含空格,使用引号(如引用[3]的启示,虽然它是关于工作目录的,但路径处理原则相同)。 步骤6:如果头文件位于子项目中,使用`add_subdirectory`引入子项目,然后通过`target_link_libraries`链接子项目,这样头文件路径会自动传递(如果子项目正确设置了INTERFACE_INCLUDE_DIRECTORIES)。 示例: ```cmake add_subdirectory(subproject) target_link_libraries(my_target PRIVATE subproject_target) ``` 步骤7:在构建后,如果仍然出现错误,检查生成的头文件是否在预期位置。有时生成头文件需要在编译开始前完成,确保在包含之前有正确的依赖关系(例如,使用add_custom_command或add_custom_target确保头文件生成)。 总结配置示例(非ROS): ```cmake cmake_minimum_required(VERSION 3.10) project(my_project) # 设置C++标准 set(CMAKE_CXX_STANDARD 11) # 添加生成的头文件目录(如果有) set(GENERATED_DIR "${CMAKE_BINARY_DIR}/generated") file(MAKE_DIRECTORY ${GENERATED_DIR}) # 确保目录存在 # 如果有自定义命令生成头文件,这里添加 # 添加可执行文件 add_executable(my_app main.cpp) # 添加头文件路径(推荐使用target_include_directories) target_include_directories(my_app PRIVATE ${PROJECT_SOURCE_DIR}/include ${GENERATED_DIR} ) # 如果使用了第三方库,使用find_package find_package(SomeLibrary REQUIRED) target_include_directories(my_app PRIVATE ${SomeLibrary_INCLUDE_DIRS}) target_link_libraries(my_app ${SomeLibrary_LIBRARIES}) # 如果有子目录 add_subdirectory(lib) target_link_libraries(my_app PRIVATE my_lib) ``` 对于ROS项目,参考引用[2]的配置: ```cmake # ROS特定的配置 find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs message_generation # 如果需要生成消息 ) # 添加消息文件 add_message_files( FILES MyMessage.msg ) # 生成消息 generate_messages( DEPENDENCIES std_msgs ) # 设置包含路径 include_directories( ${catkin_INCLUDE_DIRS} ${CATKIN_DEVEL_PREFIX}/include # 生成的消息头文件在此 ) # 添加可执行文件 add_executable(my_ros_node src/main.cpp) # 链接库 target_link_libraries(my_ros_node ${catkin_LIBRARIES}) # 添加对生成消息的依赖(确保先编译生成消息) add_dependencies(my_ros_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS}) ``` 最后,确保在构建项目时,工作目录设置正确(如引用[3]所述,在CLion中设置工作目录为项目根目录,或者在CMake中设置运行时工作目录)。 通过以上步骤,应该能够解决CMake项目中头文件找不到的问题。</think>### 如何配置 CMakeLists.txt 解决头文件找不到的问题 以下是解决 `no such file or directory` 错误的完整指南,结合引用内容和最佳实践: --- #### 一、核心配置步骤(必做) 1. **添加头文件搜索路径** 使用 `include_directories()` 或 `target_include_directories()` 指定头文件位置: ```cmake # 添加项目内头文件路径 include_directories( ${PROJECT_SOURCE_DIR}/include # 自定义头文件目录 ${CATKIN_DEVEL_PREFIX}/include # ROS生成的头文件[^2] ) # 添加第三方库路径(推荐方式) target_include_directories(your_target PRIVATE /usr/local/include/opencv4 # 绝对路径 ${SomeLibrary_INCLUDE_DIRS} # 通过find_package获取的变量 ) ``` 2. **声明组件依赖**(ESP32/ROS等组件化项目) 在 `COMPONENT_REQUIRES` 中添加头文件所属组件[^4]: ```cmake # ESP32项目示例 set(COMPONENT_REQUIRES esp_actions adf_utils # 添加头文件所在组件[^4] ) ``` 3. **处理生成的头文件** 对通过工具生成的头文件(如ROS消息/Protobuf): ```cmake # ROS消息生成配置[^2] add_message_files(FILES your_msg.msg) generate_messages(DEPENDENCIES std_msgs) include_directories(${CATKIN_DEVEL_PREFIX}/include) ``` --- #### 二、进阶配置技巧 1. **路径变量使用规范** ```cmake # 正确写法(含空格路径用引号) include_directories("C:/Program Files/opencv/include") # 错误写法(路径被截断) include_directories(C:/Program Files/opencv/include) # 报错[^3] ``` 2. **相对路径基准设置** 在CLion等IDE中指定工作目录: ```cmake # 设置运行时工作目录(避免cmake-build-debug问题)[^3] set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) ``` 3. **自动配置文件生成** 处理模板生成的头文件: ```cmake configure_file( "${PROJECT_SOURCE_DIR}/config.h.in" "${PROJECT_BINARY_DIR}/config.h" # 生成到构建目录[^1] ) include_directories(${PROJECT_BINARY_DIR}) ``` --- #### 三、验证配置是否生效 1. **检查包含路径** 在构建目录执行: ```bash cmake --build . --verbose | grep "-I" # 查看实际包含路径 ``` 2. **测试预处理** 强制重新生成依赖关系: ```bash touch CMakeLists.txt && cmake --build . --target rebuild_cache ``` --- #### 四、不同场景解决方案 | 场景 | 解决方案 | |-----------------------|--------------------------------------------------------------------------| | **ROS消息头文件缺失** | 包含 `${CATKIN_DEVEL_PREFIX}/include` 并检查 `package.xml`[^2] | | **ESP32组件头文件** | 在 `COMPONENT_REQUIRES` 添加组件名[^4] | | **Windows路径问题** | 使用引号包裹含空格路径,避免 `Program Files` 等目录[^3] | | **生成头文件缺失** | 确保 `configure_file` 或 `add_custom_command` 在目标之前执行 | > **关键原则**: > 所有头文件路径必须满足: > $$ \text{编译时路径} = \text{CMake配置路径} + \text{代码包含路径} $$ --- ### 配置示例(ROS项目) ```cmake cmake_minimum_required(VERSION 3.5) project(your_project) find_package(catkin REQUIRED COMPONENTS roscpp message_generation # 消息生成依赖 ) # 1. 声明消息文件 add_message_files(FILES YourMessage.msg) # 2. 生成消息头文件 generate_messages(DEPENDENCIES std_msgs) # 3. 包含路径(关键!) include_directories( ${catkin_INCLUDE_DIRS} ${CATKIN_DEVEL_PREFIX}/include # 生成头文件位置[^2] ) # 4. 添加可执行文件 add_executable(node_name src/main.cpp) # 5. 链接库和依赖 target_link_libraries(node_name ${catkin_LIBRARIES}) add_dependencies(node_name ${${PROJECT_NAME}_EXPORTED_TARGETS}) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值