@@ -147,6 +147,50 @@ endif()
147147message ("Current c++ debug flags used: '${CMAKE_C_FLAGS } '" )
148148message ("Current c++ release flags used: '${CMAKE_CXX_FLAGS } '" )
149149
150+ # Minimal engine source files (for bootstrap compiler only)
151+ # These files are needed to run PG scripts (VM + modules + ECS for module registration)
152+ set (MINIMAL_ENGINESOURCE
153+ # Core compiler/VM files
154+ src/Engine/Compiler/compiler_debug.cpp
155+ src/Engine/Compiler/vm.cpp
156+ src/Engine/Compiler/vm_profiler.cpp
157+ src/Engine/Compiler/compiler.cpp
158+ src/Engine/Compiler/object.cpp
159+ src/Engine/Compiler/cparser.cpp
160+ src/Engine/Compiler/bytecode_pass.cpp
161+ src/Engine/Compiler/bytecode_rewriter.cpp
162+ src/Engine/Compiler/chunk_serializer.cpp
163+ src/Engine/Compiler/pass/bytecode_pass_module.cpp
164+ src/Engine/Compiler/pass/long_jump_optimization_pass.cpp
165+ src/Engine/Compiler/pass/basic_operator_local_indexing.cpp
166+ src/Engine/Compiler/pass/constant_folding.cpp
167+ # Minimal interpreter (only lexer and token for parsing)
168+ src/Engine/Interpreter/lexer.cpp
169+ src/Engine/Interpreter/token.cpp
170+ # ECS system (needed for module registration and VM integration)
171+ src/Engine/ECS/commanddispatcher.cpp
172+ src/Engine/ECS/componentregistry.cpp
173+ src/Engine/ECS/entity.cpp
174+ src/Engine/ECS/entitysystem.cpp
175+ src/Engine/ECS/group.cpp
176+ src/Engine/ECS/savemanager.cpp
177+ src/Engine/ECS/sparseset.cpp
178+ src/Engine/ECS/standardsystem.cpp
179+ src/Engine/ECS/system.cpp
180+ src/Engine/ECS/uniqueid.cpp
181+ # Essential support files
182+ src/Engine/logger.cpp
183+ src/Engine/serialization.cpp
184+ src/Engine/Files/filemanager.cpp
185+ src/Engine/Files/fileparser.cpp
186+ src/Engine/Memory/elementtype.cpp
187+ src/Engine/Memory/parallelfor.cpp
188+ src/Engine/Profiler/profiler.cpp
189+ # Core systems (provides EntityName component)
190+ src/Engine/Systems/coresystems.cpp
191+ )
192+
193+ # Full engine source files
150194set (ENGINESOURCE
151195 src/Engine/engine.cpp
152196 src/Engine/window.cpp
@@ -170,6 +214,7 @@ set(ENGINESOURCE
170214 src/Engine/Compiler/bytecode_pass.cpp
171215 src/Engine/Compiler/bytecode_rewriter.cpp
172216 src/Engine/Compiler/chunk_serializer.cpp
217+ src/Engine/Compiler/pass/bytecode_pass_module.cpp
173218 src/Engine/Compiler/pass/long_jump_optimization_pass.cpp
174219 src/Engine/Compiler/pass/basic_operator_local_indexing.cpp
175220 src/Engine/Compiler/pass/constant_folding.cpp
@@ -241,8 +286,157 @@ set(ENGINESOURCE
241286 src/Engine/UI/uisystem.cpp
242287)
243288
244- # Create the static library
245- add_library (ColumbaEngine STATIC ${ENGINESOURCE} )
289+ # ===============================================
290+ # COMPONENT GENERATION SETUP (Two-stage build)
291+ # ===============================================
292+
293+ # Find all .pgcomp component definition files
294+ file (GLOB COMPONENT_DEFINITIONS
295+ "${CMAKE_CURRENT_SOURCE_DIR } /src/Engine/Components/*.pgcomp"
296+ )
297+
298+ # Note: ColumbaEngine library will be created AFTER component generation
299+
300+ # ===============================================
301+ # MINIMAL ENGINE LIBRARY (for bootstrap compiler)
302+ # ===============================================
303+ # Create a minimal engine library with only VM + modules + ECS
304+ # This is used ONLY for building the bootstrap compiler
305+ add_library (ColumbaEngineMinimal STATIC ${MINIMAL_ENGINESOURCE} )
306+
307+ # Disable PCH for minimal engine to avoid rebuilding it
308+ # (The minimal engine is small enough that PCH overhead isn't worth it,
309+ # and it would need a separate PCH due to PG_MINIMAL_BUILD definition)
310+ set_target_properties (ColumbaEngineMinimal PROPERTIES DISABLE_PRECOMPILE_HEADERS ON )
311+
312+ # Define PG_MINIMAL_BUILD for the minimal engine
313+ target_compile_definitions (ColumbaEngineMinimal PRIVATE PG_MINIMAL_BUILD )
314+
315+ message (STATUS "Created minimal engine library" )
316+
317+ # Minimal engine needs the same include directories as full engine
318+ target_include_directories (ColumbaEngineMinimal PUBLIC
319+ $<BUILD_INTERFACE :${CMAKE_CURRENT_SOURCE_DIR } /src /Engine >
320+ $<BUILD_INTERFACE :${CMAKE_CURRENT_SOURCE_DIR } /${GLM_DIR} >
321+ $<BUILD_INTERFACE :${CMAKE_CURRENT_SOURCE_DIR } /${TASKFLOW_DIR} >
322+ )
323+
324+ # Add platform-specific includes for minimal engine
325+ if (NOT ${CMAKE_SYSTEM_NAME } MATCHES "Emscripten" )
326+ target_include_directories (ColumbaEngineMinimal PUBLIC
327+ $<BUILD_INTERFACE :${CMAKE_CURRENT_SOURCE_DIR } /${SDL2_DIR} /include >
328+ )
329+ endif ()
330+
331+ # Minimal engine linking (much simpler - no rendering, no audio, no networking)
332+ if (${CMAKE_SYSTEM_NAME } MATCHES "Emscripten" )
333+ target_link_libraries (ColumbaEngineMinimal PUBLIC glm )
334+ else ()
335+ # Native platforms - only need basic SDL2 for minimal functionality
336+ if (TARGET SDL2-static)
337+ target_link_libraries (ColumbaEngineMinimal PUBLIC SDL2-static glm )
338+ elseif (TARGET SDL2::SDL2-static)
339+ target_link_libraries (ColumbaEngineMinimal PUBLIC SDL2::SDL2-static glm )
340+ endif ()
341+ endif ()
342+
343+ # ===============================================
344+ # BOOTSTRAP COMPILER EXECUTABLE
345+ # ===============================================
346+ # Create a minimal PgCompiler executable that can run component generator
347+ # This uses the minimal engine library to avoid circular dependencies
348+ add_executable (PgCompilerBootstrap
349+ exemples/PgCompiler/main.cpp
350+ exemples/PgCompiler/application.cpp
351+ exemples/PgCompiler/constant_uniformity_pass.cpp
352+ )
353+
354+ target_compile_definitions (PgCompilerBootstrap PRIVATE PG_MINIMAL_BUILD )
355+
356+ target_include_directories (PgCompilerBootstrap PUBLIC exemples/PgCompiler )
357+
358+ # Link against minimal engine (no rendering, no generated components)
359+ target_link_libraries (PgCompilerBootstrap PRIVATE ColumbaEngineMinimal )
360+
361+ message (STATUS "Bootstrap compiler 'PgCompilerBootstrap' created (links to minimal engine)" )
362+
363+ # ===============================================
364+ # COMPONENT REGENERATION TARGET
365+ # ===============================================
366+ # Create a target to regenerate components when .pgcomp files change
367+ # This uses the bootstrap compiler to avoid circular dependencies
368+ if (COMPONENT_DEFINITIONS)
369+ set (ALL_GENERATED_FILES "" )
370+
371+ foreach (COMP_DEF ${COMPONENT_DEFINITIONS} )
372+ get_filename_component (COMP_NAME ${COMP_DEF} NAME_WE )
373+
374+ # Define the output files
375+ set (GENERATED_HEADER "${CMAKE_CURRENT_SOURCE_DIR } /src/Engine/Components/${COMP_NAME} .generated.h" )
376+ set (GENERATED_CPP "${CMAKE_CURRENT_SOURCE_DIR } /src/Engine/Components/${COMP_NAME} .generated.cpp" )
377+ set (GENERATED_SER "${CMAKE_CURRENT_SOURCE_DIR } /src/Engine/Components/${COMP_NAME} .serialization.cpp" )
378+
379+ # Add custom command that only runs when inputs change
380+ add_custom_command (
381+ OUTPUT ${GENERATED_HEADER} ${GENERATED_CPP} ${GENERATED_SER}
382+ COMMAND ${CMAKE_COMMAND } -E echo "Regenerating ${COMP_NAME} ..."
383+ COMMAND $<TARGET_FILE :PgCompilerBootstrap >
384+ ${CMAKE_CURRENT_SOURCE_DIR } /tools/component_generator.pg
385+ ${COMP_DEF}
386+ DEPENDS
387+ PgCompilerBootstrap
388+ ${COMP_DEF}
389+ ${CMAKE_CURRENT_SOURCE_DIR } /tools/component_generator.pg
390+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR } /src/Engine/Components
391+ COMMENT "Regenerating ${COMP_NAME} from ${COMP_DEF} "
392+ VERBATIM
393+ )
394+
395+ # Create a target for this component (for manual regeneration)
396+ add_custom_target (Regenerate_${COMP_NAME}
397+ DEPENDS ${GENERATED_HEADER} ${GENERATED_CPP} ${GENERATED_SER}
398+ )
399+
400+ list (APPEND ALL_GENERATED_FILES ${GENERATED_HEADER} ${GENERATED_CPP} ${GENERATED_SER} )
401+
402+ # Mark the generated files as GENERATED so CMake knows they'll be created
403+ set_source_files_properties (
404+ ${GENERATED_HEADER} ${GENERATED_CPP} ${GENERATED_SER}
405+ PROPERTIES GENERATED TRUE
406+ )
407+ endforeach ()
408+
409+ # Create a target to regenerate all components (for manual use)
410+ add_custom_target (RegenerateComponents
411+ DEPENDS ${ALL_GENERATED_FILES}
412+ COMMENT "All components up to date"
413+ )
414+
415+ message (STATUS "Component regeneration configured for ${NUM_DEFINITIONS} components" )
416+ message (STATUS " Components will regenerate only when .pgcomp files change" )
417+ message (STATUS " Manual regeneration: cmake --build . --target RegenerateComponents" )
418+ endif ()
419+
420+ # ===============================================
421+ # FULL ENGINE LIBRARY (with generated components)
422+ # ===============================================
423+ # Build the list of generated component sources
424+ set (GENERATED_COMPONENT_SOURCES "" )
425+ if (COMPONENT_DEFINITIONS)
426+ foreach (COMP_DEF ${COMPONENT_DEFINITIONS} )
427+ get_filename_component (COMP_NAME ${COMP_DEF} NAME_WE )
428+ list (APPEND GENERATED_COMPONENT_SOURCES
429+ "${CMAKE_CURRENT_SOURCE_DIR } /src/Engine/Components/${COMP_NAME} .generated.cpp"
430+ "${CMAKE_CURRENT_SOURCE_DIR } /src/Engine/Components/${COMP_NAME} .serialization.cpp"
431+ )
432+ endforeach ()
433+
434+ list (LENGTH GENERATED_COMPONENT_SOURCES NUM_GEN_SOURCES)
435+ message (STATUS "ColumbaEngine will include ${NUM_GEN_SOURCES} generated component source files" )
436+ endif ()
437+
438+ # Create the full engine library with generated components
439+ add_library (ColumbaEngine STATIC ${ENGINESOURCE} ${GENERATED_COMPONENT_SOURCES} )
246440
247441# Todo find why the pch doesn't work on windows
248442if (MINGW)
@@ -252,6 +446,11 @@ endif()
252446# Set precompiled headers - but don't make them public for consumers
253447target_precompile_headers (ColumbaEngine PRIVATE src/Engine/stdafx.h )
254448
449+ # Make ColumbaEngine depend on component regeneration
450+ if (COMPONENT_DEFINITIONS)
451+ add_dependencies (ColumbaEngine RegenerateComponents )
452+ endif ()
453+
255454# Include directories - ONLY use generator expressions for proper build/install interface
256455target_include_directories (ColumbaEngine PUBLIC
257456 $<BUILD_INTERFACE :${CMAKE_CURRENT_SOURCE_DIR } /src /Engine >
@@ -765,6 +964,55 @@ if(NOT BUILD_STATIC_LIB AND BUILD_EXAMPLES)
765964
766965 target_link_libraries (PgCompiler PRIVATE ColumbaEngine )
767966
967+ # ===============================================
968+ # COMPONENT GENERATION BUILD STEP
969+ # ===============================================
970+ # Populate the GenerateComponents target now that PgCompiler exists
971+ if (COMPONENT_DEFINITIONS AND TARGET GenerateComponents)
972+ # Make GenerateComponents depend on PgCompiler being built
973+ add_dependencies (GenerateComponents PgCompiler )
974+
975+ foreach (COMP_DEF ${COMPONENT_DEFINITIONS} )
976+ get_filename_component (COMP_NAME ${COMP_DEF} NAME_WE )
977+
978+ # Expected output files
979+ set (GENERATED_HEADER "${CMAKE_CURRENT_SOURCE_DIR } /src/Engine/Components/${COMP_NAME} .generated.h" )
980+ set (GENERATED_CPP "${CMAKE_CURRENT_SOURCE_DIR } /src/Engine/Components/${COMP_NAME} .generated.cpp" )
981+ set (GENERATED_SER "${CMAKE_CURRENT_SOURCE_DIR } /src/Engine/Components/${COMP_NAME} .serialization.cpp" )
982+
983+ # Add custom command to generate this component
984+ add_custom_command (
985+ OUTPUT ${GENERATED_HEADER} ${GENERATED_CPP} ${GENERATED_SER}
986+ COMMAND ${CMAKE_COMMAND } -E echo "Generating ${COMP_NAME} component..."
987+ COMMAND $<TARGET_FILE :PgCompiler >
988+ ${CMAKE_CURRENT_SOURCE_DIR } /tools/component_generator.pg
989+ ${COMP_DEF}
990+ COMMAND ${CMAKE_COMMAND } -E copy
991+ ${CMAKE_CURRENT_BINARY_DIR } /${COMP_NAME}.generated.h
992+ ${GENERATED_HEADER}
993+ COMMAND ${CMAKE_COMMAND } -E copy
994+ ${CMAKE_CURRENT_BINARY_DIR } /${COMP_NAME}.generated.cpp
995+ ${GENERATED_CPP}
996+ COMMAND ${CMAKE_COMMAND } -E copy
997+ ${CMAKE_CURRENT_BINARY_DIR } /${COMP_NAME}.serialization.cpp
998+ ${GENERATED_SER}
999+ DEPENDS PgCompiler ${COMP_DEF} ${CMAKE_CURRENT_SOURCE_DIR } /tools/component_generator.pg
1000+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR }
1001+ COMMENT "Generating ${COMP_NAME} from ${COMP_DEF} "
1002+ VERBATIM
1003+ )
1004+
1005+ # Add the outputs to the GenerateComponents target
1006+ add_custom_target (Generate_${COMP_NAME}
1007+ DEPENDS ${GENERATED_HEADER} ${GENERATED_CPP} ${GENERATED_SER}
1008+ )
1009+ add_dependencies (GenerateComponents Generate_${COMP_NAME} )
1010+ endforeach ()
1011+
1012+ message (STATUS "Component generation configured for ${NUM_DEFINITIONS} components" )
1013+ message (STATUS "Run 'cmake --build . --target GenerateComponents' to generate components" )
1014+ endif ()
1015+
7681016 ###
7691017
7701018 add_executable (EcsSerializationExample exemples/PgCompiler/ecs_serialization_example.cpp )
0 commit comments