今天,我們就通過一個簡單的Linux C 語言實戰(zhàn)案例,帶你深度剖析嵌入式 CMake 的核心套路。
使用 CMake 的好處
平臺無關(guān)性:一套配置文件,適配 ARM、x86 等多種架構(gòu)。
模塊化管理:輕松分離驅(qū)動層、庫和應(yīng)用程序,代碼結(jié)構(gòu)一目了然。
自動化構(gòu)建:從編譯、鏈接到生成固件,一條make
命令搞定。
CMake例子
我們的例子包含三個核心模塊:
- 靜態(tài)庫(strutils):字符串處理工具。
- 動態(tài)庫(mathutils):數(shù)學計算工具。
- 應(yīng)用程序(myapp):主程序,調(diào)用上述兩個庫。
1.項目結(jié)構(gòu)
linux-cmake-example/
├── CMakeLists.txt # 頂層配置文件
├── lib/
│ ├── CMakeLists.txt # 庫模塊配置
│ ├── include/
│ │ ├── string_utils.h # 字符串庫頭文件
│ │ └── math_utils.h # 數(shù)學庫頭文件
│ ├── string_utils.c # 字符串庫實現(xiàn)
│ └── math_utils.c # 數(shù)學庫實現(xiàn)
├── app/
│ ├── CMakeLists.txt # 應(yīng)用程序配置
│ ├── include/
│ └── main.c # 主程序代碼
└── test/
├── CMakeLists.txt # 測試模塊配置
└── test_string_utils.c # 字符串庫測試代碼
每個文件夾都有獨立的CMakeLists.txt
,各司其職,這種 “分而治之” 的思想是嵌入式項目管理的精髓。
2. 頂層 CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(LinuxSystem C)
# 核心編譯選項:開啟嚴格檢查 + 優(yōu)化
set(CMAKE_C_STANDARD 11)
add_compile_options(
-Wall -Wextra -Werror
-O2
)
# 引入子模塊:庫、應(yīng)用、測試
add_subdirectory(lib)
add_subdirectory(app)
add_subdirectory(test)
關(guān)鍵點:
add_compile_options
統(tǒng)一設(shè)置編譯規(guī)則。add_subdirectory
讓 CMake 自動掃描子目錄的配置文件,簡化頂層邏輯。
3. 庫模塊:靜態(tài)庫、動態(tài)庫
靜態(tài)庫(strutils)配置
add_library(strutils STATIC
string_utils.c
)
target_include_directories(strutils PUBLIC include)
關(guān)鍵點:
add_library(strutils STATIC)
:創(chuàng)建靜態(tài)庫,代碼將直接嵌入可執(zhí)行文件。PUBLIC include
:將頭文件路徑暴露給依賴它的模塊,確保其他代碼能調(diào)用庫函數(shù)。
動態(tài)庫(mathutils)配置
add_library(mathutils SHARED
math_utils.c
)
target_include_directories(mathutils PUBLIC include)
關(guān)鍵點::
SHARED
選項:生成獨立的動態(tài)鏈接庫,可被多個程序復(fù)用。- 實際部署時,需確保庫文件在系統(tǒng)庫路徑中,否則運行會報錯。
4. 應(yīng)用程序:整合所有模塊
add_executable(myapp
main.c
)
target_include_directories(myapp PRIVATE include)
target_link_libraries(myapp
strutils
mathutils
m # 鏈接標準數(shù)學庫
)
關(guān)鍵點::
target_link_libraries
將靜態(tài)庫、動態(tài)庫與主程序綁定。PRIVATE include
:僅在應(yīng)用程序內(nèi)部使用頭文件,不對外暴露。
5. 測試模塊
add_executable(test_strutils
test_string_utils.c
)
target_link_libraries(test_strutils
strutils
cmocka # 引入單元測試框架
)
add_test(NAME test_strutils COMMAND test_strutils)
關(guān)鍵點:
- 使用
cmocka
框架編寫單元測試。 add_test
定義測試任務(wù),make test
一鍵運行。
6、編譯執(zhí)行
CMake進階技巧
1、 交叉編譯:在頂層CMakeLists.txt
中添加工具鏈配置,適配 ARM 等嵌入式平臺。
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
2、代碼覆蓋率分析:引入CodeCoverage
模塊,定位測試盲區(qū)
if(CMAKE_BUILD_TYPE MATCHES Coverage)
include(CodeCoverage)
append_coverage_compiler_flags()
setup_target_for_coverage_lcov(
NAME coverage
EXECUTABLE ctest -j ${PROCESSOR_COUNT}
DEPENDENCIES test_strutils
)
endif()
3、自動化部署:通過install
命令,一鍵將程序和庫部署到目標系統(tǒng)
install(TARGETS myapp DESTINATION bin)
install(TARGETS strutils mathutils DESTINATION lib)
install(DIRECTORY include/ DESTINATION include)