diff --git a/CMakeLists.txt b/CMakeLists.txt index e4358c3..9e64035 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,20 @@ -cmake_minimum_required(VERSION 3.10) +cmake_minimum_required(VERSION 3.12) project(progressia) +set(VERSION "0.0.1") -list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/cmake") -include(embed) +set(tools ${PROJECT_SOURCE_DIR}/tools) +set(generated ${PROJECT_BINARY_DIR}/generated) +file(MAKE_DIRECTORY "${generated}") +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/") +include(embed/embed) +include(glslc) + +# Options +option(VULKAN_ERROR_CHECKING "Enable Vulkan validation layers to detect Vulkan API usage errors at runtime") + +# Source files add_executable(progressia desktop/main.cpp desktop/graphics/glfw_mgmt.cpp @@ -27,40 +37,56 @@ add_executable(progressia main/rendering/image.cpp main/stb_image.c - ${generated}/embedded_resources.cpp + ${generated}/embedded_resources/embedded_resources.cpp ) -target_include_directories(progressia PRIVATE ${generated}) - -# Do Windows-specific tweaks -if (WIN32) - set_target_properties(progressia PROPERTIES WIN32_EXECUTABLE true) - target_link_options(progressia PRIVATE -static-libstdc++ -static-libgcc) -endif() +# Embedded resources +target_glsl_shaders(progressia + desktop/graphics/shaders/shader.frag + desktop/graphics/shaders/shader.vert) +compile_glsl(progressia) +compile_embeds(progressia) +target_include_directories(progressia PRIVATE ${generated}/embedded_resources) # Compilation settings + +if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR + CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(gcc_like_compiler TRUE) +else() + set(gcc_like_compiler FALSE) +endif() + set_property(TARGET progressia PROPERTY CXX_STANDARD 17) set_property(TARGET progressia PROPERTY CXX_STANDARD_REQUIRED ON) -target_compile_options(progressia PRIVATE -Wall) + +# Do Windows-specific tweaks for release builds +if (WIN32 AND DEFINED ENV{PROGRESSIA_BUILD_ID}) + set_target_properties(progressia PROPERTIES WIN32_EXECUTABLE true) + + if (gcc_like_compiler) + target_link_options(progressia PRIVATE -static-libstdc++ -static-libgcc) + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + target_link_options(progressia PRIVATE /entry:mainCRTStartup) + message(WARNING "Release builds with MSVC are not supported") + endif() +endif() # Extra options for gcc -- we're using this for extra static analisys for now -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - target_compile_options(progressia PRIVATE -Wextra -Wpedantic -Werror) +if (gcc_like_compiler) + target_compile_options(progressia PRIVATE -Wall -Wextra -Wpedantic -Werror) endif() -# Version information -if (NOT DEFINED BUILD_ID) - set(BUILD_ID "dev") -endif() - -set(VERSION "0.0.1") - -# Debug options -option(VULKAN_ERROR_CHECKING "Enable Vulkan validation layers to detect Vulkan API usage errors at runtime") - # Pass configuration options +if (DEFINED ENV{PROGRESSIA_BUILD_ID}) + set(BUILD_ID ENV{PROGRESSIA_BUILD_ID}) +else() + set(BUILD_ID "dev") +endif() +file(MAKE_DIRECTORY "${generated}/config") configure_file(${PROJECT_SOURCE_DIR}/main/config.h.in - ${PROJECT_BINARY_DIR}/config.h) + ${generated}/config/config.h) +target_include_directories(progressia PRIVATE ${generated}/config) # Libraries diff --git a/desktop/graphics/vulkan_common.cpp b/desktop/graphics/vulkan_common.cpp index 82c2375..9c84913 100644 --- a/desktop/graphics/vulkan_common.cpp +++ b/desktop/graphics/vulkan_common.cpp @@ -1,6 +1,5 @@ #include "vulkan_common.h" -#include "../config.h" #include "vulkan_adapter.h" #include "vulkan_frame.h" #include "vulkan_physical_device.h" diff --git a/desktop/graphics/vulkan_mgmt.cpp b/desktop/graphics/vulkan_mgmt.cpp index 53792eb..55d50dd 100644 --- a/desktop/graphics/vulkan_mgmt.cpp +++ b/desktop/graphics/vulkan_mgmt.cpp @@ -1,6 +1,5 @@ #include "vulkan_mgmt.h" -#include "../config.h" #include "vulkan_common.h" #include "vulkan_swap_chain.h" diff --git a/main/meta.h b/main/meta.h index be8a203..d15fcdd 100644 --- a/main/meta.h +++ b/main/meta.h @@ -1,6 +1,6 @@ #pragma once -#include "../config.h" +#include #include namespace progressia { diff --git a/tools/cmake/embed.cmake b/tools/cmake/embed.cmake deleted file mode 100644 index a436298..0000000 --- a/tools/cmake/embed.cmake +++ /dev/null @@ -1,56 +0,0 @@ -# Global variables. Yikes. FIXME -set(tools ${PROJECT_SOURCE_DIR}/tools) -set(generated ${PROJECT_BINARY_DIR}/generated) -set(assets_to_embed "") -set(assets_to_embed_args "") - -file(MAKE_DIRECTORY ${generated}) - -find_package(Vulkan COMPONENTS glslc REQUIRED) -find_program(glslc_executable NAMES glslc HINTS Vulkan::glslc) -set(shaders ${generated}/shaders) -file(MAKE_DIRECTORY ${shaders}) - -# Shedules compilation of shaders -# Adapted from https://stackoverflow.com/a/60472877/4463352 -macro(compile_shader) - foreach(source ${ARGV}) - get_filename_component(source_basename ${source} NAME) - set(tmp "${shaders}/${source_basename}.spv") - add_custom_command( - OUTPUT ${tmp} - DEPENDS ${source} - COMMAND ${glslc_executable} - -o ${tmp} - ${CMAKE_CURRENT_SOURCE_DIR}/${source} - COMMENT "Compiling shader ${source}" - ) - list(APPEND assets_to_embed_args "${tmp};as;${source_basename}.spv") - list(APPEND assets_to_embed "${tmp}") - unset(tmp) - unset(source_basename) - endforeach() -endmacro() - -compile_shader( - desktop/graphics/shaders/shader.frag - desktop/graphics/shaders/shader.vert -) - -# Generate embed files -add_custom_command( - OUTPUT ${generated}/embedded_resources.cpp - ${generated}/embedded_resources.h - - COMMAND ${tools}/embed/embed.py - --cpp ${generated}/embedded_resources.cpp - --header ${generated}/embedded_resources.h - -- - ${assets_to_embed_args} - - DEPENDS "${assets_to_embed}" - ${tools}/embed/embed.py - - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMENT "Embedding assets" -) diff --git a/tools/embed/embed.cmake b/tools/embed/embed.cmake new file mode 100644 index 0000000..df721c7 --- /dev/null +++ b/tools/embed/embed.cmake @@ -0,0 +1,151 @@ +# embed.cmake +# Generates embedded_resources.h and embedded_resources.cpp + +find_package(Vulkan COMPONENTS glslc REQUIRED) +find_program(glslc_EXECUTABLE NAMES glslc HINTS Vulkan::glslc) + +find_package(Python3 COMPONENTS Interpreter REQUIRED) + +macro (get_target_property_or var target prop default) + get_property(__is_set TARGET ${target} PROPERTY ${prop} SET) + if (__is_set) + get_property(${var} TARGET ${target} PROPERTY ${prop}) + else() + set(${var} "${default}") + endif() + unset(__is_set) +endmacro() + +function (target_embeds) + set(expecting_name FALSE) + set(target "") + set(current_asset "") + + foreach (word ${ARGV}) + + # First argument is target name + if (target STREQUAL "") + set(target "${word}") + get_target_property_or(script_args "${target}" EMBED_ARGS "") + get_target_property_or(embeds "${target}" EMBEDS "") + continue() + endif() + + if (current_asset STREQUAL "") + # Beginning of asset declaration (1/2) + set(current_asset "${word}") + + elseif (expecting_name) + # End of "asset AS asset_name" + list(APPEND script_args "${current_asset};as;${word}") + list(APPEND embeds ${current_asset}) + set(current_asset "") + set(expecting_name FALSE) + + elseif ("${word}" STREQUAL "AS") + # Keyword AS in "asset AS asset_name" + set(expecting_name TRUE) + + else() + # End of asset without AS, beginning of asset declaration (2/2) + list(APPEND script_args "${current_asset};as;${current_asset}") + list(APPEND embeds ${current_asset}) + set(current_asset "${word}") + endif() + + endforeach() + + if (expecting_name) + message(FATAL_ERROR "No name given for asset \"${current_asset}\"") + endif() + + if (NOT current_asset STREQUAL "") + list(APPEND script_args "${current_asset};as;${current_asset}") + endif() + + set_target_properties("${target}" PROPERTIES EMBED_ARGS "${script_args}") + set_target_properties("${target}" PROPERTIES EMBEDS "${embeds}") +endfunction() + +file(MAKE_DIRECTORY "${generated}/embedded_resources") + +function(compile_embeds target) + get_target_property(script_args "${target}" EMBED_ARGS) + get_target_property(embeds "${target}" EMBEDS) + + add_custom_command( + OUTPUT ${generated}/embedded_resources/embedded_resources.cpp + ${generated}/embedded_resources/embedded_resources.h + + COMMAND ${Python3_EXECUTABLE} ${tools}/embed/embed.py + --cpp ${generated}/embedded_resources/embedded_resources.cpp + --header ${generated}/embedded_resources/embedded_resources.h + -- + ${script_args} + + DEPENDS ${embeds} + ${tools}/embed/embed.py + + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + COMMENT "Embedding assets" + ) +endfunction() + + +## Global variables. Yikes. FIXME +#set(tools ${PROJECT_SOURCE_DIR}/tools) +#set(generated ${PROJECT_BINARY_DIR}/generated) +#set(assets_to_embed "") +#set(assets_to_embed_args "") +# +#file(MAKE_DIRECTORY ${generated}) +# +#find_package(Vulkan COMPONENTS glslc REQUIRED) +#find_program(glslc_executable NAMES glslc HINTS Vulkan::glslc) +#set(shaders ${generated}/shaders) +#file(MAKE_DIRECTORY ${shaders}) +# +## Shedules compilation of shaders +## Adapted from https://stackoverflow.com/a/60472877/4463352 +#macro(compile_shader) +# foreach(source ${ARGV}) +# get_filename_component(source_basename ${source} NAME) +# set(tmp "${shaders}/${source_basename}.spv") +# add_custom_command( +# OUTPUT ${tmp} +# DEPENDS ${source} +# COMMAND ${glslc_executable} +# -o ${tmp} +# ${CMAKE_CURRENT_SOURCE_DIR}/${source} +# COMMENT "Compiling shader ${source}" +# ) +# list(APPEND assets_to_embed_args "${tmp};as;${source_basename}.spv") +# list(APPEND assets_to_embed "${tmp}") +# unset(tmp) +# unset(source_basename) +# endforeach() +#endmacro() +# +#compile_shader( +# desktop/graphics/shaders/shader.frag +# desktop/graphics/shaders/shader.vert +#) +# +## Generate embed files +#add_custom_command( +# OUTPUT ${generated}/embedded_resources.cpp +# ${generated}/embedded_resources.h +# +# COMMAND ${tools}/embed/embed.py +# --cpp ${generated}/embedded_resources.cpp +# --header ${generated}/embedded_resources.h +# -- +# ${assets_to_embed_args} +# +# DEPENDS "${assets_to_embed}" +# ${tools}/embed/embed.py +# +# WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} +# COMMENT "Embedding assets" +#) +# diff --git a/tools/glslc.cmake b/tools/glslc.cmake new file mode 100644 index 0000000..4172dcc --- /dev/null +++ b/tools/glslc.cmake @@ -0,0 +1,112 @@ +# glslc.cmake +# Compiles GLSL shaders to SPV files + +find_package(Vulkan COMPONENTS glslc REQUIRED) +find_program(glslc_EXECUTABLE NAMES glslc HINTS Vulkan::glslc) + +macro (get_target_property_or var target prop default) + get_property(__is_set TARGET ${target} PROPERTY ${prop} SET) + if (__is_set) + get_property(${var} TARGET ${target} PROPERTY ${prop}) + else() + set(${var} "${default}") + endif() + unset(__is_set) +endmacro() + +function (target_glsl_shaders) + set(target "") + + foreach (word ${ARGV}) + # First argument is target name + if (target STREQUAL "") + set(target ${word}) + get_target_property_or(glsl_shaders ${target} GLSL_SHADERS "") + else() + list(APPEND glsl_shaders ${word}) + endif() + endforeach() + + set_target_properties(${target} PROPERTIES GLSL_SHADERS "${glsl_shaders}") +endfunction() + +file(MAKE_DIRECTORY "${generated}/compiled_glsl_shaders") + +function(compile_glsl target) + get_target_property(glsl_shaders ${target} GLSL_SHADERS) + + foreach (source_path ${glsl_shaders}) + get_filename_component(source_basename ${source_path} NAME) + set(spv_path + "${generated}/compiled_glsl_shaders/${source_basename}.spv") + + add_custom_command( + OUTPUT ${spv_path} + DEPENDS ${source_path} + COMMAND ${glslc_EXECUTABLE} + -o ${spv_path} + ${CMAKE_CURRENT_SOURCE_DIR}/${source_path} + COMMENT "Compiling shader ${source_path}" + ) + target_embeds(${target} ${spv_path} AS "${source_basename}.spv") + endforeach() +endfunction() + + +## Global variables. Yikes. FIXME +#set(tools ${PROJECT_SOURCE_DIR}/tools) +#set(generated ${PROJECT_BINARY_DIR}/generated) +#set(assets_to_embed "") +#set(assets_to_embed_args "") +# +#file(MAKE_DIRECTORY ${generated}) +# +#find_package(Vulkan COMPONENTS glslc REQUIRED) +#find_program(glslc_executable NAMES glslc HINTS Vulkan::glslc) +#set(shaders ${generated}/shaders) +#file(MAKE_DIRECTORY ${shaders}) +# +## Shedules compilation of shaders +## Adapted from https://stackoverflow.com/a/60472877/4463352 +#macro(compile_shader) +# foreach(source ${ARGV}) +# get_filename_component(source_basename ${source} NAME) +# set(tmp "${shaders}/${source_basename}.spv") +# add_custom_command( +# OUTPUT ${tmp} +# DEPENDS ${source} +# COMMAND ${glslc_executable} +# -o ${tmp} +# ${CMAKE_CURRENT_SOURCE_DIR}/${source} +# COMMENT "Compiling shader ${source}" +# ) +# list(APPEND assets_to_embed_args "${tmp};as;${source_basename}.spv") +# list(APPEND assets_to_embed "${tmp}") +# unset(tmp) +# unset(source_basename) +# endforeach() +#endmacro() +# +#compile_shader( +# desktop/graphics/shaders/shader.frag +# desktop/graphics/shaders/shader.vert +#) +# +## Generate embed files +#add_custom_command( +# OUTPUT ${generated}/embedded_resources.cpp +# ${generated}/embedded_resources.h +# +# COMMAND ${tools}/embed/embed.py +# --cpp ${generated}/embedded_resources.cpp +# --header ${generated}/embedded_resources.h +# -- +# ${assets_to_embed_args} +# +# DEPENDS "${assets_to_embed}" +# ${tools}/embed/embed.py +# +# WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} +# COMMENT "Embedding assets" +#) +#