Add CMakeLists.txt
This commit is contained in:
1 parent
4ad7eb3622
commit
cd8e61933f
1 file changed
+401
+401
@@ -0,0 +1,401 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
|
||||
project(window_renderer_test VERSION 0.1.0 LANGUAGES C CXX)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Build type" FORCE)
|
||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel)
|
||||
endif()
|
||||
|
||||
option(WR_FETCH_MISSING_DEPENDENCIES
|
||||
"Download and build dependencies (SDL3, Vulkan, Slang) that are not installed" ON)
|
||||
option(WR_COMPILE_SHADERS
|
||||
"Compile the Slang shader during the build (requires slangc)" ON)
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# SDL3
|
||||
# ---------------------------------------------------------------------------
|
||||
find_package(SDL3 3.2 CONFIG QUIET)
|
||||
|
||||
if(NOT SDL3_FOUND)
|
||||
if(NOT WR_FETCH_MISSING_DEPENDENCIES)
|
||||
message(FATAL_ERROR
|
||||
"SDL3 was not found. Install SDL3, or configure with "
|
||||
"-DWR_FETCH_MISSING_DEPENDENCIES=ON.")
|
||||
endif()
|
||||
|
||||
message(STATUS "SDL3 not found; fetching and building it from source")
|
||||
|
||||
# Build a static SDL3 so the result does not depend on a system SDL3
|
||||
# runtime being present when the application is run.
|
||||
set(SDL_SHARED OFF CACHE BOOL "Build the SDL3 shared library")
|
||||
set(SDL_STATIC ON CACHE BOOL "Build the SDL3 static library")
|
||||
set(SDL_TEST_LIBRARY OFF CACHE BOOL "Build the SDL3 test library")
|
||||
set(SDL_TESTS OFF CACHE BOOL "Build the SDL3 tests")
|
||||
set(SDL_EXAMPLES OFF CACHE BOOL "Build the SDL3 examples")
|
||||
set(SDL_INSTALL OFF CACHE BOOL "Enable SDL3 install rules")
|
||||
|
||||
FetchContent_Declare(SDL3
|
||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL.git
|
||||
GIT_TAG release-3.4.18
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(SDL3)
|
||||
endif()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Vulkan headers
|
||||
# ---------------------------------------------------------------------------
|
||||
find_package(Vulkan QUIET)
|
||||
|
||||
if(Vulkan_FOUND AND Vulkan_INCLUDE_DIRS)
|
||||
set(WR_VULKAN_INCLUDE_DIRS ${Vulkan_INCLUDE_DIRS})
|
||||
else()
|
||||
if(NOT WR_FETCH_MISSING_DEPENDENCIES)
|
||||
message(FATAL_ERROR
|
||||
"Vulkan headers were not found. Install the Vulkan SDK, or configure "
|
||||
"with -DWR_FETCH_MISSING_DEPENDENCIES=ON.")
|
||||
endif()
|
||||
|
||||
message(STATUS "Vulkan headers not found; fetching Vulkan-Headers")
|
||||
|
||||
FetchContent_Declare(vulkan_headers
|
||||
GIT_REPOSITORY https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
GIT_TAG vulkan-sdk-1.4.350.0
|
||||
GIT_SHALLOW TRUE
|
||||
)
|
||||
FetchContent_MakeAvailable(vulkan_headers)
|
||||
|
||||
set(WR_VULKAN_INCLUDE_DIRS ${vulkan_headers_SOURCE_DIR}/include)
|
||||
endif()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# volk (Vulkan meta-loader)
|
||||
#
|
||||
# volk is not guaranteed to be shipped with Vulkan headers. The project
|
||||
# includes <volk/volk.h>, so a fetched volk checkout is placed in a generated
|
||||
# include directory with the expected layout.
|
||||
# ---------------------------------------------------------------------------
|
||||
find_path(WR_VOLK_INCLUDE_DIR
|
||||
NAMES volk/volk.h
|
||||
HINTS ${WR_VULKAN_INCLUDE_DIRS}
|
||||
)
|
||||
find_file(WR_VOLK_SOURCE_FILE
|
||||
NAMES volk.c
|
||||
HINTS ${WR_VULKAN_INCLUDE_DIRS}
|
||||
PATH_SUFFIXES volk
|
||||
)
|
||||
|
||||
if(NOT WR_VOLK_INCLUDE_DIR OR NOT WR_VOLK_SOURCE_FILE)
|
||||
if(NOT WR_FETCH_MISSING_DEPENDENCIES)
|
||||
message(FATAL_ERROR
|
||||
"volk was not found in the Vulkan headers. Install volk, or configure "
|
||||
"with -DWR_FETCH_MISSING_DEPENDENCIES=ON.")
|
||||
endif()
|
||||
|
||||
message(STATUS "volk not found; fetching it")
|
||||
|
||||
FetchContent_Declare(volk
|
||||
GIT_REPOSITORY https://github.com/zeux/volk.git
|
||||
GIT_TAG vulkan-sdk-1.4.350.0
|
||||
GIT_SHALLOW TRUE
|
||||
SOURCE_SUBDIR _disable_add_subdirectory
|
||||
)
|
||||
FetchContent_MakeAvailable(volk)
|
||||
|
||||
set(WR_VOLK_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated/include)
|
||||
file(MAKE_DIRECTORY ${WR_VOLK_INCLUDE_DIR}/volk)
|
||||
configure_file(
|
||||
${volk_SOURCE_DIR}/volk.h
|
||||
${WR_VOLK_INCLUDE_DIR}/volk/volk.h
|
||||
COPYONLY
|
||||
)
|
||||
set(WR_VOLK_SOURCE_FILE ${volk_SOURCE_DIR}/volk.c)
|
||||
endif()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Vulkan Memory Allocator (VMA)
|
||||
#
|
||||
# VMA is not part of the Vulkan headers either. The project includes
|
||||
# <vma/vk_mem_alloc.h>, so a fetched copy is placed in the same generated
|
||||
# include directory.
|
||||
# ---------------------------------------------------------------------------
|
||||
find_path(WR_VMA_INCLUDE_DIR
|
||||
NAMES vma/vk_mem_alloc.h
|
||||
HINTS ${WR_VULKAN_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
if(NOT WR_VMA_INCLUDE_DIR)
|
||||
if(NOT WR_FETCH_MISSING_DEPENDENCIES)
|
||||
message(FATAL_ERROR
|
||||
"Vulkan Memory Allocator (VMA) was not found. Install VMA, or configure "
|
||||
"with -DWR_FETCH_MISSING_DEPENDENCIES=ON.")
|
||||
endif()
|
||||
|
||||
message(STATUS "Vulkan Memory Allocator not found; fetching it")
|
||||
|
||||
FetchContent_Declare(vma
|
||||
GIT_REPOSITORY https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git
|
||||
GIT_TAG v3.5.0
|
||||
GIT_SHALLOW TRUE
|
||||
SOURCE_SUBDIR _disable_add_subdirectory
|
||||
)
|
||||
FetchContent_MakeAvailable(vma)
|
||||
|
||||
set(WR_VMA_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated/include)
|
||||
file(MAKE_DIRECTORY ${WR_VMA_INCLUDE_DIR}/vma)
|
||||
configure_file(
|
||||
${vma_SOURCE_DIR}/include/vk_mem_alloc.h
|
||||
${WR_VMA_INCLUDE_DIR}/vma/vk_mem_alloc.h
|
||||
COPYONLY
|
||||
)
|
||||
endif()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Application
|
||||
# ---------------------------------------------------------------------------
|
||||
add_executable(main
|
||||
src/main.c
|
||||
src/wapp/wapp.c
|
||||
src/config/config_src.c
|
||||
src/window/window_src.c
|
||||
src/gpu/gpu_c_src.c
|
||||
src/gpu/gpu_cc_src.cpp
|
||||
${WR_VOLK_SOURCE_FILE}
|
||||
)
|
||||
|
||||
target_include_directories(main PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src
|
||||
${WR_VULKAN_INCLUDE_DIRS}
|
||||
${WR_VOLK_INCLUDE_DIR}
|
||||
${WR_VMA_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
target_compile_definitions(main PRIVATE
|
||||
WP_DEBUG_ASSERT
|
||||
CGLM_DEFINE_PRINTS
|
||||
USE_SDL_WINDOW_BACKEND
|
||||
USE_VULKAN_RENDER_BACKEND
|
||||
VK_NO_PROTOTYPES
|
||||
)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
target_compile_options(main PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:CXX>:-Wno-nullability-completeness>
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(main PRIVATE
|
||||
SDL3::SDL3
|
||||
${CMAKE_DL_LIBS}
|
||||
)
|
||||
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(main PRIVATE m)
|
||||
endif()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Shaders
|
||||
#
|
||||
# The application loads "shaders/shader.spv" relative to its working directory,
|
||||
# so the SPIR-V output is placed in <build-dir>/shaders.
|
||||
# ---------------------------------------------------------------------------
|
||||
if(WR_COMPILE_SHADERS)
|
||||
find_program(SLANGC_EXECUTABLE NAMES slangc)
|
||||
|
||||
if(NOT SLANGC_EXECUTABLE AND WR_FETCH_MISSING_DEPENDENCIES)
|
||||
# Download the prebuilt Slang release instead of requiring the user to
|
||||
# install the compiler. Asset names and hashes come from the pinned
|
||||
# GitHub release below.
|
||||
set(WR_SLANG_VERSION "2026.20")
|
||||
|
||||
string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" WR_SLANG_ARCH)
|
||||
if(WR_SLANG_ARCH MATCHES "^(x86_64|amd64|x64)$")
|
||||
set(WR_SLANG_ARCH "x86_64")
|
||||
elseif(WR_SLANG_ARCH MATCHES "^(aarch64|arm64|arm64e)$")
|
||||
set(WR_SLANG_ARCH "aarch64")
|
||||
else()
|
||||
set(WR_SLANG_ARCH "")
|
||||
endif()
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(WR_SLANG_OS "linux")
|
||||
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
|
||||
set(WR_SLANG_OS "macos")
|
||||
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(WR_SLANG_OS "windows")
|
||||
else()
|
||||
set(WR_SLANG_OS "")
|
||||
endif()
|
||||
|
||||
if(WR_SLANG_OS AND WR_SLANG_ARCH)
|
||||
set(WR_SLANG_PLATFORM "${WR_SLANG_OS}-${WR_SLANG_ARCH}")
|
||||
else()
|
||||
set(WR_SLANG_PLATFORM "")
|
||||
endif()
|
||||
|
||||
if(WR_SLANG_PLATFORM STREQUAL "linux-x86_64")
|
||||
set(WR_SLANG_ASSET
|
||||
"slang-${WR_SLANG_VERSION}-linux-x86_64-glibc-2.28.tar.gz")
|
||||
set(WR_SLANG_SHA256
|
||||
"84ebd777968caceea26b21bfd014341078be6047be6c5a963a69f984f896cebd")
|
||||
elseif(WR_SLANG_PLATFORM STREQUAL "linux-aarch64")
|
||||
set(WR_SLANG_ASSET
|
||||
"slang-${WR_SLANG_VERSION}-linux-aarch64-glibc-2.28.tar.gz")
|
||||
set(WR_SLANG_SHA256
|
||||
"9959d741713162efdbd863ff6d32400432b6e103eae3a9ee0afbdba6a00c6a9e")
|
||||
elseif(WR_SLANG_PLATFORM STREQUAL "macos-x86_64")
|
||||
set(WR_SLANG_ASSET
|
||||
"slang-${WR_SLANG_VERSION}-macos-x86_64.tar.gz")
|
||||
set(WR_SLANG_SHA256
|
||||
"b4f01f615dc625f60c593d7d0a4bbd38e05dfa2a34bfd3973017c309d866feaa")
|
||||
elseif(WR_SLANG_PLATFORM STREQUAL "macos-aarch64")
|
||||
set(WR_SLANG_ASSET
|
||||
"slang-${WR_SLANG_VERSION}-macos-aarch64.tar.gz")
|
||||
set(WR_SLANG_SHA256
|
||||
"07fa8833fdbb343c3674c84fdd885910f495f3daaaa0c732b32980151e8b58c4")
|
||||
elseif(WR_SLANG_PLATFORM STREQUAL "windows-x86_64")
|
||||
set(WR_SLANG_ASSET
|
||||
"slang-${WR_SLANG_VERSION}-windows-x86_64.zip")
|
||||
set(WR_SLANG_SHA256
|
||||
"e6dd32bbddf1720ebb4e679d55e9635ce792865a5bd84f3d2cd9af28647c0174")
|
||||
elseif(WR_SLANG_PLATFORM STREQUAL "windows-aarch64")
|
||||
set(WR_SLANG_ASSET
|
||||
"slang-${WR_SLANG_VERSION}-windows-aarch64.zip")
|
||||
set(WR_SLANG_SHA256
|
||||
"4f18a7e76a59969bc9bf6ea596bd9e496a3c689af173990ae028b18f03e1ac1a")
|
||||
else()
|
||||
set(WR_SLANG_ASSET "")
|
||||
endif()
|
||||
|
||||
if(NOT WR_SLANG_ASSET)
|
||||
message(FATAL_ERROR
|
||||
"slangc was not found, and no prebuilt Slang archive is available "
|
||||
"for ${CMAKE_HOST_SYSTEM_NAME}/${CMAKE_HOST_SYSTEM_PROCESSOR}. "
|
||||
"Install the Slang compiler, or configure with "
|
||||
"-DWR_COMPILE_SHADERS=OFF.")
|
||||
endif()
|
||||
|
||||
set(WR_SLANG_DOWNLOAD_DIR "${CMAKE_CURRENT_BINARY_DIR}/_deps/slang")
|
||||
set(WR_SLANG_ARCHIVE
|
||||
"${WR_SLANG_DOWNLOAD_DIR}/${WR_SLANG_ASSET}")
|
||||
set(WR_SLANG_URL
|
||||
"https://github.com/shader-slang/slang/releases/download/v${WR_SLANG_VERSION}/${WR_SLANG_ASSET}")
|
||||
|
||||
if(EXISTS "${WR_SLANG_ARCHIVE}")
|
||||
file(SHA256 "${WR_SLANG_ARCHIVE}" WR_SLANG_ACTUAL_SHA256)
|
||||
if(NOT WR_SLANG_ACTUAL_SHA256 STREQUAL WR_SLANG_SHA256)
|
||||
message(STATUS "Removing corrupt Slang archive")
|
||||
file(REMOVE "${WR_SLANG_ARCHIVE}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${WR_SLANG_ARCHIVE}")
|
||||
message(STATUS "Downloading Slang ${WR_SLANG_VERSION} for ${WR_SLANG_PLATFORM}")
|
||||
file(DOWNLOAD
|
||||
"${WR_SLANG_URL}"
|
||||
"${WR_SLANG_ARCHIVE}"
|
||||
EXPECTED_HASH SHA256=${WR_SLANG_SHA256}
|
||||
STATUS WR_SLANG_DOWNLOAD_STATUS
|
||||
TLS_VERIFY ON
|
||||
)
|
||||
list(GET WR_SLANG_DOWNLOAD_STATUS 0 WR_SLANG_DOWNLOAD_CODE)
|
||||
list(GET WR_SLANG_DOWNLOAD_STATUS 1 WR_SLANG_DOWNLOAD_MESSAGE)
|
||||
if(NOT WR_SLANG_DOWNLOAD_CODE EQUAL 0)
|
||||
file(REMOVE "${WR_SLANG_ARCHIVE}")
|
||||
message(FATAL_ERROR
|
||||
"Failed to download Slang from ${WR_SLANG_URL}: "
|
||||
"${WR_SLANG_DOWNLOAD_MESSAGE}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
|
||||
set(WR_SLANG_EXECUTABLE
|
||||
"${WR_SLANG_DOWNLOAD_DIR}/bin/slangc.exe")
|
||||
else()
|
||||
set(WR_SLANG_EXECUTABLE
|
||||
"${WR_SLANG_DOWNLOAD_DIR}/bin/slangc")
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${WR_SLANG_EXECUTABLE}")
|
||||
message(STATUS "Extracting Slang ${WR_SLANG_VERSION}")
|
||||
file(ARCHIVE_EXTRACT
|
||||
INPUT "${WR_SLANG_ARCHIVE}"
|
||||
DESTINATION "${WR_SLANG_DOWNLOAD_DIR}"
|
||||
)
|
||||
endif()
|
||||
|
||||
if(NOT EXISTS "${WR_SLANG_EXECUTABLE}")
|
||||
message(FATAL_ERROR
|
||||
"The Slang archive did not contain bin/slangc")
|
||||
endif()
|
||||
|
||||
set(SLANGC_EXECUTABLE "${WR_SLANG_EXECUTABLE}")
|
||||
message(STATUS "Using downloaded Slang compiler: ${SLANGC_EXECUTABLE}")
|
||||
endif()
|
||||
|
||||
if(NOT SLANGC_EXECUTABLE)
|
||||
message(FATAL_ERROR
|
||||
"slangc was not found. Install the Slang compiler, configure with "
|
||||
"-DWR_FETCH_MISSING_DEPENDENCIES=ON to download it, or configure with "
|
||||
"-DWR_COMPILE_SHADERS=OFF.")
|
||||
endif()
|
||||
|
||||
set(WR_SHADER_SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/src/shaders/shader.slang)
|
||||
set(WR_SHADER_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/shaders)
|
||||
set(WR_SHADER_OUTPUT ${WR_SHADER_OUTPUT_DIR}/shader.spv)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${WR_SHADER_OUTPUT}
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory ${WR_SHADER_OUTPUT_DIR}
|
||||
COMMAND ${SLANGC_EXECUTABLE}
|
||||
${WR_SHADER_SOURCE}
|
||||
-entry vertMain
|
||||
-entry fragMain
|
||||
-o ${WR_SHADER_OUTPUT}
|
||||
DEPENDS ${WR_SHADER_SOURCE}
|
||||
COMMENT "Compiling shader.slang"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target(shaders ALL DEPENDS ${WR_SHADER_OUTPUT})
|
||||
add_dependencies(main shaders)
|
||||
endif()
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Assets
|
||||
#
|
||||
# The application loads "assets/collections.png" relative to its working
|
||||
# directory, so the assets directory is copied into <build-dir>/assets.
|
||||
# ---------------------------------------------------------------------------
|
||||
set(WR_ASSETS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/assets)
|
||||
set(WR_ASSETS_DEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/assets)
|
||||
|
||||
if(EXISTS ${WR_ASSETS_SOURCE_DIR})
|
||||
add_custom_target(copy_assets ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${WR_ASSETS_SOURCE_DIR}
|
||||
${WR_ASSETS_DEST_DIR}
|
||||
COMMENT "Copying assets"
|
||||
VERBATIM
|
||||
)
|
||||
add_dependencies(main copy_assets)
|
||||
endif()
|
||||
|
||||
add_custom_target(run
|
||||
COMMAND $<TARGET_FILE:main>
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS main
|
||||
USES_TERMINAL
|
||||
)
|
||||
|
||||
if(TARGET shaders)
|
||||
add_dependencies(run shaders)
|
||||
endif()
|
||||
Reference in new issue
Block a user