【问题标题】:How do I run a python script every time in a CMake build?如何每次在 CMake 构建中运行 python 脚本?
【发布时间】:2018-03-01 15:51:00
【问题描述】:

目前我需要每次在 CMake 中运行一个 Python 脚本,它会生成一个 .qrc 文件。我不能使用 Qt Designer,我必须使用 CMake。 正在使用 set(CMAKE_AUTORCC ON) 并且每当添加资源或更改名称时都会失败,这就是 python 脚本的原因。脚本本身已经生成输出,之后一切正常,所以我不需要 CMake 本身的输出。我目前尝试了以下方法:

include(FindPythonInterp)
set (py_cmd "QRC_Updater.py")
execute_process(
                  COMMAND ${PYTHON_EXECUTABLE} ${py_cmd}
                  WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
                  RESULT_VARIABLE py_result
               )
message(STATUS "Python result: ${py_result})

它可以工作,但不是每次都执行。仅在修改 CMakeLists.txt 时执行。

所以经过一番搜索,人们建议使用

add_custom_target(...)

add_custom_command(...)

我也试过这个:

add_custom_target(
   always_run_target ALL
   DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/__header.h
   )

add_custom_command(
    OUTPUT
        ${CMAKE_CURRENT_BINARY_DIR}/__header.h
        ${CMAKE_CURRENT_BINARY_DIR}/header.h
    COMMAND ${PYTHON_EXECUTABLE} ${py_cmd}
    )

它根本不运行脚本。我知道它没有运行脚本,因为我在 Notepad++ 中打开了文件,并且它不会像 execute_process() 运行后那样询问我是否要切换到文件的较新版本。 add_custom_command() 的其他变体也不会运行该脚本。没有与此运行相关的错误,除非我不包含 ${PYTHON_EXECUTABLE} 导致“%1 不是有效的 Win32 命令”。那么如何才能有效地让 Python 脚本在 CMake 中每次都运行呢?

编辑: 这里的答案不起作用。 How to always run command when building regardless of any dependency?

【问题讨论】:

  • 也许你在add_custom_command 中也需要WORKING_DIRECTORY
  • 我实际上在 add_custom_command 中使用了 WORKING_DIRECTORY 并以相同的结果结束。脚本永远不会运行。
  • 这个答案 - stackoverflow.com/a/43206544/3440745 - 似乎是实现目标的最优雅方式,不知道为什么它不是得分最高的答案。
  • @Tsyvarev 我也试过那个。脚本永远不会运行。如果您查看 cmets,它会显示我已经尝试过的内容,几乎是逐字记录。该问题的 OP 还说它不能可靠地工作。

标签: cmake cmake-custom-command


【解决方案1】:

您需要向自定义命令添加依赖项以检查 OriginalHeader.h 上的更改,并在更改时重新生成 __header.h 和 header.h。

add_executable(MyExe main.cpp ${CMAKE_CURRENT_BINARY_DIR}/__header.h)

add_custom_target(
        always_run_target ALL
        DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/__header.h
)

add_custom_command(
        OUTPUT
            ${CMAKE_CURRENT_BINARY_DIR}/__header.h
            ${CMAKE_CURRENT_BINARY_DIR}/header.h
        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/OriginalHeader.h
        COMMAND python ${py_cmd}
)

我只用 python 更改了 ${PYTHON_EXECUTABLE}。 每次在 OriginalHeader.h 或 __header.h/header.h 中检测到更改时,我都能够运行此打印、创建目录并生成两个文件 __header.h 和 header.h 的 python 脚本(如下)还存在。

import os

print("TEST")

if not os.path.exists("TESTDIR"):
    os.makedirs("TESTDIR")
with open("header.h", 'w+'):
    os.utime("header.h", None)

【讨论】:

  • 我不需要由此创建的可执行文件,我只需要每次运行我的 Python 脚本。 __header.h 是一个伪造的文件,用来欺骗 CMake 每次都运行,而 header.h 是一个我不关心的文件,因为 Python 脚本创建了我需要的一切。我很抱歉没有具体说明这一点。我不能依赖检测到的更改,因为人们不应该直接更改 .qrc 文件。每当构建项目以考虑添加、删除和名称更改时,都需要由脚本创建它。
  • 好的,为什么自定义命令应该输出 __header.h ?它应该取决于它吗?没有
  • 从我现在看到的情况来看,如果 __header.h 和 header.h,不存在并且不会在第一次构建项目时,它应该调用 python 脚本。在 custom_command 中添加依赖应该会触发,__header.h 和 header.h 的重新生成,以及对 python 脚本的新调用。
  • 这是我用来欺骗 CMake 每次都运行该命令的示例的一部分。如果您查看我提供的链接并转到 ideaman42 的答案,它会解释。
  • 你觉得你的剧本还好吗?因为,对我来说,上面的代码有效,每次我在自定义命令上使用或不使用 DEPENDS 关键字重建项目时。我正在使用 CMake 3.3.2
猜你喜欢
  • 2017-10-07
  • 1970-01-01
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
相关资源
最近更新 更多