英文:
CMake: USES_TERMINAL argument in add_custom_command(TARGET) does not use console pool with Ninja
问题
在CMake中,如果我在使用add_custom_command
时使用USES_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上,如果有帮助的话。
更新:
关于此问题已提交错误报告:https://gitlab.kitware.com/cmake/cmake/-/issues/25040
英文:
In CMake, if I use add_custom_command
with USES_TERMINAL
in order to get a prompt for a user's password when running a command using sudo
, as seen in the following CMakeLists.txt snippet:
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
)
And then configure and build using Ninja:
$ cmake -G Ninja -B build
$ cmake --build build
The prompt for the user's password does not appear, and the build hangs. Looking at the resulting build.ninja
file, I would expect there to be a pool = console
setting for building my-app, but it's not present:
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
If I manually add pool = console
to that list, it properly prompts for the user's password when runnning the command.
I was able to get this to work in a more kludgey way using add_custom_target
, but I'd like to know why USES_TERMINAL
is not working as I interpret the documentation.
I'm using cmake version 3.24.1 and running on Ubuntu 22.04, if that helps.
Update:
Bug report submitted regarding this issue: https://gitlab.kitware.com/cmake/cmake/-/issues/25040
答案1
得分: 1
原来 USES_TERMINAL
从未打算在调用带有 TARGET
参数的 add_custom_command
时使用。
使自定义命令可用于终端的最佳方法是在添加自定义命令的目标上设置属性 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>)
另一个潜在的解决方法是使用带有 USES_TERMINAL
参数的 add_custom_target
,但这会导致命令在每次构建时执行,这可能是不希望的:
add_custom_target(
run_sudo_setcap
ALL
COMMAND sudo setcap cap_net_admin+eip $<TARGET_FILE:my-app>
DEPENDS my-app
USES_TERMINAL)
Solution 取自与此问题相关的错误报告中发布的建议: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
英文:
It turns out that USES_TERMINAL
was never intended to be used when calling add_custom_command
with TARGET
in its signature.
The best way to have the terminal available to the custom command is to set the property JOB_POOL_LINK
to console
on the target on which the custom command is being added:
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>)
One other potential workaround would be to use add_custom_target
with the USES_TERMINAL
parameter, but this results in undesirable behavior of the command being executed on every build:
add_custom_target(
run_sudo_setcap
ALL
COMMAND sudo setcap cap_net_admin+eip $<TARGET_FILE:my-app>
DEPENDS my-app
USES_TERMINAL)
Solution taken from the recommendation posted on the bug report related to this issue: https://gitlab.kitware.com/cmake/cmake/-/issues/25040#note_1381770
And note that the newest docs for CMake will no longer show USES_TERMINAL
as a supported parameter to the add_custom_command(TARGET)
command:
https://gitlab.kitware.com/cmake/cmake/-/merge_requests/8602
https://cmake.org/cmake/help/git-master/command/add_custom_command.html#build-events
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论