可以在CMake中的同一个自定义目标中为不同命令设置不同的工作目录吗?

huangapple go评论51阅读模式
英文:

Is it possible to have different working directories for various commands in the same custom target in CMake?

问题

我在尝试理解,是否可以为不同的命令指定多个工作目录?

我添加了一个名为run_projects的自定义目标:

add_custom_target(run_projects
    COMMAND first_project &
    COMMAND second_project
    COMMAND killall first_project &> /dev/null &
    COMMAND killall second_project &> /dev/null
    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)

它应该运行可执行项目:first_project + second_project
问题在于first_project的资源在根目录:${PROJECT_SOURCE_DIR},但second_project的资源在${PROJECT_SOURCE_DIR}/second_project中。

my_project:
    resources/ <- first_project外部apps/first_project目录的资源
    second_project/resources/ <- second_project目录中的资源

有没有可能仅通过CMake使其工作?

英文:

I'm trying to understand, is it possible to specify multiple working directories for different commands?

I added a custom target called run_projects:

add_custom_target(run_projects
    COMMAND first_project &amp;
    COMMAND second_project
    COMMAND killall first_project &amp;&gt; /dev/null &amp;
    COMMAND killall second_project &amp;&gt; /dev/null
    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
)

It should run executable projects: first_project + second_project.
The problem is resources of first_project in root directory:
${PROJECT_SOURCE_DIR}, but second_project resources is in ${PROJECT_SOURCE_DIR}/second_project

my_project:
    resources/ &lt;- resources of first_project outside apps/first_project dir
    second_project/resources/ &lt;- resources of second project inside second_project dir

Any chance to make it work via CMake only?

答案1

得分: 1

以下是翻译的部分:

至于文档,不。如文档中所述的命令签名是

add_custom_target(Name [ALL] [command1 [args1...]]
                  [COMMAND command2 [args2...] ...]
                  [DEPENDS depend depend depend ... ]
                  [BYPRODUCTS [files...]]
                  [WORKING_DIRECTORY dir]
                  [COMMENT comment]
                  [JOB_POOL job_pool]
                  [VERBATIM] [USES_TERMINAL]
                  [COMMAND_EXPAND_LISTS]
                  [SOURCES src1 [src2...]])

我建议将您正在进行的操作拆分为单独的自定义目标(或自定义命令,如果您不希望命令始终运行),然后使用DEPENDS字段或add_dependencies指定它们之间的依赖关系。这样,您可以为每个目标指定工作目录。

看起来您正在尝试使用类似Bash的后台运行操作符(&)的特定于shell的内容。如果将每个命令分别放入其自定义命令/目标中,只要您选择的构建系统生成器支持并行构建/运行目标,那么默认情况下就会获得您想要的,并且会自动实现跨平台(而不依赖于特定shell的语法)。


我在我的Ubuntu机器上进行了快速测试,使用Ninja和以下命令:

add_custom_target(
cd ALL
COMMAND pwd
COMMAND cd build
COMMAND pwd
COMMAND cd ..
COMMAND pwd
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)

CMake生成的运行命令为cd /home/david/code/mine/cmake-playground/16 && pwd && cd build && pwd && cd .. && pwd && echo hi,显示了在至少一个平台+生成器组合中在每个命令之间进行cd的可能性。

但是,您不应该依赖此行为。这是内部/实现细节。关于add_custom_targetCOMMAND参数的文档表示:

指定构建时要执行的命令行。如果指定了多个COMMAND,它们将按顺序执行,但不一定会组成有状态的shell或批处理脚本。 (要运行完整的脚本,请使用configure_file()命令或file(GENERATE)命令来创建它,然后指定COMMAND来启动它。)

英文:

As far as documentation goes, no. The command signature as documented is:

add_custom_target(Name [ALL] [command1 [args1...]]
                  [COMMAND command2 [args2...] ...]
                  [DEPENDS depend depend depend ... ]
                  [BYPRODUCTS [files...]]
                  [WORKING_DIRECTORY dir]
                  [COMMENT comment]
                  [JOB_POOL job_pool]
                  [VERBATIM] [USES_TERMINAL]
                  [COMMAND_EXPAND_LISTS]
                  [SOURCES src1 [src2...]])

I would split what you're doing into separate custom targets (or custom commands if you don't want the commands to always run), and specify the dependencies between them using the DEPENDS fields or add_dependencies. That way, you can specify the working directory for each one specifically.

It looks as though you're trying to use shell-specific things like Bash's run-in-background operator (&amp;). If you write your commands each in their own custom command / target, as long as the buildsystem generator you have chosen supports building/running targets in parallel, then you will get what you want by default, and it will be cross-platform automatically (instead of depending on the syntax of a specific shell).


I did do a quick test on my Ubuntu machine with Ninja and the following:

add_custom_target(
cd ALL
COMMAND pwd
COMMAND cd build
COMMAND pwd
COMMAND cd ..
COMMAND pwd
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)

, which CMake generates to run as cd /home/david/code/mine/cmake-playground/16 &amp;&amp; pwd &amp;&amp; cd build &amp;&amp; pwd &amp;&amp; cd .. &amp;&amp; pwd &amp;&amp; echo hi, which shows that it's possible to cd around places in between each command on at least one platform + generator combination.

But you shouldn't rely on this behaviour. It's an internal / implementation detail. The documentation for add_custom_target's COMMAND argument says:

> Specify the command-line(s) to execute at build time. If more than one COMMAND is specified they will be executed in order, but not necessarily composed into a stateful shell or batch script. (To run a full script, use the configure_file() command or the file(GENERATE) command to create it, and then specify a COMMAND to launch it.)

huangapple
  • 本文由 发表于 2023年4月1日 00:40:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75900870.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定