CMake構建學習筆記11-minizip庫的構建

charlee44發表於2024-08-29

準確來說,minizip其實是zlib提供的輔助工具,位於zlib庫的contrib資料夾內。minizip提供了更為高階一點的介面,能直接操作檔案進行壓縮。不過,有點麻煩的是這個工具並沒有提供CMake構建的方式。那麼可以按照構建giflib的方式,自己組織CMakeList.txt,正好這個專案的程式碼量並不多。

另一個問題是,minizip其實是個可執行程式,Windows下不能直接將其構建成動態連結庫,因為Windows下的動態連結庫是需要設定匯出的,否則就會提示找不到符號的問題。這種情況下最簡便的方式就是將其組織成靜態庫了(專案地址),CMakeList.txt如下所示:

# 輸出cmake版本提示
message(STATUS "The CMAKE_VERSION is ${CMAKE_VERSION}.")

# cmake的最低版本要求
cmake_minimum_required (VERSION 3.10)

# 工程名稱、版本、語言
project(minizip VERSION 5.2.2)

# 支援當前目錄
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 /wd4996)  
else()
    message(">> unknow compiler.")
endif()

# 查詢 ZLIB 模組
find_package(ZLIB REQUIRED)

# 原始碼檔案
set(PROJECT_SOURCES ioapi.c iowin32.c miniunz.c minizip.c mztools.c unzip.c zip.c)
set(PROJECT_HEADER crypt.h ioapi.h iowin32.h mztools.h unzip.h zip.h)

# 將原始碼新增到此專案的可執行檔案。
add_library(${PROJECT_NAME} STATIC ${PROJECT_SOURCES} ${PROJECT_HEADER})

#
target_link_libraries(${PROJECT_NAME} ZLIB::ZLIB)

# TODO: 如有需要,請新增測試

# 安裝標頭檔案到 include 目錄
install(FILES ${PROJECT_HEADER} DESTINATION include/${PROJECT_NAME})

# 安裝庫檔案到 lib 目錄
install(TARGETS ${PROJECT_NAME}
        LIBRARY DESTINATION lib  # 對於共享庫
        ARCHIVE DESTINATION lib  # 對於靜態庫
        RUNTIME DESTINATION bin  # 對於可執行檔案
)

關鍵的構建指令如下所示:

# 配置CMake  
cmake .. -G "$Generator" -A x64 `
-DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo `
-DCMAKE_PREFIX_PATH="$InstallDir" `
-DCMAKE_INSTALL_PREFIX="$InstallDir"

# 構建階段,指定構建型別
cmake --build . --config RelWithDebInfo

# 安裝階段,指定構建型別和安裝目標
cmake --build . --config RelWithDebInfo --target install

在最後談談動態庫和靜態庫的問題。動態庫和靜態庫各有優缺點,這裡就不細緻的論述了。但是在Windows下筆者還是傾向於優先使用動態庫。一直以來,二進位制相容的問題一直是困擾C/C++程式設計的重要問題。比如說,你用VS2010編譯的動態庫在VS2013的環境下可能是無法使用的,這還是同一家產品的不同版本就會造成這個二進位制成果的差異性問題。但是,根據Microsoft提供的文件(參看:https://learn.microsoft.com/zh-cn/cpp/porting/binary-compat-2015-2017 ),VS2015以後的版本就會開始提供二進位制相容的特性了,原理是標準庫、執行時庫(如 msvcp140.dll)、C++ 標準庫保證了ABI(二進位制介面)的穩定。筆者也確實發現很多產品的MSVC的預編譯成果能夠在MSVC環境中混用了。比如VS2017編譯的Qt就能夠在VS2019的環境下正常使用。不過這些能混用的成果一般都是動態庫,也就是動態庫的二進位制相容特性更好一點。至於靜態庫,文件中宣稱靜態庫也可以做到,但是筆者實測至少這個基於VS2017的minizip靜態庫在VS2019中用不了。這一點就留待以後解決了。

相關文章