cmake,add_custom_command和来自不同目录的依赖关系 [英] cmake, add_custom_command with dependencies from a different directory
问题描述
我有一个关于CMake的问题,这似乎是常见的问题,但没有答案似乎解决我的问题。
在 details
子目录中,有一个 CMakeLists.txt
,其中包含:
add_custom_command(OUTPUT part.out
COMMAND foo --input = part.src --output = part.out
DEPENDS part.src)
add_custom_target(part_out
DEPENDS part.out)
在主目录中有一个 CMakeLists.txt
其使用 part.out
生成另一个文件:
add_custom_command(OUTPUT full.out
COMMAND bar --input =。/ details / part.out --output = full.out)
add_custom_target(full_out
DEPENDS full.out)
问题是我想要3件事发生在这里:
- 如果
part.out
不存在,生成 - 如果
part.out
已过期(part.src
是part.out
)我想要重新生成 - 如果
full.out
已过期(part.out
比full.out
或c> full.out
desn't exists)我想要它(重新)生成
如果我添加 DEPENDS ./details/part.out
到 add_custom_command(OUTPUT full.out)
和3,但不是第1点,因为如果我删除 part.out
然后调用 make full_out
得到一个错误,没有规则使 ./ detail / part.out
(因为它是来自另一个目录的规则)。
如果我将 DEPENDS full_out
添加到 add_custom_command(OUTPUT full.out)
或 add_custom_target(full_out)
我将实现点1和2,但不是3,因为即使 part.out
full.out
不会被重新生成,因为它不依赖于 part.out
文件本身。 p>
那么我该如何连接这两种情况呢?
我正在考虑添加 DEPENDS
,但我怎么知道这将总是工作?我的意思是在这种情况下,构建的顺序在这里。
CMake docs for add_custom_target
:
默认情况下,不依赖于自定义目标。使用ADD_DEPENDENCIES
向其他目标添加依赖项。
因此,我建议使用
ADD_DEPENDENCIES(full_out part_out)
b $ b
EDIT:
工作示例
结果是,您需要设置源文件属性 part.out
这是我的工作示例(在VS2008的Windows下试过):
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project
add_subdirectory(details)
add_custom_command(OUTPUT full.out
COMMAND $ {CMAKE_COMMAND} -E copy ./details/part.out full.out
DEPENDS details / part.out
)
add_custom_target(full_out
DEPENDS full.out details / part.out details / part.src
)
set_source_files_properties(details / part.out PROPERTIES GENERATED TRUE)
add_dependencies(full_out part_out)
详情/ CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project(part)
add_custom_command(OUTPUT part.out
COMMAND $ {CMAKE_COMMAND} -E copy $ {CMAKE_CURRENT_SOURCE_DIR} /part.src part.out
DEPENDS part.src)
add_custom_target(part_out
DEPENDS part.out)
这个例子适用于你所有的3种情况。
I have a question about CMake which seems to be commonly asked here, but none of the answers seem to solve my problem.
In the details
subdirectory, there is a CMakeLists.txt
which contains:
add_custom_command(OUTPUT part.out
COMMAND foo --input=part.src --output=part.out
DEPENDS part.src)
add_custom_target(part_out
DEPENDS part.out)
In the main directory there is a CMakeLists.txt
which uses part.out
for generating another file:
add_custom_command(OUTPUT full.out
COMMAND bar --input=./details/part.out --output=full.out)
add_custom_target(full_out
DEPENDS full.out)
The problem is that I want 3 things to happen here:
- if
part.out
doesn't exist it needs to be generated - if
part.out
is out of date (part.src
is newer thanpart.out
) I want it to be regenerated - if
full.out
is out of date (part.out
is newer thanfull.out
, orfull.out
desn't exist) I want it to be (re)generated
So if I add DEPENDS ./details/part.out
to add_custom_command(OUTPUT full.out)
I will achieve points 2 and 3, but not point 1, because if I delete part.out
and then I call make full_out
I'll get an error that there is no rule to make ./details/part.out
(as it is a rule from another directory).
If I add DEPENDS full_out
to add_custom_command(OUTPUT full.out)
or to add_custom_target(full_out)
I'll achieve points 1 and 2, but not 3, because even if part.out
was regenerated, a full.out
will not be regenerated, as it doesn't depend on the part.out
file itself.
So how can I connect both scenarios?
I was thinking about adding both DEPENDS
but how do I know if that will always work? I mean in such case the order of build will matter here.
CMake docs for add_custom_target
:
By default nothing depends on the custom target. Use ADD_DEPENDENCIES to add dependencies to or from other targets.
So I suggest to "connect" the targets with
ADD_DEPENDENCIES( full_out part_out )
EDIT: Working example
As it turned out, you need to set the source file properties for part.out
Here is my working example (tried under Windows with VS2008):
CMakeLists.txt:
cmake_minimum_required(VERSION 2.8 )
project( full )
add_subdirectory( details )
add_custom_command( OUTPUT full.out
COMMAND ${CMAKE_COMMAND} -E copy ./details/part.out full.out
DEPENDS details/part.out
)
add_custom_target( full_out
DEPENDS full.out details/part.out details/part.src
)
set_source_files_properties( details/part.out PROPERTIES GENERATED TRUE )
add_dependencies( full_out part_out )
details/CMakeLists.txt:
cmake_minimum_required(VERSION 2.8 )
project(part)
add_custom_command(OUTPUT part.out
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/part.src part.out
DEPENDS part.src)
add_custom_target(part_out
DEPENDS part.out)
This example worked for all of your 3 stated cases.
这篇关于cmake,add_custom_command和来自不同目录的依赖关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!