C++ CMake
CMake跨平台,可以快速生成Makefile
CMake语法
1.基本格式
指令(参数1 参数2)
参数之间不能使用,可以使用;或空格
指令大小写无关,参数和变量区分大小写
例如:
set(HELLO hello.cpp)
变量使用${}取值,在IF中直接使用变量名
ADD_EXECUTABLE(hello main.cpp ${HELLO})
使用方式和常用变量,指令
1. cmake_minimum_required
#指定CMake的最小版本要求,一般写在第一行
#语法:
cmake_minimum_required(VERSION version [选项])
cmake_minimum_required(VERSION 2.8.3)
2. project -定义工程名称,指定支持的语言
#语法:(一般在第二行)
project(name [][][])
#例如:
project(helloworld [C++])
3. set-显式定义变量
#语法:set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
#定义SRC变量
set(SRC main.cpp hello.cpp)
4. 向工程添加多个头文件搜索路径
相当于g++的 -I
include_directories([AFTER|BEFORE][SYSTEM] dir1 dir2....)
include_directories(/usr/lib/folder ./include)
5. 添加特定的库文件搜索路径
g++指定 -L
link_directories(dir1 dir2...)
6. 生成库文件
SHARED为动态库
STATIC为静态库
语法:add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL]
source1 source2 ... sourceN)
add_library(hello SHARED ${SRC})#SRC即为之前定义的变量(文件名)
7. 添加编译参数
add_compile_options()
add_compile_options(-Wall -std=c++11 -O2)
8. 生成可执行文件
add_executable(name source1 source2 ... sourceN)
add_executable(main main.cpp)
9.为target添加需要连接的共享库
相当于g++ 中的-l(小写L)
语法:target_link_librasries(target library1<debug | optmized> library2....)
将hello动态库文件链接到可执行文件main
target_link_librasries(main hello)
10.
add_subdirectory - 向当前工程添加存放源文件的子目录,并可以指定中间二进制和目标二进制存放的位置
语法: add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
# 添加src子目录,src中需有一个CMakeLists.txt
add_subdirectory(src)
11. aux_source_directory
aux_source_directory - 发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指 令临时被用来自动构建源文件列表
语法: aux_source_directory(dir VARIABLE)
# 定义SRC变量,其值为当前目录下所有的源代码文件
aux_source_directory(. SRC)
# 编译SRC变量所代表的源代码文件,生成main可执行文件
add_executable(main ${SRC})
常用变量
gcc编译选项:CMAKE_C_FLAGS
,g++:CMAKE_CXX_FLAGS
#例如:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
设置编译类型:
#(1)设置调试:debug
set(CMAKE_BUILD_TYPE Debug)
#(2)设置发布 release
set(CMAKE_BUILD_TYPE Release)
使用CMake构建C++工程
终于到了实践的时候
我们项目的主目录中需要包含一个CMakeLists.txt文件
CMake有两种编译规则:
- 一种是项目目录中包含源文件的子文件夹中也有CMakeLists.txt,则我们需要通过aux_source_directory, 向当前工程添加存放源文件的子目录
- 另一种就是不包含的情况,这样我们就需要在主目录的CMakeLists.txt中添加子目录的编译规则
编译的步骤:
手写CMake(😀)
执行命令:cmake PATH
(PATH是主目录中的CMakeLists.txt所在的目录
执行make,编译并生成可执行文件
构建方式:分为内部,外部构建
内部:
在当前目录下编译本目录的CMakeLists.txt,生成Makefile
外部:
在当前目录创建build文件夹,进入文件夹,编译上级目录的CMakeLists.txt,生成的文件会保存到build文件夹中,再执行make命令(主要使用这种)
CMake实践
1. Hello,World
最简单的输出一行Hello,World的程序
CMakeLists.txt放于项目文件夹的顶层目录
1.在当前文件夹下(顶层文件夹下)直接编译CMakeLists.txt
cmake_minimum_required(VERSION 3.0)
project(helloworld)
# 指令大小写无关
#指定可执行文件名字和源文件
add_executable(helloworld_cmake helloworld.cpp)
2.外部构建
root@ziggy-virtual-machine:~/CMake_pj# mkdir build
root@ziggy-virtual-machine:~/CMake_pj# cd build/
root@ziggy-virtual-machine:~/CMake_pj/build# cmake ..
root@ziggy-virtual-machine:~/CMake_pj/build# make
2. 多目录多文件的项目构建
目录结构:
//swap.h
#pragma once
#include<iostream>
class Swap{
int _a,_b;
public:
Swap(){
}
Swap(int a,int b):_a{a},_b{b}
{
}
void run();
void printInfo();
};
//swap.cpp
#include"swap.h"
void Swap::printInfo(){
std::cout<<this->_a<<" "<<this->_b<<std::endl;
}
void Swap::run(){
int t = this->_a;
this->_a = this->_b;
this->_b = t;
}
//main.cpp
#include<iostream>
#include"swap.h"
using namespace std;
int main()
{
Swap a{1,2};
a.run();
a.printInfo();
return 0;
}
cmake_minimum_required(VERSION 3.0)
project(SWAP)
add_compile_options(-std=c++11 -O2)
include_directories(include)
add_executable(main_cmake main.cpp src/swap.cpp)