From 237e7c313859ba623fb4b2db90f66c03dd1e81af Mon Sep 17 00:00:00 2001 From: MH Hung Date: Tue, 23 Sep 2025 13:34:55 +0800 Subject: [PATCH] feat: scaffold C++ template with tooling helpers --- .clang-format | 33 ++++++++++++++++++++++++++++ .clang-tidy | 15 +++++++++++++ Makefile | 29 +++++++++++++++++++++++++ README.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main.cpp | 14 ++++++++++++ utils/build.sh | 9 ++++++++ utils/clean.sh | 9 ++++++++ utils/format.sh | 21 ++++++++++++++++++ utils/run.sh | 9 ++++++++ 9 files changed, 197 insertions(+) create mode 100644 .clang-format create mode 100644 .clang-tidy create mode 100644 Makefile create mode 100644 src/main.cpp create mode 100755 utils/build.sh create mode 100755 utils/clean.sh create mode 100755 utils/format.sh create mode 100755 utils/run.sh diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..a0c99c8 --- /dev/null +++ b/.clang-format @@ -0,0 +1,33 @@ +BasedOnStyle: LLVM +Language: Cpp +Standard: c++20 +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +ColumnLimit: 100 +AccessModifierOffset: -4 +NamespaceIndentation: All +AllowShortFunctionsOnASingleLine: Empty +BreakBeforeBraces: Custom +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterStruct: false + AfterUnion: false + BeforeCatch: true + BeforeElse: true + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^<.*>$' + Priority: 1 + - Regex: '^".*"$' + Priority: 2 + +SpacesInAngles: false +SpaceBeforeParens: ControlStatements diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..39a07c7 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,15 @@ +Checks: >- + bugprone-*, + clang-analyzer-*, + cppcoreguidelines-avoid-magic-numbers, + cppcoreguidelines-init-variables, + google-*, + modernize-*, + performance-*, + readability-* +WarningsAsErrors: '' +HeaderFilterRegex: 'src/.*' +AnalyzeTemporaryDtors: false +FormatStyle: file +User: codex +ExtraArgs: ['-std=c++20'] diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6c60fe5 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +CXX := g++ +CXXFLAGS := -std=c++20 -Wall -Wextra -Wpedantic -O2 +LDFLAGS := +SRC_DIR := src +BUILD_DIR := build +TARGET := app + +SRCS := $(wildcard $(SRC_DIR)/*.cpp) +OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(BUILD_DIR)/%.o,$(SRCS)) + +$(TARGET): $(OBJS) + $(CXX) $(OBJS) $(LDFLAGS) -o $@ + +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp | $(BUILD_DIR) + $(CXX) $(CXXFLAGS) -c $< -o $@ + +$(BUILD_DIR): + mkdir -p $(BUILD_DIR) + +.PHONY: clean run format + +run: $(TARGET) + ./$(TARGET) + +clean: + rm -rf $(BUILD_DIR) $(TARGET) + +format: + clang-format -i $(SRCS) diff --git a/README.md b/README.md index eb024de..757d39e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,60 @@ # cpp-template +這個專案提供一個簡單的 C++ 樣板,包含基本的目錄結構、Makefile 與開發輔助工具,方便快速開始新專案。 + +## 目錄結構 +- `src/`: 主要的 C++ 原始碼,目前包含 `main.cpp`。 +- `build/`: 由 Makefile 自動建立,用來存放編譯後的物件檔。 +- `utils/`: 收錄常用腳本,例如編譯、執行、清理以及格式化。 +- `.clang-format`: 定義 clang-format 的專案格式規則。 +- `.clang-tidy`: 定義 clang-tidy 的檢查設定。 +- `Makefile`: 管理編譯、執行、清理與格式化等命令。 + +## 建置與執行 +若系統已安裝 `g++`,可使用以下命令: + +```bash +# 編譯 (預設目標 app) +make + +# 編譯並執行 +make run + +# 清理 build 及執行檔 +make clean +``` + +也可以透過 `utils/` 底下的腳本快速操作: + +```bash +./utils/build.sh # 執行 make,接受額外參數 +./utils/run.sh # 編譯並執行 +./utils/clean.sh # 移除 build/ 與 app +./utils/format.sh # 依據 .clang-format 重新排版 src/ 下的檔案 +``` + +如需指定不同的目標或旗標,可直接傳入 `utils/build.sh`: + +```bash +./utils/build.sh TARGET=my_app CXXFLAGS="-O3 -DNDEBUG" +``` + +## 程式碼格式化 +`utils/format.sh` 會檢查 `clang-format` 是否存在,並對 `src/` 目錄內的 `.cpp/.hpp/.h` 檔案進行格式化。專案提供的 `.clang-format` 以 LLVM 風格為基礎,並設定: +- C++20 標準 +- 4 空格縮排,最大列寬 100 +- 自訂括號換行與 namespace 縮排規則 + +## 靜態分析 +`.clang-tidy` 啟用了一些常用的檢查(`bugprone-*`、`clang-analyzer-*`、`modernize-*` 等)。要檢查特定檔案,可執行: + +```bash +clang-tidy src/main.cpp -- +``` + +可視需求調整 `Checks`、`HeaderFilterRegex` 或其他設定來符合專案需求。 + +## 下一步 +- 在 `src/` 新增更多檔案與模組。 +- 依專案需求擴充 Makefile 或 utils 腳本。 +- 若需要不同的編碼規範或靜態分析工具,修改 `.clang-format` 與 `.clang-tidy` 即可。 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..0151347 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,14 @@ +#include +#include +#include +#include +#include + +int main() { + std::ios::sync_with_stdio(false); + std::cin.tie(nullptr); + + // TODO: Add program logic here. + + return 0; +} diff --git a/utils/build.sh b/utils/build.sh new file mode 100755 index 0000000..04924fd --- /dev/null +++ b/utils/build.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="${SCRIPT_DIR}/.." + +cd "${PROJECT_ROOT}" + +make "$@" diff --git a/utils/clean.sh b/utils/clean.sh new file mode 100755 index 0000000..85a49cc --- /dev/null +++ b/utils/clean.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="${SCRIPT_DIR}/.." + +cd "${PROJECT_ROOT}" + +make clean diff --git a/utils/format.sh b/utils/format.sh new file mode 100755 index 0000000..ca743fb --- /dev/null +++ b/utils/format.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="${SCRIPT_DIR}/.." +SRC_DIR="${PROJECT_ROOT}/src" + +if ! command -v clang-format >/dev/null 2>&1; then + echo "error: clang-format is not installed or not in PATH" >&2 + exit 1 +fi + +if [ ! -d "${SRC_DIR}" ]; then + echo "warning: src directory not found; nothing to format" >&2 + exit 0 +fi + +find "${SRC_DIR}" -name '*.cpp' -o -name '*.hpp' -o -name '*.h' | while read -r file; do + clang-format -i "$file" + echo "formatted $file" +done diff --git a/utils/run.sh b/utils/run.sh new file mode 100755 index 0000000..e59fed2 --- /dev/null +++ b/utils/run.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="${SCRIPT_DIR}/.." + +cd "${PROJECT_ROOT}" + +make "$@" run