CMake: пользовательская команда copy_directory не работает в macOS - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть кроссплатформенный проект (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.Когда я использую тот же трюк $<TARGET_FILE_DIR> в macOS, я получаю адрес выходного пакета приложений (что очень хорошо), поэтому я добавляю /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)?

1 Ответ

0 голосов
/ 20 февраля 2019

В сети не так много полезной документации для создания фреймворка / комплекта с CMake.Большая часть мудрости скрыта в файлах CMakeLists.txt, а не в руководствах по CMake.

Известно, что оба метода работают, но их немного сложно понять.Я использовал их вместе в проекте версионного фреймворка с генератором CMake Unix Makefiles.

Сначала вы добавляете ресурсы в ваш фреймворк / комплект (у меня такое же имя, как и у проекта, поэтому я использую ${PROJECT_NAME} на протяжении всегоследующие строки) либо , добавив их в качестве аргументов к 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 с помощью вспомогательной функции

# 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)

Наконец, установка выполняется одной командой:

install(TARGETS ${PROJECT_NAME} FRAMEWORK DESTINATION . COMPONENT development)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...