【CMake】构建和链接静态库和动态库

C++源码:

 1 /**
 2  * @file Message.hpp
 3  */
 4 #ifndef MESSAGE_H
 5 #define MESSAGE_H
 6 
 7 #include <iosfwd>
 8 #include <string>
 9 class Message
10 {
11 public:
12     Message(const std::string &m) : message_(m) {}
13     friend std::ostream &operator<<(std::ostream &os, Message &obj)
14     {
15         return obj.printObject(os);
16     }
17 
18 private:
19     std::string message_;
20     std::ostream &printObject(std::ostream &os);
21 };
22 
23 #endif // !MESSAGE_H
 1 /**
 2  * @file Message.cpp
 3  */
 4 #include "Message.hpp"
 5 #include <iostream>
 6 #include <string>
 7 std::ostream &Message::printObject(std::ostream &os)
 8 {
 9     os << "This is my very nice message: " << std::endl;
10     os << message_;
11     return os;
12 }
 1 /**
 2  * @file main.cpp
 3  */
 4 #include "Message.hpp"
 5 #include <cstdlib>
 6 #include <iostream>
 7 int main()
 8 {
 9     Message say_hello("Hello, CMake World!");
10     std::cout << say_hello << std::endl;
11     Message say_goodbye("Goodbye, CMake World");
12     std::cout << say_goodbye << std::endl;
13     return EXIT_SUCCESS;
14 }

 

CMakeLists.txt

 1 # 设置cmake所需的最低版本
 2 cmake_minimum_required(VERSION 3.21)
 3 # 声明工程名称和工程支持的编程语言
 4 project(CmakeTest LANGUAGES CXX)
 5 # 创建静态库目标,生成目标libmessage.<扩展后缀>
 6 add_library(message
 7   STATIC
 8     Message.hpp
 9     Message.cpp
10   )
11 
12 # 指示cmake生成一个可执行程序,该程序通过编译、连接源文件main.cpp生成
13 add_executable(${PROJECT_NAME} main.cpp)
14 
15 # 链接静态库
16 target_link_libraries(${PROJECT_NAME} message)

 

add_library的第一个参数是目标名。整个CMakeLists.txt中,可使用相同的名称来引用库。生成的库的实际名称将由CMake通过在前面添加前缀lib和适当的扩展名作为后缀来形成。生成库是根据第二个参数(STATICSHARED)和操作系统确定的。

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库将被视为不可变的。
  • INTERFACE:与IMPORTED库类似。不过,该类型库可变,没有位置信息。它主要用于项目之外的目标构建使用。我们将在本章第5节中演示INTERFACE库的示例。
  • ALIAS:顾名思义,这种库为项目中已存在的库目标定义别名。不过,不能为IMPORTED库选择别名。

 

target_link_libraries(hello-world message): 将库链接到可执行文件。此命令还确保hello-world可执行文件可以正确地依赖于消息库。因此,在消息库链接到hello-world可执行文件之前,需要完成消息库的构建。

posted @ 2022-08-04 15:17  禅元天道  阅读(2802)  评论(0编辑  收藏  举报