在 waf 中,如何定义对另一个子目录生成的 header 的依赖
In waf, how do I define a dependency on a generated header from another subdir
我正在尝试让 waf 生成由任务链生成的 header 文件,并使用 c 预处理器的 scan
函数自动获取它们。
这是一个示例项目。一些文件在项目的 gen
目录中生成,用于项目的 `prog' 目录。
布局:
├── gen
│ ├── test.txt
│ └── wscript
├── prog
│ ├── main.c
│ └── wscript
├── waf
└── wscript
.h
文件的生成是通过 top-level 文件中声明的任务链进行的:
top = '.'
def configure(cfg):
cfg.load('compiler_c')
def build(bld):
from waflib import TaskGen
TaskGen.declare_chain(name = 'int',
rule = 'cat ${SRC} > ${TGT}',
ext_in = '.txt', ext_out = '.int')
TaskGen.declare_chain(name = 'inttoh',
rule = 'cat ${SRC} > ${TGT}',
ext_in = '.int', ext_out = '.h')
bld.recurse(['prog', 'gen'])
在gen中,我们只需要将build
定义为bld(source = 'test.txt', target='test.h')
即可。
在prog中,我们建一个程序只设置include路径,不要直接提到test.h
(main.c
包括test.h
):
def build(bld):
includes = [ bld.path.parent.find_dir('gen').get_bld().abspath() ]
bld.program(source = 'main.c', target = 'prog', includes = includes)
当我 运行 waf
在顶层时,一切都按预期进行。但是,当我从 prog
目录中 运行 它时,它永远不会触发 test.h
的创建。我的印象是,在创建所有节点之前,来自扫描的 c 预处理器不应该 运行,但似乎如果我从 prog
目录中 运行,waf
不会不知道这些生成的 headers,即使它们被定义为其他目录的 wscript
文件中的目标。
[编辑:我刚刚意识到,这在一定程度上是有道理的——当从顶层 运行ning 时,它将安排构建 headers,然后依赖关系将很好地解决。 Waf 似乎没有 "could be built, if needed"]
的项目列表
有一些解决方法,例如使用 name
并在 C 文件 wscript 中添加 use = ...
指令。有没有办法。但是,让它自动工作?似乎 waf
应该拥有让它自动运行所需的所有信息。
(使用 waf 1.7.8 和 2.0.8 测试)
当您在子目录中启动 waf 时,它只会发布在子目录中定义的任务生成器。这是为了允许部分构建。 waf 知道您的依赖项扫描包含在您的 C 文件中,但由于包含可以是系统包含,因此不会触发任何内容。要在树的另一部分触发任务生成器,最好的办法是 use =
,我认为这是最好的方法。你也可以去使用:
bld.program(source = ["main.c", "../gen/test.h"], ...)
但我发现它不够模块化。
我正在尝试让 waf 生成由任务链生成的 header 文件,并使用 c 预处理器的 scan
函数自动获取它们。
这是一个示例项目。一些文件在项目的 gen
目录中生成,用于项目的 `prog' 目录。
布局:
├── gen
│ ├── test.txt
│ └── wscript
├── prog
│ ├── main.c
│ └── wscript
├── waf
└── wscript
.h
文件的生成是通过 top-level 文件中声明的任务链进行的:
top = '.'
def configure(cfg):
cfg.load('compiler_c')
def build(bld):
from waflib import TaskGen
TaskGen.declare_chain(name = 'int',
rule = 'cat ${SRC} > ${TGT}',
ext_in = '.txt', ext_out = '.int')
TaskGen.declare_chain(name = 'inttoh',
rule = 'cat ${SRC} > ${TGT}',
ext_in = '.int', ext_out = '.h')
bld.recurse(['prog', 'gen'])
在gen中,我们只需要将build
定义为bld(source = 'test.txt', target='test.h')
即可。
在prog中,我们建一个程序只设置include路径,不要直接提到test.h
(main.c
包括test.h
):
def build(bld):
includes = [ bld.path.parent.find_dir('gen').get_bld().abspath() ]
bld.program(source = 'main.c', target = 'prog', includes = includes)
当我 运行 waf
在顶层时,一切都按预期进行。但是,当我从 prog
目录中 运行 它时,它永远不会触发 test.h
的创建。我的印象是,在创建所有节点之前,来自扫描的 c 预处理器不应该 运行,但似乎如果我从 prog
目录中 运行,waf
不会不知道这些生成的 headers,即使它们被定义为其他目录的 wscript
文件中的目标。
[编辑:我刚刚意识到,这在一定程度上是有道理的——当从顶层 运行ning 时,它将安排构建 headers,然后依赖关系将很好地解决。 Waf 似乎没有 "could be built, if needed"]
的项目列表有一些解决方法,例如使用 name
并在 C 文件 wscript 中添加 use = ...
指令。有没有办法。但是,让它自动工作?似乎 waf
应该拥有让它自动运行所需的所有信息。
(使用 waf 1.7.8 和 2.0.8 测试)
当您在子目录中启动 waf 时,它只会发布在子目录中定义的任务生成器。这是为了允许部分构建。 waf 知道您的依赖项扫描包含在您的 C 文件中,但由于包含可以是系统包含,因此不会触发任何内容。要在树的另一部分触发任务生成器,最好的办法是 use =
,我认为这是最好的方法。你也可以去使用:
bld.program(source = ["main.c", "../gen/test.h"], ...)
但我发现它不够模块化。