如何在cmake中构建目标的开始和结束时调用功能

发布于 2025-02-11 08:25:25 字数 164 浏览 1 评论 0原文

我正在寻找一种在启动和完成CMAKE目标构建时执行Shell代码的方法。最终目标是向数据跟踪工具发送消息,以指示何时构建开始和完成。

因此,例如,如果“制作”构建目标Alpha,Beta和Gamma,那么当Alpha成功构建目标Alpha时,我想致电foo_begin()。

这可能吗?

I'm looking for a way to execute shell code when starting and finishing the build of a target in cmake. The final goal is to send a message to a data tracking tool indicating when builds start and finish.

So for example, if "make" build targets alpha, beta and gamma, I'd like to call foo_begin() when alpha starts building and foo_end when target alpha is successfully built, and so on for all the targets.

Is this possible?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

垂暮老矣 2025-02-18 08:25:25

不是可以在构建时间调用任意CMAKE功能。生成构建系统后,所有正常变量状态和功能定义都将丢弃(即它们不在缓存中)。 命令参数到add_custom_command获取shell命令,而不是cmake函数。

但是,您可以使用Cmake的脚本模式,因此,如果您想要的是将CMake用作脚本语言只是为了实现一些构建钩子,则可以执行此操作:

让我们创建一个称为proc_target.cmake.cmake.cmake With With With这些内容:

cmake_minimum_required(VERSION 3.23)

if (PRE_BUILD)
  message(STATUS "PRE_BUILD: ${TARGET}")
else ()
  message(STATUS "POST_BUILD: ${TARGET}")
endif ()

现在在cmakelists.txt中,我们可以写:

cmake_minimum_required(VERSION 3.23)
project(example)

add_executable(foo main.cpp)

add_custom_command(
  TARGET foo PRE_BUILD
  COMMAND "${CMAKE_COMMAND}"
          -DTARGET=foo
          -DPRE_BUILD=1
          -P "${CMAKE_CURRENT_SOURCE_DIR}/proc_target.cmake"
)

add_custom_command(
  TARGET foo POST_BUILD
  COMMAND "${CMAKE_COMMAND}"
          -DTARGET=foo
          -DPRE_BUILD=0
          -P "${CMAKE_CURRENT_SOURCE_DIR}/proc_target.cmake"
)

然后,当您运行此构建时,您会看到以下命令:

$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release
...
$ cmake --build build -- -nv
[1/2] /usr/bin/c++   -O3 -DNDEBUG -MD -MT CMakeFiles/foo.dir/main.cpp.o -MF CMakeFiles/foo.dir/main.cpp.o.d -o CMakeFiles/foo.dir/main.cpp.o -c /path/to/main.cpp
[2/2] cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=1 -P /path/to/proc_target.cmake && cd /path/to/build && /usr/bin/c++ -O3 -DNDEBUG  CMakeFiles/foo.dir/main.cpp.o -o foo   && cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=0 -P /path/to/proc_target.cmake

您可以看到proc_target.cmake.cmake被调用两次:一次调用foo的链接器后。如果要在编译任何源之前运行proc_target,则要编写:

add_custom_command(
  OUTPUT pre-foo.stamp
  COMMAND "${CMAKE_COMMAND}"
          -DTARGET=foo
          -DPRE_BUILD=1
          -P "${CMAKE_CURRENT_SOURCE_DIR}/proc_target.cmake"
  COMMAND "${CMAKE_COMMAND}" -E touch pre-foo.stamp
  DEPENDS "
lt;TARGET_PROPERTY:foo,SOURCES>"
)
add_custom_target(pre-foo DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pre-foo.stamp")
add_dependencies(foo pre-foo)

而不是上面的pre_build自定义命令。然后,您将获得:

[1/3] cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=1 -P /path/to/proc_target.cmake
[2/3] /usr/bin/c++   -O3 -DNDEBUG -MD -MT CMakeFiles/foo.dir/main.cpp.o -MF CMakeFiles/foo.dir/main.cpp.o.d -o CMakeFiles/foo.dir/main.cpp.o -c /path/to/main.cpp
[3/3] : && /usr/bin/c++ -O3 -DNDEBUG  CMakeFiles/foo.dir/main.cpp.o -o foo   && cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=0 -P /path/to/proc_target.cmake

现在您可以看到自定义目标pre-foo是在foo之前处理的。

但是,这很可能不是您想要的。它是过度设计的。如果要为目标生成源文件,则应直接使用add_custom_command(outption)直接将输出连接到目标(即,当您调用add_executable 或通过target_sources)。

It is not possible to call arbitrary CMake functions at build time. Once the build system is generated, all the normal variable state and function definitions are discarded (i.e. they are not in cache). The COMMAND argument to add_custom_command takes a shell command, not a CMake function.

However, you can use CMake's script mode, so if what you want is to use CMake as a scripting language just to implement some build hooks, you can do this:

Let's create a file called proc_target.cmake with these contents:

cmake_minimum_required(VERSION 3.23)

if (PRE_BUILD)
  message(STATUS "PRE_BUILD: ${TARGET}")
else ()
  message(STATUS "POST_BUILD: ${TARGET}")
endif ()

Now in the CMakeLists.txt we can write:

cmake_minimum_required(VERSION 3.23)
project(example)

add_executable(foo main.cpp)

add_custom_command(
  TARGET foo PRE_BUILD
  COMMAND "${CMAKE_COMMAND}"
          -DTARGET=foo
          -DPRE_BUILD=1
          -P "${CMAKE_CURRENT_SOURCE_DIR}/proc_target.cmake"
)

add_custom_command(
  TARGET foo POST_BUILD
  COMMAND "${CMAKE_COMMAND}"
          -DTARGET=foo
          -DPRE_BUILD=0
          -P "${CMAKE_CURRENT_SOURCE_DIR}/proc_target.cmake"
)

Then when you run this build, you'll see the following commands:

$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release
...
$ cmake --build build -- -nv
[1/2] /usr/bin/c++   -O3 -DNDEBUG -MD -MT CMakeFiles/foo.dir/main.cpp.o -MF CMakeFiles/foo.dir/main.cpp.o.d -o CMakeFiles/foo.dir/main.cpp.o -c /path/to/main.cpp
[2/2] cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=1 -P /path/to/proc_target.cmake && cd /path/to/build && /usr/bin/c++ -O3 -DNDEBUG  CMakeFiles/foo.dir/main.cpp.o -o foo   && cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=0 -P /path/to/proc_target.cmake

You can see how proc_target.cmake is called twice: once just before and once just after invoking the linker for foo. If you want proc_target to run before any of the sources are compiled, then you would want to write:

add_custom_command(
  OUTPUT pre-foo.stamp
  COMMAND "${CMAKE_COMMAND}"
          -DTARGET=foo
          -DPRE_BUILD=1
          -P "${CMAKE_CURRENT_SOURCE_DIR}/proc_target.cmake"
  COMMAND "${CMAKE_COMMAND}" -E touch pre-foo.stamp
  DEPENDS "
lt;TARGET_PROPERTY:foo,SOURCES>"
)
add_custom_target(pre-foo DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/pre-foo.stamp")
add_dependencies(foo pre-foo)

instead of the PRE_BUILD custom command above. Then you would get:

[1/3] cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=1 -P /path/to/proc_target.cmake
[2/3] /usr/bin/c++   -O3 -DNDEBUG -MD -MT CMakeFiles/foo.dir/main.cpp.o -MF CMakeFiles/foo.dir/main.cpp.o.d -o CMakeFiles/foo.dir/main.cpp.o -c /path/to/main.cpp
[3/3] : && /usr/bin/c++ -O3 -DNDEBUG  CMakeFiles/foo.dir/main.cpp.o -o foo   && cd /path/to/build && /usr/bin/cmake -DTARGET=foo -DPRE_BUILD=0 -P /path/to/proc_target.cmake

And now you can see that the custom target pre-foo is processed before foo.

This is most likely not what you want, however. It's over-engineered. If you want to generate a source file for a target, you should use add_custom_command(OUTPUT) directly and attach the output to the target as a source file (i.e. when you call add_executable or via target_sources).

衣神在巴黎 2025-02-18 08:25:25

PER @botje的评论,似乎我需要cmake的add_custom_command with Build Event指定。但是,我将需要pre_build,该文档告诉我,这仅适用于VS-Studio,而我正在建造CMAKE&海湾合作委员会因此,我想我有一个新问题:如何在CMAKE/GCC构建环境中复制PRE_BUILD的行为。

Per @botje's comment, it seems I need cmake's add_custom_command with build event specifies. I will however need PRE_BUILD, which the documentation informs me is only available for vs-studio, while I am building use cmake & gcc. So I guess I have a new question: how to duplicate the behavior of PRE_BUILD in a cmake/gcc build environment.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文