【问题标题】:add_custom_command depending on another add_custom_commandadd_custom_command 取决于另一个 add_custom_command
【发布时间】:2016-12-02 10:39:22
【问题描述】:

我们有两个add_custom_command 子句,其中一个依赖于另一个:

  1. 第一个命令使用oslc 编译器将.osl 源文件编译成.oso 目标文件:

    set (oslc ${PROJECT_SOURCE_DIR}/sandbox/bin/oslc)
    
    add_custom_command (
        OUTPUT "${oso_dir}/${oso_filename}"
        COMMAND ${CMAKE_COMMAND} -E make_directory "${oso_dir}"
        COMMAND "${oslc}" -I"${osl_include_path}" -o "${oso_dir}/${oso_filename}" "${osl_src_abs}"
        MAIN_DEPENDENCY ${osl_src_abs}
        DEPENDS ${${headers}} ${osl_src_abs} "${oslc}"
    )
    

    注意对${oslc} 的依赖:我们显式依赖${oslc},因为我们需要确保它存在才能执行此命令。

  2. 第二个命令“构建”(实际上,部署oslc 编译器,方法是从其他地方复制它:

    add_custom_command (
        OUTPUT "${PROJECT_SOURCE_DIR}/sandbox/bin/oslc"
        COMMAND ${CMAKE_COMMAND} -E copy ${OSL_COMPILER} ${PROJECT_SOURCE_DIR}/sandbox/bin/
    )
    

虽然此设置有效,但它的副作用是两个命令总是执行(第二个命令后跟第一个命令)即使.osl 输入文件未被修改。

似乎这种行为是特定于 Windows 的。它似乎在 Linux 上运行良好。

如果从第一个命令中删除了对${oslc} 的依赖,则根本不再执行第二个命令,即使在缺少oslc 编译器的情况下也是如此;但另一方面,.osl 文件现在仅在自上次构建后根据需要发生更改时才重新编译(只要存在oslc)。

这个设置有什么问题吗?如果没有,结合这两个功能的正确方法是什么:编译.osl 文件最后一次构建,并在 oslc 编译器(第一步需要)还不存在时“构建”它?

GitHub 上提供了实际的 CMake 脚本:

【问题讨论】:

  • 我希望第二个命令也有一个DEPENDS。它应该取决于第一个命令的一些输出。你必须弄清楚为什么第一个命令总是构建。为什么要使用 MAIN_DEPENDENCY?为什么有一个 DEPENDS 引号的参数?
  • oslc 是一个可执行文件,对吧?你不应该依赖它,你应该检查它(FindOslc 或类似的),然后将整个 add_custom_command 包装在 OSCL_FOUND 中。
  • @usr1234567 第二个命令没有DEPENDS,因为它不依赖任何东西。它只需要在输出(oslc 编译器)丢失时运行。它用引号括起来,因为在 Windows 上,oslc 的完整路径可能包含空格。
  • It seems that this behavior is specific to Windows. - 在 which generator (Visual Studio, NMake) 下您观察到了这种行为?只是一个猜测:对应于这个生成器的构建工具不理解没有依赖关系的命令,并将它们视为 CMake target (始终构建)。在第二个命令中添加DEPENDS ${OSL_COMPILER} 应该会有所帮助。 (而不是${OSL_COMPILER} 可以是任何从未修改过的源文件)。
  • @Tsyvarev 使用Visual Studio 14 2015 Win64 生成器可以观察到这种行为。我会尝试你的建议并在这里报告。谢谢!

标签: cmake cmake-custom-command


【解决方案1】:

至少对于 Windows 而言,一个简单的解决方案是将第二个命令更改为

add_custom_command (
    TARGET appleseed.shaders
    PRE_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy ${OSL_COMPILER} ${PROJECT_SOURCE_DIR}/sandbox/bin/
)

(注意PRE_BUILD 关键字)

并从第一个命令中删除对${oslc} 的显式依赖。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多