2010-04-12 22:06:51 +10:00
# functions for handling cross-compilation
2015-10-27 20:46:46 +01:00
import os , sys , re , shlex
2018-06-27 16:42:29 +03:00
from waflib import Utils , Logs , Options , Errors , Context
2018-01-31 11:48:43 +02:00
from waflib . Configure import conf
2019-02-06 15:27:41 +00:00
from wafsamba import samba_utils
2010-04-12 22:06:51 +10:00
real_Popen = None
2010-04-19 15:58:37 +10:00
ANSWER_UNKNOWN = ( 254 , " " )
2015-05-03 22:56:15 +03:00
ANSWER_NO = ( 1 , " " )
2010-04-19 15:58:37 +10:00
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 )
2015-05-18 21:12:06 +03:00
( retcode , retstring ) = answer
# if retstring is more than one line then we probably
# don't care about its actual content (the tests should
# yield one-line output in order to comply with the cross-answer
# format)
retstring = retstring . strip ( )
if len ( retstring . split ( ' \n ' ) ) > 1 :
retstring = ' '
answer = ( retcode , retstring )
2010-04-19 15:58:37 +10:00
if answer == ANSWER_OK :
f . write ( ' %s : OK \n ' % msg )
elif answer == ANSWER_UNKNOWN :
f . write ( ' %s : UNKNOWN \n ' % msg )
2015-05-03 22:56:15 +03:00
elif answer == ANSWER_NO :
f . write ( ' %s : NO \n ' % msg )
2010-04-19 15:58:37 +10:00
else :
2015-05-03 22:56:15 +03:00
if retcode == 0 :
f . write ( ' %s : " %s " \n ' % ( msg , retstring ) )
else :
f . write ( ' %s : ( %d , " %s " ) \n ' % ( msg , retcode , retstring ) )
2010-04-19 15:58:37 +10:00
f . close ( )
def cross_answer ( ca_file , msg ) :
''' return a (retcode,retstring) tuple from a answers file '''
try :
f = open ( ca_file , ' r ' )
except :
return ANSWER_UNKNOWN
for line in f :
line = line . strip ( )
if line == ' ' or line [ 0 ] == ' # ' :
continue
if line . find ( ' : ' ) != - 1 :
2015-05-04 09:12:45 +03:00
a = line . split ( ' : ' , 1 )
2010-04-19 15:58:37 +10:00
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 ( )
2015-05-03 22:56:15 +03:00
return ANSWER_NO
2010-04-19 15:58:37 +10:00
elif ans [ 0 ] == ' " ' :
2015-05-18 20:40:11 +03:00
f . close ( )
2010-04-19 15:58:37 +10:00
return ( 0 , ans . strip ( ' " ' ) )
elif ans [ 0 ] == " ' " :
2015-05-18 20:40:11 +03:00
f . close ( )
2010-04-19 15:58:37 +10:00
return ( 0 , ans . strip ( " ' " ) )
else :
2022-04-28 20:31:50 +12:00
m = re . match ( r ' \ ( \ s*(-? \ d+) \ s*, \ s* \ " (.*) \ " \ s* \ ) ' , ans )
2010-04-19 15:58:37 +10:00
if m :
f . close ( )
return ( int ( m . group ( 1 ) ) , m . group ( 2 ) )
else :
2018-01-31 11:48:43 +02:00
raise Errors . WafError ( " Bad answer format ' %s ' in %s " % ( line , ca_file ) )
2010-04-19 15:58:37 +10:00
f . close ( )
return ANSWER_UNKNOWN
2018-01-31 11:48:43 +02:00
class cross_Popen ( Utils . subprocess . Popen ) :
2010-04-12 22:06:51 +10:00
''' cross-compilation wrapper for Popen '''
def __init__ ( * k , * * kw ) :
( obj , args ) = k
2015-05-18 21:15:19 +03:00
use_answers = False
ans = ANSWER_UNKNOWN
# Three possibilities:
# 1. Only cross-answers - try the cross-answers file, and if
# there's no corresponding answer, add to the file and mark
# the configure process as unfinished.
# 2. Only cross-execute - get the answer from cross-execute
# 3. Both - try the cross-answers file, and if there is no
# corresponding answer - use cross-execute to get an answer,
# and add that answer to the file.
if ' --cross-answers ' in args :
2010-04-19 15:58:37 +10:00
# when --cross-answers is set, then change the arguments
# to use the cross answers if available
2015-05-18 21:15:19 +03:00
use_answers = True
2010-04-19 15:58:37 +10:00
i = args . index ( ' --cross-answers ' )
ca_file = args [ i + 1 ]
msg = args [ i + 2 ]
ans = cross_answer ( ca_file , msg )
2015-05-18 21:15:19 +03:00
if ' --cross-execute ' in args and ans == ANSWER_UNKNOWN :
# when --cross-execute is set, then change the arguments
# to use the cross emulator
i = args . index ( ' --cross-execute ' )
2015-05-19 11:09:55 +03:00
newargs = shlex . split ( args [ i + 1 ] )
2015-05-18 21:15:19 +03:00
newargs . extend ( args [ 0 : i ] )
if use_answers :
p = real_Popen ( newargs ,
2018-06-27 16:34:53 +03:00
stdout = Utils . subprocess . PIPE ,
2019-10-07 00:37:41 +03:00
stderr = Utils . subprocess . PIPE ,
env = kw . get ( ' env ' , { } ) )
2015-05-18 21:15:19 +03:00
ce_out , ce_err = p . communicate ( )
2019-02-06 15:27:41 +00:00
ans = ( p . returncode , samba_utils . get_string ( ce_out ) )
2015-05-18 21:15:19 +03:00
add_answer ( ca_file , msg , ans )
else :
args = newargs
if use_answers :
2010-04-19 15:58:37 +10:00
if ans == ANSWER_UNKNOWN :
global cross_answers_incomplete
cross_answers_incomplete = True
2015-05-18 21:15:19 +03:00
add_answer ( ca_file , msg , ans )
2010-04-19 15:58:37 +10:00
( retcode , retstring ) = ans
2022-02-10 00:02:17 +03:00
args = [ ' /bin/sh ' , ' -c ' , " printf %% s ' %s ' ; exit %d " % ( retstring , retcode ) ]
2010-04-19 15:58:37 +10:00
real_Popen . __init__ ( * ( obj , args ) , * * kw )
2010-04-12 22:06:51 +10:00
@conf
2010-04-19 15:58:37 +10:00
def SAMBA_CROSS_ARGS ( conf , msg = None ) :
2019-10-07 00:37:17 +03:00
''' get test_args to pass when running cross compiled binaries '''
2010-04-19 15:58:37 +10:00
if not conf . env . CROSS_COMPILE :
2010-04-12 22:06:51 +10:00
return [ ]
global real_Popen
if real_Popen is None :
2018-06-27 16:34:53 +03:00
real_Popen = Utils . subprocess . Popen
Utils . subprocess . Popen = cross_Popen
2019-10-07 00:37:31 +03:00
Utils . run_process = Utils . run_regular_process
Utils . get_process = Utils . alloc_process_pool = Utils . nada
2010-04-12 22:06:51 +10:00
2010-04-19 15:58:37 +10:00
ret = [ ]
if conf . env . CROSS_EXECUTE :
ret . extend ( [ ' --cross-execute ' , conf . env . CROSS_EXECUTE ] )
2015-05-18 21:15:19 +03:00
if conf . env . CROSS_ANSWERS :
2010-04-19 15:58:37 +10:00
if msg is None :
2018-01-31 11:48:43 +02:00
raise Errors . WafError ( " Cannot have NULL msg in cross-answers " )
2018-06-27 16:42:29 +03:00
ret . extend ( [ ' --cross-answers ' , os . path . join ( Context . launch_dir , conf . env . CROSS_ANSWERS ) , msg ] )
2010-04-19 15:58:37 +10:00
if ret == [ ] :
2018-01-31 11:48:43 +02:00
raise Errors . WafError ( " Cannot cross-compile without either --cross-execute or --cross-answers " )
2010-04-19 15:58:37 +10:00
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 :
2018-01-31 11:48:43 +02:00
raise Errors . WafError ( " Cross answers file %s is incomplete " % conf . env . CROSS_ANSWERS )
2010-04-19 15:58:37 +10:00
return True