Как скопировать целевые файлы с помощью cmake из основного CMakeLists.txt?

В качестве примера предположим, что четыре папки (app1, app2, app3 и main), такие как ниже

main
|__ CMakeLists.txt
\__ module1
|______ CMakeLists.txt
|______ sub1.cpp
|______ sub1.h
\__ library5
|______ CMakeLists.txt
|______ sub5.cpp
|______ sub5.h
\__app1
\__app2
\__app3

Какой вывод module1 является module1.dll, а вывод library5 - lib5.dll. Папка app1 должна содержать module1.dll и lib5.dll, app2 нужна lib5.dll и, наконец, app3 нужна module1.dll (количество приложений, модулей и библиотек больше, чем в этом примере, и, как я объясню ниже, мы не хотим менять модули / библиотеки-х CMakeLists.txtМейн CMakeLists.txt это наше).

PS:

у меня есть cmake проект, который имеет несколько библиотек и модулей. Они включены в мой проект с помощью add_subdirectory (обратите внимание, что мой проект просто состоит из нескольких модулей, и он не имеет каких-либо add_library или же add_target).

Мне нужно скопировать выводы библиотек / модулей без изменения их CMakeLists.txt (add_custom_command с POST_BUILD вариант на самом деле не является хорошим выбором, потому что на данный момент мне нужно изменить CMakeLists.txt библиотек / модулей, которые они не просто принадлежат моему проекту). С другой стороны это должно быть сделано во внешнем (главном) CMakeLists.txt у которого есть другие (библиотеки / модули).

Я пробовал некоторые другие команды, такие как file (COPY ) а также configure_file() но я думаю, что они работают в генерации cmake-cacheфаза и просто можно скопировать файлы ресурсов, которые существуют на этапе предварительной сборки.

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

add_custom_target (copy_all
        COMMAND ${CMAKE_SOURCE_DIR}/copy.sh ${files}
        WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)

files есть список файлов. Но копия не выполнена! Я вручную тестирую скрипт, который работает как нужно. Но я понятия не имею, почему он не может работать при вызове в CMakeLists.txt.

Что я могу сделать, чтобы скопировать результаты подпроектов в некоторые места из основных CMakeLists.txt?

1 ответ

Настройка

Чтобы немного упростить это, скажем, у вас есть:

CMakeLists.txt

cmake_minimum_required(VERSION 3.0)

project(PostBuildCopyFromRoot)

add_subdirectory(module)

модуль /CMakeLists.txt

file(WRITE "module.h" "int ModuleFunc();")
file(WRITE "module.cpp" "int ModuleFunc() { return 1; }")

add_library(module SHARED "module.cpp" "module.h")
target_include_directories(module PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
set_target_properties(module PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS 1)

Приложение /app.mexw64

Эта проблема

Если вы сейчас просто добавляете подписку в корень CMakeLists.txt:

add_custom_command(
    TARGET module
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy
        "$<TARGET_FILE:module>"
        "app/$<TARGET_FILE_NAME:module>"
)

Вы получите от CMake:

CMake Warning (dev) at CMakeLists.txt:8 (add_custom_command):
  Policy CMP0040 is not set: The target in the TARGET signature of
  add_custom_command() must exist.  Run "cmake --help-policy CMP0040" for
  policy details.  Use the cmake_policy command to set the policy and
  suppress this warning.

  TARGET 'module' was not created in this directory.

Решения

Вы всегда можете переписать поведение команд:

    function(add_library _target)
        _add_library(${_target} ${ARGN})

        add_custom_command(
            TARGET ${_target}
            POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy
                "$<TARGET_FILE:${_target}>"
                "${CMAKE_SOURCE_DIR}/app/$<TARGET_FILE_NAME:${_target}>"
        )
    endfunction()

ПРИМЕЧАНИЕ. Поместите фрагменты кода перед add_subdirectory() вызов

Рекомендации

Другие вопросы по тегам