summaryrefslogtreecommitdiff
path: root/cmake/DemoCommon.cmake
diff options
context:
space:
mode:
authorskal <pascal.massimino@gmail.com>2026-02-11 08:19:05 +0100
committerskal <pascal.massimino@gmail.com>2026-02-11 08:19:05 +0100
commitfdf9345d5de1c951603e5da3ee8454e9efe2dc28 (patch)
treeee0dcf35de7d2800b20faf861cd70cb168d773f8 /cmake/DemoCommon.cmake
parent6d64674f7e3d00a9d18ec61eaf968ed37c8e849b (diff)
refactor: Modularize CMake build system into 10 specialized modules
Refactor monolithic 866-line CMakeLists.txt into 54-line orchestrator + 10 modules: - DemoOptions.cmake - Build option declarations - DemoConfig.cmake - Option implications and platform detection - DemoCommon.cmake - Shared macros (conditional sources, size opts, linking) - DemoDependencies.cmake - External library discovery (WGPU, GLFW) - DemoSourceLists.cmake - Conditional source file lists - DemoLibraries.cmake - Subsystem library targets - DemoTools.cmake - Build tools (asset_packer, compilers) - DemoCodegen.cmake - Code generation (assets, timeline, music) - DemoExecutables.cmake - Main binaries (demo64k, test_demo) - DemoTests.cmake - Test infrastructure (36 tests) - Validation.cmake - Uniform buffer validation Benefits: - 94% reduction in main file size (866 → 54 lines) - Conditional module inclusion (tests only parsed if DEMO_BUILD_TESTS=ON) - Shared macros eliminate 200+ lines of repetition - Clear separation of concerns All 36 tests passing. All build modes verified. Documentation: Created doc/CMAKE_MODULES.md with module architecture. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'cmake/DemoCommon.cmake')
-rw-r--r--cmake/DemoCommon.cmake199
1 files changed, 199 insertions, 0 deletions
diff --git a/cmake/DemoCommon.cmake b/cmake/DemoCommon.cmake
new file mode 100644
index 0000000..1c63b26
--- /dev/null
+++ b/cmake/DemoCommon.cmake
@@ -0,0 +1,199 @@
+# CMake Common Utilities
+# Shared macros and functions for the demo64k build system
+
+# =============================================================================
+# demo_set_conditional_sources(VAR HEADLESS_LIST STRIP_LIST NORMAL_LIST)
+# =============================================================================
+# Simplifies 3-branch conditional source lists based on build mode
+#
+# Arguments:
+# VAR - Output variable name (e.g., GPU_SOURCES)
+# HEADLESS_LIST - Sources for DEMO_HEADLESS mode
+# STRIP_LIST - Sources for DEMO_STRIP_EXTERNAL_LIBS mode
+# NORMAL_LIST - Sources for normal builds
+#
+# Usage:
+# demo_set_conditional_sources(GPU_SOURCES
+# "src/gpu/headless_gpu.cc;src/gpu/effect.cc"
+# "src/gpu/stub_gpu.cc"
+# "src/gpu/gpu.cc;src/gpu/effect.cc"
+# )
+function(demo_set_conditional_sources VAR HEADLESS_LIST STRIP_LIST NORMAL_LIST)
+ if(DEMO_HEADLESS)
+ set(${VAR} ${HEADLESS_LIST} PARENT_SCOPE)
+ elseif(DEMO_STRIP_EXTERNAL_LIBS)
+ set(${VAR} ${STRIP_LIST} PARENT_SCOPE)
+ else()
+ set(${VAR} ${NORMAL_LIST} PARENT_SCOPE)
+ endif()
+endfunction()
+
+# =============================================================================
+# demo_apply_size_optimizations(TARGET)
+# =============================================================================
+# Applies platform-specific size optimization flags to a target
+#
+# Arguments:
+# TARGET - CMake target name
+#
+# Behavior:
+# - Only applies if DEMO_SIZE_OPT is enabled
+# - MSVC: /Os /GS- /OPT:REF /OPT:ICF
+# - Apple: -Os -Wl,-dead_strip
+# - Linux: -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -s
+#
+# Usage:
+# demo_apply_size_optimizations(demo64k)
+function(demo_apply_size_optimizations TARGET)
+ if(DEMO_SIZE_OPT)
+ if(MSVC)
+ target_compile_options(${TARGET} PRIVATE /Os /GS-)
+ target_link_options(${TARGET} PRIVATE /OPT:REF /OPT:ICF /INCREMENTAL:NO)
+ elseif(APPLE)
+ target_compile_options(${TARGET} PRIVATE -Os)
+ target_link_options(${TARGET} PRIVATE -Wl,-dead_strip)
+ else()
+ target_compile_options(${TARGET} PRIVATE -Os -ffunction-sections -fdata-sections)
+ target_link_options(${TARGET} PRIVATE -Wl,--gc-sections -s)
+ endif()
+ endif()
+endfunction()
+
+# =============================================================================
+# demo_link_libraries_ordered(TARGET)
+# =============================================================================
+# Links subsystem libraries in correct order with platform-specific quirks
+#
+# Arguments:
+# TARGET - CMake target name
+#
+# Link Order:
+# - Circular dependencies on Linux require --start-group/--end-group
+# - Apple uses direct linking
+# - DEMO_STRIP_EXTERNAL_LIBS mode excludes DEMO_LIBS
+#
+# Usage:
+# demo_link_libraries_ordered(demo64k)
+function(demo_link_libraries_ordered TARGET)
+ if(DEMO_STRIP_EXTERNAL_LIBS)
+ # Size measurement mode: No external libraries
+ if(APPLE)
+ target_link_libraries(${TARGET} PRIVATE 3d gpu audio procedural util)
+ else()
+ target_link_libraries(${TARGET} PRIVATE
+ -Wl,--start-group 3d gpu audio procedural util -Wl,--end-group
+ pthread m)
+ endif()
+ else()
+ # Normal mode: Link external libraries
+ if(APPLE)
+ target_link_libraries(${TARGET} PRIVATE 3d gpu audio procedural util ${DEMO_LIBS})
+ else()
+ target_link_libraries(${TARGET} PRIVATE
+ -Wl,--start-group 3d gpu audio procedural util -Wl,--end-group
+ ${DEMO_LIBS})
+ endif()
+ endif()
+endfunction()
+
+# =============================================================================
+# demo_add_test_with_deps(NAME TEST_NAME LABEL SOURCE [SOURCES...]
+# [LINK libs...] [DEPENDS targets...]
+# [DEFINITIONS defs...] [INCLUDES dirs...])
+# =============================================================================
+# Streamlined test registration with automatic dependency handling
+#
+# Arguments:
+# NAME - Executable target name
+# TEST_NAME - CTest test name
+# LABEL - Test label for subsystem grouping (audio, gpu, 3d, assets, util)
+# SOURCE - First source file (required)
+# SOURCES... - Additional source files (parsed until keyword)
+#
+# Optional Keywords:
+# LINK libs... - Libraries to link (parsed until next keyword)
+# DEPENDS targets... - Target dependencies (parsed until next keyword)
+# DEFINITIONS defs... - Compile definitions (parsed until next keyword)
+# INCLUDES dirs... - Include directories (parsed until next keyword)
+#
+# Usage:
+# demo_add_test_with_deps(test_window HammingWindowTest audio
+# src/tests/audio/test_window.cc
+# ${GEN_DEMO_CC}
+# LINK audio util procedural ${DEMO_LIBS}
+# DEPENDS generate_demo_assets
+# )
+function(demo_add_test_with_deps NAME TEST_NAME LABEL)
+ set(options "")
+ set(oneValueArgs "")
+ set(multiValueArgs LINK DEPENDS DEFINITIONS INCLUDES)
+
+ # Collect sources until we hit a keyword
+ set(SOURCES "")
+ set(current_list SOURCES)
+ set(keyword_mode FALSE)
+
+ foreach(arg ${ARGN})
+ if(arg STREQUAL "LINK" OR arg STREQUAL "DEPENDS" OR
+ arg STREQUAL "DEFINITIONS" OR arg STREQUAL "INCLUDES")
+ set(current_list ${arg})
+ set(keyword_mode TRUE)
+ else()
+ list(APPEND ${current_list} ${arg})
+ endif()
+ endforeach()
+
+ # Create test executable
+ add_executable(${NAME} ${SOURCES})
+ add_test(NAME ${TEST_NAME} COMMAND ${NAME})
+ set_tests_properties(${TEST_NAME} PROPERTIES LABELS "${LABEL}")
+
+ # Apply optional parameters
+ if(DEFINED LINK)
+ target_link_libraries(${NAME} PRIVATE ${LINK})
+ endif()
+
+ if(DEFINED DEPENDS)
+ add_dependencies(${NAME} ${DEPENDS})
+ endif()
+
+ if(DEFINED DEFINITIONS)
+ target_compile_definitions(${NAME} PRIVATE ${DEFINITIONS})
+ endif()
+
+ if(DEFINED INCLUDES)
+ target_include_directories(${NAME} PRIVATE ${INCLUDES})
+ endif()
+endfunction()
+
+# =============================================================================
+# add_demo_executable(NAME SOURCES...)
+# =============================================================================
+# Creates an executable for the demo
+#
+# Arguments:
+# NAME - Executable target name
+# SOURCES - Source files
+#
+# Note: target_link_libraries must be called manually to ensure correct order
+macro(add_demo_executable NAME)
+ add_executable(${NAME} ${ARGN})
+endmacro()
+
+# =============================================================================
+# add_demo_test(NAME TEST_NAME LABEL SOURCES...)
+# =============================================================================
+# Creates a test executable and registers it with CTest (legacy macro)
+#
+# Arguments:
+# NAME - Executable target name
+# TEST_NAME - CTest test name
+# LABEL - Test label for subsystem grouping
+# SOURCES - Source files
+#
+# Note: Use demo_add_test_with_deps() for new tests
+macro(add_demo_test NAME TEST_NAME LABEL)
+ add_executable(${NAME} ${ARGN})
+ add_test(NAME ${TEST_NAME} COMMAND ${NAME})
+ set_tests_properties(${TEST_NAME} PROPERTIES LABELS "${LABEL}")
+endmacro()