I am trying to get waf to generate header files generated by a task chain and pick up on them automatically using the c preprocessor's scan
function.
Here is an example project. Some files get generated in the project's gen
directory, to be used in the project's `prog' directory.
The layout:
├── gen
│ ├── test.txt
│ └── wscript
├── prog
│ ├── main.c
│ └── wscript
├── waf
└── wscript
The generation of the .h
file happens through a task chain declared in the top-level file:
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'])
In gen, all we need is to define build
as bld(source = 'test.txt', target='test.h')
.
In prog, we build a program and only set the include path, don't mention test.h
directly (main.c
includes test.h
):
def build(bld):
includes = [ bld.path.parent.find_dir('gen').get_bld().abspath() ]
bld.program(source = 'main.c', target = 'prog', includes = includes)
When I run waf
at the top level, everything works as expected. When I run it from the prog
directory though, it never triggers the creation of test.h
. I was under the impression that the c preprocessor from scan shouldn't run until all nodes are created, but it seems if I run from the prog
directory, waf
doesn't know about these generated headers, even though they are defined as targets in the other directory's wscript
file.
[edit: This makes some amount of sense I just realized - when running from top level it will schedule building the headers, and then dependencies will resolve fine. Waf does not seem to have a list of items that "could be built, if needed"]
There are some workarounds, such as using name
and adding a use = ...
directive in the C file wscript. Is there a way. though, to make it work automatically? It seems waf
should have all the information it needs to make it work automatically.
(tested with waf 1.7.8 and 2.0.8)
When you launch waf in a subdirectory, it only posts the task generator defined in the subtree. This is to allow partial builds. waf know of your dependencies scanning includes in your C files, but as includes can be system includes, that does not trigger anything. To trigger a task generator in another part of your tree, the best thing to do is use =
, in my opinion that's the best way. You can also go for using:
bld.program(source = ["main.c", "../gen/test.h"], ...)
but I find it less modular.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With