步骤 10:选择静态库或共享库¶
在本节中,我们将展示如何使用 BUILD_SHARED_LIBS
变量来控制 add_library()
的默认行为,并允许控制如何构建没有显式类型(STATIC
、SHARED
、MODULE
或 OBJECT
)的库。
为此,我们需要将 BUILD_SHARED_LIBS
添加到顶层 CMakeLists.txt
中。我们使用 option()
命令,因为它允许用户选择值是 ON
还是 OFF
。
CMakeLists.txt¶
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
接下来,我们需要为静态库和共享库指定输出目录。
CMakeLists.txt¶
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
最后,更新 MathFunctions/MathFunctions.h
以使用 dll 导出定义
MathFunctions/MathFunctions.h¶
#if defined(_WIN32)
# if defined(EXPORTING_MYMATH)
# define DECLSPEC __declspec(dllexport)
# else
# define DECLSPEC __declspec(dllimport)
# endif
#else // non windows
# define DECLSPEC
#endif
namespace mathfunctions {
double DECLSPEC sqrt(double x);
}
此时,如果您构建所有内容,您可能会注意到链接失败,因为我们将没有位置无关代码的静态库与具有位置无关代码的库组合在一起。解决方案是,在构建共享库时,将 SqrtLibrary 的 POSITION_INDEPENDENT_CODE
目标属性显式设置为 True
。
MathFunctions/CMakeLists.txt¶
# state that SqrtLibrary need PIC when the default is shared libraries
set_target_properties(SqrtLibrary PROPERTIES
POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
)
定义 EXPORTING_MYMATH
,表示在 Windows 上构建时使用 declspec(dllexport)
。
MathFunctions/CMakeLists.txt¶
# define the symbol stating we are using the declspec(dllexport) when
# building on windows
target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
练习:我们修改了 MathFunctions.h
以使用 dll 导出定义。您能查阅 CMake 文档,找到一个辅助模块来简化此操作吗?