Настраиваемая цель CMake не создается

Я создаю две цели, используя:

add_library(tgt1 SHARED a.cpp)
add_library(tgt2 SHARED b.cpp)

После того, как оба будут построены, мне нужно запустить этап пост-сборки, который зависит от обеих целей. Я пробовал множество комбинаций из следующего, но безуспешно:

add_custom_target(final_tgt DEPENDS tgt1 tgt2)
add_custom_command(TARGET final_tgt POST_BUILD COMMAND <command> ARGS <args>)

Конечная цель просто не будет построена, даже если ее build.make содержит настраиваемую команду.

Пытался использовать ВСЕ для настраиваемой цели, однако сначала попытайся построить ее, пропустив первые цели.

И я не могу использовать add_library или add_executable для конечной цели, поскольку они требуют указания исходных файлов.

Как правильно это делать?

===================================

Изменить: ниже приведен минимальный проверяемый исходный код. Что он пытается сделать, так это скомпилировать код (для Mac) в двух архитектурах и в качестве пост-сборки для создания универсального двоичного файла с использованием липо:

cmake_minimum_required(VERSION 2.8)
set(icpc_req_path "/usr/local/bin/icpc-16.0.146")

set(CMAKE_CXX_COMPILER "${icpc_req_path}")

project("CMakeTest")
set(SOURCE_FILES a.cpp)

set (TARGET_NAME "TGT")
set(TARGETS "")
set(ARCHITECTURES i386 x86_64)

foreach(ar ${ARCHITECTURES})
    set(CMAKE_CXX_FLAGS_RELEASE "")
    set(CMAKE_CXX_FLAGS_DEBUG "")
    set(CMAKE_CXX_FLAGS "")

    add_library(TGT_${ar} SHARED ${SOURCE_FILES})
    set_target_properties(${TARGET_NAME}_${ar}
        PROPERTIES COMPILE_FLAGS "-arch ${ar} -xSSE3")
    set_target_properties(${TARGET_NAME}_${ar}
        PROPERTIES LINK_FLAGS "-arch ${ar}")
    set(TARGETS "${TARGETS};lib${TARGET_NAME}_${ar}.dylib")
endforeach(ar)

message("Targets: ${TARGETS}")
add_custom_target(${TARGET_NAME} DEPENDS ${TARGETS})
add_custom_command(TARGET ${TARGET_NAME} POST_BUILD
     COMMAND "lipo"
     ARGS "-create" ${TARGETS} "-output" "${TARGET_NAME}.dylib")

А содержимое a.cpp:

int main(){}

person gil_mo    schedule 06.05.2018    source источник
comment
Не могли бы вы пожалуйста улучшить вопрос, предоставив минимальный, полный и проверяемый пример? Чтобы правильно ответить на этот вопрос, я хотел бы знать, что такое ‹command› и почему существует зависимость от обеих целей.   -  person Unapiedra    schedule 07.05.2018
comment
Я добавил свой минимальный код.   -  person gil_mo    schedule 07.05.2018
comment
Я обновил свой ответ, чтобы он соответствовал вашему конкретному вопросу.   -  person Unapiedra    schedule 14.05.2018


Ответы (2)


add_custom_command бывает двух видов: создание нового продукта и действие на отдельные цели. Документы

Какую команду вы выполняете? Дает ли это каким-либо образом результат (новые файлы и т. Д.)? Если да, используйте add_custom_command следующим образом:

add_custom_command(
  OUTPUT <output-file>
  DEPENDS tgt1 tgt2
  COMMAND <command>
  ARGS <args>
  COMMENT "Running  <command> on targets tgt1 and tgt2."
)

Для использования второго варианта add_custom_command, который не имеет аргумента OUTPUT, поскольку он изменяет <target> на POST_BUILD (или предварительную сборку, предварительную ссылку), требуется одна цель. Итак, какой из tgt1 и tgt2 будет изменен вашим <command>?

Предположим, что tgt1 изменяется на шаге POST_BUILD, а tgt2 не изменяется. Тогда вы можете сделать это так:

add_library(tgt2 SHARED b.cpp)

add_library(tgt1 SHARED a.cpp)
add_custom_command(
  TARGET tgt1 POST_BUILD
  COMMAND <command>
  ARGS <args>
)
add_dependencies(tgt1 tgt2) # tgt1 depends on tgt2 because
# POST_BUILD-step is just the final step to build 'tgt1'
# NOTE: It is incorrect to modify 'tgt2' as POST_BUILD step for tgt1.
#       So this example expects no changes to tgt2 in add_custom_command.

- ИЗМЕНИТЬ после более подробной информации, указанной в вопросе:

Рабочий пример

CMakeLists.txt

# I don't have 'icpc' and could not find it easily available for macOS.
# Instead, let's create a file "TGT" where contents are the two hashes of the two
# libraries, like done in 'Th.Thielemann's answer.
cmake_minimum_required(VERSION 3.10)
project(q50198141)

add_library(Big SHARED library1.cpp)
add_library(Foo SHARED library2.cpp)

add_custom_command(OUTPUT combined
    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/combine.sh
    ARGS $<TARGET_FILE:Big> $<TARGET_FILE:Foo> combined
    DEPENDS Big Foo combine.sh
    COMMENT Build output 'combined'
)
add_custom_target(run_combined ALL DEPENDS combined)

combined.sh (Убедитесь, что это возможно!)

#!/bin/bash

# Hardcoded for q50198141    
# Args: In1 In2 Out
md5sum $1 $2 > $3
person Unapiedra    schedule 06.05.2018

Следующий пример мне подходит.

Две независимые друг от друга мишени. Одна настраиваемая цель, зависящая от обоих.

add_library(Big SHARED ${SOURCES_BIG})
add_library(Foo SHARED ${SOURCES_FOO})

add_custom_target(pack ALL
    COMMAND ${CMAKE_COMMAND} -E md5sum ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}Big${CMAKE_SHARED_LIBRARY_SUFFIX}
    COMMAND ${CMAKE_COMMAND} -E md5sum ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}Foo${CMAKE_SHARED_LIBRARY_SUFFIX}
    DEPENDS Big Foo
    COMMENT Build target pack
)

Примечание. Расчет хэша кода нужен только для того, чтобы показать, перестраиваются ли целевые объекты при изменениях или нет.

person Th. Thielemann    schedule 07.05.2018
comment
Пробовал, указав ВСЕ, вызывает эту ошибку: *** Нет правила, чтобы сделать цель <first target>', needed by ‹конечной целью› '. Останавливаться. - Во время процесса CMake. - person gil_mo; 08.05.2018
comment
@gil_mo Опубликованный пример у меня отлично работает! (Но это не полностью отвечает на ваш вопрос: вы хотите add_custom_command b / c, вам нужно произвести реальный результат.) - person Unapiedra; 14.05.2018