DDZZ669 发表于 2024-10-19 14:24

CMake构建实战读书笔记05-CMake项目构建实践


本篇来学习使用CMake来构建项目。

# 1 编译单个源文件

## 1.1 基础CMake

c++源文件,hello.cpp

```c++
#include <stdio.h>

int main()
{
    printf("hello\n");
    return 0;
}
```

CMakeLists.txt

```cmake
project(HELLO)

add_executable(hello ./hello.cpp)
```

这个是最基础的CMakeLists

- 第一行 project:该命令用于设置工程的名称,设置工程名称并不是强制性的,但是最好加上。
- 第二行 add_executable:该命令用于生成一个可执行文件

然后编译

```sh
cmake .
make
```

实际编译运行效果如下:



cmake先生成了MakeFile文件,然后使用make指令来编译出可执行文件,然后运行hello可执行文件,打印出hello。

## 1.2 在单独的build目录进行编译

上述测试过程中,cmake编译生成的文件与代码源文件混在一起了,不太好。

可以单独新建一个build目录进行编译,后续如果要清理代码功能,直接删除build目录即可。

```sh
mkdir build
cd build
cmake ..
make
```

运行效果如下:



可以看到编译生成的文件都在build目录中了。

# 2 编译多个文件

将打印hello函数从main函数中抽离出,单独编写一个cpp文件来打印hello。

hello.h

```c++
#pragma once

void hello();
```

hello.cpp

```cpp
#include "hello.h"
#include <stdio.h>

void hello()
{
    printf("hello\n");
}
```

main.cpp

```c++
#include "hello.h"

int main()
{
    hello();
    return 0;
}
```

CMakeLists.txt

```cmake
project(HELLO)

set(SRC_LIST main.cpp hello.cpp)

add_executable(hello ${SRC_LIST})
```

这里用到了set指令,经cpp文件的名称赋值给SRC_LIST变量。

运行效果如下:



可以看到多个文件的情况,最终也编译出了可执行文件,并能正常运行。

# 3 生成库文件

如果想要把hello函数功能编译成库文件,CMake中可以使用add_library指令来实现

## 3.1 静态库

CMakeLists.txt

```cmake
project(HELLO)

add_library(libhello hello.cpp)

add_executable(hello main.cpp)

target_link_libraries(hello libhello)
```

默认生成的是静态库,与add_library(libhello STATIC hello.c)的效果是一样的。

再通过target_link_libraries将libhello库文件链接到目标文件。

运行效果如下:



可以看到,生成了静态库liblibhello.a和可执行文件hello

## 3.2 动态库

编译动态库也是使用add_library指令,只需要再增加SHARED参数即可实现动态库的编译。

CMakeLists.txt

```cmake
project(HELLO)

add_library(libhello SHARED hello.cpp)

add_executable(hello main.cpp)

target_link_libraries(hello libhello)
```

运行效果如下:



可以看到,生成了动态库liblibhello.so和可执行文件hello

## 3.3 修改库的名字

刚才生成的静态库liblibhello.a和动态库liblibhello.so,名字上多了一个lib,看起来比较奇怪,可以使用set_target_properties对库文件这个目标的属性进行修改,进行重命名。

CMakeLists.txt

```cmake
project(HELLO)

add_library(libhello SHARED hello.cpp)

set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")

add_executable(hello main.cpp)

target_link_libraries(hello libhello)
```

- set_target_properties:设置目标的属性,对libhello目标的OUTPUT_NAME属性进行了设置,将其设置为hello

运行效果如下:



## 3.4 将目标文件生成到指定目录

刚才生成的库文件和可执行文件,和编译生成的其它文件,都在build目标中,混杂在一起,也不太好。

可以修改LIBRARY_OUTPUT_PATH和EXECUTABLE_OUTPUT_PATH变量的值,来执行库文件和可执行文件的位置,例如分别放到当前目录下的lib目录和bin目录。

CMakeLists.txt

```cmake
project(HELLO)

set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
add_library(libhello SHARED hello.cpp)

set_target_properties(libhello PROPERTIES OUTPUT_NAME "hello")

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
add_executable(hello main.cpp)

target_link_libraries(hello libhello)
```

- set_target_properties:设置目标的属性,对libhello目标的OUTPUT_NAME属性进行了设置,将其设置为hello

运行效果如下:



# 4 总结

本篇介绍了使用CMake来构建项目,包括单文件、多文件项目的构建,以及静态库、动态库的生成等。

Jacktang 发表于 2024-10-20 08:56

<p>修改库的名字是必须要用set_target_properties对库文件这个目标的属性进行修改吧</p>

DDZZ669 发表于 2024-10-20 21:35

Jacktang 发表于 2024-10-20 08:56
修改库的名字是必须要用set_target_properties对库文件这个目标的属性进行修改吧

<p>是的</p>
页: [1]
查看完整版本: CMake构建实战读书笔记05-CMake项目构建实践