From aa1a52cb5553f883a59c4dc70c8a8a06919e7d6f Mon Sep 17 00:00:00 2001 From: Bill Date: Tue, 17 Feb 2026 21:40:36 -0700 Subject: [PATCH] Step 637: platform CMake target generator --- editor/CMakeLists.txt | 9 ++ editor/src/PlatformCMakeTargetGenerator.h | 43 ++++++++ editor/tests/step637_test.cpp | 117 ++++++++++++++++++++++ progress.md | 31 ++++++ 4 files changed, 200 insertions(+) create mode 100644 editor/src/PlatformCMakeTargetGenerator.h create mode 100644 editor/tests/step637_test.cpp diff --git a/editor/CMakeLists.txt b/editor/CMakeLists.txt index 03f1fb1..e682c7a 100644 --- a/editor/CMakeLists.txt +++ b/editor/CMakeLists.txt @@ -4612,4 +4612,13 @@ target_link_libraries(step636_test PRIVATE tree_sitter_javascript tree_sitter_typescript tree_sitter_java tree_sitter_rust tree_sitter_go) +add_executable(step637_test tests/step637_test.cpp) +target_include_directories(step637_test PRIVATE src) +target_link_libraries(step637_test PRIVATE + nlohmann_json::nlohmann_json + unofficial::tree-sitter::tree-sitter + tree_sitter_python tree_sitter_cpp tree_sitter_elisp + tree_sitter_javascript tree_sitter_typescript + tree_sitter_java tree_sitter_rust tree_sitter_go) + # Step 12: Dear ImGui shell scaffolding created (main.cpp exists but not built due to dependencies) diff --git a/editor/src/PlatformCMakeTargetGenerator.h b/editor/src/PlatformCMakeTargetGenerator.h new file mode 100644 index 0000000..391880c --- /dev/null +++ b/editor/src/PlatformCMakeTargetGenerator.h @@ -0,0 +1,43 @@ +#pragma once +// Step 637: Cross-platform CMake target generator + +#include + +struct PlatformBlockInput { + std::string targetName; + std::string processorPattern; + std::string sourceFile; + std::string annotationTarget; +}; + +class PlatformCMakeTargetGenerator { +public: + static bool isSupportedAnnotation(const std::string& annotationTarget) { + return !annotationTarget.empty(); + } + + static std::string generateCMakeGuard(const PlatformBlockInput& in) { + if (in.targetName.empty() || in.processorPattern.empty() || in.sourceFile.empty()) { + return ""; + } + std::string cmake; + cmake += "if(CMAKE_SYSTEM_PROCESSOR MATCHES \"" + in.processorPattern + "\")\n"; + cmake += " target_sources(" + in.targetName + " PRIVATE " + in.sourceFile + ")\n"; + cmake += " target_compile_definitions(" + in.targetName + " PRIVATE WHETSTONE_PLATFORM_MATCH=1)\n"; + cmake += "endif()\n"; + return cmake; + } + + static std::string generateIfdef(const std::string& macroName, + const std::string& code) { + if (macroName.empty()) return ""; + return "#ifdef " + macroName + "\n" + code + "\n#endif\n"; + } + + static std::string macroForAnnotationTarget(const std::string& annotationTarget) { + if (annotationTarget == "aarch64-apple-darwin") return "WHETSTONE_AARCH64_APPLE_DARWIN"; + if (annotationTarget == "x86_64-linux") return "WHETSTONE_X86_64_LINUX"; + if (annotationTarget == "x86_64-windows") return "WHETSTONE_X86_64_WINDOWS"; + return "WHETSTONE_PLATFORM_GENERIC"; + } +}; diff --git a/editor/tests/step637_test.cpp b/editor/tests/step637_test.cpp new file mode 100644 index 0000000..5d307f5 --- /dev/null +++ b/editor/tests/step637_test.cpp @@ -0,0 +1,117 @@ +// Step 637: Cross-platform CMake target generator (12 tests) + +#include "PlatformCMakeTargetGenerator.h" + +#include + +static int passed = 0, failed = 0; +#define TEST(name) { std::cout << " " << #name << "... "; } +#define PASS() { std::cout << "PASS\n"; ++passed; } +#define FAIL(msg) { std::cout << "FAIL: " << msg << "\n"; ++failed; } +#define CHECK(cond, msg) if (!(cond)) { FAIL(msg); return; } + +void test_supported_annotation_rejects_empty() { + TEST(supported_annotation_rejects_empty); + CHECK(!PlatformCMakeTargetGenerator::isSupportedAnnotation(""), "empty annotation should be rejected"); + PASS(); +} + +void test_supported_annotation_accepts_platform_target() { + TEST(supported_annotation_accepts_platform_target); + CHECK(PlatformCMakeTargetGenerator::isSupportedAnnotation("aarch64-apple-darwin"), "annotation should be accepted"); + PASS(); +} + +void test_generate_cmake_guard_requires_target_name() { + TEST(generate_cmake_guard_requires_target_name); + PlatformBlockInput in{"", "aarch64", "src/main.cpp", "aarch64-apple-darwin"}; + CHECK(PlatformCMakeTargetGenerator::generateCMakeGuard(in).empty(), "missing target should fail"); + PASS(); +} + +void test_generate_cmake_guard_includes_if_block() { + TEST(generate_cmake_guard_includes_if_block); + PlatformBlockInput in{"drone", "aarch64", "src/main.cpp", "aarch64-apple-darwin"}; + auto txt = PlatformCMakeTargetGenerator::generateCMakeGuard(in); + CHECK(txt.find("if(CMAKE_SYSTEM_PROCESSOR MATCHES \"aarch64\")") != std::string::npos, "if guard missing"); + PASS(); +} + +void test_generate_cmake_guard_emits_target_sources() { + TEST(generate_cmake_guard_emits_target_sources); + PlatformBlockInput in{"drone", "aarch64", "src/main.cpp", "aarch64-apple-darwin"}; + auto txt = PlatformCMakeTargetGenerator::generateCMakeGuard(in); + CHECK(txt.find("target_sources(drone PRIVATE src/main.cpp)") != std::string::npos, "target_sources missing"); + PASS(); +} + +void test_generate_cmake_guard_emits_compile_definition() { + TEST(generate_cmake_guard_emits_compile_definition); + PlatformBlockInput in{"drone", "aarch64", "src/main.cpp", "aarch64-apple-darwin"}; + auto txt = PlatformCMakeTargetGenerator::generateCMakeGuard(in); + CHECK(txt.find("WHETSTONE_PLATFORM_MATCH=1") != std::string::npos, "compile definition missing"); + PASS(); +} + +void test_generate_ifdef_rejects_empty_macro() { + TEST(generate_ifdef_rejects_empty_macro); + CHECK(PlatformCMakeTargetGenerator::generateIfdef("", "int x=1;").empty(), "empty macro should fail"); + PASS(); +} + +void test_generate_ifdef_wraps_code() { + TEST(generate_ifdef_wraps_code); + auto txt = PlatformCMakeTargetGenerator::generateIfdef("WHETSTONE_X", "int x = 1;"); + CHECK(txt.find("#ifdef WHETSTONE_X") != std::string::npos, "ifdef missing"); + CHECK(txt.find("int x = 1;") != std::string::npos, "code missing"); + CHECK(txt.find("#endif") != std::string::npos, "endif missing"); + PASS(); +} + +void test_macro_mapping_for_aarch64_apple() { + TEST(macro_mapping_for_aarch64_apple); + CHECK(PlatformCMakeTargetGenerator::macroForAnnotationTarget("aarch64-apple-darwin") == + "WHETSTONE_AARCH64_APPLE_DARWIN", "macro mismatch"); + PASS(); +} + +void test_macro_mapping_for_linux() { + TEST(macro_mapping_for_linux); + CHECK(PlatformCMakeTargetGenerator::macroForAnnotationTarget("x86_64-linux") == + "WHETSTONE_X86_64_LINUX", "macro mismatch"); + PASS(); +} + +void test_macro_mapping_for_windows() { + TEST(macro_mapping_for_windows); + CHECK(PlatformCMakeTargetGenerator::macroForAnnotationTarget("x86_64-windows") == + "WHETSTONE_X86_64_WINDOWS", "macro mismatch"); + PASS(); +} + +void test_macro_mapping_falls_back_generic() { + TEST(macro_mapping_falls_back_generic); + CHECK(PlatformCMakeTargetGenerator::macroForAnnotationTarget("riscv64") == + "WHETSTONE_PLATFORM_GENERIC", "fallback macro mismatch"); + PASS(); +} + +int main() { + std::cout << "Step 637: Cross-platform CMake target generator\n"; + + test_supported_annotation_rejects_empty(); + test_supported_annotation_accepts_platform_target(); + test_generate_cmake_guard_requires_target_name(); + test_generate_cmake_guard_includes_if_block(); + test_generate_cmake_guard_emits_target_sources(); + test_generate_cmake_guard_emits_compile_definition(); + test_generate_ifdef_rejects_empty_macro(); + test_generate_ifdef_wraps_code(); + test_macro_mapping_for_aarch64_apple(); + test_macro_mapping_for_linux(); + test_macro_mapping_for_windows(); + test_macro_mapping_falls_back_generic(); + + std::cout << "\nResults: " << passed << "/" << (passed + failed) << " passed\n"; + return failed == 0 ? 0 : 1; +} diff --git a/progress.md b/progress.md index ae7889e..7f68d09 100644 --- a/progress.md +++ b/progress.md @@ -12920,3 +12920,34 @@ rules, and `std::expected` alias generation helpers. - `editor/src/DroneErrorSynthesis.h` (`62` <= `600`) - `editor/tests/step636_test.cpp` within test-file size guidance (`109` lines) - Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md` + +### Step 637: Cross-platform CMake target generator +**Status:** PASS (12/12 tests) + +Adds cross-platform generation helpers for platform-annotated blocks, including +CMake processor guards, compile-definition emission, and platform macro mapping +for generated `#ifdef` paths. + +**Files added:** +- `editor/src/PlatformCMakeTargetGenerator.h` - platform-target generator: + - guarded CMake target-source generation + - annotation-to-macro mapping + - compile-time `#ifdef` wrapper generation +- `editor/tests/step637_test.cpp` - 12 tests covering: + - annotation and input validation + - CMake guard/text emission behavior + - macro mapping for target platforms and fallback behavior + +**Files modified:** +- `editor/CMakeLists.txt` - `step637_test` target + +**Verification run:** +- `cmake -S editor -B editor/build-native` - PASS +- `cmake --build editor/build-native --target step637_test step636_test` - PASS +- `./editor/build-native/step637_test` - PASS (12/12) +- `./editor/build-native/step636_test` - PASS (12/12) regression coverage + +**Architecture gate check:** +- `editor/src/PlatformCMakeTargetGenerator.h` (`43` <= `600`) +- `editor/tests/step637_test.cpp` within test-file size guidance (`117` lines) +- Header-only architecture and naming conventions remain aligned with `ARCHITECTURE.md`