cmake基本语法
发表于:2024-12-23 | 分类: C++ cmake
字数统计: 1.8k | 阅读时长: 8分钟 | 阅读量:

CMakeLists.txt写法,环境Ubuntu+VS Code

项目信息

语法

  • cmake_minimum_required(VERSION <version>)
  • 指定支持的最低 CMake 版本。

  • 必须是 CMakeLists.txt 文件的第一条指令。

  • project(<name> [LANGUAGES <languages>])
  • 定义项目名称、支持的语言等。

  • 可选参数包括 VERSION(设置项目版本号),DESCRIPTION(描述项目)等

1
2
3
4
5
6
cmake_minimum_required(VERSION <cmake_version>)

project(<project_name>
VERSION <major.minor.patch>
DESCRIPTION "<project_description>"
LANGUAGES <languages>)

案例

1
2
3
4
5
#设置 CMake 最小版本要求
cmake_minimum_required(VERSION 3.10)

# 设置项目名称和语言为 C++
project(MyProject CXX)

变量定义

set

  • 可以设置与项目相关的变量,如编译器标准、路径、选项等。

  • CMAKE_是cmake自带的变量

1
2
3
4
5
6
7
8
9
10
11
 设置 C++ 标准
set(CMAKE_CXX_STANDARD 11)

# 设置可执行文件输出路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/out)

# 设置编译选项(开启调试,关闭警告)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall")

# 设置库文件输出路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/lib)

头文件

target_include_directories(<target> <INTERFACE|PUBLIC|PRIVATE> [directories...])

  • <target>指定目标的名称(通常是通过 add_executableadd_library 创建的目标)。

    <INTERFACE|PUBLIC|PRIVATE>
    用于设置路径的可见性(防止污染)。决定了这些包含路径对目标及其依赖者的影响:

    • INTERFACE:仅适用于链接到该目标的其他目标,不会直接影响当前目标。
    • PRIVATE:仅适用于当前目标,不会影响其他目标。
    • PUBLIC:既适用于当前目标,也会影响链接到该目标的其他目标。

    [directories...]
    一个或多个头文件的目录路径。这些路径可以是绝对路径,也可以是相对路径(相对路径是相对于 CMakeLists.txt 的位置)。

  • 在目标文件之后使用

1
2
3
4
5
# 定义主程序
add_executable(MyApp ${SRC_FILES})

# 添加头文件搜索路径,设置为PRIVATE,即header下的.h只在MyApp目标中使用
target_include_directories(MyApp PRIVATE ${CMAKE_SOURCE_DIR}/header)
1
2
3
4
5
# 创建静态库
add_library(MyLOG_LIB STATIC log.cpp)

# 添加头文件搜索路径,置为PUBLIC,因为该头文件需要在其他目标(如可执行文件)中使用
target_include_directories(MyLOG_LIB PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

源文件

1
2
# 添加源文件路径,确保引用正确的 C++ 源文件
file(GLOB SRC_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp")

可执行文件

1
2
# 把SRC_FILES下的所有cpp文件生成可执行文件
add_executable(my_project ${SRC_FILES})

条件逻辑

  • message([<mode>] "message text")
  • <mode>(可选):指定消息的类型或重要性。常见模式包括:
    • STATUS:输出一般的状态信息。
    • WARNING:输出警告信息(突出显示),但不会中断配置过程。
    • AUTHOR_WARNING:输出面向开发者的警告,只有当设置了 CMAKE_WARN_DEVELOPER=ON 时才会显示。
    • SEND_ERROR:报告错误,但不会立即停止配置过程;只会标记为错误。
    • FATAL_ERROR:报告错误并立即终止 CMake 配置。
1
2
3
4
5
6
 # 检查变量是否有效
if(SQLITE3_LIB)
message(STATUS "SQLite library found at: ${SQLITE3_LIB}")
else()
message(WARNING "SQLite library not found. Continuing without SQLite support.")
endif()

库文件

链接库语法

1
2
3
target_link_libraries(<target>
[PRIVATE | PUBLIC | INTERFACE] <library> ...
)
1
2
add_executable(MyApp main.cpp)
target_link_libraries(MyApp PRIVATE pthread m)

项目库生成

add_library(<name> [STATIC | SHARED | MODULE] <source1> <source2> ...)

  • 用于将项目中的源文件编译成一个库
  • 参数
    • <name>:库的名称。
    • STATIC:生成静态库(.a.lib)。
    • SHARED:生成动态库(.so.dylib.dll)。
    • MODULE:生成不被链接的可加载模块(通常用于插件)。
    • <source1> <source2>:用于生成库的源文件列表。
1
2
3
4
5
6
7
8
9
10
11
# 创建静态库
add_library(MyStaticLibrary STATIC src/library.cpp)

# 创建动态库
add_library(MySharedLibrary SHARED src/library.cpp)

# 添加可执行文件
add_executable(MyExecutable src/main.cpp)

# 链接静态库到可执行文件
target_link_libraries(MyExecutable MyStaticLibrary)

三方库或已有库

find_library(<VAR> <name> PATHS <path1> <path2>... NO_DEFAULT_PATH)

  • 用于查找系统中已经存在的、预编译好的库,用于三方库
  • 参数
    • <VAR>:查找到的库的路径会存储到这个变量中。
    • <name>:库的名称,不需要加文件扩展名(例如 libsqlite3.so 只需写 sqlite3)。
    • PATHS:可选参数,用于指定查找库的额外路径。
    • NO_DEFAULT_PATH:可选参数,禁用默认搜索路径。
  • REQUIRED表示该库必须,没有会报错和终止
1
2
3
4
5
6
7
8
# 查找 SQLite 库
find_library(SQLITE3_LIB sqlite3 REQUIRED)

# 添加可执行文件
add_executable(MyApp src/main.cpp)

# 链接 SQLite 库
target_link_libraries(MyApp ${SQLITE3_LIB})

综合案例

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef LOG_H
#define LOG_H

#include <iostream>
#include <string>
using namespace std;

void LOG_DEBUG(string msg);
void LOG_INFO(string msg);
void LOG_WARN(string msg);
void LOG_ERROR(string msg);

#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "log.h"
void LOG_DEBUG(string msg)
{
cout << "---[DEBUG]--- " << msg << endl;
}
void LOG_INFO(string msg)
{
cout << "---[INFO]--- " << msg << endl;
}
void LOG_WARN(string msg)
{
cout << "---[WARN]--- " << msg << endl;
}
void LOG_ERROR(string msg)
{
cout << "---[ERROR]--- " << msg << endl;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#ifndef MYCLASS_H
#define MYCLASS_H

#include <string>
#include <sqlite3.h>

class MyClass
{
public:
MyClass();
~MyClass();

void executeQuery(const std::string &query);
};

#endif
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include "db.h"
#include <iostream>
#include "log.h"

using namespace std;
MyClass::MyClass()
{
LOG_INFO("MyClass created!");
}

MyClass::~MyClass()
{
LOG_INFO("MyClass destroyed!");
}

void MyClass::executeQuery(const string &query)
{
sqlite3 *db;
char *errMsg = nullptr;

// 打开 SQLite 数据库
if (sqlite3_open(":memory:", &db) != SQLITE_OK)
{
LOG_ERROR("Failed to open database");
return;
}

// 执行 SQL 查询
if (sqlite3_exec(db, query.c_str(), nullptr, nullptr, &errMsg) != SQLITE_OK)
{
LOG_INFO("Failed to execute query: " + string(errMsg));
sqlite3_free(errMsg);
}
else
{
LOG_INFO("Query executed successfully");
}

// 关闭数据库
sqlite3_close(db);
}
1
2
3
4
5
6
7
8
9
10
#include "db.h"
#include <iostream>

int main()
{
MyClass myObj;
myObj.executeQuery("CREATE TABLE test (id INT, name TEXT);");

return 0;
}

单模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# 设置 CMake 最低版本要求
cmake_minimum_required(VERSION 3.10)

# 定义项目名称和支持的语言
project(MySQLiteProject CXX)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)

# 设置必须使用指定的 C++ 标准,编译器不支持则报错
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 设置可执行文件和库文件的输出路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build/lib)

# 搜索源文件
file(GLOB SRC_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp")

# 添加可执行文件
add_executable(MySQLiteProject ${SRC_FILES})

# 创建静态库
add_library(MyLOG_LIB STATIC ${CMAKE_SOURCE_DIR}/lib/log/log.cpp)

# 包含头文件目录
target_include_directories(MySQLiteProject PRIVATE ${CMAKE_SOURCE_DIR}/header)

# 包含头文件目录(注意添加 PUBLIC)
target_include_directories(MyLOG_LIB PUBLIC ${CMAKE_SOURCE_DIR}/lib/log)

# 显示设置静态库的输出路径(当前情况下,前面的设置可能失效,这里显式设置)
set_target_properties(MyLOG_LIB PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build/lib)

# 链接 SQLite 库
find_library(SQLITE3_LIB sqlite3 REQUIRED)

# 检查 SQLite 库
if(SQLITE3_LIB)
message(STATUS "SQLite library found: ${SQLITE3_LIB}")
else()
message(FATAL_ERROR "SQLite library not found!")
endif()

# 链接库文件
target_link_libraries(MySQLiteProject PRIVATE MyLOG_LIB ${SQLITE3_LIB})

分模块优化(推荐)

在子模块编写相应cmake文件,注意添加子cmake文件路径
add_subdirectory(lib/log)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 设置 CMake 最低版本要求
cmake_minimum_required(VERSION 3.10)

# 定义项目名称和支持的语言
project(MyProject CXX)

# 设置 C++ 标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 设置全局输出路径
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build/bin)

# 搜索主程序源文件
file(GLOB SRC_FILES "${CMAKE_SOURCE_DIR}/src/*.cpp")

# 定义主程序
add_executable(MyApp ${SRC_FILES})

# 添加头文件搜索路径
target_include_directories(MyApp PRIVATE ${CMAKE_SOURCE_DIR}/header)

# 添加子目录
add_subdirectory(lib/log)

# 链接静态库和 SQLite3
target_link_libraries(MyApp PRIVATE MyLOG_LIB sqlite3)

1
2
3
4
5
# 创建静态库
add_library(MyLOG_LIB STATIC log.cpp)

# 添加头文件搜索路径
target_include_directories(MyLOG_LIB PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
上一篇:
cmake项目安装和打包
下一篇:
cmake基本命令