# 构建和链接静态库和动态库 ## 前提 准备三个文件 ```c++ //main.cpp #include "Message.hpp" #include #include int main() { Message say_hello("Hello, CMake World!"); std::cout << say_hello << std::endl; Message say_goodbye("Goodbye, CMake World"); std::cout << say_goodbye << std::endl; return EXIT_SUCCESS; } ``` ```c++ //Message.hpp #pragma once #include #include class Message { public: Message(const std::string &m) : message_(m) {} friend std::ostream &operator<<(std::ostream &os, Message &obj) { return obj.printObject(os); } private: std::string message_; std::ostream &printObject(std::ostream &os); }; ``` ```c++ //Message.cpp #include "Message.hpp" #include #include std::ostream &Message::printObject(std::ostream &os) { os << "This is my very nice message: " << std::endl; os << message_; return os; } ``` ## CMake构建和链接 ```txt #最低CMake版本 cmake_minimum_required(VERSION 3.5) #项目信息 project(project4 LANGUAGES CXX) # set(USE_LIBRARY YES) message(STATUS "Compile sources into a library? ${USE_LIBRARY}") # set(BUILD_SHARED_LIBS NO) list(APPEND _sources Message.hpp Message.cpp) if(USE_LIBRARY) add_library(message ${_sources}) add_executable(wang4 main.cpp) target_link_libraries(wang4 message) else() add_executable(wang5 main.cpp ${_sources}) endif() ``` CMake接受其他值作为`add_library`的第二个参数的有效值,我们来看下本书会用到的值: - **STATIC**:用于创建静态库,即编译文件的打包存档,以便在链接其他目标时使用,例如:可执行文件。 - **SHARED**:用于创建动态库,即可以动态链接,并在运行时加载的库。可以在`CMakeLists.txt`中使用`add_library(message SHARED Message.hpp Message.cpp)`从静态库切换到动态共享对象(DSO)。 - **OBJECT**:可将给定`add_library`的列表中的源码编译到目标文件,不将它们归档到静态库中,也不能将它们链接到共享对象中。如果需要一次性创建静态库和动态库,那么使用对象库尤其有用。我们将在本示例中演示。 - **MODULE**:又为DSO组。与`SHARED`库不同,它们不链接到项目中的任何目标,不过可以进行动态加载。该参数可以用于构建运行时插件。 CMake还能够生成特殊类型的库,这不会在构建系统中产生输出,但是对于组织目标之间的依赖关系,和构建需求非常有用: - **IMPORTED**:此类库目标表示位于项目外部的库。此类库的主要用途是,对现有依赖项进行构建。因此,`IMPORTED`库将被视为不可变的。我们将在本书的其他章节演示使用`IMPORTED`库的示例。 - **INTERFACE**:与`IMPORTED`库类似。不过,该类型库可变,没有位置信息。它主要用于项目之外的目标构建使用。我们将在本章第5节中演示`INTERFACE`库的示例。 - **ALIAS**:顾名思义,这种库为项目中已存在的库目标定义别名。不过,不能为`IMPORTED`库选择别名。 ## 说明 经过编译和链接测试,CMake的 `add_library()` 的第一个参数为库名称,第二个参数默认为 `STATIC` ,即默认会构建成静态链接库。