修复add_resource_file
This commit is contained in:
parent
2ebd7f9182
commit
4d9ccc73c0
@ -158,82 +158,160 @@ function(retrieve_files path out_files)
|
||||
endfunction()
|
||||
|
||||
#[=======================================================================[
|
||||
用于添加资源文件并在编译后复制到目标文件 (可执行文件或库) 所在目录
|
||||
参数:
|
||||
TARGET_NAME: 目标 (可执行文件或库) 的名称
|
||||
RESOURCE_FILE_PATHS - 一个或多个要复制的资源文件的路径 (可以是相对或绝对路径)
|
||||
# 用于添加资源文件并在编译后复制到最终可执行文件所在目录
|
||||
# 注意:此函数依赖于 CMAKE_RUNTIME_OUTPUT_DIRECTORY 或 EXECUTABLE_OUTPUT_PATH
|
||||
# 变量的设置,以确定可执行文件的输出目录。请确保在项目中设置了其中之一。
|
||||
#
|
||||
# 参数:
|
||||
# TARGET_NAME: (必需) - 关联的目标 (库或可执行文件) 的名称。
|
||||
# 资源复制命令将在 TARGET_NAME 构建后执行。
|
||||
# RESOURCE_FILES: (必需) - 一个或多个要复制的资源文件的路径列表 (相对或绝对)
|
||||
# OUTPUT_SUBDIR: (可选) - 相对于可执行文件输出目录的子目录路径 (例如 "assets")
|
||||
#
|
||||
# 例子:
|
||||
# # 确保设置了可执行文件输出目录 (通常在顶层 CMakeLists.txt)
|
||||
# set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
||||
#
|
||||
# # 添加库
|
||||
# add_library(my_lib STATIC src/my_lib.cpp)
|
||||
#
|
||||
# # 添加资源到 my_lib,但复制到最终可执行文件的输出目录下的 'config' 子目录
|
||||
# add_resource_file(
|
||||
# TARGET_NAME my_lib
|
||||
# RESOURCE_FILES config/settings.json config/defaults.ini
|
||||
# OUTPUT_SUBDIR config
|
||||
# )
|
||||
#
|
||||
# # 添加可执行文件
|
||||
# add_executable(my_app main.cpp)
|
||||
# target_link_libraries(my_app PRIVATE my_lib)
|
||||
#
|
||||
# # 添加 my_app 的资源,复制到可执行文件输出目录的根目录
|
||||
# add_resource_file(
|
||||
# TARGET_NAME my_app
|
||||
# RESOURCE_FILES assets/icon.png
|
||||
# )
|
||||
#]=======================================================================]
|
||||
function(add_resources TARGET_NAME)
|
||||
# 获取 TARGET_NAME 之后的所有参数作为资源文件列表
|
||||
set(RESOURCE_FILES ${ARGN})
|
||||
function(add_resource_file)
|
||||
# 定义预期的参数
|
||||
set(options "") # 无布尔选项
|
||||
set(oneValueArgs TARGET_NAME OUTPUT_SUBDIR)
|
||||
set(multiValueArgs RESOURCE_FILES)
|
||||
|
||||
# 检查目标是否存在 (可选,但推荐)
|
||||
if(NOT TARGET ${TARGET_NAME})
|
||||
message(FATAL_ERROR "目标 '${TARGET_NAME}' 不存在,无法添加资源。")
|
||||
return()
|
||||
# 解析传递给函数的参数
|
||||
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||
|
||||
# --- 参数验证 ---
|
||||
if(NOT ARG_TARGET_NAME)
|
||||
message(FATAL_ERROR "**add_resource_file**: **缺少必需参数** **TARGET_NAME**.")
|
||||
endif()
|
||||
if(NOT ARG_RESOURCE_FILES)
|
||||
message(FATAL_ERROR "**add_resource_file**: **缺少必需参数** **RESOURCE_FILES**.")
|
||||
endif()
|
||||
if(NOT TARGET ${ARG_TARGET_NAME})
|
||||
message(WARNING "**add_resource_file**: 目标 '${ARG_TARGET_NAME}' (尚)不存在。请确保在调用 add_executable/add_library('${ARG_TARGET_NAME}') 之后调用此函数。")
|
||||
# 即使目标尚不存在,仍然尝试配置命令。CMake通常能处理好依赖关系。
|
||||
endif()
|
||||
|
||||
# **获取目标可执行文件的输出目录** (只需执行一次)
|
||||
# 对于多配置生成器 (如 Visual Studio, Xcode),使用 $<TARGET_FILE_DIR:TARGET_NAME>
|
||||
# 对于单配置生成器 (如 Makefiles, Ninja),使用 CMAKE_RUNTIME_OUTPUT_DIRECTORY 或 $<TARGET_FILE_DIR:TARGET_NAME>
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
set(DESTINATION_DIR "$<TARGET_FILE_DIR:${TARGET_NAME}>")
|
||||
# --- 确定最终可执行文件的目标基础目录 ---
|
||||
set(DESTINATION_BASE "")
|
||||
if(DEFINED CMAKE_RUNTIME_OUTPUT_DIRECTORY AND CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
set(DESTINATION_BASE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
|
||||
elseif(DEFINED EXECUTABLE_OUTPUT_PATH AND EXECUTABLE_OUTPUT_PATH)
|
||||
# EXECUTABLE_OUTPUT_PATH 是旧变量,但也检查一下
|
||||
set(DESTINATION_BASE "${EXECUTABLE_OUTPUT_PATH}")
|
||||
else()
|
||||
if(CMAKE_RUNTIME_OUTPUT_DIRECTORY)
|
||||
set(DESTINATION_DIR "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
|
||||
# 如果是多配置生成器(如 Visual Studio, Xcode),需要考虑配置类型
|
||||
get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
||||
if(is_multi_config)
|
||||
# 对于多配置,没有单一的顶级运行时目录变量。
|
||||
# 可以考虑使用 $<OUTPUT_DIRECTORY> 配合一个已知的可执行文件名,但这会使函数复杂化。
|
||||
# 最好的做法是要求用户设置 CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG>
|
||||
# 或者我们直接报错,强制用户设置 CMAKE_RUNTIME_OUTPUT_DIRECTORY
|
||||
message(FATAL_ERROR "**add_resource_file**: **无法确定可执行文件输出目录**。请在您的项目中设置 **CMAKE_RUNTIME_OUTPUT_DIRECTORY** 变量 (例如 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"\${CMAKE_BINARY_DIR}/bin\"))。对于多配置生成器,可能需要设置 CMAKE_RUNTIME_OUTPUT_DIRECTORY_<CONFIG> 变量。")
|
||||
else()
|
||||
# 使用 $<TARGET_FILE_DIR:TARGET_NAME> 通常更健壮
|
||||
set(DESTINATION_DIR "$<TARGET_FILE_DIR:${TARGET_NAME}>")
|
||||
# 对于单配置生成器(如 Makefiles, Ninja),可以默认到 CMAKE_BINARY_DIR
|
||||
set(DESTINATION_BASE "${CMAKE_BINARY_DIR}")
|
||||
message(WARNING "**add_resource_file**: **未设置 CMAKE_RUNTIME_OUTPUT_DIRECTORY**。默认将资源复制到 CMAKE_BINARY_DIR ('${CMAKE_BINARY_DIR}')。强烈建议设置 CMAKE_RUNTIME_OUTPUT_DIRECTORY 以获得可预测的行为。")
|
||||
endif()
|
||||
# message(FATAL_ERROR "**add_resource_file**: **无法确定可执行文件输出目录**。请在您的项目中设置 **CMAKE_RUNTIME_OUTPUT_DIRECTORY** 变量 (例如 set(CMAKE_RUNTIME_OUTPUT_DIRECTORY \"\${CMAKE_BINARY_DIR}/bin\"))。")
|
||||
endif()
|
||||
|
||||
# 处理子目录
|
||||
set(DESTINATION_DIR "${DESTINATION_BASE}") # 默认目标目录
|
||||
if(ARG_OUTPUT_SUBDIR)
|
||||
# 清理子目录路径字符串
|
||||
string(STRIP "${ARG_OUTPUT_SUBDIR}" _subdir)
|
||||
if(IS_ABSOLUTE "${_subdir}")
|
||||
message(FATAL_ERROR "**add_resource_file**: **OUTPUT_SUBDIR** ('${ARG_OUTPUT_SUBDIR}') **必须是相对路径**。")
|
||||
else()
|
||||
# 移除可能存在的前导/后导斜杠,以便干净地拼接路径
|
||||
string(REGEX REPLACE "^[/\\\\]+" "" _subdir "${_subdir}")
|
||||
string(REGEX REPLACE "[/\\\\]+$" "" _subdir "${_subdir}")
|
||||
if(_subdir) # 仅当子目录清理后非空时才追加
|
||||
set(DESTINATION_DIR "${DESTINATION_BASE}/${_subdir}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# **遍历所有传入的资源文件**
|
||||
foreach(RESOURCE_FILE ${RESOURCE_FILES})
|
||||
set(ABS_RESOURCE_FILE "") # 重置/初始化
|
||||
# --- 准备源文件路径 ---
|
||||
set(ABS_RESOURCE_FILES "")
|
||||
foreach(RESOURCE_FILE ${ARG_RESOURCE_FILES})
|
||||
get_filename_component(RESOURCE_FILE_REALPATH "${RESOURCE_FILE}" REALPATH BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
# if(IS_ABSOLUTE "${RESOURCE_FILE}")
|
||||
# # 如果已经是绝对路径,直接使用
|
||||
# list(APPEND ABS_RESOURCE_FILES "${RESOURCE_FILE}")
|
||||
# else()
|
||||
# # 如果是相对路径,相对于当前源目录进行解析
|
||||
# list(APPEND ABS_RESOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${RESOURCE_FILE}")
|
||||
# endif()
|
||||
list(APPEND ABS_RESOURCE_FILES "${RESOURCE_FILE_REALPATH}")
|
||||
|
||||
# **处理相对路径和绝对路径,并检查文件是否存在**
|
||||
if(IS_ABSOLUTE "${RESOURCE_FILE}")
|
||||
# 如果是绝对路径,直接检查是否存在
|
||||
if(EXISTS "${RESOURCE_FILE}")
|
||||
set(ABS_RESOURCE_FILE "${RESOURCE_FILE}")
|
||||
else()
|
||||
message(WARNING "资源文件未找到 (绝对路径,将跳过): ${RESOURCE_FILE}")
|
||||
continue() # 处理下一个文件
|
||||
endif()
|
||||
else()
|
||||
# 如果是相对路径,相对于当前 CMakeLists.txt 文件所在目录解析
|
||||
set(TEMP_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${RESOURCE_FILE}")
|
||||
if(EXISTS "${TEMP_PATH}")
|
||||
set(ABS_RESOURCE_FILE "${TEMP_PATH}")
|
||||
else()
|
||||
message(WARNING "资源文件未找到 (相对路径,将跳过): ${RESOURCE_FILE} (相对于: ${CMAKE_CURRENT_SOURCE_DIR})")
|
||||
continue() # 处理下一个文件
|
||||
endif()
|
||||
# 检查文件是否存在 (在配置时发出警告,有助于早期发现错误)
|
||||
# list(GET ABS_RESOURCE_FILES -1 _current_abs_file) # 获取刚才添加的绝对路径
|
||||
if(NOT EXISTS "${RESOURCE_FILE_REALPATH}")
|
||||
message(WARNING "**add_resource_file**: **资源文件** '${RESOURCE_FILE}' (解析为 '${RESOURCE_FILE_REALPATH}') **在配置时不存在**。")
|
||||
endif()
|
||||
|
||||
# **检查是否是文件而非目录** (copy_if_different 用于文件)
|
||||
if(IS_DIRECTORY "${ABS_RESOURCE_FILE}")
|
||||
message(WARNING "提供的资源是一个目录,而非文件 (将跳过): ${ABS_RESOURCE_FILE}. 请使用其他方法复制目录。")
|
||||
continue()
|
||||
endif()
|
||||
|
||||
# **获取资源文件的文件名部分**
|
||||
get_filename_component(RESOURCE_FILENAME "${ABS_RESOURCE_FILE}" NAME)
|
||||
|
||||
# **为每个文件添加自定义构建后命令**
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME} # 关联到目标
|
||||
POST_BUILD # 在目标构建完成后执行
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different # 使用 cmake 内建命令复制文件 (仅在文件不同时复制)
|
||||
"${ABS_RESOURCE_FILE}" # 源文件 (绝对路径)
|
||||
"${DESTINATION_DIR}/${RESOURCE_FILENAME}" # **目标路径** (可执行文件目录 + 文件名)
|
||||
COMMENT "正在复制资源 ${RESOURCE_FILENAME} 到 ${TARGET_NAME} 的输出目录" # 构建时显示的注释
|
||||
VERBATIM # 确保特殊字符被正确处理
|
||||
)
|
||||
|
||||
# (可选) 将资源文件添加到目标源文件中,以便在某些 IDE 中显示
|
||||
# 注意:如果文件不在源目录树下,某些 IDE 可能不会正确显示
|
||||
# target_sources(${TARGET_NAME} PRIVATE "${ABS_RESOURCE_FILE}")
|
||||
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
# --- 添加自定义命令 ---
|
||||
# 使用 add_custom_command 在目标构建完成后执行复制操作
|
||||
if(ABS_RESOURCE_FILES) # 确保有文件需要复制
|
||||
# 注意:DESTINATION_DIR 可能包含特定于配置的路径(例如,如果 CMAKE_RUNTIME_OUTPUT_DIRECTORY
|
||||
# 设置为 ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)。
|
||||
# add_custom_command 的 COMMAND 参数在构建时执行,此时这些变量/生成器表达式已解析。
|
||||
add_custom_command(
|
||||
TARGET ${ARG_TARGET_NAME}
|
||||
POST_BUILD # 指定在目标构建之后执行
|
||||
# 步骤 1: 确保目标目录存在 (copy_if_different 不会创建目录)
|
||||
COMMAND ${CMAKE_COMMAND} -E make_directory "${DESTINATION_DIR}"
|
||||
# 步骤 2: 复制文件
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different # 使用CMake内置命令复制(仅当文件不同时)
|
||||
${ABS_RESOURCE_FILES} # 要复制的源文件列表(绝对路径)
|
||||
"${DESTINATION_DIR}" # 最终可执行文件所在的目标目录 (带引号以处理空格)
|
||||
COMMENT "为 ${ARG_TARGET_NAME} 将资源复制到可执行文件目录: ${DESTINATION_DIR}..." # 构建时显示的注释
|
||||
VERBATIM # 确保参数(尤其是路径和生成器表达式)被正确处理
|
||||
)
|
||||
else()
|
||||
message(WARNING "**add_resource_file**: 没有有效的资源文件提供给目标 '${ARG_TARGET_NAME}'。")
|
||||
endif()
|
||||
|
||||
# --- 可选: 将资源文件添加到 IDE 项目结构中 ---
|
||||
if(ABS_RESOURCE_FILES)
|
||||
set(_source_group_name "Resource Files") # 基础组名
|
||||
if(ARG_OUTPUT_SUBDIR)
|
||||
# 使用与目标目录结构匹配的组名
|
||||
string(STRIP "${ARG_OUTPUT_SUBDIR}" _clean_subdir)
|
||||
string(REPLACE "\\" "/" _clean_subdir "${_clean_subdir}") # 统一使用正斜杠
|
||||
string(REGEX REPLACE "^[/]+" "" _clean_subdir "${_clean_subdir}")
|
||||
string(REGEX REPLACE "[/]+$" "" _clean_subdir "${_clean_subdir}")
|
||||
if(_clean_subdir)
|
||||
set(_source_group_name "Resource Files/${_clean_subdir}")
|
||||
endif()
|
||||
endif()
|
||||
# 使用 source_group 将文件添加到 IDE 的指定组下
|
||||
source_group(${_source_group_name} FILES ${ABS_RESOURCE_FILES})
|
||||
endif()
|
||||
|
||||
endfunction()
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
#include "color.h"
|
||||
|
||||
#include <charconv>
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* @brief 将十六进制字符转换为整数值
|
||||
*
|
||||
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <complex>
|
||||
#include <optional>
|
||||
|
||||
/**
|
||||
* @class linear_color
|
||||
|
@ -9,4 +9,7 @@ add_library(${PROJECT_NAME} STATIC ${SRC_FILES})
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC mirage_core mirage_render tomlplusplus::tomlplusplus)
|
||||
|
||||
add_resources(${PROJECT_NAME} src/style/default_style.toml)
|
||||
add_resource_file(
|
||||
TARGET_NAME ${PROJECT_NAME}
|
||||
RESOURCE_FILES src/style/default_style.toml
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user