4

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)

user69453
  • 1,279
  • 1
  • 17
  • 43
wds
  • 31,873
  • 11
  • 59
  • 84

1 Answers1

3

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.

neuro
  • 14,948
  • 3
  • 36
  • 59