Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In waf, how do I define a dependency on a generated header from another subdir

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)

like image 992
wds Avatar asked Oct 15 '25 14:10

wds


1 Answers

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.

like image 70
neuro Avatar answered Oct 17 '25 02:10

neuro