s3:client: Make sure we work on a copy of the title
[Samba.git] / buildtools / wafsamba / samba_cross.py
blobb8f2000659f01663b1d288b45ea522a62f2b66db
1 # functions for handling cross-compilation
3 import os, sys, re, shlex
4 import Utils, Logs, Options
5 from Configure import conf
7 real_Popen = None
9 ANSWER_UNKNOWN = (254, "")
10 ANSWER_NO = (1, "")
11 ANSWER_OK = (0, "")
13 cross_answers_incomplete = False
16 def add_answer(ca_file, msg, answer):
17 '''add an answer to a set of cross answers'''
18 try:
19 f = open(ca_file, 'a')
20 except:
21 Logs.error("Unable to open cross-answers file %s" % ca_file)
22 sys.exit(1)
23 (retcode, retstring) = answer
24 # if retstring is more than one line then we probably
25 # don't care about its actual content (the tests should
26 # yield one-line output in order to comply with the cross-answer
27 # format)
28 retstring = retstring.strip()
29 if len(retstring.split('\n')) > 1:
30 retstring = ''
31 answer = (retcode, retstring)
33 if answer == ANSWER_OK:
34 f.write('%s: OK\n' % msg)
35 elif answer == ANSWER_UNKNOWN:
36 f.write('%s: UNKNOWN\n' % msg)
37 elif answer == ANSWER_NO:
38 f.write('%s: NO\n' % msg)
39 else:
40 if retcode == 0:
41 f.write('%s: "%s"\n' % (msg, retstring))
42 else:
43 f.write('%s: (%d, "%s")\n' % (msg, retcode, retstring))
44 f.close()
47 def cross_answer(ca_file, msg):
48 '''return a (retcode,retstring) tuple from a answers file'''
49 try:
50 f = open(ca_file, 'r')
51 except:
52 return ANSWER_UNKNOWN
53 for line in f:
54 line = line.strip()
55 if line == '' or line[0] == '#':
56 continue
57 if line.find(':') != -1:
58 a = line.split(':', 1)
59 thismsg = a[0].strip()
60 if thismsg != msg:
61 continue
62 ans = a[1].strip()
63 if ans == "OK" or ans == "YES":
64 f.close()
65 return ANSWER_OK
66 elif ans == "UNKNOWN":
67 f.close()
68 return ANSWER_UNKNOWN
69 elif ans == "FAIL" or ans == "NO":
70 f.close()
71 return ANSWER_NO
72 elif ans[0] == '"':
73 f.close()
74 return (0, ans.strip('"'))
75 elif ans[0] == "'":
76 f.close()
77 return (0, ans.strip("'"))
78 else:
79 m = re.match('\(\s*(-?\d+)\s*,\s*\"(.*)\"\s*\)', ans)
80 if m:
81 f.close()
82 return (int(m.group(1)), m.group(2))
83 else:
84 raise Utils.WafError("Bad answer format '%s' in %s" % (line, ca_file))
85 f.close()
86 return ANSWER_UNKNOWN
89 class cross_Popen(Utils.pproc.Popen):
90 '''cross-compilation wrapper for Popen'''
91 def __init__(*k, **kw):
92 (obj, args) = k
93 use_answers = False
94 ans = ANSWER_UNKNOWN
96 # Three possibilities:
97 # 1. Only cross-answers - try the cross-answers file, and if
98 # there's no corresponding answer, add to the file and mark
99 # the configure process as unfinished.
100 # 2. Only cross-execute - get the answer from cross-execute
101 # 3. Both - try the cross-answers file, and if there is no
102 # corresponding answer - use cross-execute to get an answer,
103 # and add that answer to the file.
104 if '--cross-answers' in args:
105 # when --cross-answers is set, then change the arguments
106 # to use the cross answers if available
107 use_answers = True
108 i = args.index('--cross-answers')
109 ca_file = args[i+1]
110 msg = args[i+2]
111 ans = cross_answer(ca_file, msg)
113 if '--cross-execute' in args and ans == ANSWER_UNKNOWN:
114 # when --cross-execute is set, then change the arguments
115 # to use the cross emulator
116 i = args.index('--cross-execute')
117 newargs = shlex.split(args[i+1])
118 newargs.extend(args[0:i])
119 if use_answers:
120 p = real_Popen(newargs,
121 stdout=Utils.pproc.PIPE,
122 stderr=Utils.pproc.PIPE)
123 ce_out, ce_err = p.communicate()
124 ans = (p.returncode, ce_out)
125 add_answer(ca_file, msg, ans)
126 else:
127 args = newargs
129 if use_answers:
130 if ans == ANSWER_UNKNOWN:
131 global cross_answers_incomplete
132 cross_answers_incomplete = True
133 add_answer(ca_file, msg, ans)
134 (retcode, retstring) = ans
135 args = ['/bin/sh', '-c', "echo -n '%s'; exit %d" % (retstring, retcode)]
136 real_Popen.__init__(*(obj, args), **kw)
139 @conf
140 def SAMBA_CROSS_ARGS(conf, msg=None):
141 '''get exec_args to pass when running cross compiled binaries'''
142 if not conf.env.CROSS_COMPILE:
143 return []
145 global real_Popen
146 if real_Popen is None:
147 real_Popen = Utils.pproc.Popen
148 Utils.pproc.Popen = cross_Popen
150 ret = []
152 if conf.env.CROSS_EXECUTE:
153 ret.extend(['--cross-execute', conf.env.CROSS_EXECUTE])
155 if conf.env.CROSS_ANSWERS:
156 if msg is None:
157 raise Utils.WafError("Cannot have NULL msg in cross-answers")
158 ret.extend(['--cross-answers', os.path.join(Options.launch_dir, conf.env.CROSS_ANSWERS), msg])
160 if ret == []:
161 raise Utils.WafError("Cannot cross-compile without either --cross-execute or --cross-answers")
163 return ret
165 @conf
166 def SAMBA_CROSS_CHECK_COMPLETE(conf):
167 '''check if we have some unanswered questions'''
168 global cross_answers_incomplete
169 if conf.env.CROSS_COMPILE and cross_answers_incomplete:
170 raise Utils.WafError("Cross answers file %s is incomplete" % conf.env.CROSS_ANSWERS)
171 return True