1 # functions for handling cross-compilation
3 import os
, sys
, re
, shlex
4 from waflib
import Utils
, Logs
, Options
, Errors
, Context
5 from waflib
.Configure
import conf
6 from wafsamba
import samba_utils
10 ANSWER_UNKNOWN
= (254, "")
14 cross_answers_incomplete
= False
17 def add_answer(ca_file
, msg
, answer
):
18 '''add an answer to a set of cross answers'''
20 f
= open(ca_file
, 'a')
22 Logs
.error("Unable to open cross-answers file %s" % ca_file
)
24 (retcode
, retstring
) = answer
25 # if retstring is more than one line then we probably
26 # don't care about its actual content (the tests should
27 # yield one-line output in order to comply with the cross-answer
29 retstring
= retstring
.strip()
30 if len(retstring
.split('\n')) > 1:
32 answer
= (retcode
, retstring
)
34 if answer
== ANSWER_OK
:
35 f
.write('%s: OK\n' % msg
)
36 elif answer
== ANSWER_UNKNOWN
:
37 f
.write('%s: UNKNOWN\n' % msg
)
38 elif answer
== ANSWER_NO
:
39 f
.write('%s: NO\n' % msg
)
42 f
.write('%s: "%s"\n' % (msg
, retstring
))
44 f
.write('%s: (%d, "%s")\n' % (msg
, retcode
, retstring
))
48 def cross_answer(ca_file
, msg
):
49 '''return a (retcode,retstring) tuple from a answers file'''
51 f
= open(ca_file
, 'r')
56 if line
== '' or line
[0] == '#':
58 if line
.find(':') != -1:
59 a
= line
.split(':', 1)
60 thismsg
= a
[0].strip()
64 if ans
== "OK" or ans
== "YES":
67 elif ans
== "UNKNOWN":
70 elif ans
== "FAIL" or ans
== "NO":
75 return (0, ans
.strip('"'))
78 return (0, ans
.strip("'"))
80 m
= re
.match(r
'\(\s*(-?\d+)\s*,\s*\"(.*)\"\s*\)', ans
)
83 return (int(m
.group(1)), m
.group(2))
85 raise Errors
.WafError("Bad answer format '%s' in %s" % (line
, ca_file
))
90 class cross_Popen(Utils
.subprocess
.Popen
):
91 '''cross-compilation wrapper for Popen'''
92 def __init__(*k
, **kw
):
97 # Three possibilities:
98 # 1. Only cross-answers - try the cross-answers file, and if
99 # there's no corresponding answer, add to the file and mark
100 # the configure process as unfinished.
101 # 2. Only cross-execute - get the answer from cross-execute
102 # 3. Both - try the cross-answers file, and if there is no
103 # corresponding answer - use cross-execute to get an answer,
104 # and add that answer to the file.
105 if '--cross-answers' in args
:
106 # when --cross-answers is set, then change the arguments
107 # to use the cross answers if available
109 i
= args
.index('--cross-answers')
112 ans
= cross_answer(ca_file
, msg
)
114 if '--cross-execute' in args
and ans
== ANSWER_UNKNOWN
:
115 # when --cross-execute is set, then change the arguments
116 # to use the cross emulator
117 i
= args
.index('--cross-execute')
118 newargs
= shlex
.split(args
[i
+1])
119 newargs
.extend(args
[0:i
])
121 p
= real_Popen(newargs
,
122 stdout
=Utils
.subprocess
.PIPE
,
123 stderr
=Utils
.subprocess
.PIPE
,
124 env
=kw
.get('env', {}))
125 ce_out
, ce_err
= p
.communicate()
126 ans
= (p
.returncode
, samba_utils
.get_string(ce_out
))
127 add_answer(ca_file
, msg
, ans
)
132 if ans
== ANSWER_UNKNOWN
:
133 global cross_answers_incomplete
134 cross_answers_incomplete
= True
135 add_answer(ca_file
, msg
, ans
)
136 (retcode
, retstring
) = ans
137 args
= ['/bin/sh', '-c', "printf %%s '%s'; exit %d" % (retstring
, retcode
)]
138 real_Popen
.__init
__(*(obj
, args
), **kw
)
142 def SAMBA_CROSS_ARGS(conf
, msg
=None):
143 '''get test_args to pass when running cross compiled binaries'''
144 if not conf
.env
.CROSS_COMPILE
:
148 if real_Popen
is None:
149 real_Popen
= Utils
.subprocess
.Popen
150 Utils
.subprocess
.Popen
= cross_Popen
151 Utils
.run_process
= Utils
.run_regular_process
152 Utils
.get_process
= Utils
.alloc_process_pool
= Utils
.nada
156 if conf
.env
.CROSS_EXECUTE
:
157 ret
.extend(['--cross-execute', conf
.env
.CROSS_EXECUTE
])
159 if conf
.env
.CROSS_ANSWERS
:
161 raise Errors
.WafError("Cannot have NULL msg in cross-answers")
162 ret
.extend(['--cross-answers', os
.path
.join(Context
.launch_dir
, conf
.env
.CROSS_ANSWERS
), msg
])
165 raise Errors
.WafError("Cannot cross-compile without either --cross-execute or --cross-answers")
170 def SAMBA_CROSS_CHECK_COMPLETE(conf
):
171 '''check if we have some unanswered questions'''
172 global cross_answers_incomplete
173 if conf
.env
.CROSS_COMPILE
and cross_answers_incomplete
:
174 raise Errors
.WafError("Cross answers file %s is incomplete" % conf
.env
.CROSS_ANSWERS
)