构建和链接静态库和动态库 前提 准备三个文件
1 2 3 4 5 6 7 8 9 10 11 #include "Message.hpp" #include <cstdlib> #include <iostream> 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; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 #pragma once #include <iosfwd> #include <string> 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) ; };
1 2 3 4 5 6 7 8 9 #include "Message.hpp" #include <iostream> #include <string> std::ostream &Message::printObject (std::ostream &os) { os << "This is my very nice message: " << std::endl; os << message_; return os; }
CMake构建和链接 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #最低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
,即默认会构建成静态链接库。