cmake_minimum_required(VERSION 3.26)
if(NOT DEFINED CMAKE_CUDA_ARCHITECTURES)
set(CMAKE_CUDA_ARCHITECTURES 86)
endif()
project(2DFastTurboWin LANGUAGES CXX CUDA)
option(TURBO_DISTRIBUTION "Link redistributable runtimes statically" OFF)
if(TURBO_DISTRIBUTION)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_CUDA_RUNTIME_LIBRARY Static)
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_STANDARD 20)
find_package(CUDAToolkit 13.0 REQUIRED)
add_library(turbo_core src/solver.cu src/fft.cpp)
target_include_directories(turbo_core PUBLIC src ${CUDAToolkit_INCLUDE_DIRS})
target_include_directories(turbo_core PRIVATE ../reference-macos/2DFastTurbo/ThirdParty/VkFFTSource/vkFFT)
target_compile_definitions(turbo_core PUBLIC NOMINMAX WIN32_LEAN_AND_MEAN)
target_compile_options(turbo_core PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:--fmad=false> $<$<COMPILE_LANGUAGE:CXX>:/fp:strict> $<$<COMPILE_LANGUAGE:CXX>:/utf-8>)
if(TURBO_DISTRIBUTION)
# CUDA 13.4 static NVRTC imports RtlGetLastNtStatus from the Windows runtime.
target_link_libraries(turbo_core PUBLIC CUDA::cudart_static CUDA::cuda_driver CUDA::nvrtc_static CUDA::nvrtc_builtins_static CUDA::nvptxcompiler_static user32 ws2_32 ntdll)
else()
target_link_libraries(turbo_core PUBLIC CUDA::cudart CUDA::cuda_driver CUDA::nvrtc)
endif()
option(TURBO_BUILD_GUI "Build the native Windows application" ON)
if(TURBO_BUILD_GUI)
enable_language(RC)
add_executable(shader_compiler tools/shader_compiler.cpp)
target_link_libraries(shader_compiler PRIVATE d3dcompiler)
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/embedded")
set(SHADER_OUTPUTS)
foreach(ENTRY fieldVertex fieldPixel flowVertex flowPixel)
list(APPEND SHADER_OUTPUTS "${CMAKE_CURRENT_BINARY_DIR}/embedded/${ENTRY}.cso")
endforeach()
add_custom_command(OUTPUT ${SHADER_OUTPUTS}
 COMMAND shader_compiler "${CMAKE_CURRENT_SOURCE_DIR}/src/render.hlsl" "${CMAKE_CURRENT_BINARY_DIR}/embedded"
 DEPENDS shader_compiler src/render.hlsl VERBATIM)
add_custom_target(embedded_shaders DEPENDS ${SHADER_OUTPUTS})
find_file(TURBO_CUDA_LICENSE EULA.txt HINTS "${CUDAToolkit_LIBRARY_ROOT}" "${CUDAToolkit_TARGET_DIR}" "$ENV{CUDA_PATH}" REQUIRED NO_DEFAULT_PATH)
configure_file(src/embedded.rc.in embedded/embedded.rc @ONLY)
set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/embedded/embedded.rc" PROPERTIES OBJECT_DEPENDS "${SHADER_OUTPUTS}")
add_executable(2DFastTurbo WIN32 src/main.cpp src/app.cpp src/desktop_ui.cpp src/renderer.cpp src/controller.cpp src/application.rc "${CMAKE_CURRENT_BINARY_DIR}/embedded/embedded.rc")
set_source_files_properties(src/application.rc PROPERTIES OBJECT_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/assets/2DFastTurbo.ico;${CMAKE_CURRENT_SOURCE_DIR}/assets/navier-stokes.png;${CMAKE_CURRENT_SOURCE_DIR}/assets/header-hurricane.svg")
add_dependencies(2DFastTurbo embedded_shaders)
target_link_libraries(2DFastTurbo PRIVATE turbo_core d3d11 dxgi d2d1 dwrite windowscodecs dwmapi comdlg32 shell32 ole32 winmm)
target_compile_options(2DFastTurbo PRIVATE /utf-8 /W4 /fp:strict)
target_compile_definitions(2DFastTurbo PRIVATE UNICODE _UNICODE)
endif()
add_executable(core_tests tests/core_tests.cpp)
target_link_libraries(core_tests PRIVATE turbo_core)
enable_testing()
add_test(NAME core_lifecycle COMMAND core_tests)
