cmake学习(一)
为了编写项目的cmake文件,简单学习一下。
一、cmake主要介绍
编写项目时,需要决定代码的组织方式以及编译方式,需要工具来构建、维护代码
cmake首先是makefile的上层工具,目的是为了产生可移植的makefile,不需要自己手写makefile。
另外,makefile在不同的环境下,可能有不同的写法,cmake也可以来规避这个问题,让我们不需要关心环境。
cmake的几个特点:
- 开放源代码,使用类 BSD 许可发布。
- 跨平台
- 管理大型项目
- 简化编译构建过程和编译过程
- 可扩展
二、基本语法介绍
通过自己编写的几个小例子,边编写边分析边学习。
1、单源文件的cmake构建
目录结构:
.
├── build
├── CMakeLists.txt
└── main.cpp
main.cpp
#include <iostream>
using namespace std;
int main()
{
cout<<"hello world"<<endl;
return 0;
}
CMakeLists.txt(注意名字,只能这么写)
#指定cmake最低版本要求
cmake_minimum_required(VERSION 2.6)
#项目名称
project(single_dir_single_source)
# 添加可执行文件 [可执行文件名称][参数(一般不用)][source1 source2...]
add_executable(sdss main.cpp)
cmake命令:cmake CMakeLists.txt所在路径
- 为了有条理,一般会在项目中新建一个build文件夹,用来存放cmake后的生成文件
# CMakeLists.txt所在路径
cd build
cmake .. #生成MakeFile
make #编译
执行后的结果:
2、多源文件的构建
目录结构:
.
├── build
├── CMakeLists.txt
├── include
│ ├── CMakeLists.txt
│ ├── math
│ │ ├── add.cpp
│ │ ├── add.h
│ │ ├── add_plus.cpp
│ │ └── add_plus.h
│ └── str
│ ├── str_demo.cpp
│ └── str_demo.h
└── src
└── main.cpp
说明:
- include文件夹下定义了两个库
- 分别在两个文件下,定义了源文件以及对应的.h文件
- math文件夹下,add_plus引用了add
- src文件夹下的main.cpp源文件调用了楼上的两个库
main.cpp
#include <iostream>
#include <cstdio>
#include "../include/math/add.h"
#include "../include/str/str_demo.h"
#include "../include/math/add_plus.h"
#include <cstring>
using namespace std;
int main()
{
int a = 1;
int b = 2;
string as = "hel";
string bs = "lo";
//math
cout<<"test math include"<<endl;
cout<<add_two(a,b)<<endl;
ADD* add_ = new ADD(a,b);
cout<<add_->add_two()<<endl;
cout<<add_ns::add_two_ns(a,b)<<endl;
cout<<add_plus(a,b)<<endl;
cout<<"test str include"<<endl;
cout<<add_str(as,bs)<<endl;
return 0;
}
这里如果只是单纯地add_executable,会发生找不到头文件的问题。
正确做法:
在目录include下创建CMakeLists.txt文件,用于构建链接库:
include/CMakeLists.txt
# 创建链接库 [name] [参数 SHARED:动态链接 STATIC:静态链接] [对应的源文件]
add_library(math SHARED ./math/add.cpp)
add_library(str_demo SHARED ./str/str_demo.cpp)
# 源文件的顺序貌似没关系?(经过测试)
add_library(add_plus SHARED ./math/add.cpp ./math/add_plus.cpp)
主目录下的CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project(multi_source)
# 使用命令 ADD_SUBDIRECTORY 指明本项目包含一个子目录
add_subdirectory(include)
#定义两个变量 存储两个库目录下的源文件路径
# 虽然这个文件里没用到,但是还是很实用的
aux_source_directory(./include/math DIR_MATH_SRCS)
aux_source_directory(./inlcude/str DIR_STR_SRCS)
add_executable(ms ./src/main.cpp)
# 不链接的话找不到头文件的
# [可执行文件] [依赖的库文件]
target_link_libraries(ms str_demo math add_plus)
之后的步骤同上一个例子的步骤
结果:
另外,在上面例子的基础上,在src路径下创建一个test1.h和test.cpp文件,在main.cpp中引用头文件。
CMakeLists.txt的修改:
# 源文件的顺序也是不影响的?
add_executable(ms ./src/main.cpp ./src/test1.cpp)
另外,在main.cpp中引用头文件时,使用了相对路径(比较丑)。可以使用include_directories将指定目录添加到编译器的头文件搜索路径之下,指定的目录被解释成当前源码路径的相对路径。
修改后的CMakeLists.txt
#将指定目录添加到编译器的头文件搜索路径之下,指定的目录被解释成当前源码路径的相对路径。
include_directories(./include)
修改后的main.cpp
#include "math/add.h"
#include "str/str_demo.h"
#include "math/add_plus.h"
测试正确。
学习链接
cmake快速入门 https://blog.youkuaiyun.com/kai_zone/article/details/82656964
Cmake命令之add_executable介绍 https://www.jianshu.com/p/19765d4932a4
cmake : add_library详解 https://blog.youkuaiyun.com/LaineGates/article/details/108242803
Cmake命令之add_subdirectory介绍 https://www.jianshu.com/p/07acea4e86a3
aux_source_directory https://blog.youkuaiyun.com/ccf19881030/article/details/107506936
Cmake命令之include_directories介绍 https://www.jianshu.com/p/e7de3de1b0fa