步驟 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 文件,您可以找到簡化此操作的輔助模組嗎?