diff options
Diffstat (limited to 'py/waf/waf.py')
-rw-r--r-- | py/waf/waf.py | 437 |
1 files changed, 437 insertions, 0 deletions
diff --git a/py/waf/waf.py b/py/waf/waf.py new file mode 100644 index 0000000000..3988dbf5cb --- /dev/null +++ b/py/waf/waf.py @@ -0,0 +1,437 @@ +from waflib.Task import Task +from waflib.TaskGen import feature, before, after, extension, after_method +from waflib.Configure import conf +from waflib.Logs import pprint +#from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext +#from waflib import Build, Scripting +#from waflib.Tools import c_preproc +#from py.tools import gccdeps +#from waflib import Logs +#import ConfigParser + + +################# +# Handle .S Files +################# +class casm(Task): +# run_str = '${CC} ${ARCH_ST:ARCH} ${CFLAGS} ${CPPFLAGS} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT}' + run_str = '${CC} -DASM ${ARCH_ST:ARCH} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CC_SRC_F}${SRC} ${CC_TGT_F}${TGT}' + ext_in = ['.h'] + ext_out = ['.o'] + color = 'BLUE' + +@extension('.S') +def asm_hook(self, node): + return self.create_compiled_task('casm', node) + + +########## +# Features +########## +@feature('bld_include') +@after_method('apply_incpaths') +def insert_blddir(self): + self.env.prepend_value('INCPATHS', ['include']) + +@feature('src_include') +@after_method('apply_incpaths', 'insert_blddir') +def insert_srcdir(self): + path = self.bld.srcnode.abspath() + self.env.append_value('INCPATHS', "%s/include" % path) + + if self.env.ENABLE_SMP: +# self.env.append_value('INCPATHS', "%s/cpukit/score/cpu/%s/include/" % (path, self.env.RTEMS_ARCH)) + self.env.append_value('INCPATHS', "%s/cpukit/include/" % path) + +@feature('src_include_rtems') +@after_method('apply_incpaths', 'insert_blddir') +def insert_srcdir_rtems(self): + self.env.append_value('INCPATHS', "%s/cpukit/include/" % self.bld.srcnode.abspath()) + +@feature('src_include_networking') +@after_method('apply_incpaths', 'insert_blddir') +def insert_srcdir_networking(self): + self.env.append_value('INCPATHS', "%s/cpukit/libnetworking" % self.bld.srcnode.abspath()) + +@feature('src_include_bsp_common') +@after_method('apply_incpaths', 'insert_blddir') +def src_include_bsp_common(self): + self.env.append_value('INCPATHS', "%s/bsps/include" % self.bld.srcnode.abspath()) + +@feature('src_include_bsp') +@after_method('apply_incpaths', 'insert_blddir') +def insert_srcdir_bsp(self): + self.env.append_value('INCPATHS', "%s/bsps/%s/%s/include/" % (self.bld.srcnode.abspath(), self.env.RTEMS_ARCH, self.env.BSP_SOURCE_DIR)) + +@feature('src_include_bsp_shared') +@after_method('apply_incpaths', 'insert_blddir') +def insert_srcdir_bsp_shared(self): + self.env.append_value('INCPATHS', "%s/bsps/%s/include/" % (self.bld.srcnode.abspath(), self.env.RTEMS_ARCH)) + +@feature('src_include_libcpu') +@after_method('apply_incpaths', 'insert_blddir') +def insert_srcdir_libcpu(self): + self.env.append_value('INCPATHS', "%s/include/libcpu" % self.bld.srcnode.abspath()) + +@feature('src_include_libchip') +@after_method('apply_incpaths', 'insert_blddir') +def insert_srcdir_libchip(self): + self.env.append_value('INCPATHS', "%s/include/libchip" % self.bld.srcnode.abspath()) + +@feature('src_include_score') +@after_method('apply_incpaths', 'insert_blddir') +def insert_srcdir_score(self): + self.env.append_value('INCPATHS', "%s/cpukit/score/cpu/%s/include/" % (self.bld.srcnode.abspath(), self.env.RTEMS_ARCH)) + +@feature('src_include_bsp_arch') +@after_method('apply_incpaths', 'insert_blddir') +def insert_bsp_arch(self): + self.env.append_value('INCPATHS', "%s/bsps/%s/include//" % (self.bld.srcnode.abspath(), self.env.RTEMS_ARCH)) + + + +########### +# Shortcuts +########### +def rtems_build(cmd, ctx, target_name, source, **kwarg): + feature = "c bld_include" + if "features" in kwarg: + feature = "%s %s" % (kwarg["features"], feature) + del kwarg["features"] + + cmd( + source = source, + target = target_name, + features = feature, + install_path = ctx.env.LIBDIR, + **kwarg) + +# There's probably a better way to do this. +@conf +def rtems_lib(ctx, target_name, source, **kwarg): + rtems_build(ctx.stlib, ctx, target_name, source, **kwarg) + +@conf +def rtems_obj(ctx, target_name, source, **kwarg): + rtems_build(ctx, ctx, target_name, source, **kwarg) + +@conf +def rtems_program(ctx, target_name, source, **kwarg): + rtems_build(ctx.program, ctx, target_name, source, **kwarg) + + +@conf +def copy(ctx, source, target, name): + ctx( + features = 'subst', + source = source, + target = target, + is_copy = True, + name = name, + ) + +@conf +def copy_or_subst(ctx, source, target, name): + if source.endswith(".in"): + # This is required as not all 'linkcmd' files are named as such see the + # bottom of c/wscript It can be removed when the names are normalised + # XXX: fix 'linkcmd' names. + + if target.endswith(".in"): + target = target[:-3] + + ctx( + features = 'subst', + source = source, + target = target, + encoding = 'ascii', # for python3. + name = name, +# is_copy = True + ) + else: + ctx.copy(source, target, name) + + +################# +# Configure Steps +################# + +SNIP_FUNCTION = ''' +%s +int main(int argc, char **argv) { + void (*p)(); + (void)argc; (void)argv; + p=(void(*)())(%s); + return !p; +} +''' + +SNIP_TYPE = ''' +#include <%(header)s> +int main(int argc, char **argv) { + (void)argc; (void)argv; + if ((%(type)s *) 0) return 0; + if (sizeof (%(type)s)) return 0; + return 1; +} +''' + +SNIP_FIELD = ''' +int main(int argc, char **argv) { + char *off; + (void)argc; (void)argv; + off = (char*) &((%(type_name)s*)0)->%(field_name)s; + return (size_t) off < sizeof(%(type_name)s); +} +''' + + +SNIP_FUNC_DECL = ''' +%(header)s +int main(int argc, char **argv) { + %(decl)s; + return 1; +} +''' + + +@conf +def check_type(ctx, type, header_n, mandatory=False): + ctx.check_cc( + mandatory = mandatory, + fragment = SNIP_TYPE % {"type": type, "header": header_n}, + define_name = "HAVE_%s" % type.upper(), + execute = False, + msg = "Checking for type %s in header %s" % (type, header_n) +) + + +@conf +def check_func_header(ctx, func, header_n, mandatory=False): + header_msg = "" + header_inc = "" + + if header_n: + if isinstance(header_n, list): + for header in header_n: + header_inc += "#include <%s>\n" % header + header_msg = "in %s" % ", ".join(header_n) + else: + header_inc = "#include <%s>\n" % header_n + header_msg = "in %s" % header_n + + ctx.check_cc( + mandatory = mandatory, + fragment = SNIP_FUNCTION % (header_inc, func), + define_name = "HAVE_%s" % func.upper(), + execute = False, + msg = "Checking for C library function %s %s" % (func, header_msg), + features = 'c' + ) + + +@conf +def check_func(ctx, func, mandatory=False): + ctx.check_cc( + mandatory = mandatory, + fragment = "char %s();\n int main() { return %s(); return 0; }" % (func, func), + define_name = "HAVE_%s" % func.upper(), + execute = False, + msg = "Checking for C library function %s" % func +) + +@conf +def check_func_decl(ctx, decl, header_n, define, mandatory=False): + if header_n: + if isinstance(header_n, list): + for header in header_n: + header_inc += "#include <%s>\n" % header + header_msg = "in %s" % ", ".join(header_n) + else: + header_inc = "#include <%s>\n" % header_n + header_msg = "in %s" % header_n + + ctx.check_cc( + mandatory = mandatory, + fragment = SNIP_FUNC_DECL % {"decl": decl, "header": header_inc}, + define_name = "HAVE_%s" % define.upper(), + execute = False, + msg = "Checking for function decleration\n %s %s" % (decl, header_msg) +) + + +# ctx.check_cc( +# mandatory = mandatory, +# fragment = SNIP_FUNCTION % (header_inc, func), +# fragment = "%s\n %s\n int main() { return %s(); return 0; }\n" % (header_inc, char_check, func), +# define_name = "HAVE_%s" % func.upper(), +# execute = False, +# msg = "Checking for C library function %s%s" % (func, header_msg), +# features = 'c' +# ) + + + + + +@conf +def check_size(ctx, field, mandatory=False, define_name=None): + if define_name is None: + define_name = "SIZEOF_%s" % field.upper() + + ctx.check_cc( + mandatory = mandatory, + fragment = """ + #include <sys/types.h> + #include <stdio.h> + main() { + printf("%%d", sizeof(%s)); + return 0; + } + """ % field, + execute = True, + define_ret = True, + define_name = define_name, + quote = False, + msg = "Checking size of %s" % field + ) + +@conf +def check_define(ctx, define, header, mandatory=False): + ctx.check( + mandatory = mandatory, + fragment = '''#include <%s>\n int main () {\n #ifndef %s\n #error "missing define"\n #endif\n return 0; }\n''' % (header, define), + define_name = "HAVE_%s" % define.upper(), + features = "c", + msg = "Checking for define %s in %s" % (define, header) + ) + + +################################################# +# This writes objects to a file if there are > 25 +# objects to avoid commandline arg limits for ar. +################################################# +def rtems_stlib_command(self, *k, **kw): + # Following block borrowed from waflib/Tools/msvc.py + bld = self.generator.bld + + try: + if not kw.get('cwd', None): + kw['cwd'] = bld.cwd + except AttributeError: + bld.cwd = kw['cwd'] = bld.variant_dir + + # Put the objects on the commandline if there aren't enough to + # warrant writing to a file. + if len(self.inputs) < 25: + return self.generator.bld.exec_command(*k, **kw) + + file_obj = "%s_files" % self.outputs[0].abspath() + with open(file_obj, "w") as fp: + for f in self.inputs: + fp.write("%s\n" % f.bldpath()) + + pprint("YELLOW", "Wrote %d objects to %s" % (len(self.inputs), file_obj)) + cmd = self.env.AR + ["rc", self.outputs[0].bldpath(), "@%s_files" % self.outputs[0].bldpath()] + + # Task information for JSON build output. + if self.env.BUILD_JSON: + kw["json_task_self"] = self + + return self.generator.bld.exec_command(cmd, **kw) + + + +# Tests +@feature('test_include') +@after_method('apply_incpaths') +def insert_test_include(self): + self.env.prepend_value('INCPATHS', "%s/testsuites/support/include" % self.bld.srcnode.abspath()) + +@feature('test_cprogram') +@after_method('apply_incpaths', 'apply_link', 'src_include_bsp_common') +def re_fix_linkcmds(self): + linkcmds = self.env.LINKCMDS[0] + assert linkcmds + assert self.link_task + for x in ('linkcmds_linkcmds', 'linkcmds_base', 'start_start_o'): + tg = self.bld.get_tgen_by_name(x) + tg.post() + self.link_task.dep_nodes.append(tg.tasks[0].outputs[0]) + +from waflib.Tools.c import cprogram +from waflib.Tools.ccroot import USELIB_VARS + +USELIB_VARS['test_cprogram'] = set(['STLIB', 'STLIBPATH', 'LDFLAGS']) + +#from StringIO import StringIO +from os import fdopen, pipe, read, close +class test_cprogram(cprogram): + run_str = '${LINK_CC} ${LDFLAGS} ${CFLAGS} ${CCLNK_SRC_F}${SRC} ${CCLNK_TGT_F}${TGT[0].abspath()} -specs gcc_spec -Wl,-Bstatic -Lc -Lcpukit -Wl,-start-group -lc -lgcc ${STLIBPATH_ST:STLIBPATH} ${STLIB_ST:STLIB} -Wl,-end-group' + + def exec_command(self, cmd, **kw): + r, w = pipe() + rfd = fdopen(r, "r", encoding="utf-8") + kw["stderr"] = fdopen(w, "wb", 0) + ret = cprogram.exec_command(self, cmd, **kw) + kw["stderr"].close() + + if ret == 1: + data = rfd.readlines() + + if " ".join(data).find("will not fit in region") != -1: + file = self.outputs[0].abspath() + with open(file, "w") as fp: + fp.write("Target does not meet test memory constraints.\n") + pprint("RED", "Target \"%s\" does not meet test memory constraints." % file) + rfd.close() + return 0 + print("".join(data)) + + rfd.close() + return ret + + + +@conf +def rtems_test(ctx, target_name, source_name, **kwarg): + features_merged = "c test_cprogram bld_include src_include src_include_rtems" # test" + if "features" in kwarg: + features_merged = "%s %s" % (kwarg["features"], features_merged) + del kwarg["features"] + + use_merged = "rtemsbsp rtemscpu" + if "use" in kwarg: + use_merged = "%s %s" % (kwarg["use"], use_merged) + del kwarg["use"] + + name = "test_%s" % target_name + + ctx( + source = source_name, + target = name, + features = features_merged, + use = use_merged, + install_path = ctx.env.TESTDIR, + ut_cmd = "%s %%s" % ctx.env.BIN_RTEMS_RUN[0], + **kwarg + ) + + +@conf +def rtems_doc(ctx, section): + pprint("YELLOW", "See http://docs.rtems.org/%s/user/#%s (Not activated yet!)" % (ctx.env.RTEMS_VERSION, section)) + + +@conf +def rtems_fatal(ctx, message, section): + pprint("RED", message) + ctx.rtems_doc(section) + ctx.fatal("Fatal error") + + +@conf +def rtems_warn(ctx, message, section): + pprint("YELLOW", message) + ctx.rtems_doc(section) + |