1. cmake与make 的区别
程序的生成过程分为:源文件–编译–链接,这几个过程。
如果源文件太多,一个一个编译将成为问题,因此大佬们设计了一种批量编译程序的工具(make),这种工具需要根据规则对源码进行编译,这种规则就是makefile。
对于一个大的工程使用makefile编译,写这个makefile文本会比较复杂,为此大佬们又设计了一种工具,在读入原文件以后,自动生成makefile文件,这就是cmake,它能够输出各种各样makefile或者project文件,减轻了手写makefile的负担,因此cmake被称为半自助编译,两者之间的关系如图1所示,同样,cmake也需要遵循一定的语法规则,这就是下面要讲的内容。
参考资料: link.
2. 同一目录下只有一个原文件(内部编译)
a.建立ch1目录,在该目录下建立两个文件:main.cpp, CMakeLists.txt。他们关系如下图所示:
dong@pc:~/CMAKE/ch1$ tree
.
├── CMakeLists.txt
└── main.cpp
其中main.cpp代码为:
#include<iostream>
using namespace std;
int main()
{
cout << "Hello SLAM" << endl;
return 0;
}
CMakeLists.txt的代码为:
cmake_minimum_required(VERSION 2.8)
project(ch1)
add_executable(main main.cpp)
cmake_minimum_required:表示cmake的最低版本要求
project:设置生成的工程名
add_executable:定义该工程会生成一个文件名为main的可执行文件
b.回到ch1目录下,执行:
dong@pc:~/CMAKE/ch1$ cmake .
c.执行
dong@pc:~/CMAKE/ch1$ make
d.执行
dong@pc:~/CMAKE/ch1$ ./main
Hello SLAM
可以看到程序成功运行。
3.同一目录下只有一个原文件(外部编译)
内部编译生成的中间文件和执行文件与原文件混合在一起不方便管理,为此这里推荐一种外部编译方式。
a.建立ch2目录,在ch2目录下建立:build目录,main.cpp和CMakeLists.txt。其中main.cpp和CMakeLists.txt与ch1中的内容相同,结构如下图所示,
dong@pc:~/CMAKE/ch2$ tree
.
├── build
├── CMakeLists.txt
└── main.cpp
b.进入build目录
dong@pc:~/CMAKE/ch2$ cd build/
c.执行
dong@pc:~/CMAKE/ch2/build$ cmake ..
d.执行
dong@pc:~/CMAKE/ch2/build$ make
e.执行
dong@pc:~/CMAKE/ch2/build$ ./main
Hello SLAM
可以看到最后生成的中间文件和目标文件在build目录下。
4.同一个目录下多个原文件
建立ch3目录,在ch3目录下建立:build目录,main.cpp,fun.cpp, fun.h,CmakeLists.txt,结构图如下图所示:
dong@pc:~/CMAKE/ch3$ tree
.
├── build
├── CMakeLists.txt
├── fun.cpp
├── fun.h
└── main.cpp
a.各文件内容
fun.cpp
#include<iostream>
#include"fun.h"
using namespace std;
void function(void)
{
cout << "function" << endl;
}
fun.h
#ifndef _FUN_H
#define _FUN_H
void function(void);
#endif
main.cpp
#include<iostream>
#include"fun.h"
using namespace std;
int main()
{
function();
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(ch1)
add_executable(main main.cpp fun.cpp)
这里相对于第3节内容在CMakeLists.txt中的add_executable()添加了一丢丢内容,其他没有改变。
PS:对于多个原文件我们可以使用
add_executable(main a.cpp b.cpp ...)
也可以
set(SRC_LIST a.cpp b.cpp ...)
add_executable(main ${SRC_LIST})
还可以
aux_source_directory(. SRC_LIST)
add_executable(main ${SRC_LIST})
aux_source_directory(dir var) : 指定目录下所有的源文件存储在一个变量中,dir 表示指定目录,var用于存放源文件列表的变量。
b.其他步骤与第3节内容相同。
5. 对库的链接
建立ch6目录,目录结构如下所示
dong@pc:~/CMAKE/ch6$ tree
.
├── bin
├── build
├── CMakeLists.txt
├── lib
│ ├── libfun.a
│ └── libfun.so
├── lib_fun
│ ├── CMakeLists.txt
│ ├── fun.cpp
│ └── fun.h
└── src
├── CMakeLists.txt
└── main.cpp
这里ch6下的CMakeLists.txt为
cmake_minimum_required(VERSION 2.8)
project(ch6)
add_subdirectory(src)
add_subdirectory(lib_fun)
这里add_subdirectory()用于向当前工程添加存放源文件的子目录。
src目录下的CMakeLists.txt为:
aux_source_directory(. SRC_LIST)
include_directories(../lib_fun)
link_directories(${PROJECT_SOURCE_DIR}/lib)
add_executable(main ${SRC_LIST})
target_link_libraries(main fun)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
这里:
include_directories()用来向工程添加多个指定的头文件搜索路径
link_directories()添加非标准的共享库搜索路径
target_link_libraries(target library1 library2)用来为target添加需要链接的共享库。
参考资料: link.