CMake链接第三方库

简介: CMake链接第三方库

一.了解CMake

学习CMake之前,你一定得了解makrfile相关内容及其意义,CMake和makefile都是用于构建软件项目的工具,但它们的设计原则有很大的区别。


makefile是一种比较老的构建工具,它是基于规则的依赖关系来完成编译的。makefile将整个构建过程分为多个步骤,并且使用文件时间戳来判断是否需要重新构建目标。makefile通常需要手动编写,而且需要对底层系统的细节有一定的了解。


相比之下,CMake是一个跨平台的高级构建工具,它可以自动生成makefile或其他构建工具所需要的文件。CMake提供了一个简单的语言来描述项目的结构和依赖关系,并可根据不同平台和编译器生成相应的构建文件。CMake还支持交叉编译,可以方便地在不同的操作系统和架构上构建相同的项目。


总的来说,CMake比makefile更加高级和灵活,可以更轻松地管理复杂的项目和跨平台编译。


谈一谈我个人的理解,原本是C语言链接其他库碰到的,尤其是使用CLion编译器,其他编译器链接体积小的库还好,但是如果链接的第三方库比较大,特别容易出现卡死的情况,还是CLion比较好,但是使用这个软件你会发现它的每个项目都有一个 CMakeLists.txt文件,链接库的话需要编写这个文件,如果不知道它,链接库操作总是不顺畅。

二.CMake基础命令

1.cmake_minimum_required

在使用CMake编写项目时,必须在CMakeLists.txt文件的开头指定要求的最低版本号。这通常通过使用cmake_minimum_required命令来完成。该命令告诉CMake要求的最低版本号是多少,如果运行CMake的机器上安装的CMake版本低于指定的最低版本,则会产生错误。


因此,在CMake项目中,cmake_minimum_required(VERSION 3.10)这样的命令通常是必填的。当然,你也可以根据你的实际情况来设置更高的最小版本号。

2.project

在 CMake 中,project 命令用于定义项目名称及其基本信息。一般而言,CMakeLists.txt 文件的第一个非注释行就是 project 命令。

project 命令的基本语法如下:

project(projectname
    [VERSION version]
    [DESCRIPTION description]
    [HOMEPAGE_URL url]
    [LANGUAGES language1 [language2 ...]])

projectname:必填,表示项目名称。

VERSION:可选,表示项目的版本号。

DESCRIPTION:可选,描述项目的简短说明。

HOMEPAGE_URL:可选,表示项目主页的 URL 地址。

LANGUAGES:可选,表示项目所使用的编程语言,默认情况下为 C 和 C++。

project 命令通常会将以下变量设置为对应的值:


PROJECT_NAME:项目名称。

PROJECT_VERSION:项目版本号。

PROJECT_DESCRIPTION:项目描述。

PROJECT_HOMEPAGE_URL:项目主页的 URL 地址。

PROJECT_LANGUAGES:项目所使用的编程语言。

通过执行 project 命令,我们可以在 CMake 中定义项目名称及其基本信息,从而方便管理和构建整个项目。

3.add_executable

add_executable 的语法如下:

add_executable(target_name source1 [source2 ...])

其中,target_name 为创建的目标的名称,source1, source2, … 是源文件的列表,可以包括多个源文件。每一个源文件都应该是一个相对或绝对路径。


在 CMakeLists.txt 文件中,通常会把 add_executable 命令放在其他命令的前面,以便在生成项目时先创建可执行文件的目标。


注意:这里的target不一定非要和项目名一样,毕竟一个项目包含多个可执行文件,但是后面必须写依赖的文件。

4.message

message()函数用于输出一条消息到CMake的生成日志中,可用于调试或显示某些信息。它的语法如下:

message([<mode>] "message to display")

其中是一个可选参数,指定输出的消息类型,可以是以下之一:


STATUS:输出为绿色。

WARNING:输出为黄色。

AUTHOR_WARNING:输出为红色。

SEND_ERROR:输出为红色,并停止 CMake 过程。

FATAL_ERROR:输出为红色,并且停止 CMake 过程并返回错误代码。

DEPRECATION:输出为带有前缀“–”,并在尝试使用过时功能时输出。

示例:

# 输出普通(默认)消息
message("This is a normal message")
# 输出警告消息
message(WARNING "This is a warning message")
# 输出错误消息
message(SEND_ERROR "This is an error message")
# 输出致命错误消息
message(FATAL_ERROR "This is a fatal error message")

三.CMake补充命令

1.option

在CMake中,option命令用于定义一个可选的开关变量,这个变量可以通过命令行或者CMake GUI进行设置。语法如下:

option(<option_variable> "help string describing option" [initial value])

其中,是变量名,"help string describing option"是对该选项的描述文本,[initial value]是该选项的初始值(默认值为OFF)。

例如,我们可以定义一个名为 EXAMPLE_OPTION 的选项:

option(EXAMPLE_OPTION "Enable example feature" OFF)

这将定义一个名为 EXAMPLE_OPTION 的选项,它的默认值为 OFF,同时还提供了一个描述文本 "Enable example feature"。

在使用时,可以通过 if 命令根据该选项的值来控制代码的编译。

if(EXAMPLE_OPTION)
    add_compile_definitions(ENABLE_EXAMPLE_FEATURE)
endif()

这里我们使用了 add_compile_definitions 命令来添加编译选项 -DENABLE_EXAMPLE_FEATURE,如果 EXAMPLE_OPTION 的值为 ON,则这个选项就会被启用。

2.set

set()函数用于设置变量的值。它的语法如下:

set(<variable> <value> [CACHE <type> <docstring> [FORCE]])

其中,是要设置的变量名,是要设置的变量值。如果要将变量写入缓存,请使用CACHE选项。指定缓存值的类型,是对该缓存变量的描述。如果要覆盖现有的缓存变量,请使用FORCE选项。

示例:

# 设置一个普通变量
set(my_var "Hello World")
# 设置一个缓存变量
set(my_cache_var "Hello Cache" CACHE STRING "Description of my_cache_var")

3.include_directories

include_directories是CMake的一个命令,用于向编译器添加头文件搜索路径。


例如,如果你的项目在/path/to/project目录下,并且你需要使用foo.h和bar.h这两个头文件,那么你需要将它们的搜索路径添加到 CMakeLists.txt 文件中:

include_directories(/path/to/project/include)

这样,CMake就会将 /path/to/project/include 添加到编译器的搜索路径中,使得在源代码中包含foo.h和bar.h时能够正确地找到它们。

你也可以指定多个搜索路径:

include_directories(
  /path/to/project/include
  /path/to/other/include
)

当然,你也可以使用相对路径。例如,在以下示例中,假定你的头文件位于./include目录下:

include_directories(include)

需要注意的是,include_directories只影响当前目录及其子目录中的源文件。如果你需要在更高级别的目录中使用头文件,请考虑使用target_include_directories命令,该命令可将头文件搜索路径添加到特定的目标或库中。

4.target_include_directories

target_include_directories命令的详细使用方法如下:

target_include_directories(target
  [SYSTEM | BEFORE]
  [INTERFACE | PUBLIC | PRIVATE]
  <directory> [<directory> ...]
)

参数说明:


target:要添加头文件搜索路径的目标或库名称。

SYSTEM:将指定的目录作为系统路径添加,这通常用于包含操作系统提供的头文件。

BEFORE:将指定的目录添加到其他搜索路径之前。

INTERFACE、PUBLIC、PRIVATE:控制头文件搜索路径的可见性。如果使用多个关键字,则它们之间应该按照INTERFACE、PUBLIC、PRIVATE的顺序排列。

<directory>:要添加的头文件搜索目录。

举例来说,如果你要向名为mymath的库添加一个头文件搜索路径,可以使用以下命令:

target_include_directories(mymath PUBLIC include)

这将把include目录添加到mymath库的公共接口中,使得其他依赖于mymath的目标也能够访问这个头文件目录。

四.库的链接

1.add_library

add_library命令是CMake中用于创建静态库或共享库的命令。它的基本语法如下:

Copy Codeadd_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            source1 [source2 ...])

其中,参数说明如下:


<name>:要创建的库的名称。

STATIC、SHARED、MODULE:指定库的类型,分别表示静态库、共享库和模块库,默认是静态库。

EXCLUDE_FROM_ALL:如果添加了这个参数,那么这个库将不会被默认构建,需要显式地使用make <target>命令来构建它。

source1、source2等:库的源文件列表。

举例来说,如果你有两个源文件foo.cpp和bar.cpp,并希望创建一个名为mylib的静态库,可以使用以下命令:

add_library(mylib STATIC foo.cpp bar.cpp)

这将创建一个名为libmylib.a(在Linux和Mac上)或mylib.lib(在Windows上)的静态库文件,包含foo.cpp和bar.cpp中定义的函数和变量。

如果你希望创建一个共享库而不是静态库,可以使用以下命令:

add_library(mylib SHARED foo.cpp bar.cpp)

这将创建一个名为libmylib.so(在Linux和Mac上)或mylib.dll(在Windows上)的共享库文件。

如果你希望创建一个模块库,可以使用以下命令:

add_library(mylib MODULE foo.cpp bar.cpp)

这将创建一个名为mylib.so(在Linux和Mac上)或mylib.dll(在Windows上)的模块库文件。

最后,如果你希望将库文件从生成的默认构建目标中排除,可以添加EXCLUDE_FROM_ALL参数,例如:

add_library(mylib STATIC EXCLUDE_FROM_ALL foo.cpp bar.cpp)

这将使得mylib库不会被默认构建,需要显式地使用make mylib命令来构建它。

2.target_link_libraries()

target_link_libraries() 是 CMake 中用于链接库的命令。该命令的语法如下:

target_link_libraries(target library1 <library2> ... <libraryN>)

其中,target 表示要链接库的目标(例如可执行文件或库文件);library1、library2、……、libraryN 表示要链接到目标中的库文件的名称。


使用 target_link_libraries 命令可以将库文件链接到目标文件中,以便在运行时能够调用其中定义的函数和数据结构。例如,在创建一个可执行文件时,如果需要使用某个库文件,则可以使用 target_link_libraries 命令将该库文件链接到可执行文件中,使得程序能够编译并运行。


此外,还可以通过 target_link_libraries 添加链接选项和链接器标志。例如,将 -lm 选项添加到链接操作中,可以告诉链接器链接数学库文件。


总之,target_link_libraries 命令是 CMake 中非常重要的一个命令,它可以方便地管理多个源文件和依赖项之间的关系,简化了项目的构建过程。

五.实例操作

1.链接sds

cmake_minimum_required(VERSION 3.25)
project(untitled C)
set(CMAKE_C_STANDARD 11)
add_executable(untitled main.c)
add_library(sds sds.c sds.h)
target_link_libraries(untitled sds)

2.链接sqlite

cmake_minimum_required(VERSION 3.25)
project(db_work C)
set(CMAKE_C_STANDARD 11)
add_compile_options(-l sqlite3)
add_executable(db_work main.c sqlite3.c)

注释:


这是一个使用C语言编写的项目的CMakeLists.txt文件,用于构建生成可执行文件。


cmake_minimum_required(VERSION 3.25): 指定最低的 CMake 版本号。

project(db_work C): 定义项目名称为db_work,并指定使用C语言进行编译。

set(CMAKE_C_STANDARD 11): 设置C标准为C11。

add_compile_options(-l sqlite3): 添加编译选项,链接SQLite 3动态库。

add_executable(db_work main.c sqlite3.c): 添加要编译的源代码文件,包括主程序main.c和SQLite 3的C文件sqlite3.c,并生成可执行文件db_work。

六.总结

本篇博客,虽然知识点比较偏,但是非常有用。

相关文章
|
3天前
|
自然语言处理
CMake基础(3)静态库
CMake基础(3)静态库
17 1
|
3天前
CMake基础(4)动态库
CMake基础(4)动态库
11 1
|
3天前
|
Windows
CMake基础(5)安装项目
CMake基础(5)安装项目
25 3
|
1月前
|
程序员 API 数据库
【Cmake工程 库相关教程 】深入理解CMake工程C/C++ 库管理技巧
【Cmake工程 库相关教程 】深入理解CMake工程C/C++ 库管理技巧
60 0
|
2月前
|
算法 API 计算机视觉
[opencv学习笔记] jiazhigang 30讲源码C++版本(含Makefile)
[opencv学习笔记] jiazhigang 30讲源码C++版本(含Makefile)
26 0
|
3天前
|
存储 缓存 Unix
CMake基础(8)包含第三方库
CMake基础(8)包含第三方库
7 1
|
11月前
|
Linux 编译器 C语言
gcc后续——链接时的静态库和动态库
gcc后续——链接时的静态库和动态库
107 0
编译编译时,用不到的库,一定不要链接
编译编译时,用不到的库,一定不要链接
90 0
|
iOS开发
CMake教程7:安装与编译
CMake教程7:安装与编译
352 0