1

I have a implement a custom C compiler tool, but at the last step (linking) I am struggling to get it working. The linker produces to output files, one is the binary, and the second one is some file with additional information.

Normally you would have a wscript with something like this:

def configure(cnf):
        cnf.load('my_compiler_c')
def build(bld):
        bld(features='c cprogram', source='main.c', target='app.bbin')

And I could fake a second target like this

class cprogram(link_task):
    run_str = (
        "${LINK_CC} ${CFLAGS} ${OTHERFLAGS} "
        "${INFO_FILE}${TGT[0].relpath()+'.abc'} "  # TGT[0] + some string concatenating will be the app.bbin.abc file
        "${CCLNK_TGT_F}${TGT[0].relpath()} "  # TGT[0] this is the app.bbin file
        "${CCLNK_SRC_F}${SRC} ${STLIB_MARKER} ${STLIBPATH_ST:STLIBPATH} "
        "${CSTLIB_ST:CSTLIB} ${STLIB_ST:STLIB} ${LIBPATH_ST:LIBPATH} ${LIB_ST:LIB} ${LDFLAGS}"
    )
    ext_out = [".bbin"]
    vars = ["LINKDEPS"]

But of course, with this hacky implementation waf does not know about the second target and rebuilds will not be triggered when app.bbin.abc is missing.

So how do I correctly pass two or more targets to the cprogram class?

wafwafwaf
  • 191
  • 9

1 Answers1

0

Well, you just have to tell waf that you need two targets:

def configure(cnf):
    cnf.load('my_compiler_c')
def build(bld):
    bld(features='c cprogram', source='main.c', target=['app.bbin', 'app.bbin.abc'])

As I suppose you dont want to type two targets, you can use an alias to build your task generator:

# Naive, non-tested code. 

from waflib.Configure import conf

@conf
def myprogram(bld, *k, **kw):

    kw['features'] = "c cprogram"
    add_my_abc_target_to_target(kw) # I'm lazy

    return bld(*k, **kw)

You call:

def build(bld):
    bld.myprogram(source='main.c', target='app.bbin')

Note: You can put all your code in a plugin, to have clean wscripts:

def configure(cnf):
    cnf.load('myprogram') # loads my_c_compiler and myprogram alias

def build(bld):
    bld.myprogram(source='main.c', target='app.bbin')
neuro
  • 14,948
  • 3
  • 36
  • 59
  • Your first idea I a tried and this is not good for 2 reasons: First you need to declare the target like this `target=[bld.path.find_or_declare("app.bbin"), bld.path.find_or_declare("app.bbin.abc")]` otherwise waf thinks you are passing only strings. I think this solution looks not good. Second waf does not hash the output of both files. So the first time on rebuild it builds `.abc again`, the next time it builds `.bbin` again etc. Your second answer, to be honest, I dont understand your implementation. What has to be done in `add_my_abc_target_to_target`? But anyway, thanks for you help sofar! – wafwafwaf Aug 21 '19 at 11:42