cmake使用教程
本教程是参考高翔视觉SLAM十四讲中的讲解。
在一个 cmake工程中,首先会用 cmake 命令生成一个 makefile 文件,然后用make命令根据这个makefile 文件的内容编译整个工程。
示例:
示例
基础编译流程
先建立一个项目文件夹 project1,在文件夹里面建立一个名为 helloSLAM.cpp 的文件:
//helloSLAM.cpp
#include <iostream>
using namespace std;
int main(int argc, char **argv)
{
cout << "Hello SLAM!" << endl;
return 0;
}
然后建立一个 CMakeLists.txt 文件:
#声明要求的cmake最低版本
cmake_minimum_required( VERSION 2.8 )
#声明一个cmake工程
project( HelloSLAM )
#添加一个可执行程序
#语法:add_executable(程序名 源代码文件)
add_executable(helloSLAM helloSLAM.cpp)
CMakeLists.txt 文件用于告诉 cmake 要对这个目录下的文件做什么事情。CMakeLists.txt文件内容需要遵守 cmake 的语法。在这个示例中,演示了最基本的工程:指定一个工程名和一个可执行程序。
在该文件下,利用终端输入:
mkdir build
cd build
cmake ..
make
新建一个 build 文件夹,然后进入 build 文件夹,通过 cmake … 命令对上一层文件夹进行编译,这样 cmake 产生的中间文件就会生成在 build 文件夹中,与源码分开。当发布源码时,只要把 build 文件夹删除即可。
使用库
在 C++工程中,并不是所有代码都会编码成可执行文件。只有 main 函数的文件才会生成可执行文件。而另一些代码,可以把1它们打包成一个东西,使其他程序调用。这个东西叫做库。
如何用 cmake 生成库
在文件夹下新建一个 libHelloSLAM.cpp 文件:
//这是一个库文件
#include <iostream>
using namespace std;
void printHello()
{
cout << "Hello SLAM" << endl;
}
这个库提供了一个 printHello() 函数,调用此函数将输出一条消息。但是它没有 main() 函数,这意味着这个库中没有可执行文件。
在 CMakeLists.txt 中加上如下内容:
add_library( hello libHelloSLAM.cpp )
这条命令告诉 cmake,想把这个文件编译成一个叫作 “hello” 的库。然后,和上面一样,利用cmake 编译整个工程:
cd build
cmake ..
make
这时,在 build 文件夹中就会生成一个 libhello.a 文件,这就是得到的库。
在 linux 中, 库分为静态库和动态库两种。 静态库以 .a 作为后缀名,共享库以 .so 结尾。所有库都是一些函数打包后的集合,差别在于静态库每次被调用都会生成一个副本,而共享库则只有一个副本,更省空间。如果想生成共享库而不是静态库,只需要在 CMakeLists.txt 中使用如下内容:
add_library( hello_shared SHARED libHelloSLAM.cpp )
和上面一样,利用cmake 编译整个工程:
cd build
cmake ..
make
此时得到的文件就是 libhello_shared.so。
如何调用库
库文件是一个压缩包,里面有编译好的二进制函数。如果仅有 .a 或者 .so 文件,并不知道里面的函数到底是什么,调用的形式又是什么样的。为了让别人使用这个库,需要提供一个头文件。
下面编写 libhello 的头文件 libHelloSLAM.h:
#ifndef LIBHELLOSLAM_H_
#define LIBHELLOSLAM_H_
//上面的宏定义是为了防止重复引用这个头文件而引起的重定义错误
//打印一句Hello的函数
void printHello();
#endif
这样,根据这个文件和刚才编译得到的库文件就可以使用 printHello 函数了。
例如,使用下方这个可执行程序来调用这个简单的函数 useHello.cpp:
#include "libHelloSLAM.h"
//使用libHelloSLAM.h中的printHello()函数
int main(int argc, char **argv) {
printHello();
return 0;
}
在 CMakeLists.txt 中添加一个可执行程序的生成命令,链接到刚才生成的库上:
add_executable(useHello, useHello.cpp)
target_link_libraries(useHello, hello_shared)
通过这两行语句, useHello 程序就能顺利使用 hello_shared 库中的代码了。
这个例子演示了如何生成并调用一个库。对于他人提供的库,也可以用同样的方式对它们进行调用并整合到自己的程序中。