build: added --cross-answers support
authorAndrew Tridgell <tridge@samba.org>
Mon, 19 Apr 2010 05:58:37 +0000 (15:58 +1000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 19 Apr 2010 06:34:14 +0000 (16:34 +1000)
This allows you to easily cross-compile even without a --cross-execute
emulator

See http://wiki.samba.org/index.php/Waf#cross-compiling for details

buildtools/wafsamba/samba_autoconf.py
buildtools/wafsamba/samba_conftests.py
buildtools/wafsamba/samba_cross.py
buildtools/wafsamba/wscript

index dd7abe2864c810a4fb8e8bcd157437e8995d64c9..fa58e8f2499a0bf5730e62da1253e6ebea5a11e7 100644 (file)
@@ -372,7 +372,7 @@ def CHECK_CODE(conf, code, define,
     cflags = TO_LIST(cflags)
     cflags.extend(ccflags)
 
-    exec_args = conf.SAMBA_CROSS_ARGS()
+    exec_args = conf.SAMBA_CROSS_ARGS(msg=msg)
 
     ret = conf.check(fragment=fragment,
                      execute=execute,
@@ -567,6 +567,7 @@ def SAMBA_CONFIG_H(conf, path=None):
         conf.write_config_header('config.h', top=True)
     else:
         conf.write_config_header(path)
+    conf.SAMBA_CROSS_CHECK_COMPLETE()
 
 
 @conf
index ccd476345ef8c6b5ae5afd663c77ea597baf6d4b..e86f9393fe08247f6796f685e5fe469ff97312ad 100644 (file)
@@ -165,7 +165,7 @@ def CHECK_LIBRARY_SUPPORT(conf, rpath=False, msg=None):
         ADD_LD_LIBRARY_PATH(os.path.join(bdir, 'default/libdir'))
 
     # we need to run the program, try to get its result
-    args = conf.SAMBA_CROSS_ARGS()
+    args = conf.SAMBA_CROSS_ARGS(msg=msg)
     proc = Utils.pproc.Popen([lastprog] + args, stdout=Utils.pproc.PIPE, stderr=Utils.pproc.PIPE)
     (out, err) = proc.communicate()
     w = conf.log.write
index 70d74e0c94070833bc797c2933ec4b95c2d69bef..7c3e7d228c0068bc76cb06f36196a1247e48a47b 100644 (file)
@@ -1,15 +1,83 @@
 # functions for handling cross-compilation
 
-import pproc, Utils
+import Utils, Logs, sys, os, Options, re
 from Configure import conf
-from pproc import Popen
 
 real_Popen = None
 
-class cross_Popen(Popen):
+ANSWER_UNKNOWN = (254, "")
+ANSWER_FAIL    = (255, "")
+ANSWER_OK      = (0, "")
+
+cross_answers_incomplete = False
+
+
+def add_answer(ca_file, msg, answer):
+    '''add an answer to a set of cross answers'''
+    try:
+        f = open(ca_file, 'a')
+    except:
+        Logs.error("Unable to open cross-answers file %s" % ca_file)
+        sys.exit(1)
+    if answer == ANSWER_OK:
+        f.write('%s: OK\n' % msg)
+    elif answer == ANSWER_UNKNOWN:
+        f.write('%s: UNKNOWN\n' % msg)
+    elif answer == ANSWER_FAIL:
+        f.write('%s: FAIL\n' % msg)
+    else:
+        (retcode, retstring) = answer
+        f.write('%s: (%d, "%s")' % (msg, retcode, retstring))
+    f.close()
+
+
+def cross_answer(ca_file, msg):
+    '''return a (retcode,retstring) tuple from a answers file'''
+    try:
+        f = open(ca_file, 'r')
+    except:
+        add_answer(ca_file, msg, ANSWER_UNKNOWN)
+        return ANSWER_UNKNOWN
+    for line in f:
+        line = line.strip()
+        if line == '' or line[0] == '#':
+            continue
+        if line.find(':') != -1:
+            a = line.split(':')
+            thismsg = a[0].strip()
+            if thismsg != msg:
+                continue
+            ans = a[1].strip()
+            if ans == "OK" or ans == "YES":
+                f.close()
+                return ANSWER_OK
+            elif ans == "UNKNOWN":
+                f.close()
+                return ANSWER_UNKNOWN
+            elif ans == "FAIL" or ans == "NO":
+                f.close()
+                return ANSWER_FAIL
+            elif ans[0] == '"':
+                return (0, ans.strip('"'))
+            elif ans[0] == "'":
+                return (0, ans.strip("'"))
+            else:
+                m = re.match('\(\s*(-?\d+)\s*,\s*\"(.*)\"\s*\)', ans)
+                if m:
+                    f.close()
+                    return (int(m.group(1)), m.group(2))
+                else:
+                    raise Utils.WafError("Bad answer format '%s' in %s" % (line, ca_file))
+    f.close()
+    add_answer(ca_file, msg, ANSWER_UNKNOWN)
+    return ANSWER_UNKNOWN
+
+
+class cross_Popen(Utils.pproc.Popen):
     '''cross-compilation wrapper for Popen'''
     def __init__(*k, **kw):
         (obj, args) = k
+
         if '--cross-execute' in args:
             # when --cross-execute is set, then change the arguments
             # to use the cross emulator
@@ -17,13 +85,25 @@ class cross_Popen(Popen):
             newargs = args[i+1].split()
             newargs.extend(args[0:i])
             args = newargs
-        Popen.__init__(*(obj, args), **kw)
+        elif '--cross-answers' in args:
+            # when --cross-answers is set, then change the arguments
+            # to use the cross answers if available
+            i = args.index('--cross-answers')
+            ca_file = args[i+1]
+            msg     = args[i+2]
+            ans = cross_answer(ca_file, msg)
+            if ans == ANSWER_UNKNOWN:
+                global cross_answers_incomplete
+                cross_answers_incomplete = True
+            (retcode, retstring) = ans
+            args = ['/bin/sh', '-c', 'echo %s; exit %d' % (retstring, retcode)]
+        real_Popen.__init__(*(obj, args), **kw)
 
 
 @conf
-def SAMBA_CROSS_ARGS(conf):
+def SAMBA_CROSS_ARGS(conf, msg=None):
     '''get exec_args to pass when running cross compiled binaries'''
-    if not conf.env.CROSS_COMPILE or not conf.env.CROSS_EXECUTE:
+    if not conf.env.CROSS_COMPILE:
         return []
 
     global real_Popen
@@ -31,4 +111,24 @@ def SAMBA_CROSS_ARGS(conf):
         real_Popen  = Utils.pproc.Popen
         Utils.pproc.Popen = cross_Popen
 
-    return ['--cross-execute', conf.env.CROSS_EXECUTE]
+    ret = []
+
+    if conf.env.CROSS_EXECUTE:
+        ret.extend(['--cross-execute', conf.env.CROSS_EXECUTE])
+    elif conf.env.CROSS_ANSWERS:
+        if msg is None:
+            raise Utils.WafError("Cannot have NULL msg in cross-answers")
+        ret.extend(['--cross-answers', os.path.join(Options.launch_dir, conf.env.CROSS_ANSWERS), msg])
+
+    if ret == []:
+        raise Utils.WafError("Cannot cross-compile without either --cross-execute or --cross-answers")
+
+    return ret
+
+@conf
+def SAMBA_CROSS_CHECK_COMPLETE(conf):
+    '''check if we have some unanswered questions'''
+    global cross_answers_incomplete
+    if conf.env.CROSS_COMPILE and cross_answers_incomplete:
+        raise Utils.WafError("Cross answers file %s is incomplete" % conf.env.CROSS_ANSWERS)
+    return True
index a611797b473eb51fd7d47669b0ea04afad298dc1..a49e5e7368c68d0dfe5e469ed72378296aae4dc5 100644 (file)
@@ -93,6 +93,9 @@ def set_options(opt):
     gr.add_option('--cross-execute',
                   help=("command prefix to use for cross-execution in configure"),
                   action='store', dest='CROSS_EXECUTE', default='')
+    gr.add_option('--cross-answers',
+                  help=("answers to cross-compilation configuration (auto modified)"),
+                  action='store', dest='CROSS_ANSWERS', default='')
     gr.add_option('--hostcc',
                   help=("set host compiler when cross compiling"),
                   action='store', dest='HOSTCC', default=False)
@@ -152,6 +155,7 @@ def configure(conf):
 
     conf.env.CROSS_COMPILE = Options.options.CROSS_COMPILE
     conf.env.CROSS_EXECUTE = Options.options.CROSS_EXECUTE
+    conf.env.CROSS_ANSWERS = Options.options.CROSS_ANSWERS
     conf.env.HOSTCC        = Options.options.HOSTCC
 
     conf.env.AUTOCONF_BUILD = Options.options.AUTOCONF_BUILD