CMake,make,CMakeLists.txt,CMakeFiles之间的关系

参考https://www.zhihu.com/question/36609459

对于一个只在windows界混的菜鸟程序员,平常用Visual Studio(号称宇宙最强IDE),就能实现新建工程,编写*.cpp,*.h,编译(即build,这里的编译实际包括了编译,汇编,链接等等,见下面截图)

过程神马的都帮你弄好了,按个快捷键(ctrl +shift+B或者F7,好像还可以自定义),Build就开始了。

然而,当我知道CMake后,通常介绍说跨平台特别方便,高手必备技能,晕了。。。

下面只简单说下CMake,make,CMakeLists.txt,CMakeFiles之间的关系

1.gcc是GNU Compiler Collection(就是GNU编译器套件),也可以简单认为是编译器,它可以编译很多种编程语言(括C、C++、Objective-C、Fortran、Java等等)。

2.当你的程序只有一个源文件时,直接就可以用gcc命令编译它。

3.但是当你的程序包含很多个源文件时,用gcc命令逐个去编译时,你就很容易混乱而且工作量大

4.所以出现了make工具
make工具可以看成是一个智能的批处理工具,它本身并没有编译和链接的功能,而是用类似于批处理的方式—通过调用makefile文件中用户指定的命令来进行编译和链接的。

5.makefile是什么?简单的说就像一首歌的乐谱,make工具就像指挥家,指挥家根据乐谱指挥整个乐团怎么样演奏,make工具就根据makefile中的命令进行编译和链接的。

6.makefile命令中就包含了调用gcc(也可以是别的编译器)去编译某个源文件的命令。

7.makefile在一些简单的工程完全可以人工手下,但是当工程非常大的时候,手写makefile也是非常麻烦的,如果换了个平台makefile又要重新修改。

8.这时候就出现了Cmake这个工具,cmake就可以更加简单的生成makefile文件给上面那个make用。当然cmake还有其他功能,就是可以跨平台生成对应平台能用的makefile,你不用再自己去修改了。

9.可是cmake根据什么生成makefile呢?它又要根据一个叫CMakeLists.txt文件(学名:组态档)去生成makefile。

10.到最后CMakeLists.txt文件谁写啊?亲,是你自己手写的。

举例

从源文件

hello.c

生成(构建)可执行文件

hello

需要执行

gcc hello.c -ohello

将上面的命令写到一个文件中,这个文件就是Makefile文件,执行make会执行Makefile中的所有命令

cmake是用来生成Makefile文件的工具,生成Makefile文件的工具不止有cmake,还有autotools。Qt环境下还有qmake

Windows下CMake,CMakeLists.txt的作用

CMakeLists.txt为描述编译链接的规则文件,也就是CMake.exe这个软件是根据解析这个txt文件来生成了VS工程文件(如.sln, vcproject)。个人理解:在windows下,CMakeLists.txt是用来生成组织层次。说白了就是,sln下有多少project,每个project下都有哪些*.cpp,*.h,每个project依赖于哪些其他的project等。

但是,编译,调试代码,还是用VS。即CMake.exe根据CMakeLists.txt生成了*.sln. 用VS打开sln,快捷键ctrl +shift+B。。。

至于Makefile用·没用到,我也不清楚。欢迎大神告知。

 

### CMake 解析错误分析 CMake 报错 `Parse error. Expected a command name, got unquoted argument` 表明在解析 `CMakeLists.txt` 文件时遇到了语法问题。具体来说,CMake 预期的是一个命令名称(如 `project()` 或 `add_executable()`),但却得到了未被正确引用的参数 `/opt/ros/<distro>/share/catkin/cmake/toplevel.cmake`。 #### 错误原因 1. **不完整的 `CMakeLists.txt` 文件** 如果 `CMakeLists.txt` 中仅包含一行路径字符串(如 `/opt/ros/noetic/share/catkin/cmake/toplevel.cmake`),这显然是不符合 CMake 语法规则的[^3]。CMake 要求文件中的每一行都必须是一个有效的命令调用。 2. **ROS 工作空间配置问题** 当使用 ROS 的 `catkin_make` 构建工具时,工作目录下的 `src/CMakeLists.txt` 应该由 Catkin 自动生成并填充必要的内容。如果此文件为空或者只有上述路径,则可能是由于初始化工作空间失败所致[^4]。 3. **依赖项缺失或版本冲突** 若系统中存在多个 ROS 版本(如 Melodic 和 Noetic 同时安装),可能会导致构建过程中加载错误的 `toplevel.cmake` 文件,从而引发解析错误[^5]。 --- ### 解决方案 #### 方法一:修复 `CMakeLists.txt` 确保 `src/CMakeLists.txt` 是标准的 Catkin 包模板文件。可以手动创建如下内容: ```cmake cmake_minimum_required(VERSION 2.8.3) project(your_package_name) find_package(catkin REQUIRED COMPONENTS roscpp std_msgs ) catkin_package() include_directories( ${catkin_INCLUDE_DIRS} ) add_executable(example_node src/example.cpp) target_link_libraries(example_node ${catkin_LIBRARIES}) ``` > 替换 `your_package_name` 和其他组件为你实际使用的包名及依赖库。 对于新项目,建议通过以下命令自动生成正确的结构: ```bash catkin_create_pkg your_package_name roscpp std_msgs ``` --- #### 方法二:重新初始化工作空间 删除现有的构建缓存并重新初始化工作空间可能解决问题: ```bash cd ~/catkin_ws/ rm -rf build devel source /opt/ros/<distro>/setup.bash catkin_init_workspace src/ catkin_make ``` 其中 `<distro>` 可能是 `melodic`, `noetic` 等具体的 ROS 发行版名称。 --- #### 方法三:检查环境变量设置 确认当前终端已正确加载目标 ROS 版本的环境变量: ```bash echo $ROS_DISTRO ``` 应返回对应的发行版名称(如 `noetic`)。如果没有生效,请执行以下命令: ```bash source /opt/ros/<distro>/setup.bash ``` 同时验证是否存在多版本冲突的情况。如果有重复定义的路径,可能导致加载了错误的 `toplevel.cmake` 文件。 --- #### 方法四:查看日志详情 当遇到无法定位的具体错误时,可以通过检查生成的日志文件获取更多信息: ```bash less ~/wpr_ws/build/CMakeFiles/CMakeOutput.log less ~/wpr_ws/build/CMakeFiles/CMakeError.log ``` 这些日志通常会提供更详细的上下文信息来帮助诊断问题所在。 --- ### 总结 以上方法涵盖了从基础到高级的不同层次解决方案。优先尝试修复 `CMakeLists.txt` 并清理重建工作区;若仍存在问题,则需进一步排查环境变量以及潜在的版本兼容性矛盾。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值