CMake構建學習筆記23-SQLite庫的構建
1. 構建思路
在前文中構建了大量的庫包程序(參看CMake構建學習筆記-目錄)之后,可以總結一下在Windows下使用腳本構建程序的辦法:
- 使用CMake構建。這是目前最通用最流行的構建方式,大部分C/C++程序都在逐漸向這個方向轉。
- 使用namke構建。在CMake流行之前,有的程序會提供MSVC項目文件,這種情況下可以使用namke來進行構建。
- 使用MSYS2/MinGW構建。適用于只提供了Linux環境構建方式的程序,不過可能會有二進制兼容問題,一般不推薦。
- 使用第三方的項目構建。比如自己組織CMake項目,或者使用vcpkg這樣的庫包管理工具直接安裝。
2. 構建SQLite
SQLite是一個輕量級的、無需獨立服務器進程的嵌入式關系型數據庫。它將整個數據庫(包括表、索引和數據)存儲在一個單一的磁盤文件中,支持標準的SQL語法,廣泛用于嵌入式設備、移動應用和小型Web項目。SQLite是一個老牌的C庫,不提供CMake的構建方式,而且它還是個可執行程序而不僅僅是庫,這給程序的集成帶來一定的麻煩。
那么如何在Windows下將SQLite構建成庫文件呢?這里選擇第4種方案,根據源代碼文件生成CMake項目。SQLite提供了一個很不錯的特性,就是支持將所有的實現代碼組合成一個sqlite.c文件,因此自己組織CMake項目就比較簡單,組織結構如下:
project-root/
├── include/
│ ├── sqlite3.h
│ └── sqlite3ext.h
├── src/
│ └── sqlite3.c
├── CMakeLists.txt
├── CMakePresets.json
└── sqlite3.def
源代碼sqlite.c、sqlite3.h、sqlite3ext.h是SQLite的源代碼文件,不用進行修改。需要注意的是SQLite提供兩種源代碼文件,一種是分散組織的,一種是組合成單文件的,一定要選擇后者才能看到sqlite.c文件(比如sqlite-amalgamation-3460000.zip)。
另外,sqlite3.def是模塊定義文件,為Windows的DLL模塊定義各種屬性和導出符號。如果是像筆者一樣需要構建成動態庫,那么這個文件一定要有。這個文件可以在SQLite提供預編譯包種找到(比如sqlite-dll-win-x64-3460000)。
最后,CMakeLists.txt中的內容如下:
# 輸出cmake版本提示
message(STATUS "The CMAKE_VERSION is ${CMAKE_VERSION}.")
# cmake的最低版本要求
cmake_minimum_required (VERSION 3.10)
# 工程名稱、版本、語言
project(sqlite3 VERSION 3.4.6)
# 支持當前目錄
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# 判斷編譯器類型
message("CMAKE_CXX_COMPILER_ID: ${CMAKE_CXX_COMPILER_ID}")
# 判斷編譯器類型
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
message(">> using Clang")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
message(">> using GCC")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
message(">> using Intel C++")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
message(">> using Visual Studio C++")
add_compile_options(/utf-8)
else()
message(">> unknow compiler.")
endif()
# 設置編譯定義
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \
-DSQLITE_THREADSAFE=1 \
-DSQLITE_ENABLE_COLUMN_METADATA \
-DSQLITE_ENABLE_PREUPDATE_HOOK \
-DSQLITE_ENABLE_RTREE \
-DSQLITE_ENABLE_GEOPOLY \
-DSQLITE_ENABLE_SESSION \
-DSQLITE_ENABLE_RBU")
# 源代碼文件
set(INCLUDE_FILES
./include/sqlite3.h
./include/sqlite3ext.h
)
set(SOURCE_FILES
./src/sqlite3.c
${INCLUDE_FILES}
)
# 動態庫前綴與后綴
IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
set(LibraryPrefix lib)
set(LibraryPostfix so)
ELSEIF(CMAKE_SYSTEM_NAME MATCHES "Windows")
set(LibraryPrefix )
set(LibraryPostfix lib)
ENDIF()
# 將源代碼添加到此項目的可執行文件。
add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES})
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
# 指定.def文件
set_target_properties(${PROJECT_NAME} PROPERTIES
OUTPUT_NAME ${PROJECT_NAME}
LINK_FLAGS "/DEF:${CMAKE_CURRENT_SOURCE_DIR}/sqlite3.def")
endif()
# TODO: 如有需要,請添加測試
# 安裝頭文件到 include 目錄
install(DIRECTORY include/ DESTINATION include)
# 安裝庫文件到 lib 目錄
install(TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION lib # 對于共享庫
ARCHIVE DESTINATION lib # 對于靜態庫
RUNTIME DESTINATION bin # 對于可執行文件
)
然后執行如下腳本指令:
cmake $SourceLocalPath `
-B "$BuildDir" `
-G "$Generator" `
-A x64 `
-DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo `
-DCMAKE_INSTALL_PREFIX="$InstallDir"
# 構建階段,指定構建類型
cmake --build $BuildDir --config RelWithDebInfo
# 安裝階段,指定構建類型和安裝目標
cmake --build $BuildDir --config RelWithDebInfo --target install
即可完成編譯、鏈接到安裝的完整構建過程。$SourceLocalPath是源代碼目錄,也就是前面的CMake項目文件夾;$BuildDir是構建目錄文件夾;"$Generator"是生成器,比如Visual Studio 16 2019。

浙公網安備 33010602011771號