CMake:add_custom_command(TARGET)中的USES_TERMINAL参数未将控制台池与Ninja一起使用

falq053o  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(126)

在CMake中,如果我使用add_custom_commandUSES_TERMINAL,以便在使用sudo运行命令时获得用户密码提示,如以下CMakeLists.txt片段所示:

add_executable(my-app main.c)

add_custom_command(
    TARGET my-app
    POST_BUILD
    COMMAND sudo setcap cap_net_admin+eip $<TARGET_FILE:my-app>
    USES_TERMINAL
)

字符串
然后使用Ninja进行配置和构建:

$ cmake -G Ninja -B build
$ cmake --build build


不出现输入用户密码的提示,生成挂起。查看生成的build.ninja文件,我希望有一个用于构建my-app的pool = console设置,但它不存在:

build my-app: C_EXECUTABLE_LINKER__my-app_ CMakeFiles/my-app.dir/main.c.o
  OBJECT_DIR = CMakeFiles/my-app.dir
  POST_BUILD = cd /home/bob/test_cmake_uses_terminal/build && sudo setcap cap_net_admin+eip /home/bob/test_cmake_uses_terminal/build/my-app
  PRE_LINK = :
  TARGET_COMPILE_PDB = CMakeFiles/my-app.dir/
  TARGET_FILE = my-app
  TARGET_PDB = my-app.pdb


如果我手动将pool = console添加到该列表中,它会在运行命令时正确提示输入用户密码。
我能够用add_custom_target以一种更笨拙的方式来实现这一点,但我想知道为什么在解释文档时USES_TERMINAL不能工作。
我使用的是cmake版本3.24.1,运行在Ubuntu 22.04上,如果这有帮助的话。
更新:
提交了关于此问题的Bug报告:https://gitlab.kitware.com/cmake/cmake/-/issues/25040

ni65a41a

ni65a41a1#

结果表明,在调用签名中包含TARGETadd_custom_command时,USES_TERMINAL从未打算被使用。
使终端可用于自定义命令的最佳方法是在要添加自定义命令的目标上将属性JOB_POOL_LINK设置为console

set_property(TARGET my-app PROPERTY JOB_POOL_LINK console)
add_custom_command(
    TARGET my-app
    POST_BUILD
    COMMAND sudo setcap cap_net_admin+eip $<TARGET_FILE:my-app>)

字符串
另一种可能的解决方法是使用add_custom_targetUSES_TERMINAL参数,但这会导致在每次构建时执行命令的不良行为:

add_custom_target(
    run_sudo_setcap
    ALL
    COMMAND sudo setcap cap_net_admin+eip $<TARGET_FILE:my-app>
    DEPENDS my-app
    USES_TERMINAL)


解决方案取自与此问题相关的错误报告中发布的建议:https://gitlab.kitware.com/cmake/cmake/-/issues/25040#note_1381770
请注意,CMake的最新文档将不再显示USES_TERMINAL作为add_custom_command(TARGET)命令的支持参数:
https://gitlab.kitware.com/cmake/cmake/-/merge_requests/8602
https://cmake.org/cmake/help/git-master/command/add_custom_command.html#build-events

相关问题