CMake 学习笔记
什么是CMake
CMake 一种跨平台编译工具。CMake通过编写CMakeLists.txt文件,然后使用cmake命令将CMakeLists.txt文件转化为make所需要的Makefile文件。从而我们就可以用make指令编译源码生成可执行文件或库。实际项目中C、C++ 文件可能很多,位置分散,makefile文件在不同平台上编写的方式可能不同,因此我们可以使用可以跨平台的Cmake工具生成makefile文件。
为什么用CMake
还用问吗? 当然是老板逼的。
怎么用CMake
Linux系统下CMake的使用流程基本如下:
(1)编写CMake所需的CMakeLists.txt文件
(2)执行指令:cmake PATH 生成makefile文件
(3)执行指令:make 编译
接下来本文介绍CMake一些基本的使用方法和示例,更多详细的介绍和复杂功能建议查询官方文档:
https://cmake.org/cmake/help/v3.0/index.html
介绍几个常用指令
#指定CMake编译最低要求版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
#给项目命名
PROJECT(HelloWorld)
#指定头文件目录
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
#将值VALUE 赋给变量NAME
SET(NAME VALUE)
# 指定可执行文件
ADD_EXECUTABLE(Hello SOURCE_PATH)
# 使用指定的源文件将库添加到项目中。STATIC是对象文件的存档,用于链接其他目标。SHARED动态链接并在运行时加载。MODULE是不链接到其他目标的插件,但可以在运行时使用类似dlopen的功能动态加载。
ADD_LIBRARY(NAME SHARED PATH)
# 文件操作命令
FILE(...)
举个例子
源文件在同一目录
我们来举个简单的例子,首先新建一个名为HelloWord的项目,项目结构如下:
|———Helloword目录
| |————CMakeLists.txt
| |————src目录
| | |—————main.cpp
| | |—————function.cpp
| |————include目录
| | |—————head.h
| |————lib目录
| |————build目录
接下来编辑函数和头文件
include目录下head.h文件:
#include<stdio.h>
#include<stdlib.h>
void myprint(char* str);
src目录下function.cpp文件:
#include "../include/head.h"
void myprint(char* str)
{
printf("Hello World %s\n",str);
}
main.cpp文件:
#include<iostream>
#include "../include/head.h"
using namespace std;
int main()
{
myprint("Nice to meet you!");
return 0;
}
最后编写CMakeLists.txt文件:
#指定CMake编译最低要求版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
#给项目命名
PROJECT(HelloWorld)
#收集c/c++文件并赋值给变量SRC_LIST_CPP
#${PROJECT_SOURCE_DIR}表示工程的当前路径
FILE(GLOB SRC_LIST_CPP ${PROJECT_SOURCE_DIR}/src/*.cpp)
#指定头文件目录
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
#生成可执行文件hello
ADD_EXECUTABLE(hello ${SRC_LIST_CPP})
编写完成后我们进入build目录,编译执行:
cd build
cmake ..
make
./hello
源文件在不同目录
我们重新设定项目结构,如果源文件出现在不同的目录下:
|———Helloword目录
| |————CMakeLists.txt
| |————src目录
| | |—————main.cpp
| |————include目录
| | |—————head.h
| |————fun1目录
| | |—————function.cpp
| |————lib目录
| |————build目录
这时候我们一般先在fun1目录下再建一个CMakeLists.txt文件,先将这个目录下的源文件编译成静态库或者动态库,然后供main函数调用。
编辑fun1/CMakeList.txt:
#收集路径下所有源文件
FILE(GLOB SRC_LIST_CPP ${PROJECT_SOURCE_DIR}/*.cpp)
#指定生成库文件的目录
SET(LIBRARY_OUTPUT_PATH ../lib)
#编译成静态库
ADD_LIBRARY(Fun1 STATIC ${SRC_LIST_CPP})
然后在终端执行:
cd fun1
cmake .
make
如果顺利完成我们会在 lib/ 目录下看到生成的静态库文件 libFun1.a
然后修改 build/ 目录下的CMakeLists.txt文件:
#指定CMake编译最低要求版本
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
#给项目命名
PROJECT(HelloWorld)
#收集c/c++文件并赋值给变量SRC_LIST_CPP
#${PROJECT_SOURCE_DIR}表示工程的当前路径
FILE(GLOB SRC_LIST_CPP ${PROJECT_SOURCE_DIR}/src/*.cpp)
#指定头文件目录
INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/include)
#指定链接库文件目录
LINK_DIRECTORIES(${PROJECT_SOURCE_DIR}/lib)
#生成可执行文件hello
ADD_EXECUTABLE(hello ${SRC_LIST_CPP})
#指定hello 链接库fun1
TARGET_LINK_LIBRARIES(hello Fun1)
然后在终端执行:
cd build
cmake ..
make