【问题标题】:cmake add_custom_command + Xcode: multi output = multi command invocationcmake add_custom_command + Xcode:多输出=多命令调用
【发布时间】:2020-09-20 01:53:25
【问题描述】:

我有自定义命令可以一次生成多个标题。 使用 cmake 生成的 make/ninja 文件一切正常。 但是如果我通过cmake -GXCode生成Xcode项目, 然后而不是一次 gen.sh 被调用 10 次 不仅如此,每次构建都会调用它, 即使生成文件的时间戳比 gen_in.txt 更年轻。

我该如何解决这个问题?

project(multi_output)
cmake_minimum_required(VERSION 3.17)

set(MANY_HEADERS test0.h test1.h  test2.h  test3.h  test4.h  test5.h  test6.h  test7.h  test8.h  test9.h)

add_custom_command(
  OUTPUT ${MANY_HEADERS}
  COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/gen.sh
  DEPENDS gen_in.txt
  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
  )

add_executable(foo main.cpp ${MANY_HEADERS})

gen.sh 在哪里

#!/bin/sh

echo "gen.sh: start"
sleep 1
echo "gen.sh: hard work done"
for i in `seq 0 9`; do
    cat gen_in.txt > test$i.h
    sed -i bak s/placeholder/$i/g test$i.h
done

【问题讨论】:

    标签: c++ c xcode macos cmake


    【解决方案1】:

    OUTPUT 选项中,相对路径被视为相对于二进制目录

    也就是说,您的 add_custom_command 实际上不会生成声明为​​ OUTPUT 的文件。

    这就是它被越来越多地调用的原因:构建工具发现一个 OUTPUT 文件不存在,并运行命令来构建该文件。 (许多构建工具不检查 OUTPUT 文件是否实际创建。)

    对于在源目录中创建的文件,您需要在OUTPUT选项中指定它们的绝对路径

    set(MANY_HEADERS test0.h test1.h  test2.h  test3.h  test4.h  test5.h  test6.h  test7.h  test8.h  test9.h)
    # This will be a list of _absolute paths_ to the headers
    set(MANY_HEADERS_ABS)
    
    foreach(HEADER ${MANY_HEADERS})
      list(APPEND MANY_HEADERS_ABS "${CMAKE_CURRENT_SOURCE_DIR}/${HEADER}")
    endforeach()
    
    add_custom_command(
      OUTPUT ${MANY_HEADERS_ABS}
      COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/gen.sh
      DEPENDS gen_in.txt
      WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
      )
    
    # In add_executable one could use relative paths too
    add_executable(foo main.cpp ${MANY_HEADERS})
    

    注意,add_executable 命令可以接受源代码树和二叉树中文件的相对路径

    CMake 检查源代码树中是否存在或生成文件(例如使用add_custom_command),如果是,则使用源路径。然后对二叉树执行类似的检查。 (如果此检查失败,CMake 将发出错误)。


    实际上,仔细检查make 输出可能会给出提示,make 是在 source 树中还是在 build 树中重建文件。

    这是由原始代码生成的(记住:make 是从 build 目录调用的):

    [ 33%] Generating test0.h, test1.h, test2.h, test3.h, test4.h, test5.h, test6.h, test7.h, test8.h, test9.h
    

    这就是使用源树的绝对路径时产生的结果。 (源码外构建,使用build/子目录进行构建。)

    [ 33%] Generating ../test0.h, ../test1.h, ../test2.h, ../test3.h, ../test4.h, ../test5.h, ../test6.h, ../test7.h, ../test8.h, ../test9.h
    

    【讨论】:

      猜你喜欢
      • 2014-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多