CMake:macOS上的copy_directory自定义命令失败

时间:2019-02-20 02:00:20

标签: macos cmake

我有一个跨平台(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_LINKPOST_BUILD以及copy_directorycopy

为什么会失败?我无法在iOS上进行测试,但我想两者可以以类似的方式工作。

如何将我的资产复制到macOS(也是iOS)上的捆绑软件中?

1 个答案:

答案 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)