CMake教程---添加库(第二课)

本文是CMake教程的第二课,主要介绍如何为项目添加自定义库,包括普通库、导入库、对象库、别名库和接口库的创建。通过`add_library`等命令,详细讲解了库的构建过程,并展示了如何在项目中链接和使用这些库。同时,还介绍了如何通过`option`指令添加构建可选项,控制库的启用与否。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CMake教程版本号:3.16.3

英文原文链接: https://cmake.org/cmake/help/latest/guide/tutorial/index.html#id2

github示例代码 https://github.com/sxpsxp12/cmake-learning-exampes

自定义库

第二课内容是讲解为我们的项目添加库。首先需要创建我们自己的库。

cmake_minimum_required(VERSION 3.0.0)
project(sayhello VERSION 0.1.0)

add_library(sayhello helloworld.cpp)

库目录树为:

.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── compile_commands.json
│   ├── CPackConfig.cmake
│   ├── CPackSourceConfig.cmake
│   ├── CTestTestfile.cmake
│   ├── DartConfiguration.tcl
│   ├── libhelloworld.a
│   ├── Makefile
│   └── Testing
├── CMakeLists.txt
└── helloworld.cpp

3 directories, 11 files
  • 构建项目,即可看到build目录下生成的库
cd build
cmake ..
make

使用自定义库

示例项目目录树为:

.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   ├── cmake_install.cmake
│   ├── compile_commands.json
│   ├── config.h
│   ├── helloworld
│   └── Makefile
├── CMakeLists.txt
├── config.h.in
├── main.cpp
└── sayhellolibrary
    ├── CMakeLists.txt
    ├── helloworld.cpp
    └── helloworld.h

3 directories, 12 files
  • 首先创建项目目录,然后将自定义库目录放置到根目录下
  • 在根目录创建CMakefile.txt文件,添加命令,以便库能够得到编译
add_subdirectory(sayhellolibrary)
  • 在根目录的CMakefile.txt文件中,添加指令,以搜索找到自定义库的头文件
target_include_directories(helloworld PUBLIC 
                            "${PROJECT_BINARY_DIR}"
                            "${PROJECT_SOURCE_DIR}/sayhellolibrary"
                          )
  • 为可执行程序链接库
target_link_libraries(helloworld PUBLIC sayhello)

最终我们看到的根目录的CMakefile.txt内容为:

cmake_minimum_required(VERSION 3.0.0)
project(helloworld VERSION 0.1.0)

add_executable(helloworld main.cpp)

add_subdirectory(sayhellolibrary)
target_include_directories(helloworld PUBLIC 
                            "${PROJECT_BINARY_DIR}"
                            "${PROJECT_SOURCE_DIR}/sayhellolibrary"
                          )

target_link_libraries(helloworld PUBLIC sayhello)

最后构建并运行可执行程序

cd build
cmake ..
make

构建可选项

可以通过开关项,来决定库是否启用,在大型项目中,该功能非常有用。

  • 首先在根目录的CMakefile.txt文件中添加可选项
option(USE_SAYHELLO "use say hello to provide info" OFF)
#配置一个头文件,以便将CMake的配置传递到源代码中
configure_file(config.h.in config.h)
  • 在根目录创建config.h.in文件,并将配置传递到源代码中
#cmakedefine USE_MYMATH
  • USE_SAYHELLO这个可选项可以控制是否启用该库,这个配置项会存储到Cache中,因此不需要每次构建的时候都设置该值。
  • 接下来在根目录的CMakefile.txt文件中添加条件逻辑
if(USE_SAYHELLO)
#添加子CMakefile.txt目录,以便能够build
add_subdirectory(sayhellolibrary)
#将库添加到变量EXTRA_LIBS
list(APPEND EXTRA_LIBS sayhello)
#将头文件路径添加到变量EXTRA_INCLUDES中
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/sayhellolibrary")
endif(USE_SAYHELLO)

target_include_directories(helloworld PUBLIC 
                            "${PROJECT_BINARY_DIR}"
                            ${EXTRA_INCLUDES}
                          )

target_link_libraries(helloworld PUBLIC ${EXTRA_LIBS})
  • 修改源代码,以使用可选项
#ifdef USE_SAYHELLO
#include "helloworld.h"
#endif

...

完整的CMakefile.txt为:

cmake_minimum_required(VERSION 3.0.0)
project(helloworld VERSION 0.1.0)

add_executable(helloworld main.cpp)

option(USE_SAYHELLO "use say hello to provide info" OFF)
#配置一个头文件,以便将CMake的配置传递到源代码中
configure_file(config.h.in config.h)

if(USE_SAYHELLO)
#添加子CMakefile.txt目录,以便能够build
add_subdirectory(sayhellolibrary)
#将库添加到变量EXTRA_LIBS
list(APPEND EXTRA_LIBS sayhello)
#将头文件路径添加到变量EXTRA_INCLUDES中
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/sayhellolibrary")
endif(USE_SAYHELLO)

target_include_directories(helloworld PUBLIC 
                            "${PROJECT_BINARY_DIR}"
                            ${EXTRA_INCLUDES}
                          )

target_link_libraries(helloworld PUBLIC ${EXTRA_LIBS})

最终构建并运行

cd build
cmake ..
make

可自行修改可选项USE_SAYHELLO的值,可删除构建缓冲,重新构建运行看看效果

总结

这一节,我们新学习的cmake指令如下

add_library

所属:项目命令,只能用于CMake项目

使用指定的源文件将库添加到项目中。

普通的库

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

根据命令中的源文件构建一个名为的库(如果源文件在之后使用target_sources()添加,那么此处可以忽略),必须是一个合规的名字,并且必须在项目中是唯一的。

STATIC, SHARED, or MODULE这三个关键字可以指定生成库的类型。静态库是目标文件的归档,以便其他目标链接使用。共享库动态链接,并在运行时加载。MODULE库是一个插件,不会链接到其他目标,但是可以动态加载。

如果关键字没有设置,取决于当前变量BUILD_SHARED_LIBS是否是ON, 关键字SHARED和MODULE的配置,会自动将可执行程序的属性POSITION_INDEPENDENT_CODE(是否创建一个路径无关的可执行程序或者库)设置为ON。

导入的库

add_library(<name> <SHARED|STATIC|MODULE|OBJECT|UNKNOWN> IMPORTED
            [GLOBAL])

一个IMPORTED库表示一个位于项目以外的库文件。没有规则构建它,且IMPORTED属性是True。

对象库

add_library(<name> OBJECT <src>...)

创建一个对象库,它会编译源文件,但是不会是源文件的归档或者链接这些文件到库中。

别名库

add_library(<name> ALIAS <target>)

创建一个别名目标,以便可用于在后续命令中引用。 不会作为生成目标出现在生成的构建系统中。

接口库

add_library(<name> INTERFACE [IMPORTED [GLOBAL]])

创建一个接口库。 INTERFACE库目标虽然可以设置属性,并且可以安装,导出和导入,但它不会直接创建构建输出

更多信息请查看: https://cmake.org/cmake/help/latest/command/add_library.html

add_subdirectory

所属:项目命令,只能用于CMake项目

添加要构建的子目录

add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

source_dir表示CMakefile.txt和代码文件所在的目录。相对路径是基于当前路径,也可以是绝对路径。binary_dir表示输出文件的路径。如果是相对路径,是基于当前输出路径的相对路径,也可以是绝对路径。

target_link_libraries

所属:项目命令,只能用于CMake项目

指定给定可执行程序的链接库或者标志。

target_link_libraries(<target> ... <item>... ...)

有多种形式,具体信息可查看: https://cmake.org/cmake/help/latest/command/target_link_libraries.html

option

所属:脚本指令,总是可用的

提供可选项,供用户选择

option(<variable> "<help_text>" [value])

提供一个可选项,供用户选择ON或者OFF.[value]默认是OFF。


欢迎各位大佬右侧关注、点赞、打赏,我们再会。。。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值