首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

CMake 構建複雜工程實戰:多庫依賴、跨平台配置與 Out-of-Source Build

     編輯:關於C語言

專案結構規劃

soTest/
├── CMakeLists.txt          # 根配置
├── so1/
│   ├── CMakeLists.txt
│   ├── so1.c
│   └── so1.h
├── so2/
│   ├── CMakeLists.txt
│   ├── so2.c
│   └── so2.h          # 依賴 so1
├── test/
│   ├── CMakeLists.txt
│   ├── test.c         # 依賴 so2
│   └── test.py        # Python 調用 so2
└── build/             # Out-of-source 建構目錄 (不納入版控)

根 CMakeLists.txt — 全域設定與子目錄串聯

cmake_minimum_required(VERSION 3.0)
project(soTest)

# 統一頭檔搜尋路徑
include_directories(${PROJECT_SOURCE_DIR})

# 庫檔與執行檔輸出目錄統一至 build/libs
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/libs)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/libs)

# 庫檔搜尋路徑優先序
link_directories(${PROJECT_BINARY_DIR}/libs /usr/local/lib /usr/lib)

# 納入子目錄 (各自有 CMakeLists.txt)
add_subdirectory(so1)
add_subdirectory(so2)
add_subdirectory(test)

so1/CMakeLists.txt — 基礎共享庫

project(soTest)
set(SO1_SRCS so1.c)
add_library(so1 SHARED ${SO1_SRCS})

so2/CMakeLists.txt — 依賴 so1 的共享庫

project(soTest)
set(SO2_SRCS so2.c)
add_library(so2 SHARED ${SO2_SRCS})
target_link_libraries(so2 so1)  # 關鍵:聲明鏈接依賴

test/CMakeLists.txt — 可執行檔鏈接 so2 與 so1

project(soTest)
set(TEST_SRCS test.c)
add_executable(st ${TEST_SRCS})
target_link_libraries(st so2 so1)  # 遞移依賴自動處理

Out-of-Source Build 標準流程

mkdir build && cd build
cmake ..          # 生成 Makefile / VS Solution
make              # 編譯
./libs/st         # 執行測試

建構成功輸出示意

關鍵 CMake 指令解析

指令用途備註
add_library(name SHARED srcs)建立動態庫靜態庫用 STATIC,雙模用 BOTH
target_link_libraries(tgt libs...)聲明鏈接依賴現代 CMake 推薦配合 target_include_directories
set(LIBRARY_OUTPUT_PATH ...)指定庫輸出目錄避免散落在各子目錄
link_directories(...)鏈接器搜尋路徑優先序遞減,建議改用 target_link_directories
add_subdirectory(dir)遞迴處理子目錄子目錄必須有 CMakeLists.txt

進階實務技巧

  • 版本資訊:set_target_properties(so1 PROPERTIES VERSION 1.0.0 SOVERSION 1) 生成 libso1.so.1。
  • 安裝規則:install(TARGETS so1 so2 st DESTINATION lib/bin) 支援 make install。
  • CMakePresets.json (CMake 3.19+):預設建構配置 (Debug/Release、編譯器旗標),避免命令列參數過長。
  • FetchContent / find_package:引入第三方依賴 (如 googletest, spdlog, nlohmann_json)。
  • Generator Expressions:$<BUILD_INTERFACE:...> / $<INSTALL_INTERFACE:...> 區分建構期/安裝期頭檔路徑。

跨平台注意事項

平台動態庫前綴/副檔名備註
Linuxlibxxx.sosoname 機制
Windowsxxx.dll需 __declspec(dllexport) 匯出符號
macOSlibxxx.dylibinstall_name 機制

CMake 會自動處理平台差異,但符號匯出需自行用 #ifdef _WIN32 定義巨集。

總結

CMake 以「宣告式配置 + 原生建構系統生成」解決跨平台構建痛點。本範例展示了**多層庫依賴、統一輸出目錄、Out-of-Source Build** 的最小可行專案結構。實務專案中應善用現代 CMake (3.10+) 的 target_* 族群 API,實現屬性遞移、介面隔離與安裝部署標準化。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved