From 28d84aa0188ddf8f29646a84c4b8dd158ab5c1cb Mon Sep 17 00:00:00 2001 From: Tlaloc <156491852+AlexGoodmen@users.noreply.github.com> Date: Fri, 22 Aug 2025 23:36:21 -0500 Subject: [PATCH] ci_compile.cpp This C++ utility runs locally. and performs three main operations: 1. Detect Compiler ```cpp std::string compiler = "clang++"; if (runCommand("which clang++ > /dev/null 2>&1") != 0) { compiler = "g++"; } ``` * Tries to find `clang++`. * If not available, falls back to `g++`. This ensures the script works on systems without Clang. 2. Compile `DebugDisplay.cpp` with Strict Checks** ```cpp std::string compileCmd = compiler + " -std=c++20 " "-I\"" + SRC + "\" " "-Wall -Wextra -Werror -Wpedantic -Wconversion -Wshadow " "-Wdouble-promotion -Wold-style-cast -Woverloaded-virtual -Wnon-virtual-dtor " "-Wnull-dereference -Wformat=2 -Wimplicit-fallthrough=5 -Wundef -Wredundant-decls " "-fno-omit-frame-pointer " "-O0 -g3 " "-c \"" + TU + "\" -o /tmp/DebugDisplay.o"; ``` Purpose: Compile only `GeneralsMD/Code/GameEngine/Source/GameClient/System/DebugDisplay.cpp` into an object file without linking the entire project. Flags Explained * `-Wall -Wextra`: Enable common and extra warnings. * `-Werror`: Treat warnings as errors. * `-Wpedantic -Wconversion -Wshadow`: Catch risky patterns and implicit type conversions. * `-O0 -g3`: No optimization, full debug info. * `-c`: Compile only (no linking). * `-I"$SRC"`: Adds include path for headers. * `-std=c++20`: Enforces modern standard compliance. If compilation fails, the program exits early so you know exactly which errors are in that translation unit. --- ### **3. Static Analysis with `clang-tidy`** ```cpp std::string tidyCmd = "clang-tidy \"" + TU + "\" " "--warnings-as-errors='*' " "--extra-arg=-std=c++20 " "--extra-arg=-I\"" + SRC + "\" " "--checks='clang-analyzer-*,bugprone-*,readability-*,modernize-*,performance-*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers' " "--header-filter='GeneralsMD/Code/GameEngine/Source/.*' " "--format-style=file || true"; ``` * **Purpose**: Run static analysis and style checks on the same file using `clang-tidy`. * **Checks Applied**: * `clang-analyzer-*`: Finds undefined behavior, memory leaks. * `bugprone-*`: Detects common mistakes. * `modernize-*`: Suggests C++ modernizations. * `performance-*`: Flags inefficient code. * `cppcoreguidelines-*`: Enforces core safety rules. * `WarningsAsErrors='*'`: Treat all findings as errors in CI context. * `HeaderFilterRegex`: Limits analysis to headers under your `GeneralsMD` source tree. If `clang-tidy` is not installed, it skips this step. Execution Flow 1. Print which compiler is used. 2. Show compiler version. 3. Compile `DebugDisplay.cpp` with strict warnings-as-errors. 4. Run `clang-tidy` to check for logical errors and style issues. 5. Exit with success if everything passes. --- Goal * Detect syntax and header-related issues **before full build**. * Fail fast on warnings. * Provide static analysis early. * Reduce debugging time by isolating this translation unit. --- .github/workflows/Compilers | 62 +++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 .github/workflows/Compilers diff --git a/.github/workflows/Compilers b/.github/workflows/Compilers new file mode 100644 index 00000000000..254bdd53028 --- /dev/null +++ b/.github/workflows/Compilers @@ -0,0 +1,62 @@ +#include +#include +#include +#include + +int runCommand(const std::string& cmd) { + std::cout << "[RUN] " << cmd << "\n"; + return std::system(cmd.c_str()); +} + +int main() { + // Environment settings + const std::string SRC = "GeneralsMD/Code/GameEngine/Source"; + const std::string TU = SRC + "/GameClient/System/DebugDisplay.cpp"; + + // Choose compiler: try clang++ first, then fallback to g++ + std::string compiler = "clang++"; + if (runCommand("which clang++ > /dev/null 2>&1") != 0) { + compiler = "g++"; + } + + std::cout << "Using compiler: " << compiler << "\n"; + + // Show compiler version + runCommand(compiler + " --version"); + + // Build compile command + std::string compileCmd = compiler + + " -std=c++20 " + "-I\"" + SRC + "\" " + "-Wall -Wextra -Werror -Wpedantic -Wconversion -Wshadow " + "-Wdouble-promotion -Wold-style-cast -Woverloaded-virtual -Wnon-virtual-dtor " + "-Wnull-dereference -Wformat=2 -Wimplicit-fallthrough=5 -Wundef -Wredundant-decls " + "-fno-omit-frame-pointer " + "-O0 -g3 " + "-c \"" + TU + "\" -o /tmp/DebugDisplay.o"; + + std::cout << "\nCompiling DebugDisplay.cpp with strict warnings...\n"; + if (runCommand(compileCmd) != 0) { + std::cerr << "Compilation failed. Fix errors above.\n"; + return 1; + } + + // Run clang-tidy if available + if (runCommand("which clang-tidy > /dev/null 2>&1") == 0) { + std::cout << "\nRunning clang-tidy checks...\n"; + std::string tidyCmd = + "clang-tidy \"" + TU + "\" " + "--warnings-as-errors='*' " + "--extra-arg=-std=c++20 " + "--extra-arg=-I\"" + SRC + "\" " + "--checks='clang-analyzer-*,bugprone-*,readability-*,modernize-*,performance-*,cppcoreguidelines-*,-cppcoreguidelines-avoid-magic-numbers' " + "--header-filter='GeneralsMD/Code/GameEngine/Source/.*' " + "--format-style=file || true"; + runCommand(tidyCmd); + } else { + std::cerr << "clang-tidy not found. Skipping lint step.\n"; + } + + std::cout << "\nDebugDisplay.cpp passes strict compile and lint.\n"; + return 0; +}