| 1 | # functions for handling cross-compilation
|
|---|
| 2 |
|
|---|
| 3 | import Utils, Logs, sys, os, Options, re
|
|---|
| 4 | from Configure import conf
|
|---|
| 5 |
|
|---|
| 6 | real_Popen = None
|
|---|
| 7 |
|
|---|
| 8 | ANSWER_UNKNOWN = (254, "")
|
|---|
| 9 | ANSWER_FAIL = (255, "")
|
|---|
| 10 | ANSWER_OK = (0, "")
|
|---|
| 11 |
|
|---|
| 12 | cross_answers_incomplete = False
|
|---|
| 13 |
|
|---|
| 14 |
|
|---|
| 15 | def add_answer(ca_file, msg, answer):
|
|---|
| 16 | '''add an answer to a set of cross answers'''
|
|---|
| 17 | try:
|
|---|
| 18 | f = open(ca_file, 'a')
|
|---|
| 19 | except:
|
|---|
| 20 | Logs.error("Unable to open cross-answers file %s" % ca_file)
|
|---|
| 21 | sys.exit(1)
|
|---|
| 22 | if answer == ANSWER_OK:
|
|---|
| 23 | f.write('%s: OK\n' % msg)
|
|---|
| 24 | elif answer == ANSWER_UNKNOWN:
|
|---|
| 25 | f.write('%s: UNKNOWN\n' % msg)
|
|---|
| 26 | elif answer == ANSWER_FAIL:
|
|---|
| 27 | f.write('%s: FAIL\n' % msg)
|
|---|
| 28 | else:
|
|---|
| 29 | (retcode, retstring) = answer
|
|---|
| 30 | f.write('%s: (%d, "%s")' % (msg, retcode, retstring))
|
|---|
| 31 | f.close()
|
|---|
| 32 |
|
|---|
| 33 |
|
|---|
| 34 | def cross_answer(ca_file, msg):
|
|---|
| 35 | '''return a (retcode,retstring) tuple from a answers file'''
|
|---|
| 36 | try:
|
|---|
| 37 | f = open(ca_file, 'r')
|
|---|
| 38 | except:
|
|---|
| 39 | add_answer(ca_file, msg, ANSWER_UNKNOWN)
|
|---|
| 40 | return ANSWER_UNKNOWN
|
|---|
| 41 | for line in f:
|
|---|
| 42 | line = line.strip()
|
|---|
| 43 | if line == '' or line[0] == '#':
|
|---|
| 44 | continue
|
|---|
| 45 | if line.find(':') != -1:
|
|---|
| 46 | a = line.split(':')
|
|---|
| 47 | thismsg = a[0].strip()
|
|---|
| 48 | if thismsg != msg:
|
|---|
| 49 | continue
|
|---|
| 50 | ans = a[1].strip()
|
|---|
| 51 | if ans == "OK" or ans == "YES":
|
|---|
| 52 | f.close()
|
|---|
| 53 | return ANSWER_OK
|
|---|
| 54 | elif ans == "UNKNOWN":
|
|---|
| 55 | f.close()
|
|---|
| 56 | return ANSWER_UNKNOWN
|
|---|
| 57 | elif ans == "FAIL" or ans == "NO":
|
|---|
| 58 | f.close()
|
|---|
| 59 | return ANSWER_FAIL
|
|---|
| 60 | elif ans[0] == '"':
|
|---|
| 61 | return (0, ans.strip('"'))
|
|---|
| 62 | elif ans[0] == "'":
|
|---|
| 63 | return (0, ans.strip("'"))
|
|---|
| 64 | else:
|
|---|
| 65 | m = re.match('\(\s*(-?\d+)\s*,\s*\"(.*)\"\s*\)', ans)
|
|---|
| 66 | if m:
|
|---|
| 67 | f.close()
|
|---|
| 68 | return (int(m.group(1)), m.group(2))
|
|---|
| 69 | else:
|
|---|
| 70 | raise Utils.WafError("Bad answer format '%s' in %s" % (line, ca_file))
|
|---|
| 71 | f.close()
|
|---|
| 72 | add_answer(ca_file, msg, ANSWER_UNKNOWN)
|
|---|
| 73 | return ANSWER_UNKNOWN
|
|---|
| 74 |
|
|---|
| 75 |
|
|---|
| 76 | class cross_Popen(Utils.pproc.Popen):
|
|---|
| 77 | '''cross-compilation wrapper for Popen'''
|
|---|
| 78 | def __init__(*k, **kw):
|
|---|
| 79 | (obj, args) = k
|
|---|
| 80 |
|
|---|
| 81 | if '--cross-execute' in args:
|
|---|
| 82 | # when --cross-execute is set, then change the arguments
|
|---|
| 83 | # to use the cross emulator
|
|---|
| 84 | i = args.index('--cross-execute')
|
|---|
| 85 | newargs = args[i+1].split()
|
|---|
| 86 | newargs.extend(args[0:i])
|
|---|
| 87 | args = newargs
|
|---|
| 88 | elif '--cross-answers' in args:
|
|---|
| 89 | # when --cross-answers is set, then change the arguments
|
|---|
| 90 | # to use the cross answers if available
|
|---|
| 91 | i = args.index('--cross-answers')
|
|---|
| 92 | ca_file = args[i+1]
|
|---|
| 93 | msg = args[i+2]
|
|---|
| 94 | ans = cross_answer(ca_file, msg)
|
|---|
| 95 | if ans == ANSWER_UNKNOWN:
|
|---|
| 96 | global cross_answers_incomplete
|
|---|
| 97 | cross_answers_incomplete = True
|
|---|
| 98 | (retcode, retstring) = ans
|
|---|
| 99 | args = ['/bin/sh', '-c', "echo -n '%s'; exit %d" % (retstring, retcode)]
|
|---|
| 100 | real_Popen.__init__(*(obj, args), **kw)
|
|---|
| 101 |
|
|---|
| 102 |
|
|---|
| 103 | @conf
|
|---|
| 104 | def SAMBA_CROSS_ARGS(conf, msg=None):
|
|---|
| 105 | '''get exec_args to pass when running cross compiled binaries'''
|
|---|
| 106 | if not conf.env.CROSS_COMPILE:
|
|---|
| 107 | return []
|
|---|
| 108 |
|
|---|
| 109 | global real_Popen
|
|---|
| 110 | if real_Popen is None:
|
|---|
| 111 | real_Popen = Utils.pproc.Popen
|
|---|
| 112 | Utils.pproc.Popen = cross_Popen
|
|---|
| 113 |
|
|---|
| 114 | ret = []
|
|---|
| 115 |
|
|---|
| 116 | if conf.env.CROSS_EXECUTE:
|
|---|
| 117 | ret.extend(['--cross-execute', conf.env.CROSS_EXECUTE])
|
|---|
| 118 | elif conf.env.CROSS_ANSWERS:
|
|---|
| 119 | if msg is None:
|
|---|
| 120 | raise Utils.WafError("Cannot have NULL msg in cross-answers")
|
|---|
| 121 | ret.extend(['--cross-answers', os.path.join(Options.launch_dir, conf.env.CROSS_ANSWERS), msg])
|
|---|
| 122 |
|
|---|
| 123 | if ret == []:
|
|---|
| 124 | raise Utils.WafError("Cannot cross-compile without either --cross-execute or --cross-answers")
|
|---|
| 125 |
|
|---|
| 126 | return ret
|
|---|
| 127 |
|
|---|
| 128 | @conf
|
|---|
| 129 | def SAMBA_CROSS_CHECK_COMPLETE(conf):
|
|---|
| 130 | '''check if we have some unanswered questions'''
|
|---|
| 131 | global cross_answers_incomplete
|
|---|
| 132 | if conf.env.CROSS_COMPILE and cross_answers_incomplete:
|
|---|
| 133 | raise Utils.WafError("Cross answers file %s is incomplete" % conf.env.CROSS_ANSWERS)
|
|---|
| 134 | return True
|
|---|