当前位置: 首页 > news >正文

【CMake】静态库(编译-链接-安装)完整示例

接下来我们将详细讲解一个静态库是如何从编译到链接,再到安装的完整示例。

一.install_static_mymath项目

首先我们来执行下面这个命令来一键搭建我们的项目的目录结构和文件

mkdir test && cd test && \
mkdir -p my_lib/include my_lib/src && \
touch CMakeLists.txt && \
touch my_lib/CMakeLists.txt my_lib/Config.cmake.in && \
touch my_lib/include/math.h && \
touch my_lib/src/add.cpp my_lib/src/sub.cpp && \
tree .

接下来我们来仔细观察一下这个项目的文件的内容。

1.1.CMakeLists.txt

cmake_minimum_required(VERSION 3.18)project(InstallMyMathLANGUAGES CXX
)add_subdirectory(my_lib)

这是顶级CMakeLists.txt,它也就是设置了最低CMake版本要求和创建一个项目,然后调用了子目录my_lib里面的CMakeLists.txt.

接下来我们就来看看my_lib里面的CMakeLists.txt

1.2.my_lib/CMakeLists.txt

这个可是重中之重

# 1 收集源代码
file(GLOB SRC_LISTS "src/*.cpp")# 2 添加构建目标
add_library(MyMath STATIC ${SRC_LISTS})# 3 设置库的使用要求,也就是下游消费者必须包含的头文件搜索路径
target_include_directories(MyMath INTERFACE"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" # include
)# 4 设置库的默认输出路径
set_target_properties(MyMath PROPERTIESARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
)# 5 安装我们的静态库
include(GNUInstallDirs)
install(TARGETS MyMathEXPORT MyMathTargetsDESTINATION ${CMAKE_INSTALL_LIBDIR} # lib
)# 6 安装头文件
install(DIRECTORY include/DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/math # /usr/local/include/math/math.hFILES_MATCHING PATTERN "*.h"
)# 7 安装导出目标集合 到  构建树
export(EXPORT MyMathTargetsFILE ${CMAKE_CURRENT_BINARY_DIR}/MyMathTargets.cmake
)# 8 安装导出目标集合 到  安装树
install(EXPORT MyMathTargetsFILE MyMathTargets.cmakeNAMESPACE MyMath:: # MyMath::MyMathDESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyMath # /usr/local/lib/cmake/MyMath/MyMathTargets.cmake
)# 9 生成find_package 需要的 配置文件
include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in${CMAKE_CURRENT_BINARY_DIR}/MyMathConfig.cmakeINSTALL_DESTINATION "lib/cmake/MyMath"
)# 10 安装配置文件到cmake 标准的安装路径
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/MyMathConfig.cmakeDESTINATION "lib/cmake/MyMath"
)

那这到底啥意思呢?我们可以去看看

1.2.1. 收集源代码

file(GLOB SRC_LISTS "src/*.cpp")
  • 作用:使用 GLOB 模式匹配my_lib/CMakeLists.txt所在目录下的 src/ 目录下所有 .cpp 文件

  • 说明:将匹配到的文件列表存储在变量 SRC_LISTS 中

1.2.2. 添加构建目标

add_library(MyMath STATIC ${SRC_LISTS})
  • 作用:创建一个名为 MyMath 的静态库目标

  • 参数

    • STATIC:指定创建静态库(.a 或 .lib 文件)

    • ${SRC_LISTS}:使用前面收集的源文件列表


1.2.3. 设置库的使用要求

target_include_directories(MyMath INTERFACE"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
  • 作用设置库的头文件包含目录,供下游消费者使用

INTERFACE

  • 作用:指定包含目录的可见性范围

  • 详细解释

    • PRIVATE:仅用于构建当前目标自身

    • PUBLIC:用于构建当前目标自身,也传递给依赖此目标的其他目标

    • INTERFACE:不用于构建当前目标自身,仅传递给依赖此目标的其他目标

  • 在此处的含义MyMath 库自身的构建不需要这些包含目录,但使用 MyMath 库的其他目标需要它们

"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>" 是 CMake 中最复杂的部分之一,它使用了 生成器表达式(Generator Expression)。我们可以拆开来看:

  1. $<...>

    • 作用:表示这是一个 生成器表达式

    • 特点:生成器表达式在 生成构建系统 时被求值,而不是在配置阶段(configure)就确定。

  2. INSTALL_INTERFACE

    • 类型:生成器表达式的类别,表示这是 安装接口路径

    • 含义:该路径仅在库被 安装后,通过 find_package() 被其他项目使用时才生效。

    • 对比:还有 BUILD_INTERFACE,表示在 构建期间 使用的路径。

  3. ${CMAKE_INSTALL_INCLUDEDIR}

    • 作用:CMake 变量,表示头文件的标准安装目录。

    • 默认值:通常为 include

    • 实际路径:安装后会成为 ${CMAKE_INSTALL_PREFIX}/include(例如 /usr/local/include)。

总结

  • 这个生成器表达式告诉 CMake:

    • 在构建本库时:忽略这个路径(可用 BUILD_INTERFACE 指定构建期间的路径)。

    • 在其他项目通过 find_package() 使用时:使用 ${CMAKE_INSTALL_INCLUDEDIR} 作为头文件目录。

换句话说,${CMAKE_INSTALL_INCLUDEDIR} 只有在库 被安装后,并被其他项目引用时才会生效。


1.2.4. 设置库的默认输出路径

set_target_properties(MyMath PROPERTIESARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
)
  • 作用:设置静态库文件的输出目录

  • 说明

    • ARCHIVE_OUTPUT_DIRECTORY:针对静态库(.a/.lib)的输出目录

    • ${CMAKE_BINARY_DIR}:构建目录的路径

    • 这会将库文件输出到 构建目录/lib/ 中


1.2.5. 安装静态库

include(GNUInstallDirs)
install(TARGETS MyMathEXPORT MyMathTargetsDESTINATION ${CMAKE_INSTALL_LIBDIR}
)

这段 CMake 代码是用于安装一个名为 MyMath 的目标(通常是一个库)到系统目录。

让我们逐句详细解释:

include(GNUInstallDirs)
  • 作用:包含 CMake 模块,该模块定义了 GNU 标准安装目录变量

  • 详细说明

    • 这个模块提供了一组预定义的变量,表示各种类型的文件应该安装的标准位置

    • 它会根据平台自动设置合适的目录路径(Unix、Windows 等)

    • 使用这些变量可以确保你的项目遵循标准目录布局

定义的变量包括

  • ${CMAKE_INSTALL_BINDIR} - 可执行文件目录(通常为 bin

  • ${CMAKE_INSTALL_LIBDIR} - 库文件目录(通常为 lib 或 lib64

  • ${CMAKE_INSTALL_INCLUDEDIR} - 头文件目录(通常为 include

  • ${CMAKE_INSTALL_DATADIR} - 数据文件目录(通常为 share

  • 等等...

install(TARGETS MyMath

作用:指定要安装的目标(target)。

详细解释

  • TARGETS 关键字表示后面跟的是要通过 add_library() 或 add_executable() 创建的目标名称。

  • MyMath 应该是你之前通过 add_library(MyMath ...) 定义的库目标。

  • 这告诉 CMake:"当用户运行 make install(或等价的命令)时,请安装 MyMath 这个目标。"

EXPORT MyMathTargets

作用:将目标导出到一个名为 MyMathTargets 的导出集中。

详细解释

  • EXPORT 关键字表示这个安装操作不仅安装目标本身,还生成并安装一个导出文件。

  • MyMathTargets 是你为这个导出集指定的名称(可以自定义)。

  • 这个导出文件(通常是 MyMathTargets.cmake)包含了使用这个库所需的所有信息:

    • 库文件的完整路径

    • 编译定义(compile definitions)

    • 包含目录(include directories)

    • 依赖关系(dependencies)

    • 其他使用这个库所需的属性

  • 这样,其他项目可以使用 find_package(MyMath) 来找到并使用你的库,CMake 会自动处理所有依赖和链接细节。

DESTINATION ${CMAKE_INSTALL_LIBDIR}

作用:指定目标文件的安装目的地。

详细解释

  • DESTINATION 关键字指定了安装的目标目录。

  • ${CMAKE_INSTALL_LIBDIR} 是一个变量,其值由之前的 include(GNUInstallDirs) 设置。在大多数 Linux 系统上,这通常解析为 lib 或 lib64

  • 这意味着 MyMath 库文件(如 libMyMath.a 或 libMyMath.so)将被安装到${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}目录下。

  • CMAKE_INSTALL_PREFIX的作用:指定安装的根目录。默认值:Linux/macOS: /usr/local。

完整含义

这段代码的整体作用是:

  1. 确保使用符合 GNU 标准的安装目录结构

  2. 安装 MyMath 目标(库文件)到标准的库目录

  3. 同时生成并安装导出文件,使其他项目能够通过 find_package() 轻松找到和使用这个库


1.2.6. 安装头文件

install(DIRECTORY include/DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mathFILES_MATCHING PATTERN "*.h"
)

这行代码完成了以下重要功能:

  1. 安装整个目录结构而不仅仅是单个文件

  2. 将头文件安装到标准位置的特定子目录中

  3. 只安装头文件.h),过滤掉其他类型的文件

  4. 保持原有的目录层次,便于组织和管理头文件

我们来仔细看看

1. install(DIRECTORY include/

install(DIRECTORY include/
  • 作用:安装整个目录而不仅仅是单个文件

  • 详细说明

    • DIRECTORY 关键字表示要安装的是一个目录及其内容

    • include/ 是要安装的源目录(相对于当前 CMakeLists.txt)

    • 注意:目录名后面的斜杠 / 很重要,它表示安装目录的内容,而不是目录本身

2. DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/math

    DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/math
  • 作用:指定安装的目标位置

  • 详细说明

    • DESTINATION 关键字定义安装目的地

    • ${CMAKE_INSTALL_INCLUDEDIR} 是标准包含目录变量(通常为 include

    • 也就是说这个头文件将会被安装到${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INSTALL_INCLUDEDIR}目录下。

    • CMAKE_INSTALL_PREFIX的作用:指定安装的根目录。默认值:Linux/macOS: /usr/local。

    • 最终头文件的安装路径可能是:/usr/local/include/math/

3. FILES_MATCHING PATTERN "*.h"

    FILES_MATCHING PATTERN "*.h"
)
  • 作用:过滤要安装的文件,只安装匹配特定模式的文件

  • 详细说明

    • FILES_MATCHING 关键字启用文件过滤

    • PATTERN "*.h" 指定过滤模式,只匹配 .h 后缀的文件

    • 这意味着只有头文件会被安装,其他文件(如 .cpp.txt 等)会被忽略


1.2.7. 导出目标集合到构建树

export(EXPORT MyMathTargetsFILE ${CMAKE_CURRENT_BINARY_DIR}/MyMathTargets.cmake
)
  • "将 MyMath 库的目标信息导出到一个 Target.cmake文件中,使得其他 CMake 项目可以在构建树中直接使用这个库,而无需先安装它。"

我们看看

1. export(EXPORT MyMathTargets

export(EXPORT MyMathTargets
  • 作用:将之前定义的导出集(export set)导出到文件中

  • 详细说明

    • export 命令用于从当前 CMake 项目中导出目标

    • EXPORT 关键字指定要导出的导出集名称

    • MyMathTargets 是之前通过 install(TARGETS ... EXPORT MyMathTargets) 定义的导出集名称

2. FILE ${CMAKE_CURRENT_BINARY_DIR}/MyMathTargets.cmake

    FILE ${CMAKE_CURRENT_BINARY_DIR}/MyMathTargets.cmake
)
  • 作用:指定导出文件的路径和名称

  • 详细说明

    • FILE 关键字指定输出文件

    • ${CMAKE_CURRENT_BINARY_DIR} 是当前二进制目录的路径(构建目录)

    • MyMathTargets.cmake 是生成的 CMake 脚本文件的名称


1.2.8. 导出目标集合到安装树

install(EXPORT MyMathTargetsFILE MyMathTargets.cmakeNAMESPACE MyMath::DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyMath
)
  • 作用安装一个 CMake 脚本文件(.cmake),该文件包含了关于如何导入(import)和链接你在项目中创建并导出的所有目标(targets)的必要信息。

我们来仔细看看

install(EXPORT MyMathTargets
  • EXPORT: 这是命令的关键字,表示你要安装(生成并复制)一个之前定义的“导出集”(export set)。

  • MyMathTargets: 这是导出集的名称。这个名称必须与我们之前在 install(TARGETS ... EXPORT MyMathTargets) 命令中指定的导出集名称完全一致。CMake 就是通过这个名称将安装目标(TARGETS)和安装导出(EXPORT)这两个步骤关联起来的。

作用:告诉 CMake:“请找到那个名为 MyMathTargets 的导出集(里面包含了 MyMath 库的所有信息),然后基于它生成一个配置文件并安装它。”

FILE MyMathTargets.cmake
  • FILE: 指定生成的配置文件的文件名。

  • MyMathTargets.cmake: 你为这个文件自定义的名称。虽然可以任意命名,但遵循一致的约定是很好的实践。常见的命名方式有 YourProjectTargets.cmake 或 YourProjectConfig.cmake

作用:控制最终生成的配置文件的名称。当其他项目使用 find_package(MyMath) 时,CMake 就会在指定目录下寻找这个文件(或类似的 MyMathConfig.cmake)。

NAMESPACE MyMath::
  • NAMESPACE: 指定一个命名空间前缀,该前缀会被添加到导出文件中所有目标名称的前面。

  • MyMath::: 你定义的命名空间。双冒号 :: 是 CMake 目标命名的一个约定,它明确表示这是一个导入的目标(Imported Target),而不是在当前项目中构建的目标。

作用:这是现代 CMake 最佳实践的核心。它有两个主要目的:

  1. 避免命名冲突:确保你的库目标(如 MyMath)不会与其他项目可能定义的同样叫 MyMath 的目标冲突。在其他项目中,它将通过 MyMath::MyMath 这个唯一的、带命名空间的名称来引用。

  2. 清晰表明目标类型MyMath:: 前缀立即向使用者表明这个目标来自外部项目。

使用对比

  • 没有命名空间:在其他项目中,你需要写 target_link_libraries(MyApp PRIVATE MyMath)。这看起来像是在链接一个当前项目内部的目标,容易产生混淆。

  • 有命名空间:在其他项目中,你写 target_link_libraries(MyApp PRIVATE MyMath::MyMath)。这清晰地表明 MyMath::MyMath 是一个导入的外部依赖。

DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/MyMath
  • DESTINATION: 指定上一步生成的 MyMathTargets.cmake 文件将被安装到哪个目录。

  • ${CMAKE_INSTALL_LIBDIR}: 通常由 include(GNUInstallDirs) 定义,在 Linux 上通常是 lib 或 lib64

  • 也就是说这个 MyMathTargets.cmake 文件将会被安装到${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/cmake/MyMath目录里面。在Linux下也就是/usr/local/lib/cmake/MyMath

作用:将配置文件安装到一个标准化的、可预测的位置。当其他项目使用 find_package(MyMath REQUIRED) 时,CMake 的搜索算法会自动扫描/usr/local/lib/cmake/MyMath这样的路径来查找 MyMathConfig.cmake 或 MyMathTargets.cmake 文件。

1.2.9. 生成 find_package 需要的配置文件

include(CMakePackageConfigHelpers)
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in${CMAKE_CURRENT_BINARY_DIR}/MyMathConfig.cmakeINSTALL_DESTINATION "lib/cmake/MyMath"
)

我们来看看

include(CMakePackageConfigHelpers)
  • 作用:引入一个 CMake 内置的模块,这个模块提供了三个非常实用的函数:

    1. configure_package_config_file() (我们正在使用的)

    2. write_basic_package_version_file()

    3. cmake_path()

  • 为什么需要:手动编写一个完全正确、能处理各种安装前缀(CMAKE_INSTALL_PREFIX)的 Config.cmake 文件很复杂。这个模块提供的函数自动化了这个过程,确保了生成的文件是健壮和可靠的。

configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in${CMAKE_CURRENT_BINARY_DIR}/MyMathConfig.cmakeINSTALL_DESTINATION "lib/cmake/MyMath"
)

这个函数是核心,它的工作方式是:拿一个我们自己编写的模板文件(.in),替换其中的变量和占位符,生成一个最终可用的 CMake 脚本文件。

它接受多个参数:

参数 1: ${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in

  • 这是输入文件,一个由你创建的模板文件。我们下面会列出来

参数 2: ${CMAKE_CURRENT_BINARY_DIR}/MyMathConfig.cmake

  • 这是输出文件,是函数生成的结果。

  • 它会被写入到构建目录(CMAKE_CURRENT_BINARY_DIR)中,文件名通常为 <PackageName>Config.cmake(这里是 MyMathConfig.cmake)。

  • 这个生成的文件就是最终其他项目调用 find_package(MyMath) 时所要寻找的文件。

参数 3: INSTALL_DESTINATION "lib/cmake/MyMath"

  • 这是最关键的一个参数它告诉函数,你打算将来把生成的 MyMathConfig.cmake 文件安装到哪个目录。

  • 也就是说这个 MyMathConfig.cmake 文件将会被安装到${CMAKE_INSTALL_PREFIX}/lib/cmake/MyMath目录里面。在Linux下也就是/usr/local/lib/cmake/MyMath

1.2.10. 安装配置文件

install(FILES${CMAKE_CURRENT_BINARY_DIR}/MyMathConfig.cmakeDESTINATION "lib/cmake/MyMath"
)

这段代码是 CMake 库打包流程中的最后临门一脚,它负责将配置阶段生成的、至关重要的包配置文件安装到系统的标准位置,使其能够被 find_package() 命令发现。

我们来详细拆解这段代码:

代码逐行解析

install(FILES ...)
  • install: CMake 的安装命令,用于定义在 make install 或 cmake --install 时应执行的操作。

  • FILES: 这是 install 命令的一个关键字,表明接下来要列出的都是一个具体的文件(而不是像 TARGETS 那样的目标或 DIRECTORY 那样的整个目录)。

${CMAKE_CURRENT_BINARY_DIR}/MyMathConfig.cmake
  • 这是要安装的源文件路径

  • ${CMAKE_CURRENT_BINARY_DIR}: 指向当前正在处理的 CMakeLists.txt 对应的构建目录(通常是 build/ 或 cmake-build-debug/ 下的某个子目录)。

  • MyMathConfig.cmake: 这个文件通常不是由你手动编写的,而是由之前讨论的 configure_package_config_file() 或 configure_file() 命令动态生成的。它包含了如何在你库的安装位置(而非构建位置)上找到所有组件(头文件、库文件、目标)的指令。

  • 简单说:你正在安装的是构建过程中生成的成品配置文件,而不是源目录中的模板。

DESTINATION "lib/cmake/MyMath"
  • 这是安装的目标目录,指定了文件在用户系统上的最终位置。

  • 也就是说这个 MyMathConfig.cmake 文件将会被安装到${CMAKE_INSTALL_PREFIX}/lib/cmake/MyMath目录里面。在Linux下也就是/usr/local/lib/cmake/MyMath

  • "lib/cmake/MyMath": 这是一个遵循 CMake 官方约定的标准路径。当其他项目使用 find_package(MyMath) 时,CMake 会自动在一系列已知路径下搜索 lib/cmake/MyMath/ 这个目录,并寻找 MyMathConfig.cmake 或 MyMath-config.cmake 文件。

1.3.my_lib/Config.cmake.in

@PACKAGE_INIT@
include(${CMAKE_CURRENT_LIST_DIR}/MyMathTargets.cmake)

这个文件是由库的提供者创建并安装的,目的是让其他CMake项目能够通过 find_package(MyMath) 命令轻松地找到并使用你的 MyMath 库。

1.4.其他文件

add.cpp

int add(int x, int y)
{return x + y;
}

sub.cpp

int sub(int x, int y)
{return x - y;
}

math.h

int add(int, int );
int sub(int, int);

1.5.测试

mkdir build
cd build
cmake ../
make

sudo cmake --install .

cmake生成的安装配置文件

ls -l /usr/local/lib/cmake/MyMath

这3个内容其实是很重要的。

1.6.使用find_package查找并链接MyMath库

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)project(MyMathApp)# 查找 MyMath 库
find_package(MyMath REQUIRED CONFIG)# 添加可执行文件
add_executable(main main.cpp)# 添加依赖关系
target_link_libraries(main PRIVATE MyMath::MyMath)

我们仔细看下面这个命令啥意思呢?

find_package(MyMath REQUIRED CONFIG)

find_package

这是 CMake 的一个命令,其核心作用是:在系统中查找一个外部软件包(通常是库),并加载其提供的详细信息

  • 为什么需要它? 你的项目可能依赖于一个像 MyMath 这样的外部库。编译器需要知道:

    • 头文件在哪里 (include_directories

    • 库文件在哪里 (link_directories

    • 具体要链接哪个库文件 (target_link_libraries

  • find_package 就是来自动化完成这个查找过程的。成功执行后,它会暴露一系列 CMake 变量(如 MyMath_INCLUDE_DIRSMyMath_LIBRARIES)或更现代化的 导入目标(Imported Target)(如 MyMath::MyMath),让你能轻松地将依赖项集成到你的项目中。

MyMath

这是你要查找的包(Package) 的名字。CMake 会基于这个名字去寻找对应的配置文件。

  • 在实际查找时,CMake 会寻找名为 FindMyMath.cmake(模块模式)或 MyMathConfig.cmake / mymath-config.cmake(配置模式,由 CONFIG 指定)的文件。

REQUIRED

这是一个可选关键字,用于指定该依赖项是否是必需的

  • 如果指定了 REQUIRED:表示 MyMath 库是项目构建的必要条件。如果 CMake 无法找到这个包,整个配置过程(cmake 命令)会立即停止并报错,生成失败。这是一种“没有它我就没法干活”的明确声明。

  • 如果不指定 REQUIRED:即使找不到这个包,配置过程也会继续。你需要后续通过检查变量(如 MyMath_FOUND)来判断是否找到,并编写相应的条件代码。这常用于可选的依赖项。

CONFIG

这是一个可选关键字,它强制 find_package 使用配置模式(Config Mode)

  • 两种模式的区别

    • 模块模式(Module Mode):CMake 会优先查找并运行名为 Find<PackageName>.cmake 的脚本。这类脚本通常是随 CMake 一起提供的,或是项目自己编写的“查找器”。(例如,CMake 自带了 FindOpenSSL.cmakeFindPNG.cmake 等)。

    • 配置模式(Config Mode):CMake 会直接查找由包本身提供的配置文件,通常命名为 <PackageName>Config.cmake 或 <package-name>-config.cmake。这个文件通常是由该库的开发者编写并随库一起安装的。

  • 为什么使用 CONFIG

    1. 现代最佳实践Config.cmake 文件是由库的开发者编写的,他们最清楚自己库的细节,能提供最准确、最完整的导入信息(包括传递依赖、编译器 flags 等)。

    2. 对于你自己构建或安装的库:像 MyMath 这样的库,很可能不是你系统预装的,而是你从源码编译并安装到某个目录的。这种库通常不会有一个现成的 FindMyMath.cmake 模块,但它应该在安装过程中生成一个 MyMathConfig.cmake 文件。使用 CONFIG 关键字就是明确告诉 CMake:“别去找 FindMyMath.cmake 了,直接去找库自己带来的那个配置文件”。

main.cpp

#include <iostream>
#include "math/math.h"int main()
{std::cout << "add(3,4) = " << add(3, 4) << std::endl;std::cout << "sub(3,4) = " << sub(3, 4) << std::endl;
}

接下来我们执行下面这个

mkdir build
cd build
cmake ../
cmake --build . -v

我们仔细观察一下最后一步的执行结果

root@VM-16-14-ubuntu:~/cmake/find_mymath/build# cmake --build . -v
Change Dir: '/root/cmake/find_mymath/build'Run Build Command(s): /usr/bin/cmake -E env VERBOSE=1 /usr/bin/gmake -f Makefile
/usr/bin/cmake -S/root/cmake/find_mymath -B/root/cmake/find_mymath/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /root/cmake/find_mymath/build/CMakeFiles /root/cmake/find_mymath/build//CMakeFiles/progress.marks
/usr/bin/gmake  -f CMakeFiles/Makefile2 all
gmake[1]: Entering directory '/root/cmake/find_mymath/build'
/usr/bin/gmake  -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/depend
gmake[2]: Entering directory '/root/cmake/find_mymath/build'
cd /root/cmake/find_mymath/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /root/cmake/find_mymath /root/cmake/find_mymath /root/cmake/find_mymath/build /root/cmake/find_mymath/build /root/cmake/find_mymath/build/CMakeFiles/main.dir/DependInfo.cmake "--color="
gmake[2]: Leaving directory '/root/cmake/find_mymath/build'
/usr/bin/gmake  -f CMakeFiles/main.dir/build.make CMakeFiles/main.dir/build
gmake[2]: Entering directory '/root/cmake/find_mymath/build'
[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o
/usr/bin/c++    -MD -MT CMakeFiles/main.dir/main.cpp.o -MF CMakeFiles/main.dir/main.cpp.o.d -o CMakeFiles/main.dir/main.cpp.o -c /root/cmake/find_mymath/main.cpp
[100%] Linking CXX executable main
/usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1
/usr/bin/c++ CMakeFiles/main.dir/main.cpp.o -o main  /usr/local/lib/libMyMath.a 
gmake[2]: Leaving directory '/root/cmake/find_mymath/build'
[100%] Built target main
gmake[1]: Leaving directory '/root/cmake/find_mymath/build'
/usr/bin/cmake -E cmake_progress_start /root/cmake/find_mymath/build/CMakeFiles 0

大家注意下面这句:/usr/bin/c++ CMakeFiles/main.dir/main.cpp.o -o main  /usr/local/lib/libMyMath.a ,这就代表寻找到了我们安装的静态库。

我们也可以去运行一下

./main

http://www.xdnf.cn/news/1402921.html

相关文章:

  • AI工具营销落地方案:工业产品营销
  • 编程与数学 03-004 数据库系统概论 08_逻辑结构设计
  • 【Canvas与盾牌】美国队长之盾卡通版
  • java报错问题解析
  • Dify 从入门到精通(第 65/100 篇):Dify 的自动化测试(进阶篇)
  • 疯狂星期四文案网第55天运营日记
  • 2024年INS SCI2区,基于快速成本评估和蚁群优化算法的多无人地面飞行器分层任务规划,深度解析+性能实测
  • C++/QT day2(8.30)
  • 【Python+requests】解决Python requests中的ProxyError:SSL版本错误问题详解
  • 笔记共享平台|基于Java+vue的读书笔记共享平台系统(源码+数据库+文档)
  • 简历书写---自我评价怎么写
  • offsetof宏的实现
  • Cybero: 1靶场渗透
  • HarmonyOS 应用开发:基于API 12及以上的现代化实践
  • 华为对“业务对象”是怎样定义与应用的?
  • Windows系统提示“找不到文件‘javaw‘”
  • react虚拟列表实现及原理
  • Git与DevOps实战:从版本控制到自动化部署
  • docker 启动一个clickhouse , docker 创建ck数据库
  • 介绍分布式事务之Seata
  • 【系统分析师】高分论文:论系统测试技术及应用
  • IAR工程如何搭建vscode+clangd编辑环境
  • day42-Ansible
  • “人工智能+”行动重磅发布!ElfBoard助力嵌入式教育智能化升级
  • 【Java】常见数据结构及方法
  • EVidenceModeler v2.1 安装与使用--生信工具58
  • 嵌入式开发学习 C++:day02
  • mysql(自写)
  • 10. 函数和匿名函数(二)
  • 数值分析——误差的来源与分类、误差的基本概念(绝对误差、相对误差、有效数字)