今天會學到的
30 天走到這裡,我們已經學了:
今天就把這些全部串起來,實際做一次完整專案實戰:
從寫程式、建置、測試、打包、安裝,到 CI/CD 自動化。
步驟
C_final_proj/
├─ inc/
│ └─ dog_meme.h
├─ src/
│ ├─ dog_meme.c
│ └─ main.c
├─ tests/
│ └─ test_dog.c
├─ CMakeLists.txt
└─ CMakePresets.json
#pragma once
int dog_add(int a, int b);
#include "dog_meme.h"
int dog_add(int a, int b) {
return a + b;
}
#include <stdio.h>
#include "dog_meme.h"
int main() {
int result = dog_add(2, 40);
printf("dog_add(2,40) = %d\n", result);
return 0;
}
#include <assert.h>
#include "dog_meme.h"
int main() {
assert(dog_add(2, 40) == 42);
return 0;
}
cmake_minimum_required(VERSION 3.21)
project(C_FINAL_PROJ VERSION 1.0.0 LANGUAGES C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# 建立靜態函式庫
add_library(dog_meme STATIC src/dog_meme.c)
target_include_directories(dog_meme PUBLIC ${CMAKE_SOURCE_DIR}/inc)
# 建立執行檔
add_executable(app src/main.c)
target_link_libraries(app PRIVATE dog_meme)
target_compile_options(app PRIVATE -Wall -Wextra -Wpedantic)
target_compile_definitions(app PRIVATE APP_VERSION="1.0.0")
# 測試
include(CTest)
enable_testing()
add_executable(test_dog tests/test_dog.c)
target_link_libraries(test_dog PRIVATE dog_meme)
add_test(NAME dog_meme_add_test COMMAND test_dog)
# 安裝與打包
install(TARGETS app RUNTIME DESTINATION bin)
install(DIRECTORY inc/ DESTINATION include)
include(CPack)
set(CPACK_PACKAGE_NAME "dog_meme_proj")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_GENERATOR "TGZ")
{
"version": 6,
"configurePresets": [
{
"name": "debug-ninja",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
}
},
{
"name": "release-ninja",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/release",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "asan",
"inherits": "debug-ninja",
"cacheVariables": {
"CMAKE_C_FLAGS": "-fsanitize=address -g",
"CMAKE_CXX_FLAGS": "-fsanitize=address -g"
}
}
],
"buildPresets": [
{ "name": "debug", "configurePreset": "debug-ninja", "jobs": 8 },
{ "name": "release", "configurePreset": "release-ninja", "jobs": 8 },
{ "name": "asan", "configurePreset": "asan", "jobs": 8 }
],
"testPresets": [
{ "name": "ctest-debug", "configurePreset": "debug-ninja", "output": { "outputOnFailure": true } }
]
}
cmake --preset debug-ninja
cmake --build --preset debug
ctest --preset ctest-debug --output-on-failure
cpack --config build/debug/CPackConfig.cmake
cmake --install build/debug --prefix ./dist
安裝後的結構:
dist/
├─ bin/app
└─ include/dog_meme.h
.github/workflows/cmake.yml
name: CMake CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Configure
run: cmake --preset release-ninja
- name: Build
run: cmake --build --preset release
- name: Test
run: ctest --preset ctest-debug --output-on-failure
- name: Package
run: cpack --config build/release/CPackConfig.cmake
小結
到這裡,挖已經30天的,真是辛苦大家也辛苦自己了!
在這30天的鐵人中,我們總共學會