diff options
Diffstat (limited to 'buildtools/wafsamba/samba_pidl.py')
-rw-r--r-- | buildtools/wafsamba/samba_pidl.py | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/buildtools/wafsamba/samba_pidl.py b/buildtools/wafsamba/samba_pidl.py new file mode 100644 index 0000000..72997c8 --- /dev/null +++ b/buildtools/wafsamba/samba_pidl.py @@ -0,0 +1,175 @@ +# waf build tool for building IDL files with pidl + +import os +from waflib import Build, Utils +from waflib.TaskGen import feature, before +from samba_utils import SET_TARGET_TYPE, TO_LIST, LOCAL_CACHE + +def SAMBA_PIDL(bld, pname, source, + options='', + output_dir='.', + generate_tables=True): + '''Build a IDL file using pidl. + This will produce up to 17 output files depending on the options used''' + + bname = source[0:-4] # strip off the .idl suffix + bname = os.path.basename(bname) + name = "%s_%s" % (pname, bname.upper()) + + if not SET_TARGET_TYPE(bld, name, 'PIDL'): + return + + bld.SET_BUILD_GROUP('build_source') + + # the output files depend on the options used. Use this dictionary + # to map between the options and the resulting file names + options_map = { '--header' : '%s.h', + '--ndr-parser' : 'ndr_%s.c ndr_%s.h', + '--samba3-ndr-server' : 'srv_%s.c srv_%s.h', + '--samba3-ndr-client' : 'cli_%s.c cli_%s.h', + '--server' : 'ndr_%s_s.c', + '--server-compat' : 'ndr_%s_scompat.c ndr_%s_scompat.h', + '--client' : 'ndr_%s_c.c ndr_%s_c.h', + '--python' : 'py_%s.c', + '--tdr-parser' : 'tdr_%s.c tdr_%s.h', + '--dcom-proxy' : '%s_p.c', + '--com-header' : 'com_%s.h' + } + + table_header_idx = None + out_files = [] + options_list = TO_LIST(options) + + for o in options_list: + if o in options_map: + ofiles = TO_LIST(options_map[o]) + for f in ofiles: + out_files.append(os.path.join(output_dir, f % bname)) + if f == 'ndr_%s.h': + # remember this one for the tables generation + table_header_idx = len(out_files) - 1 + + # depend on the full pidl sources + source = TO_LIST(source) + try: + pidl_src_nodes = bld.pidl_files_cache + except AttributeError: + bld.pidl_files_cache = bld.srcnode.ant_glob('pidl/lib/Parse/**/*.pm', flat=False) + bld.pidl_files_cache.extend(bld.srcnode.ant_glob('pidl', flat=False)) + pidl_src_nodes = bld.pidl_files_cache + + # the cd .. is needed because pidl currently is sensitive to the directory it is run in + cpp = "" + cc = "" + if bld.CONFIG_SET("CPP") and bld.CONFIG_GET("CPP") != "": + if isinstance(bld.CONFIG_GET("CPP"), list): + cpp = 'CPP="%s"' % " ".join(bld.CONFIG_GET("CPP")) + else: + cpp = 'CPP="%s"' % bld.CONFIG_GET("CPP") + + if cpp == "CPP=xlc_r": + cpp = "" + + if bld.env['PIDL_DEVELOPER_MODE']: + pidl_dev = 'PIDL_DEVELOPER=1 ' + else: + pidl_dev = '' + + if bld.CONFIG_SET("CC"): + if isinstance(bld.CONFIG_GET("CC"), list): + cc = 'CC="%s"' % " ".join(bld.CONFIG_GET("CC")) + else: + cc = 'CC="%s"' % bld.CONFIG_GET("CC") + + t = bld(rule='cd ${PIDL_LAUNCH_DIR} && %s%s %s ${PERL} ${PIDL} --quiet ${OPTIONS} --outputdir ${OUTPUTDIR} -- "${IDLSRC}"' % (pidl_dev, cpp, cc), + ext_out = '.c', + before = 'c', + update_outputs = True, + shell = True, + source = source, + target = out_files, + name = name, + samba_type = 'PIDL') + + + t.env.PIDL_LAUNCH_DIR = bld.srcnode.path_from(bld.bldnode) + pnode = bld.srcnode.find_resource('pidl/pidl') + t.env.PIDL = pnode.path_from(bld.srcnode) + t.env.OPTIONS = TO_LIST(options) + snode = t.path.find_resource(source[0]) + t.env.IDLSRC = snode.path_from(bld.srcnode) + t.env.OUTPUTDIR = bld.bldnode.path_from(bld.srcnode) + '/' + bld.path.find_dir(output_dir).path_from(bld.srcnode) + + bld.add_manual_dependency(snode, pidl_src_nodes) + + if generate_tables and table_header_idx is not None: + pidl_headers = LOCAL_CACHE(bld, 'PIDL_HEADERS') + pidl_headers[name] = [bld.path.find_or_declare(out_files[table_header_idx])] + + t.more_includes = '#' + bld.path.path_from(bld.srcnode) +Build.BuildContext.SAMBA_PIDL = SAMBA_PIDL + +def SAMBA_PIDL_LIST(bld, name, source, + options='', + output_dir='.', + generate_tables=True, + generate_fuzzers=True): + '''A wrapper for building a set of IDL files''' + for p in TO_LIST(source): + bld.SAMBA_PIDL(name, p, options=options, output_dir=output_dir, generate_tables=generate_tables) + + # Some IDL files don't exactly match between name and + # "interface" so we need a way to skip those, while other IDL + # files have the table generation skipped entirely, on which + # the fuzzers rely + if generate_tables and generate_fuzzers: + interface = p[0:-4] # strip off the .idl suffix + bld.SAMBA_NDR_FUZZ(interface, + auto_deps=True, + fuzz_type="TYPE_STRUCT") + + # Only generate the TYPE_STRUCT fuzzer if this isn't + # really DCE/RPC + if '--client' in options: + bld.SAMBA_NDR_FUZZ(interface, + auto_deps=True, + fuzz_type="TYPE_IN") + bld.SAMBA_NDR_FUZZ(interface, + auto_deps=True, + fuzz_type="TYPE_OUT") +Build.BuildContext.SAMBA_PIDL_LIST = SAMBA_PIDL_LIST + + +################################################################# +# the rule for generating the NDR tables +@feature('collect') +@before('exec_rule') +def collect(self): + pidl_headers = LOCAL_CACHE(self.bld, 'PIDL_HEADERS') + # The first source is tables.pl itself + self.source = Utils.to_list(self.source) + for (name, hd) in pidl_headers.items(): + y = self.bld.get_tgen_by_name(name) + self.bld.ASSERT(y is not None, 'Failed to find PIDL header %s' % name) + y.post() + for node in hd: + self.bld.ASSERT(node is not None, 'Got None as build node generating PIDL table for %s' % name) + self.source.append(node) + + +def SAMBA_PIDL_TABLES(bld, name, target): + '''generate the pidl NDR tables file''' + bld.SET_BUILD_GROUP('main') + t = bld( + features = 'collect', + rule = '${PERL} ${SRC} > ${TGT}', + ext_out = '.c', + before = 'c', + update_outputs = True, + shell = True, + source = '../../librpc/tables.pl', + target = target, + name = name) + t.env.LIBRPC = os.path.join(bld.srcnode.abspath(), 'librpc') +Build.BuildContext.SAMBA_PIDL_TABLES = SAMBA_PIDL_TABLES + |