cmake_minimum_required(VERSION 3.16) project(demo64k LANGUAGES C CXX) if(APPLE) add_definitions(-DGLFW_EXPOSE_NATIVE_COCOA) elseif(WIN32) add_definitions(-DGLFW_EXPOSE_NATIVE_WIN32) elseif(UNIX) if(DEFINED CMAKE_USE_WAYLAND) add_definitions(-DGLFW_EXPOSE_NATIVE_WAYLAND) else() add_definitions(-DGLFW_EXPOSE_NATIVE_X11) endif() endif() option(DEMO_SIZE_OPT "Enable size optimization flags" OFF) option(DEMO_STRIP_ALL "Strip all unnecessary code for final build" OFF) option(DEMO_BUILD_TESTS "Build tests" OFF) option(DEMO_BUILD_TOOLS "Build tools" OFF) option(DEMO_ALL_OPTIONS "Activate all options at once (tools, tests, optimizations, stripping)" OFF) if (DEMO_ALL_OPTIONS) set(DEMO_SIZE_OPT ON) set(DEMO_STRIP_ALL ON) set(DEMO_BUILD_TESTS ON) set(DEMO_BUILD_TOOLS ON) endif() if (DEMO_STRIP_ALL) add_definitions(-DSTRIP_ALL) set(DEMO_SIZE_OPT ON) endif() set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) if (DEMO_CROSS_COMPILE_WIN32) # --- Windows Cross-Compilation Configuration --- add_definitions(-DDEMO_CROSS_COMPILE_WIN32) set(WINDOWS_DEPS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/third_party/windows") # WGPU-Native # We use the headers from the fetched deps set(WGPU_INCLUDE_DIR "${WINDOWS_DEPS_DIR}/include/webgpu") # Link against the import library set(WGPU_LIBRARY "${WINDOWS_DEPS_DIR}/lib/libwgpu_native.dll.a") # GLFW 3.4 set(GLFW3_INCLUDE_DIR "${WINDOWS_DEPS_DIR}/include") set(GLFW3_LIBRARY "${WINDOWS_DEPS_DIR}/lib/libglfw3.a") include_directories( src third_party ${WGPU_INCLUDE_DIR} ${GLFW3_INCLUDE_DIR} third_party/glfw3webgpu ) # Link libraries # ws2_32 is winsock, required by some deps set(DEMO_LIBS ${GLFW3_LIBRARY} ${WGPU_LIBRARY} -lgdi32 -lws2_32 -luser32 -lkernel32 -lshell32 -ladvapi32 -ldwmapi ) # Statically link C/C++ runtime to avoid needing extra DLLs set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++") else() # --- Native Build Configuration --- # Find wgpu-native (system install) find_library(WGPU_LIBRARY NAMES wgpu_native libwgpu_native REQUIRED) find_path(WGPU_INCLUDE_DIR NAMES webgpu.h PATH_SUFFIXES webgpu-headers REQUIRED) include_directories( src third_party ${WGPU_INCLUDE_DIR} third_party/glfw3webgpu ) find_package(glfw3 REQUIRED) set(DEMO_LIBS glfw ${WGPU_LIBRARY}) endif() # Platform-specific dependencies if (APPLE) set_source_files_properties( src/platform.cc third_party/glfw3webgpu/glfw3webgpu.c PROPERTIES COMPILE_FLAGS "-x objective-c++" ) list(APPEND DEMO_LIBS "-framework Metal" "-framework Foundation" "-framework Cocoa" "-framework QuartzCore" ) elseif (DEMO_CROSS_COMPILE_WIN32) # Windows deps already handled above else() # Assume Linux/other POSIX-like systems might need these list(APPEND DEMO_LIBS pthread m dl) endif() # Asset Packing Tool if (DEFINED ASSET_PACKER_PATH) # Use externally provided tool (e.g., for cross-compilation) set(ASSET_PACKER_CMD ${ASSET_PACKER_PATH}) set(ASSET_PACKER_DEPENDS ${ASSET_PACKER_PATH}) else() # Build tool as part of the project add_executable(asset_packer tools/asset_packer.cc) set(ASSET_PACKER_CMD $) set(ASSET_PACKER_DEPENDS asset_packer) endif() # Configure DEMO asset generation set(DEMO_ASSETS_TXT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/assets/final/demo_assets.txt) set(GENERATED_DEMO_ASSETS_H ${CMAKE_CURRENT_BINARY_DIR}/src/assets.h) set(GENERATED_DEMO_ASSETS_DATA_CC ${CMAKE_CURRENT_BINARY_DIR}/src/assets_data.cc) add_custom_command( OUTPUT ${GENERATED_DEMO_ASSETS_H} ${GENERATED_DEMO_ASSETS_DATA_CC} COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/src COMMAND ${ASSET_PACKER_CMD} ${DEMO_ASSETS_TXT_PATH} ${GENERATED_DEMO_ASSETS_H} ${GENERATED_DEMO_ASSETS_DATA_CC} DEPENDS ${ASSET_PACKER_DEPENDS} ${DEMO_ASSETS_TXT_PATH} COMMENT "Generating demo assets.h and assets_data.cc" ) add_custom_target(generate_demo_assets ALL DEPENDS ${GENERATED_DEMO_ASSETS_H} ${GENERATED_DEMO_ASSETS_DATA_CC} ) # Configure TEST asset generation set(TEST_ASSETS_TXT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/assets/final/test_assets_list.txt) set(GENERATED_TEST_ASSETS_H ${CMAKE_CURRENT_BINARY_DIR}/src/test_assets.h) set(GENERATED_TEST_ASSETS_DATA_CC ${CMAKE_CURRENT_BINARY_DIR}/src/test_assets_data.cc) add_custom_command( OUTPUT ${GENERATED_TEST_ASSETS_H} ${GENERATED_TEST_ASSETS_DATA_CC} COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/src COMMAND ${ASSET_PACKER_CMD} ${TEST_ASSETS_TXT_PATH} ${GENERATED_TEST_ASSETS_H} ${GENERATED_TEST_ASSETS_DATA_CC} DEPENDS ${ASSET_PACKER_DEPENDS} ${TEST_ASSETS_TXT_PATH} COMMENT "Generating test assets.h and assets_data.cc" ) add_custom_target(generate_test_assets DEPENDS ${GENERATED_TEST_ASSETS_H} ${GENERATED_TEST_ASSETS_DATA_CC} ) # Main Demo Target add_executable(demo64k src/main.cc src/platform.cc src/gpu/gpu.cc src/audio/audio.cc src/audio/gen.cc src/audio/fdct.cc src/audio/idct.cc src/audio/window.cc src/audio/synth.cc src/util/asset_manager.cc third_party/glfw3webgpu/glfw3webgpu.c ${GENERATED_DEMO_ASSETS_DATA_CC} ) add_dependencies(demo64k generate_demo_assets) target_link_libraries(demo64k PRIVATE ${DEMO_LIBS}) target_include_directories(demo64k PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) if (DEMO_SIZE_OPT) if (MSVC) target_compile_options(demo64k PRIVATE /Os /GS-) target_link_options(demo64k PRIVATE /OPT:REF /OPT:ICF /INCREMENTAL:NO) elseif (APPLE) target_compile_options(demo64k PRIVATE -Os) target_link_options(demo64k PRIVATE -Wl,-dead_strip) else() target_compile_options(demo64k PRIVATE -Os -ffunction-sections -fdata-sections) target_link_options(demo64k PRIVATE -Wl,--gc-sections -s) endif() endif() # Tests enable_testing() if(DEMO_BUILD_TESTS) add_executable(test_window src/tests/test_window.cc src/audio/window.cc ) target_include_directories(test_window PRIVATE src) add_test(NAME HammingWindowTest COMMAND test_window) add_executable(test_maths src/tests/test_maths.cc src/util/mini_math.h ) target_include_directories(test_maths PRIVATE src) add_test(NAME MathUtilsTest COMMAND test_maths) add_executable(test_synth src/tests/test_synth.cc src/audio/synth.cc src/audio/idct.cc src/audio/window.cc ) target_include_directories(test_synth PRIVATE src) add_test(NAME SynthEngineTest COMMAND test_synth) add_executable(test_spectool src/tests/test_spectool.cc src/audio/audio.cc src/audio/window.cc src/audio/fdct.cc src/audio/gen.cc src/audio/synth.cc src/audio/idct.cc third_party/glfw3webgpu/glfw3webgpu.c ) target_include_directories(test_spectool PRIVATE src third_party ${WGPU_INCLUDE_DIR} third_party/glfw3webgpu ) target_compile_definitions(test_spectool PRIVATE DEMO_BUILD_TOOLS) target_link_libraries(test_spectool PRIVATE ${DEMO_LIBS}) add_test(NAME SpectoolEndToEndTest COMMAND test_spectool) add_executable(test_assets src/tests/test_assets.cc src/util/asset_manager.cc ${GENERATED_TEST_ASSETS_DATA_CC} ) target_include_directories(test_assets PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src src) add_dependencies(test_assets generate_test_assets) # Ensure test_assets also has access to the generated header via its unique name set_source_files_properties(src/tests/test_assets.cc PROPERTIES COMPILE_DEFINITIONS "USE_TEST_ASSETS") add_test(NAME AssetManagerTest COMMAND test_assets) endif() # Tools if(DEMO_BUILD_TOOLS OR DEMO_BUILD_TESTS) add_executable(spectool tools/spectool.cc src/platform.cc src/audio/audio.cc src/audio/gen.cc src/audio/fdct.cc src/audio/idct.cc src/audio/window.cc src/audio/synth.cc third_party/glfw3webgpu/glfw3webgpu.c ) target_include_directories(spectool PRIVATE src third_party ${WGPU_INCLUDE_DIR} third_party/glfw3webgpu ) target_compile_definitions(spectool PRIVATE DEMO_BUILD_TOOLS) target_link_libraries(spectool PRIVATE ${DEMO_LIBS}) add_executable(specview tools/specview.cc ) target_include_directories(specview PRIVATE src) endif() # Final assembly target (strip and pack) add_custom_target(final COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/gen_assets.sh COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/scripts/crunch_demo.sh DEPENDS demo64k COMMENT "Generating assets and performing final assembly (crunching)..." WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) # Pack Source Target add_custom_target(pack_source COMMAND tar -czf demo_all.tgz --exclude=.git --exclude=build* --exclude=.gemini* --exclude=*.tgz --exclude=*.zip --exclude=.DS_Store . COMMENT "Packing entire project source (including submodules) into demo_all.tgz..." WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )