【问题标题】:CMake custom target doesn't buildCMake 自定义目标不构建
【发布时间】:2018-05-06 09:20:10
【问题描述】:

我正在使用以下方法构建两个目标:

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 包含自定义命令。

尝试将 ALL 用于自定义目标,但尝试先构建它却错过了第一个目标。

我不能将 add_library 或 add_executable 用于最终目标,因为它们需要指定源文件。

正确的做法是什么?

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

编辑:下面是一个最小的可验证源代码。 它试图做的是在两种架构中编译代码(对于 Mac),并作为后期构建使用 lipo 创建通用二进制文件:

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(){}

【问题讨论】:

  • 您能否通过提供Minimal, Complete and Verifiable 示例来改进问题?为了正确回答这个问题,我想知道 是什么,以及为什么依赖于两个目标。
  • 我已经添加了我的最小代码。
  • 我已经更新了我的答案以适合您的具体问题。

标签: cmake post-build


【解决方案1】:

add_custom_command 有两种形式:产生新的输出和作用于单一目标。 Docs

你调用的命令是什么?它是否以任何方式产生结果(新文件等)?如果是这样,请像这样使用add_custom_command

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

使用没有OUTPUT 参数的add_custom_command 的第二个变体,因为它将&lt;target&gt; 更改为POST_BUILD(或预构建、预链接)步骤,需要一个目标。那么,tgt1tgt2 中的哪一个被您的&lt;command&gt; 修改?

让我们假设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

【讨论】:

    【解决方案2】:

    以下示例适用于我。

    两个相互独立的目标。一个自定义目标取决于两者。

    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
    )
    

    注意:计算代码的哈希值只是为了显示目标是否在更改时重建。

    【讨论】:

    • 试过了,指定 ALL 会导致这个错误:*** No rule to make target &lt;first target&gt;', needed by '。停止。 - 在 CMake 过程中。
    • @gil_mo 发布的示例对我来说很好用! (但它并没有完全回答你的问题:你想要add_custom_command b/c 你需要产生一个真实的输出。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 2021-04-17
    相关资源
    最近更新 更多