
Cmake 初探
CMake简介
CMake 是一个开源的、跨平台的构建系统(编译工具),它主要用于管理项目的构建过程。
它通过使用简明的脚本语言来生成适用于不同平台和编译器的构建文件。(可跨平台)
安装CMake
通过执行如下命令的进行安装CMake。
sudo apt install cmake -y
# 查看版本
cmake --version
简单示例
首先创建一个main.c
文件的c程序,编写一点简单的代码输出hello word。
#include <stdio.h>
int main(void)
{
printf("Hello World\n");
return 0;
}
CMakeLists.txt
是 CMake(Cross-Platform Make)构建系统中的一个核心文件,它用于定义一个项目的构建过程。
接下来我们在同一目录下创建一个CMakeLists.txt
文件,并写入如下内容。
# cmake的最低版本要求是2.8
cmake_minimum_required (VERSION 2.8)
# 工程名
project (demo)
# 由源文件main.c 生成执行文件main
add_executable(main main.c)
然后我们在当前目录中执行如下命令进行编译。
# 自动生成文件有 CMakeCache.txt CMakeFiles cmake_install.cmake Makefile
cmake .
# 编译文件(用已自动生成的Makefile文件)
make
ls
其中main
绿色的就是我们的可执行程序
./main
接下了我们执行清理编译之后的相关程序
# 清楚编译中的生成文件(如 main.o main)
make clean
多文件
重新写main.c
代码。
#include <stdio.h>
#include "fun.h"
int main(void)
{
show(10);
return 0;
}
定义fun.h
#ifndef _FUN_H_
#define _FUN_H_
void show(int data);
#endif
定义fun.c
#include <stdio.h>
#include "fun.h"
void show(int data)
{
printf("data is %d\n", data);
}
修改CMakeLists.txt
的第一种方式,在add_executable
方法中添加相关文件名
# cmake的最低版本要求是2.8
cmake_minimum_required (VERSION 2.8)
# 工程名
project (demo)
# 由源文件main.c 生成执行文件main
add_executable(main main.c fun.c)
第二种,用变量存放编译需要的源文件。
cmake_minimum_required (VERSION 2.8)
# 工程名
project (demo)
# 用变量,存放的文件列表
set( SRC_LIST
./main.c
./fun.c
)
# 根据SRC_LIST中的源文件 生成执行文件main
add_executable(main ${SRC_LIST})
源文件很多时,通过指定当前目录的位置进行编译。
cmake_minimum_required (VERSION 2.8)
project (demo)
# 把当前目录下的源文件列表,存放到变量SRC_LIST里
aux_source_directory(. SRC_LIST)
# 根据SRC_LIST中的源文件 生成执行文件main
add_executable(main ${SRC_LIST})
多目录
多目录,还有相同的接口情况下如何解决?
//main.c
#include <stdio.h>
#include "fun.h"
#include "look.h"
int main(void)
{
show(10);
look();
return 0;
}
定义两个目录fun
和look
目录。
// fun.h
#ifndef _FUN_H_
#define _FUN_H_
void show(int data);
#endif
// fun.c
#include <stdio.h>
#include "fun.h"
void show(int data)
{
printf("data is %d\n", data);
}
// look.h
#ifndef _FUN_H_
#define _FUN_H_
void look();
#endif
// look.c
#include <stdio.h>
#include "look.h"
void look()
{
printf("look go\n");
}
修改CMakeLists.txt
。
通过include_directories
的方法指定一个或多个包含目录。
通过aux_source_directory
方法用于自动添加一个目录中的所有源文件到一个变量中。
cmake_minimum_required (VERSION 2.8)
project (demo)
# 指定头文件的搜索路径(先fun目录,再look目录)
include_directories (fun look)
# 把fun目录下的源文件列表,存放到变量SRC_LIST_FUN里
aux_source_directory (fun SRC_LIST_FUN)
# 把look目录下的源文件列表,存放到变量SRC_LIST_LOOK里
aux_source_directory (look SRC_LIST_LOOK)
add_executable (main main.c ${SRC_LIST_FUN} ${SRC_LIST_LOOK})
库生成
好处就是源代码我们一般不希望对方看到。
目录结构如下:
其中的fun.c
和fun.h
的内容不变。
添加一个CMakeLists.txt
文件,内容如下:
aux_source_directory (. SRC_LIST)
# 根据SRC_LIST的源文件,生成动态库fun_shared
add_library (fun_shared SHARED ${SRC_LIST})
# 根据SRC_LIST的源文件,生成静态库fun_static
add_library (fun_static STATIC ${SRC_LIST})
# 设置库的属性(如输出库名 版本号等)
set_target_properties (fun_shared PROPERTIES OUTPUT_NAME "fun")
set_target_properties (fun_static PROPERTIES OUTPUT_NAME "fun")
#//指定生成的库文件,存放在工程根目录下的lib目录
set (LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)
修改在learning
根目录下的CMakeLists.txt
。
cmake_minimum_required (VERSION 2.8)
project (demo)
add_subdirectory (fun)
可以看见在lib
目录下已经生成了相关的文件
库使用
创建include
文件夹将fun/fun.h
复制到该目录下。
让include
成为接口目录。
创建一个新的目录src
,并在下面定义main.c
文件以及CMakeLists.txt
文件。
#include <stdio.h>
#include "fun.h"
int main(void)
{
show(10);
return 0;
}
aux_source_directory (. SRC_LIST)
include_directories (../include)
# 添加非标准的共享库搜索路径
link_directories (${PROJECT_SOURCE_DIR}/lib)
add_executable (main ${SRC_LIST})
# 连接库(默认链接动态库,无则链接静态库,也可指明链接fun.a)
target_link_libraries (main fun)
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
修改在根目录下的CMakeLists.txt
文件。
cmake_minimum_required (VERSION 2.8)
project (demo)
add_subdirectory (fun)
add_subdirectory (src)
标准结构
//bin 输出的执行文件
//build 存放构建中的中间文件
//lib 库
libfun.a libfun.so
//CMakeLists.txt cmake的总配置文件
cmake_minimum_required (VERSION 2.8) #// cmake的最低版本要求是2.8,我们安装的是3.10.2
project (demo) #//工程名
add_subdirectory (src) #//添加子目录(自动构建时,会进入src中找 子CMakeLists.txt)
//include/fun.h
#ifndef _FUN_H_
#define _FUN_H_
void show(int data);
#endif
//include/look.h
#ifndef _LOOK_H_
#define _LOOK_H_
void look();
#endif
//src/main.c
#include <stdio.h>
#include "fun.h"
#include "look.h"
int main(void)
{
show(10);
look();
return 0;
}
//src/look.c
#include <stdio.h>
#include "look.h"
void look(void)
{
printf("look go\n");
}
//src/CMakeLists.txt cmake的子配置文件
aux_source_directory (. SRC_LIST) #//把当前目录下的源文件列表,存放到变量SRC_LIST里
include_directories (../include) #//指定 上级目录下的include 为头文件的搜索路径
link_directories (${PROJECT_SOURCE_DIR}/lib) #//添加库搜索路径
add_executable (main ${SRC_LIST}) #//根据SRC_LIST中的源文件 生成执行文件main
target_link_libraries (main fun) #//连接库(默认链接动态库,无则链接静态库,也可指明链接fun.a)
#//设定 执行文件的输出位置 为工程根目录下的bin目录
set (EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
//构建运行
$ cd build
$ cmake .. //进到build 目录后再cmake构建,避免生成中间文件,污染了工程
$ make
$ cd ../bin //执行文件是输出到 bin下
$ ./main
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739

