在本节中,我们将展示如何使用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.txtset(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
#endifnamespace mathfunctions {
double DECLSPEC sqrt(double x);
}
此时,如果您构建了所有内容,您可能会注意到链接失败,因为我们正在将不依赖位置的静态库与具有位置依赖的库组合在一起。解决这个问题的方法是在构建共享库时显式地将SqrtLibrary的POSITION_INDEPENDENT_CODE目标属性设置为True。
// MathFunctions/CMakeLists.txt# state that SqrtLibrary need PIC when the default is shared librariesset_target_properties(SqrtLibrary PROPERTIESPOSITION_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")