Search code examples
wafbuild-system

waf cross-project dependencies


I have a trivial waf project:

$ root
|-- a
|   `-- wscript
|-- b
|   `-- wscript
`-- wscript

Root wscript is

def configure(conf):
    pass

def build(bld):
    bld.recurse('a b')

a wscript is

def build(bld):
    bld (rule = 'touch ${TGT}', target = 'a.target' )

b wscript is

def build(bld):
    bld (rule = 'cp ${SRC} ${TGT}', source='a.target', target='b.target')

What I'm trying to achieve is have a build system that first touches a.target, then copies it to b.target. I want to have rules for a.target and b.target to stay in their respective wscript files.

When I'm trying to launch it, I get the following error instead:

source not found: 'a.target' in bld(target=['b.target'], idx=1, tg_idx_count=2, meths=['process_rule', 'process_source'], rule='cp ${SRC} ${TGT}', _name='b.target', source='a.target', path=/<skip>/waf_playground/b, posted=True, features=[]) in /<skip>/waf_playground/b

If I put both rules into a single wscript file, everything works like a charm.

Is there a way for a target to depend on a another target defined in other wscript?


Solution

  • When you specify source/target, that is expressed relative to the current wscript file.

    $ waf configure build
    ...
    source not found: 'a.target' in bld(source='a.target, ...)
    ...
    $ tree build
    build/
    ├── a
    │   └── a.target
    ...
    

    Knowing that, the fix is to refer to the a.target source file correctly in b/wscript:

    def build(bld):
        bld (rule = 'cp ${SRC} ${TGT}', source='../a/a.target', target='b.target')
    

    The task now correctly finds the source file:

    $ waf build
    Waf: Entering directory `.../build'
    [1/2] Creating build/a/a.target
    [2/2] Compiling build/a/a.target
    Waf: Leaving directory `.../build'
    'build' finished successfully (0.055s)
    $ tree build
    build/
    ├── a
    │   └── a.target
    ├── b
    │   └── b.target
    ...