mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-07 08:15:59 -10:00
125 lines
5.4 KiB
CMake
125 lines
5.4 KiB
CMake
|
|
set(_EMBEDD_FILE_BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
|
|
|
|
function(target_embed_files _target)
|
|
set(options)
|
|
set(oneValueArgs RELATIVE_TO PATH_TYPE_PREFIX)
|
|
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}")
|
|
|
|
file(RELATIVE_PATH _pathType "${EMBED_RELATIVE_TO}" "${_absoluteFile}")
|
|
get_filename_component(_pathType ${_pathType} DIRECTORY)
|
|
if (DEFINED EMBED_PATH_TYPE_PREFIX)
|
|
if (_pathType)
|
|
set(_pathType "${EMBED_PATH_TYPE_PREFIX}/${_pathType}")
|
|
else()
|
|
# Avoid trailing / when we are in the same directory
|
|
set(_pathType "${EMBED_PATH_TYPE_PREFIX}")
|
|
endif()
|
|
endif()
|
|
|
|
if (NOT _pathType)
|
|
# If it is still empty then we need to work around yet another annoying CMake behavior where it ignores
|
|
# "empty" property strings
|
|
set(_pathType ".")
|
|
endif()
|
|
|
|
set_property(TARGET ${_target} APPEND PROPERTY EMBEDDED_FILES "${_absoluteFile}")
|
|
set_property(TARGET ${_target} APPEND PROPERTY EMBEDDED_FILES_BASE_DIR "${EMBED_RELATIVE_TO}")
|
|
set_property(TARGET ${_target} APPEND PROPERTY EMBEDDED_FILES_PATH_TYPE "${_pathType}")
|
|
endforeach()
|
|
endfunction()
|
|
|
|
function(handle_embedded_files _target)
|
|
get_target_property(_filesToEmbed ${_target} EMBEDDED_FILES)
|
|
get_target_property(_baseDirs ${_target} EMBEDDED_FILES_BASE_DIR)
|
|
get_target_property(_pathTypes ${_target} EMBEDDED_FILES_PATH_TYPE)
|
|
|
|
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)
|
|
list(GET _pathTypes ${i} _pathType)
|
|
|
|
if (_pathType STREQUAL ".")
|
|
# Handle the workaround we had to do for empty path types
|
|
set(_pathType "")
|
|
endif()
|
|
|
|
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
|
|
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 },")
|
|
|
|
IF(CMAKE_CROSSCOMPILING)
|
|
SET(EMBEDFILE_PATH "EMBEDFILE-NOTFOUND" CACHE FILEPATH "Required for a cross compiling build, point to an embedfile of a cmake build for the host OS")
|
|
IF(EMBEDFILE_PATH STREQUAL "EMBEDFILE-NOTFOUND")
|
|
#This could, possibly, be configured to compile an embedfile using host compilation automatically, but that seems to be a challenge.
|
|
message(FATAL_ERROR "A manual embedfile path must be configured for cross compilation. Set EMBEDFILE_PATH to the location of an embedfile executable, found in the build directories for the host OS.")
|
|
ENDIF()
|
|
ELSE(CMAKE_CROSSCOMPILING)
|
|
SET(EMBEDFILE_PATH "embedfile")
|
|
ENDIF(CMAKE_CROSSCOMPILING)
|
|
|
|
add_custom_command(
|
|
OUTPUT ${ALL_OUTPUTS}
|
|
COMMAND ${EMBEDFILE_PATH} "${_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()
|