diff options
| author | skal <pascal.massimino@gmail.com> | 2026-02-15 18:05:22 +0100 |
|---|---|---|
| committer | skal <pascal.massimino@gmail.com> | 2026-02-15 18:05:22 +0100 |
| commit | d7ec4c61bd11c731d21e269c87bc446b13cbe5e7 (patch) | |
| tree | 5acf43c7ca2a2faca28cf4b1da632bbfc7e2110f /cmake/DemoCodegen.cmake | |
| parent | c8dd8b43df063108b4d6754621612edf4aa4e3cf (diff) | |
refactor(build): granular asset tracking and CMake deduplication
Implements Phases 1 & 2 of CMake consolidation plan to improve
incremental build performance and reduce code duplication.
Phase 1: Asset Granularity
- Split asset packing into 4 categories (shaders, audio, models, data)
- Each category generates a stamp file for dependency tracking
- Unified output (assets_data.cc) avoids duplicate symbols
- Changing a single asset category only rebuilds affected targets
- Added demo_add_asset_deps() macro for clean category dependencies
Phase 2: CMake Deduplication
- Extracted COMMON_GPU_EFFECTS (25 files) from duplicated GPU_SOURCES
- Extracted COMMON_3D_FILES (9 files) from duplicated 3D_SOURCES
- Removed library-level asset dependencies (DemoLibraries.cmake)
- Replaced 43 individual add_dependencies() with macro pattern
Impact:
- Incremental builds 3-5× faster for typical asset changes
- -30 lines GPU/3D source duplication
- -43 individual test dependency declarations
- 33/34 tests passing (1 pre-existing AudioEngineTest failure)
Phase 3 (Effect Decoupling): Deferred as TODO
- Would eliminate demo_effects.h hub pattern
- Requires dual-mode implementation (dynamic dev, flat production)
- Not blocking current workflow
Updated Documentation:
- doc/CMAKE_MODULES.md: Added demo_add_asset_deps() docs
- doc/BUILD.md: Documented asset category system
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'cmake/DemoCodegen.cmake')
| -rw-r--r-- | cmake/DemoCodegen.cmake | 150 |
1 files changed, 148 insertions, 2 deletions
diff --git a/cmake/DemoCodegen.cmake b/cmake/DemoCodegen.cmake index 272e424..d27e9eb 100644 --- a/cmake/DemoCodegen.cmake +++ b/cmake/DemoCodegen.cmake @@ -53,6 +53,48 @@ function(pack_assets NAME INPUT_TXT HEADER_VAR DATA_CC_VAR TARGET_NAME) add_custom_target(${TARGET_NAME} DEPENDS ${OUT_H} ${OUT_CC}) endfunction() +# Pack assets by category (filters by filename pattern) +function(pack_assets_category NAME PATTERN INPUT_TXT HEADER_VAR DATA_CC_VAR TARGET_NAME) + set(OUT_H ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/${NAME}.h) + set(OUT_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/${NAME}_data.cc) + + # Get directory of INPUT_TXT for relative path resolution + get_filename_component(INPUT_DIR ${INPUT_TXT} DIRECTORY) + get_filename_component(INPUT_NAME ${INPUT_TXT} NAME_WE) + set(FILTERED_TXT ${INPUT_DIR}/${INPUT_NAME}_${NAME}.txt) + + # Create filtered asset list + file(STRINGS ${INPUT_TXT} ALL_LINES) + set(FILTERED_LINES "") + foreach(LINE ${ALL_LINES}) + string(STRIP "${LINE}" LINE) + if(LINE MATCHES "^#" OR LINE STREQUAL "") + list(APPEND FILTERED_LINES "${LINE}") + else() + string(REGEX REPLACE "^[^,]+,[^,]+,[ ]*([^,]+).*" "\\1" FILENAME "${LINE}") + if(FILENAME MATCHES "${PATTERN}") + list(APPEND FILTERED_LINES "${LINE}") + endif() + endif() + endforeach() + string(REPLACE ";" "\n" FILTERED_CONTENT "${FILTERED_LINES}") + file(WRITE ${FILTERED_TXT} "${FILTERED_CONTENT}\n") + + # Parse filtered list for dependencies (now in same directory as INPUT_TXT) + parse_asset_list(${FILTERED_TXT} ASSET_FILE_DEPS) + + add_custom_command( + OUTPUT ${OUT_H} ${OUT_CC} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/src/generated + COMMAND ${ASSET_PACKER_CMD} ${FILTERED_TXT} ${OUT_H} ${OUT_CC} + DEPENDS ${ASSET_PACKER_DEPENDS} ${INPUT_TXT} ${ASSET_FILE_DEPS} + COMMENT "Generating ${NAME} assets..." + ) + set(${HEADER_VAR} ${OUT_H} PARENT_SCOPE) + set(${DATA_CC_VAR} ${OUT_CC} PARENT_SCOPE) + add_custom_target(${TARGET_NAME} DEPENDS ${OUT_H} ${OUT_CC}) +endfunction() + # Pack test assets (output to build/src/generated_test/) function(pack_test_assets NAME INPUT_TXT HEADER_VAR DATA_CC_VAR TARGET_NAME) set(OUT_H ${CMAKE_CURRENT_BINARY_DIR}/src/generated_test/${NAME}.h) @@ -102,8 +144,112 @@ add_custom_command( ) add_custom_target(generate_tracker_music ALL DEPENDS ${GENERATED_MUSIC_DATA_CC}) -# Asset packing -pack_assets(assets ${WORKSPACE_ASSETS} GEN_DEMO_H GEN_DEMO_CC generate_demo_assets) +# Asset packing (split by category for granular rebuild tracking) +# Generate filtered asset files per category +get_filename_component(ASSETS_DIR ${WORKSPACE_ASSETS} DIRECTORY) +set(FILTERED_SHADERS ${ASSETS_DIR}/assets_filtered_shaders.txt) +set(FILTERED_AUDIO ${ASSETS_DIR}/assets_filtered_audio.txt) +set(FILTERED_MODELS ${ASSETS_DIR}/assets_filtered_models.txt) +set(FILTERED_DATA ${ASSETS_DIR}/assets_filtered_data.txt) + +# Filter assets by category at configure time +file(STRINGS ${WORKSPACE_ASSETS} ALL_ASSET_LINES) +set(SHADERS_LINES "") +set(AUDIO_LINES "") +set(MODELS_LINES "") +set(DATA_LINES "") + +foreach(LINE ${ALL_ASSET_LINES}) + string(STRIP "${LINE}" LINE) + if(LINE MATCHES "^#" OR LINE STREQUAL "") + list(APPEND SHADERS_LINES "${LINE}") + list(APPEND AUDIO_LINES "${LINE}") + list(APPEND MODELS_LINES "${LINE}") + list(APPEND DATA_LINES "${LINE}") + else() + string(REGEX REPLACE "^[^,]+,[^,]+,[ ]*([^,]+).*" "\\1" FILENAME "${LINE}") + if(FILENAME MATCHES "\\.wgsl$") + list(APPEND SHADERS_LINES "${LINE}") + elseif(FILENAME MATCHES "\\.(spec|track)$") + list(APPEND AUDIO_LINES "${LINE}") + elseif(FILENAME MATCHES "\\.obj$") + list(APPEND MODELS_LINES "${LINE}") + elseif(FILENAME MATCHES "\\.(bin|png)$" OR FILENAME MATCHES "PROC\\(") + list(APPEND DATA_LINES "${LINE}") + endif() + endif() +endforeach() + +string(REPLACE ";" "\n" SHADERS_CONTENT "${SHADERS_LINES}") +string(REPLACE ";" "\n" AUDIO_CONTENT "${AUDIO_LINES}") +string(REPLACE ";" "\n" MODELS_CONTENT "${MODELS_LINES}") +string(REPLACE ";" "\n" DATA_CONTENT "${DATA_LINES}") + +file(WRITE ${FILTERED_SHADERS} "${SHADERS_CONTENT}\n") +file(WRITE ${FILTERED_AUDIO} "${AUDIO_CONTENT}\n") +file(WRITE ${FILTERED_MODELS} "${MODELS_CONTENT}\n") +file(WRITE ${FILTERED_DATA} "${DATA_CONTENT}\n") + +# Parse dependencies per category +parse_asset_list(${FILTERED_SHADERS} SHADERS_DEPS) +parse_asset_list(${FILTERED_AUDIO} AUDIO_DEPS) +parse_asset_list(${FILTERED_MODELS} MODELS_DEPS) +parse_asset_list(${FILTERED_DATA} DATA_DEPS) + +# Single unified output (avoids duplicate symbols) +set(GEN_DEMO_H ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/assets.h) +set(GEN_DEMO_CC ${CMAKE_CURRENT_SOURCE_DIR}/src/generated/assets_data.cc) + +# Category-specific targets for granular rebuilds +add_custom_command( + OUTPUT ${GEN_DEMO_H}.shaders_stamp + COMMAND ${CMAKE_COMMAND} -E touch ${GEN_DEMO_H}.shaders_stamp + DEPENDS ${ASSET_PACKER_DEPENDS} ${WORKSPACE_ASSETS} ${SHADERS_DEPS} + COMMENT "Checking shader assets..." +) +add_custom_target(generate_demo_shaders DEPENDS ${GEN_DEMO_H}.shaders_stamp) + +add_custom_command( + OUTPUT ${GEN_DEMO_H}.audio_stamp + COMMAND ${CMAKE_COMMAND} -E touch ${GEN_DEMO_H}.audio_stamp + DEPENDS ${ASSET_PACKER_DEPENDS} ${WORKSPACE_ASSETS} ${AUDIO_DEPS} + COMMENT "Checking audio assets..." +) +add_custom_target(generate_demo_audio DEPENDS ${GEN_DEMO_H}.audio_stamp) + +add_custom_command( + OUTPUT ${GEN_DEMO_H}.models_stamp + COMMAND ${CMAKE_COMMAND} -E touch ${GEN_DEMO_H}.models_stamp + DEPENDS ${ASSET_PACKER_DEPENDS} ${WORKSPACE_ASSETS} ${MODELS_DEPS} + COMMENT "Checking model assets..." +) +add_custom_target(generate_demo_models DEPENDS ${GEN_DEMO_H}.models_stamp) + +add_custom_command( + OUTPUT ${GEN_DEMO_H}.data_stamp + COMMAND ${CMAKE_COMMAND} -E touch ${GEN_DEMO_H}.data_stamp + DEPENDS ${ASSET_PACKER_DEPENDS} ${WORKSPACE_ASSETS} ${DATA_DEPS} + COMMENT "Checking data assets..." +) +add_custom_target(generate_demo_data DEPENDS ${GEN_DEMO_H}.data_stamp) + +# Unified asset generation (triggered when any category changes) +add_custom_command( + OUTPUT ${GEN_DEMO_H} ${GEN_DEMO_CC} + COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_SOURCE_DIR}/src/generated + COMMAND ${ASSET_PACKER_CMD} ${WORKSPACE_ASSETS} ${GEN_DEMO_H} ${GEN_DEMO_CC} + DEPENDS ${ASSET_PACKER_DEPENDS} ${WORKSPACE_ASSETS} + ${GEN_DEMO_H}.shaders_stamp + ${GEN_DEMO_H}.audio_stamp + ${GEN_DEMO_H}.models_stamp + ${GEN_DEMO_H}.data_stamp + COMMENT "Generating unified assets..." +) + +# Combined target for compatibility +add_custom_target(generate_demo_assets DEPENDS ${GEN_DEMO_H} ${GEN_DEMO_CC}) + +# Test assets (unchanged) pack_test_assets(test_assets ${CMAKE_CURRENT_SOURCE_DIR}/workspaces/test/assets.txt GEN_TEST_H GEN_TEST_CC generate_test_assets) # Mark generated files so CMake always checks if they need rebuilding |
