Refactor embedded files CMake code

I have been thinking about some shader related techniques for the Vulkan
renderer and for that we will need to add embedded files in a different
environment than they are right now since the actual shader code will
not be needed in the engine.

For this reason, I extracted the "default file" mechanism to be more
generic so that all that is necessary to include a file is to just call
a custom CMake command and the function keeps track of what needs to be
done.

Also, since the "generic" code has worked pretty well so far I see no
reason to keep around two systems which just increases the amount of
code we need to maintain. So, I just removed the windows exclusive
implementation. Now all platforms use the same "generic" way of
embedding files.
This commit is contained in:
asarium committed 2020-09-23 13:38:54 +02:00
1 parent 3384699086
commit 0f2787639b
11 files changed
+104 -210

No files matched your search

+1
View File
@@ -8,6 +8,7 @@ if ("${CMAKE_CURRENT_SOURCE_DIR}" STREQUAL "${CMAKE_CURRENT_BINARY_DIR}")
endif()
include(cmake/util.cmake)
include(cmake/embed_file.cmake)
# Set a few policies
set_policy(CMP0051 NEW)
+89
View File
@@ -0,0 +1,89 @@
set(_EMBEDD_FILE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
function(target_embed_files _target)
set(options)
set(oneValueArgs RELATIVE_TO)
set(multiValueArgs FILES)
cmake_parse_arguments(EMBED "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if (NOT DEFINED EMBED_RELATIVE_TO)
set(EMBED_RELATIVE_TO "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
if (NOT IS_ABSOLUTE "${EMBED_RELATIVE_TO}")
get_filename_component(EMBED_RELATIVE_TO "${EMBED_RELATIVE_TO}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
endif()
foreach (file ${EMBED_FILES})
get_filename_component(_absoluteFile "${file}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
set_property(TARGET ${_target} APPEND PROPERTY EMBEDDED_FILES "${_absoluteFile}")
set_property(TARGET ${_target} APPEND PROPERTY EMBEDDED_FILES_BASE_DIR "${EMBED_RELATIVE_TO}")
endforeach()
endfunction()
function(handle_embedded_files _target)
get_target_property(_filesToEmbed ${_target} EMBEDDED_FILES)
get_target_property(_baseDirs ${_target} EMBEDDED_FILES_BASE_DIR)
SET(DEF_OUT_FILES)
set(INCLUDE_LIST)
set(ARRAY_ELEMENTS)
list(LENGTH _filesToEmbed _numFiles)
FOREACH(i RANGE ${_numFiles})
# Why must CMake always do the unexpected thing? The foreach variant includes the last index as opposed to every
# other sensible language which does not include it...
if (i GREATER_EQUAL _numFiles)
break()
endif()
list(GET _filesToEmbed ${i} _filePath)
list(GET _baseDirs ${i} _baseDir)
file(RELATIVE_PATH _relativeFilePath "${_baseDir}" "${_filePath}")
SET(_outputBasePath "${CMAKE_CURRENT_BINARY_DIR}/embedded_files/${_relativeFilePath}")
# For some reason this is needed...
get_filename_component(_outputDirectory ${_outputBasePath} DIRECTORY)
FILE(MAKE_DIRECTORY ${_outputDirectory})
# Retrieve the path type name from the relative path
get_filename_component(_pathType "${_relativeFilePath}" DIRECTORY)
file(TO_NATIVE_PATH "${_pathType}" _pathType)
if (MINGW)
# There is a bug in CMake where it thinks MinGW uses forward slashes for paths but we need backslashes for Windows builds
string(REPLACE "/" "\\" _pathType "${_pathType}")
endif()
# Properly escape back slashes in strings
string(REPLACE "\\" "\\\\" _pathType "${_pathType}")
get_filename_component(FILE_NAME "${_relativeFilePath}" NAME)
string(MAKE_C_IDENTIFIER "${_relativeFilePath}" FIELD_NAME)
set(HEADER_FILE "${_outputBasePath}.h")
set(SOURCE_FILE "${_outputBasePath}.cpp")
set(ALL_OUTPUTS "${HEADER_FILE}" "${SOURCE_FILE}")
set(FIELD_NAME "Embedded_${FIELD_NAME}")
set(INCLUDE_LIST "${INCLUDE_LIST}\n#include \"${HEADER_FILE}\"")
set(ARRAY_ELEMENTS "${ARRAY_ELEMENTS}\n\t{ \"${_pathType}\", \"${FILE_NAME}\" , ${FIELD_NAME} , ${FIELD_NAME}_size },")
add_custom_command(
OUTPUT ${ALL_OUTPUTS}
COMMAND embedfile "${_filePath}" "${_outputBasePath}" "${FIELD_NAME}"
MAIN_DEPENDENCY "${_filePath}"
COMMENT "Generating string file for ${_filePath}"
)
list(APPEND DEF_OUT_FILES ${ALL_OUTPUTS})
ENDFOREACH()
configure_file("${_EMBEDD_FILE_BASE_DIR}/embedded_files.inc.in" "${CMAKE_CURRENT_BINARY_DIR}/embedded_files/embedded_files.inc")
target_include_directories(${_target} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/embedded_files")
target_sources(${_target} PRIVATE ${DEF_OUT_FILES})
source_group("Generated Files\\Embedded Files" FILES ${DEF_OUT_FILES})
endfunction()
+4 -2
View File
@@ -7,8 +7,6 @@ ADD_LIBRARY(code STATIC ${source_files} ${VOICE_REC_FILES})
target_compile_features(code PUBLIC cxx_std_11)
INCLUDE(default_files.cmake)
if (MSVC)
target_compile_definitions(code PUBLIC "PDB_DEBUGGING=1")
endif(MSVC)
@@ -89,6 +87,10 @@ endif()
include(util)
target_embed_files(code FILES ${default_files_files} RELATIVE_TO "def_files")
handle_embedded_files(code)
set_precompiled_header(code "${CMAKE_CURRENT_SOURCE_DIR}/prefix_header.h")
# Ensure that Xcode generates debug symbols on macOS for Debug builds
-96
View File
@@ -1,96 +0,0 @@
/*
* You may not sell or otherwise commercially exploit the source or things you
* create based on the source.
*/
#include "globalincs/pstypes.h"
#include "def_files/def_files.h"
#include <iterator>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
struct def_file
{
const char* path_type;
const char* filename;
const TCHAR* resource_name;
};
def_file Default_files[] =
{
#include "def_files/generated_def_files-win32.inc"
};
default_file defaults_get_file(const char *filename)
{
default_file def;
auto endIter = std::end(Default_files);
for (auto iter = std::begin(Default_files); iter != endIter; ++iter)
{
if (!stricmp(iter->filename, filename))
{
HRSRC resource = FindResource(nullptr, iter->resource_name, RT_RCDATA);
if (resource == nullptr)
{
continue;
}
HGLOBAL resHandle = LoadResource(nullptr, resource);
if (resHandle == nullptr)
{
continue;
}
def.path_type = iter->path_type;
def.filename = iter->filename;
def.data = LockResource(resHandle);
def.size = SizeofResource(nullptr, resource);
return def;
}
}
//WMC - This is really bad, because it means we have a default table missing.
Error(LOCATION, "Default table '%s' missing from executable - contact a coder.", filename);
def.data = nullptr;
def.data = 0;
return def;
}
SCP_vector<default_file> defaults_get_all() {
SCP_vector<default_file> files;
for (auto& file : Default_files) {
default_file def;
HRSRC resource = FindResource(nullptr, file.resource_name, RT_RCDATA);
if (resource == nullptr)
{
continue;
}
HGLOBAL resHandle = LoadResource(nullptr, resource);
if (resHandle == nullptr)
{
continue;
}
def.path_type = file.path_type;
def.filename = file.filename;
def.data = LockResource(resHandle);
def.size = SizeofResource(nullptr, resource);
files.push_back(def);
}
return files;
}
@@ -16,11 +16,11 @@ struct def_file
const size_t size;
};
#include "def_files/generated_def_files-generic.inc"
#include "embedded_files.inc"
default_file defaults_get_file(const char *filename)
{
default_file def;
default_file def{};
auto endIter = std::end(Default_files);
for (auto iter = std::begin(Default_files); iter != endIter; ++iter)
@@ -44,7 +44,7 @@ default_file defaults_get_file(const char *filename)
SCP_vector<default_file> defaults_get_all() {
SCP_vector<default_file> files;
for (auto& file : Default_files) {
for (const auto& file : Default_files) {
default_file def;
def.path_type = file.path_type;
def.filename = file.filename;
+4 -4
View File
@@ -15,10 +15,10 @@
struct default_file
{
const char* path_type;
const char* filename;
const void* data;
size_t size;
const char* path_type = nullptr;
const char* filename = nullptr;
const void* data = nullptr;
size_t size = 0;
};
//Used to retrieve pointer to file data from def_files.cpp
@@ -1,2 +0,0 @@
@ARRAY_ELEMENTS@
-91
View File
@@ -1,91 +0,0 @@
IF(MSVC)
# Windows specific version using resource files
set(RES_CONTENT)
set(ARRAY_ELEMENTS)
FOREACH(file ${default_files_files})
set(INPUT_NAME "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
SET(OUTPUT "${GENERATED_SOURCE_DIR}/code/${file}")
file(RELATIVE_PATH RELATIVE_FILE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/def_files" "${INPUT_NAME}")
# Retrieve the path type name from the relative path
GET_FILENAME_COMPONENT(PATH_TYPE "${RELATIVE_FILE_PATH}" DIRECTORY)
file(TO_NATIVE_PATH "${PATH_TYPE}" PATH_TYPE)
string(REPLACE "\\" "\\\\" PATH_TYPE "${PATH_TYPE}")
GET_FILENAME_COMPONENT(FILE_NAME "${RELATIVE_FILE_PATH}" NAME)
string(MAKE_C_IDENTIFIER "${RELATIVE_FILE_PATH}" FIELD_NAME)
set(FIELD_NAME "Default_${FIELD_NAME}")
string(TOUPPER "${FIELD_NAME}" FIELD_NAME)
set(ARRAY_ELEMENTS "${ARRAY_ELEMENTS}\n\t{ \"${PATH_TYPE}\", \"${FILE_NAME}\" , TEXT(\"${FIELD_NAME}\") },")
set(RES_CONTENT "${RES_CONTENT}\n${FIELD_NAME} RCDATA \"${INPUT_NAME}\"")
ENDFOREACH(file)
file(WRITE "${GENERATED_SOURCE_DIR}/code/default_files.rc" "${RES_CONTENT}")
configure_file("def_files/generated_def_files-win32.inc.in" "${GENERATED_SOURCE_DIR}/code/def_files/generated_def_files-win32.inc")
target_sources(code INTERFACE "${GENERATED_SOURCE_DIR}/code/default_files.rc")
else()
# Generic version using embedfile
SET(DEF_OUT_FILES)
set(INCLUDE_LIST)
set(ARRAY_ELEMENTS)
FOREACH(file ${default_files_files})
set(INPUT_NAME "${CMAKE_CURRENT_SOURCE_DIR}/${file}")
SET(OUTPUT "${GENERATED_SOURCE_DIR}/code/${file}")
file(RELATIVE_PATH RELATIVE_FILE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/def_files" "${INPUT_NAME}")
# For some reason this is needed...
GET_FILENAME_COMPONENT(DIRECTORY_PATH ${OUTPUT} DIRECTORY)
FILE(MAKE_DIRECTORY ${DIRECTORY_PATH})
# Retrieve the path type name from the relative path
GET_FILENAME_COMPONENT(PATH_TYPE "${RELATIVE_FILE_PATH}" DIRECTORY)
file(TO_NATIVE_PATH "${PATH_TYPE}" PATH_TYPE)
if (MINGW)
# There is a bug in CMake where it thinks MinGW uses forward slashes for paths but we need backslashes for Windows builds
string(REPLACE "/" "\\" PATH_TYPE "${PATH_TYPE}")
endif()
# Properly escape back slashes in strings
string(REPLACE "\\" "\\\\" PATH_TYPE "${PATH_TYPE}")
GET_FILENAME_COMPONENT(FILE_NAME "${RELATIVE_FILE_PATH}" NAME)
string(MAKE_C_IDENTIFIER "${RELATIVE_FILE_PATH}" FIELD_NAME)
set(HEADER_FILE "${OUTPUT}.h")
set(SOURCE_FILE "${OUTPUT}.cpp")
set_source_files_properties("${HEADER_FILE}" "${SOURCE_FILE}" PROPERTIES GENERATED TRUE)
set(ALL_OUTPUTS "${HEADER_FILE}" "${SOURCE_FILE}")
set(FIELD_NAME "Default_${FIELD_NAME}")
set(INCLUDE_LIST "${INCLUDE_LIST}\n#include \"${file}.h\"")
set(ARRAY_ELEMENTS "${ARRAY_ELEMENTS}\n\t{ \"${PATH_TYPE}\", \"${FILE_NAME}\" , ${FIELD_NAME} , ${FIELD_NAME}_size },")
ADD_CUSTOM_COMMAND(
OUTPUT ${ALL_OUTPUTS}
COMMAND embedfile "${INPUT_NAME}" "${OUTPUT}" "${FIELD_NAME}"
MAIN_DEPENDENCY "${INPUT_NAME}"
DEPENDS embedfile
COMMENT "Generating string file for ${INPUT_NAME}"
)
LIST(APPEND DEF_OUT_FILES ${ALL_OUTPUTS})
ENDFOREACH(file)
configure_file("def_files/generated_def_files-generic.inc.in" "${GENERATED_SOURCE_DIR}/code/def_files/generated_def_files-generic.inc")
target_sources(code PRIVATE ${DEF_OUT_FILES})
SOURCE_GROUP("Generated Files\\Default Files" FILES ${DEF_OUT_FILES})
endif()
+2 -11
View File
@@ -143,18 +143,9 @@ add_file_folder("Decals"
add_file_folder("Default files"
def_files/def_files.h
def_files/def_files.cpp
${file_root_def_files}
)
if(MSVC)
add_file_folder("Default files"
${file_root_def_files}
def_files/def_files-win32.cpp
)
else()
add_file_folder("Default files"
${file_root_def_files}
def_files/def_files-generic.cpp
)
endif()
add_file_folder("Default files\\\\data"
)
+1 -1
View File
@@ -171,7 +171,7 @@ void do_text_content(std::ifstream& file_in, std::ofstream& file_out,
void write_header(std::ostream& out, const std::string& fieldName, bool text_content, bool wxWidgets_image) {
std::string headerDefine(fieldName);
std::transform(fieldName.begin(), fieldName.end(), headerDefine.begin(), ::toupper);
std::transform(fieldName.begin(), fieldName.end(), headerDefine.begin(), [](char c) { return (char)::toupper(c); });
headerDefine = "SCP_" + headerDefine + "_H";