make cmake catkin_make
Posted konglingbin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了make cmake catkin_make相关的知识,希望对你有一定的参考价值。
在Linux下进行C语言编程,必然要采用GNU GCC来编译C源代码生成可执行程序。
一、GCC快速入门
Gcc指令的一般格式为:Gcc [选项] 要编译的文件 [选项] [目标文件]
其中,目标文件可缺省,Gcc默认生成可执行的文件名为:a.out
然后输入./a.out 便可运行得到结果
二、GCC的命令剖析--四步走
GCC编译C源码有四个步骤:
预处理-----> 编译 ----> 汇编 ----> 链接
1.预处理,生成预编译文件(.i文件):
Gcc –E hello.c –o hello.i
2.编译,生成汇编代码(.s文件):
Gcc –S hello.i –o hello.s
3.汇编,生成目标文件(.o文件):
Gcc –c hello.s –o hello.o
4.链接,生成可执行文件:
Gcc hello.o –o hello
整个过程如果想一步到位:
gcc hello.c -o hello
gcc简介
Linux系统下的gcc(GNU C Compiler)是GNU推出的功能强大、性能优越的多平台编译器,是GNU的代表作品之一。gcc是可以在多种硬体平台上编译出可执行程序的超级编译 器,其执行效率与一般的编译器相比平均效率要高20%~30%。gcc编译器能将C、C++语言源程序、汇程式化序和目标程序编译、连接成可执行文件,如 果没有给出可执行文件的名字,gcc将生成一个名为a.out的文件。在Linux系统中,可执行文件没有统一的后缀,系统从文件的属性来区分可执行文件 和不可执行文件。而gcc则通过后缀来区别输入文件的类别,下面我们来介绍gcc所遵循的部分约定规则。
.c为后缀的文件,C语言源代码文件;
.a为后缀的文件,是由目标文件构成的档案库文件;
.C,.cc或.cxx 为后缀的文件,是C++源代码文件;
.h为后缀的文件,是程序所包含的头文件;
.i 为后缀的文件,是已经预处理过的C源代码文件;
.ii为后缀的文件,是已经预处理过的C++源代码文件;
.m为后缀的文件,是Objective-C源代码文件;
.o为后缀的文件,是编译后的目标文件;
.s为后缀的文件,是汇编语言源代码文件;
.S为后缀的文件,是经过预编译的汇编语言源代码文件
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文件谁写啊?亲,是你自己手写的。
11.当然如果你用IDE,类似VS这些一般它都能帮你弄好了,你只需要按一下那个三角形
12.接着是qmake,qmake是什么,先说一下Qt这个东西。Qt是跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。简单的说就是C++的第三方库,使用这个库你可以很容易生成windows,Linux,MAC os等等平台的图形界面。现在的Qt还包含了开发各种软件一般需要用到的功能模块(网络,数据库,XML,多线程啊等等),比你直接用C++(只带标准内裤那种)要方便和简单。
13.你可以用Qt简简单单就实现非常复杂的功能,是因为Qt对C++进行了扩展,你写一行代码,Qt在背后帮你写了几百上千行,而这些多出来的代码就是靠Qt专有的moc编译器(The Meta-Object Compiler)和uic编译器(User Interface Complier)来重新翻译你那一行代码。问题来了,你在进行程序编译前就必须先调用moc和uic对Qt源文件进行预处理,然后再调用编译器进行编译。上面说的那种普通makefile文件是不适用的,它没办法对qt源文件进行预处理。所以qmake就产生了。
14.qmake工具就是Qt公司制造出来,用来生成Qt 专用makefile文件,这种makefile文件就能自动智能调用moc和uic对源程序进行预处理和编译。qmake当然必须也是跨平台的,跟cmake一样能对应各种平台生成对应makefile文件。
15.qmake是根据Qt 工程文件(.pro)来生成对应的makefile的。工程文件(.pro)相对来说比较简单,一般工程你都可以自己手写,但是一般都是由Qt的开发环境 Qt Creator自动生成的,你还是只需要按下那个邪恶三角形就完事了。
16.还没有完,由于qmake很简单很好用又支持跨平台,而且是可以独立于它的IDE,所以你也可以用在非Qt工程上面,照样可以生成普通的makefile,只要在pro文件中加入CONFIG -= qt 就可以了。
17. 这样qmake和cmake有什么区别?
不好意思,cmake也是同样支持Qt程序的,cmake也能生成针对qt 程序的那种特殊makefile,
只是cmake的CMakeLists.txt 写起来相对与qmake的pro文件复杂点。
qmake 是为 Qt 量身打造的,使用起来非常方便,但是cmake功能比qmake强大。
一般的Qt工程你就直接使用qmake就可以了,cmake的强大功能一般人是用不到的。
当你的工程非常大的时候,又有qt部分的子工程,又有其他语言的部分子工程,据说用cmake会 方便,我也没试过。
1. catkin_make 与cmake的关系
程序在cmake编译是这样的流程, cmake指令依据你的CMakeLists.txt 文件,生成makefiles文件,make再依据此makefiles文件编译链接生成可执行文件.
catkin_make是将cmake与make的编译方式做了一个封装的指令工具, 规范了工作路径与生成文件路径.
1) cmake标准流程
- # 在一个CMake项目里
- $ mkdir build
- $ cd build
- $ cmake ..
- $ make
- $ make install # (可选)
2) catkin_make 的流程
- # In a catkin workspace
- $ catkin_make
- $ catkin_make install # (可选)
- 如果源码不在默认工作空间,需要指定编译路径:
- # In a catkin workspace
- $ catkin_make --source my_src
- $ catkin_make install --source my_src # (optionally)
1、在ros下创建工作空间:
mkdir -p catkin_ws/src
cd src
catkin_init_workspace
cd ..
catkin_make
2、创建功能包
方法一:利用catkin创建package
cd ~/catkin_ws/src
catkin_create_pkg beginner_tutorials std_msgs rospy roscpp
- 1
- 2
创建程序包的一般格式是catkin_create_pkg ,此命令的格式包括功能包名称和依赖项,在上面示例中,依赖项包括std_msg、rospy和roscpp。
运行上面命令之后,在src文件夹下会生成一个与功能包名同名的文件夹,在该文件夹下有如下文件(夹)
workspace_folder/
src/
package_name/
include --文件夹
src --文件夹
CMakeLists.txt
package.xml
- 1
方法二:利用roscreate创建package
cd ~/catkin_ws/src
roscreate-pkg beginner_tutorials std_msgs rospy roscpp
- 1
- 2
同样的,利用rosmake创建程序包的格式是roscreate-pkg ,此命令的格式也包括功能包名称和依赖项。
运行上面命令之后,在src文件夹下会生成一个与功能包名同名的文件夹,在该文件夹下有如下文件(夹)
workspace_folder/
src/
package_name/
include --文件夹
src --文件夹
CMakeLists.txt
manifest.xml
mainpage.dox
Makefile
- 1
3、编译功能包
方法一:利用catkin编译
用catkin编译的是上述第一种利用catkin创建的package,首先修改创建功能包时生成的CMakeLists.test文件,用gedit打开该文件,
⑴添加以下语句来查找添加的依赖包
find_package(catkin REQUIRED COMPONENTS
sensor_msgs
cv_bridge
image_transport)
find_package(OpenCV 2 REQUIRED)
find_package(PLC REQUIRED)
- 1
⑵添加以下语句来添加参与编译的节点程序
add_executable(node name src/node program)#添加可执行节点
target_link_libraries(node name ${catkin_LIBRARIES})#链接库
add_dependencies(node name package name_generator_messages_cpp)#为可执行文件添加对生成的消息文件的依赖,因为catkin把所有的package并行的编译,所以如果你要使用其他catkin工作空间中其他package的消息,你同样也需要添加对他们各自生成的消息文件的依赖,感觉就是一个先导入头文件的过程。
- 1
除了可以在创建功能包时添加系统提供的依赖(catkin_create_pkg beginner_tutorials std_msgs rospy roscpp),也可以修改创建功能包时生成的package.xml文件,以图像处理中所需用到的包为例,加入了以下指令来说明后面增加的依赖包
<run_depend>sensor_msgs</run_depend>
<run_depend>image_transport</run_depend>
<run_depend>cv_bridge</run_depend>
- 1
利用catkin编译的方法是:
#under workspace
catkin_make [make_targets] [-DCMAKE_VARIABLES=...]
- 1
方法二:利用rosmake编译
用rosmake编译的是上述第二种利用roscreate创建的package,同样的,在编译之前,需要修改CMakeLists.txt文件和manifest.xml文件,不同的地方是在修改CMakeLists.txt文件时需要加上如下语句来添加参与编译的节点程序:
rosbuild_add_executable(node_name src/node_name.cpp)
- 1
注意:
ROS从indigo开始就不再把opencv作为系统依赖包而是作为一个第三方包引入,如果直接使用会在rosmake编译阶段报错,no exist package “opencv2”,此时只需要在CMakeLists.txt中添加find_package(OpenCV 2 REQUIRED),然后在manifest.xml中不能添加依赖包,此处添加的为系统依赖包。
利用rosmkae编译的方法是:
#under workspace
rosmake package_name
- 1运行以上命令之后,如果编译没有出错,在bin文件夹下可以看到生成的可执行文件,可以直接运行./node_name来运行节点。
3、运行编译完成之后的节点(不用launch,还不懂)
rosrun package_name node_name
- 1注意:
1)创建功能包是在src目录下,而编译功能包是在workspace目录下。
2)编译之前要先确保添加了当前工作空间的path,查看方法是:
echo $ROS_PACKAGE_PATH
- 1添加方法是source setup.bash文件
#under the path: workspace
source ./devel/setup.bash
3)运行节点之前要下roscore
以上是关于make cmake catkin_make的主要内容,如果未能解决你的问题,请参考以下文章
如何用cmake搭建ros工程,make编译而不是catkin_make
CMake 错误:catkin_make :::Running 命令运行命令:“/ws/build”中的“make -j4 -l4”
“CMake 错误:CMake 无法确定目标的链接器语言” 当我 catkin_make ROS 工作空间时出现错误
程序找不到PCL的CMake files,catkin_make时报错
ROS Melodic笔记:catkin_make报错Invoking "make cmake_check_build_system" failed
在一个 QtCreator 版本中使用 cmake 构建失败,而它与另一个版本以及来自终端的 catkin_make 一起使用