cmake,add_custom_command和来自不同目录的依赖关系 [英] cmake, add_custom_command with dependencies from a different directory

查看:524
本文介绍了cmake,add_custom_command和来自不同目录的依赖关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于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件事发生在这里:


  1. 如果 part.out 不存在,生成

  2. 如果 part.out 已过期( part.src part.out )我想要重新生成

  3. 如果 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:

  1. if part.out doesn't exist it needs to be generated
  2. if part.out is out of date (part.src is newer than part.out) I want it to be regenerated
  3. if full.out is out of date (part.out is newer than full.out, or full.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆