我有一个跨平台(Windows,Mac,iOS)的CMake项目,需要将二进制资源(图像,音频,文本文件等)复制到最终应用程序中。之前,我只是将所有资源添加到add_executable
命令中,并且在我希望将所有内容组织到子目录中之前,它都工作正常。
要在保留文件夹结构的同时复制应用程序资产,我最终在Windows目标中使用了以下自定义命令:
add_custom_command(
TARGET ${APP_TARGET_NAME} PRE_LINK
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/${APP_ASSETS_DIR}
$<TARGET_FILE_DIR:${APP_TARGET_NAME}>/assets
)
哪个效果很好。当我尝试在macOS上执行相同的操作时,就会出现问题。当我在macOS上使用相同的$<TARGET_FILE_DIR>
技巧时,我得到了输出应用程序捆绑包的地址(非常好),因此我在末尾添加了/resources
并尝试在其中复制,但是这会失败。
在XCode中,出现以下错误:
PhaseScriptExecution CMake\ PreLink\ Rules /Users/someuser/Documents/Build/Test/Test.build/Debug/Test_MAC.build/Script-2CF8724D08BC49E4A13B9E75.sh
cd /Users/someuser/Documents/GitHub/Test
/bin/sh -c /Users/someuser/Documents/Build/Test/Test.build/Debug/Test_MAC.build/Script-2CF8724D08BC49E4A13B9E75.sh
/Users/someuser/Documents/Build/Test/Debug/Test_MAC.app/Contents/MacOS/Test_MAC -E copy_directory /Users/someuser/Documents/GitHub/Test/assets /Users/someuser/Documents/Build/Test/Debug/Test_MAC.app/Contents/Resources
make: *** [Test_MAC_buildpart_0] Segmentation fault: 11
Command /bin/sh failed with exit code 2
哪个不是特别有用。我已经尝试过PRE_LINK
和POST_BUILD
以及copy_directory
和copy
。
为什么会失败?我无法在iOS上进行测试,但我想两者可以以类似的方式工作。
如何将我的资产复制到macOS(也是iOS)上的捆绑软件中?
答案 0 :(得分:0)
在网上使用CMake生成框架/捆绑软件的文档很少。大多数智慧隐藏在CMakeLists.txt文件中,而不是CMake教程中。
这两种方法都可以使用,但是正确起来有些棘手。我在CMake的Unix Makefiles
生成器的版本化框架项目中将它们一起使用。
首先,您将资源添加到框架/捆绑中(我的名称与项目相同,因此我在以下各行中使用${PROJECT_NAME}
)或者,方法是将资源作为参数添加到{ {1}},例如
add_library
然后为框架/捆绑包设置目标属性:
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS} ${RESOURCES})
稍后使用帮助程序功能针对 if(BUILD_MAC_FRAMEWORK)
# Set the framework target properties just to make sure the relevant links inside the framework
# are created. Because the default framework name differs from the project name we change the
# output name property.
set_target_properties(${PROJECT_NAME} PROPERTIES
FRAMEWORK TRUE
FRAMEWORK_VERSION ${MAC_FRAMEWORK_VERSION}
#PUBLIC_HEADER "${PUBLIC_HEADERS}" # does not work recursively
#PRIVATE_HEADER "${PRIVATE_HEADERS}" # does not work recursively
RESOURCE "${CMAKE_BINARY_DIR}/version.plist" # does not work recursively
MACOSX_FRAMEWORK_IDENTIFIER org.company.sampleFramework.framework
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PROJECT_VERSION}
MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_FRAMEWORK_INFO_PLIST "${CMAKE_BINARY_DIR}/Info.plist"
OUTPUT_NAME ${MAC_FRAMEWORK_NAME}
)
endif()
目录设置资源文件的框架路径
Resources
helper函数将删除指定的前缀,并将其替换为安装前缀。
确保两个命令(# determine which subdirectory this file (header, resource) should be installed into.
function(set_macosx_properties _removable_prefixes _install_prefix _source_files)
foreach(_file ${_source_files})
get_filename_component(_loc "${_file}" DIRECTORY)
foreach(_prefix ${_removable_prefixes})
string(REPLACE "${_prefix}" "" _loc "${_loc}")
endforeach()
set_source_files_properties(${_file} PROPERTIES MACOSX_PACKAGE_LOCATION ${_install_prefix}${_loc})
endforeach()
endfunction()
set_macosx_properties("${CMAKE_SOURCE_DIR}/include;${CMAKE_BINARY_DIR}/include" "Headers" "${HEADERS}")
set_macosx_properties("${CMAKE_SOURCE_DIR}/data;${CMAKE_BINARY_DIR}/data" "Resources" "${RESOURCES}")
和add_library
)都从同一目录/ set_macosx_properties
中调用!命令的不同位置不起作用。
或,您可以按以下方式使用对CMakeLists.txt
的呼叫。我不记得其他类型的目标是否不起作用,但我一直使用add_custom_command
自定义目标。
POST_BUILD
最后,安装是通过单个命令完成的:
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_FILE_DIR:${PROJECT_NAME}>/Documentation
COMMAND ${CMAKE_COMMAND} -E create_symlink ./Versions/Current/Documentation $<TARGET_FILE_DIR:${PROJECT_NAME}>/../../Documentation
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/html $<TARGET_FILE_DIR:${PROJECT_NAME}>/Documentation/html)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E remove $<TARGET_FILE_DIR:${PROJECT_NAME}>/Documentation/html/${PROJECT_NAME}-${PROJECT_VERSION_MAJOR}.qch
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/html/${PROJECT_NAME}-${PROJECT_VERSION_MAJOR}.qch $<TARGET_FILE_DIR:${PROJECT_NAME}>/Documentation)