1# waf build tool for building IDL files with pidl 2 3import os 4from waflib import Build, Utils 5from waflib.TaskGen import feature, before 6from samba_utils import SET_TARGET_TYPE, TO_LIST, LOCAL_CACHE 7 8def SAMBA_PIDL(bld, pname, source, 9 options='', 10 output_dir='.', 11 generate_tables=True): 12 '''Build a IDL file using pidl. 13 This will produce up to 13 output files depending on the options used''' 14 15 bname = source[0:-4]; # strip off the .idl suffix 16 bname = os.path.basename(bname) 17 name = "%s_%s" % (pname, bname.upper()) 18 19 if not SET_TARGET_TYPE(bld, name, 'PIDL'): 20 return 21 22 bld.SET_BUILD_GROUP('build_source') 23 24 # the output files depend on the options used. Use this dictionary 25 # to map between the options and the resulting file names 26 options_map = { '--header' : '%s.h', 27 '--ndr-parser' : 'ndr_%s.c ndr_%s.h', 28 '--samba3-ndr-server' : 'srv_%s.c srv_%s.h', 29 '--samba3-ndr-client' : 'cli_%s.c cli_%s.h', 30 '--server' : 'ndr_%s_s.c', 31 '--client' : 'ndr_%s_c.c ndr_%s_c.h', 32 '--python' : 'py_%s.c', 33 '--tdr-parser' : 'tdr_%s.c tdr_%s.h', 34 '--dcom-proxy' : '%s_p.c', 35 '--com-header' : 'com_%s.h' 36 } 37 38 table_header_idx = None 39 out_files = [] 40 options_list = TO_LIST(options) 41 42 for o in options_list: 43 if o in options_map: 44 ofiles = TO_LIST(options_map[o]) 45 for f in ofiles: 46 out_files.append(os.path.join(output_dir, f % bname)) 47 if f == 'ndr_%s.h': 48 # remember this one for the tables generation 49 table_header_idx = len(out_files) - 1 50 51 # depend on the full pidl sources 52 source = TO_LIST(source) 53 try: 54 pidl_src_nodes = bld.pidl_files_cache 55 except AttributeError: 56 bld.pidl_files_cache = bld.srcnode.ant_glob('pidl/lib/Parse/**/*.pm', flat=False) 57 bld.pidl_files_cache.extend(bld.srcnode.ant_glob('pidl', flat=False)) 58 pidl_src_nodes = bld.pidl_files_cache 59 60 # the cd .. is needed because pidl currently is sensitive to the directory it is run in 61 cpp = "" 62 cc = "" 63 if bld.CONFIG_SET("CPP") and bld.CONFIG_GET("CPP") != "": 64 if isinstance(bld.CONFIG_GET("CPP"), list): 65 cpp = 'CPP="%s"' % " ".join(bld.CONFIG_GET("CPP")) 66 else: 67 cpp = 'CPP="%s"' % bld.CONFIG_GET("CPP") 68 69 if cpp == "CPP=xlc_r": 70 cpp = "" 71 72 73 if bld.CONFIG_SET("CC"): 74 if isinstance(bld.CONFIG_GET("CC"), list): 75 cc = 'CC="%s"' % " ".join(bld.CONFIG_GET("CC")) 76 else: 77 cc = 'CC="%s"' % bld.CONFIG_GET("CC") 78 79 t = bld(rule='cd ${PIDL_LAUNCH_DIR} && %s %s ${PERL} ${PIDL} --quiet ${OPTIONS} --outputdir ${OUTPUTDIR} -- "${IDLSRC}"' % (cpp, cc), 80 ext_out = '.c', 81 before = 'c', 82 update_outputs = True, 83 shell = True, 84 source = source, 85 target = out_files, 86 name = name, 87 samba_type = 'PIDL') 88 89 90 t.env.PIDL_LAUNCH_DIR = bld.srcnode.path_from(bld.bldnode) 91 pnode = bld.srcnode.find_resource('pidl/pidl') 92 t.env.PIDL = pnode.path_from(bld.srcnode) 93 t.env.OPTIONS = TO_LIST(options) 94 snode = t.path.find_resource(source[0]) 95 t.env.IDLSRC = snode.path_from(bld.srcnode) 96 t.env.OUTPUTDIR = bld.bldnode.path_from(bld.srcnode) + '/' + bld.path.find_dir(output_dir).path_from(bld.srcnode) 97 98 bld.add_manual_dependency(snode, pidl_src_nodes) 99 100 if generate_tables and table_header_idx is not None: 101 pidl_headers = LOCAL_CACHE(bld, 'PIDL_HEADERS') 102 pidl_headers[name] = [bld.path.find_or_declare(out_files[table_header_idx])] 103 104 t.more_includes = '#' + bld.path.path_from(bld.srcnode) 105Build.BuildContext.SAMBA_PIDL = SAMBA_PIDL 106 107 108def SAMBA_PIDL_LIST(bld, name, source, 109 options='', 110 output_dir='.', 111 generate_tables=True): 112 '''A wrapper for building a set of IDL files''' 113 for p in TO_LIST(source): 114 bld.SAMBA_PIDL(name, p, options=options, output_dir=output_dir, generate_tables=generate_tables) 115Build.BuildContext.SAMBA_PIDL_LIST = SAMBA_PIDL_LIST 116 117 118################################################################# 119# the rule for generating the NDR tables 120@feature('collect') 121@before('exec_rule') 122def collect(self): 123 pidl_headers = LOCAL_CACHE(self.bld, 'PIDL_HEADERS') 124 # The first source is tables.pl itself 125 self.source = Utils.to_list(self.source) 126 for (name, hd) in pidl_headers.items(): 127 y = self.bld.get_tgen_by_name(name) 128 self.bld.ASSERT(y is not None, 'Failed to find PIDL header %s' % name) 129 y.post() 130 for node in hd: 131 self.bld.ASSERT(node is not None, 'Got None as build node generating PIDL table for %s' % name) 132 self.source.append(node) 133 134 135def SAMBA_PIDL_TABLES(bld, name, target): 136 '''generate the pidl NDR tables file''' 137 bld.SET_BUILD_GROUP('main') 138 t = bld( 139 features = 'collect', 140 rule = '${PERL} ${SRC} > ${TGT}', 141 ext_out = '.c', 142 before = 'c', 143 update_outputs = True, 144 shell = True, 145 source = '../../librpc/tables.pl', 146 target = target, 147 name = name) 148 t.env.LIBRPC = os.path.join(bld.srcnode.abspath(), 'librpc') 149Build.BuildContext.SAMBA_PIDL_TABLES = SAMBA_PIDL_TABLES 150 151