doom3-gpl
Doom 3 GPL source release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
scons_utils.py
Go to the documentation of this file.
1 # -*- mode: python -*-
2 import sys, os, string, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, tempfile
3 import SCons
4 
5 # need an Environment and a matching buffered_spawn API .. encapsulate
6 class idBuffering:
7  silent = False
8 
9  def buffered_spawn( self, sh, escape, cmd, args, env ):
10  stderr = StringIO.StringIO()
11  stdout = StringIO.StringIO()
12  command_string = ''
13  for i in args:
14  if ( len( command_string ) ):
15  command_string += ' '
16  command_string += i
17  try:
18  retval = self.env['PSPAWN']( sh, escape, cmd, args, env, stdout, stderr )
19  except OSError, x:
20  if x.errno != 10:
21  raise x
22  print 'OSError ignored on command: %s' % command_string
23  retval = 0
24  print command_string
25  if ( retval != 0 or not self.silent ):
26  sys.stdout.write( stdout.getvalue() )
27  sys.stderr.write( stderr.getvalue() )
28  return retval
29 
31 
32  def SimpleCommand( self, cmd ):
33  print cmd
34  ret = commands.getstatusoutput( cmd )
35  if ( len( ret[ 1 ] ) ):
36  sys.stdout.write( ret[ 1 ] )
37  sys.stdout.write( '\n' )
38  if ( ret[ 0 ] != 0 ):
39  raise 'command failed'
40  return ret[ 1 ]
41 
42  def TrySimpleCommand( self, cmd ):
43  print cmd
44  ret = commands.getstatusoutput( cmd )
45  sys.stdout.write( ret[ 1 ] )
46 
47  def M4Processing( self, file, d ):
48  file_out = file[:-3]
49  cmd = 'm4 '
50  for ( key, val ) in d.items():
51  cmd += '--define=%s="%s" ' % ( key, val )
52  cmd += '%s > %s' % ( file, file_out )
53  self.SimpleCommand( cmd )
54 
56  f = open( 'framework/Licensee.h' )
57  l = f.readlines()
58  f.close()
59 
60  major = 'X'
61  p = re.compile( '^#define ASYNC_PROTOCOL_MAJOR\t*(.*)' )
62  for i in l:
63  if ( p.match( i ) ):
64  major = p.match( i ).group(1)
65  break
66 
67  f = open( 'framework/async/AsyncNetwork.h' )
68  l = f.readlines()
69  f.close()
70 
71  minor = 'X'
72  p = re.compile( '^const int ASYNC_PROTOCOL_MINOR\t*= (.*);' )
73  for i in l:
74  if ( p.match( i ) ):
75  minor = p.match( i ).group(1)
76  break
77 
78  return '%s.%s' % ( major, minor )
79 
80  def ExtractEngineVersion( self ):
81  f = open( 'framework/Licensee.h' )
82  l = f.readlines()
83  f.close()
84 
85  version = 'X'
86  p = re.compile( '^#define.*ENGINE_VERSION\t*"DOOM (.*)"' )
87  for i in l:
88  if ( p.match( i ) ):
89  version = p.match( i ).group(1)
90  break
91 
92  return version
93 
94  def ExtractBuildVersion( self ):
95  f = open( 'framework/BuildVersion.h' )
96  l = f.readlines()[ 4 ]
97  f.close()
98  pat = re.compile( '.* = (.*);\n' )
99  return pat.split( l )[ 1 ]
100 
101 def checkLDD( target, source, env ):
102  file = target[0]
103  if (not os.path.isfile(file.abspath)):
104  print('ERROR: CheckLDD: target %s not found\n' % target[0])
105  Exit(1)
106  ( status, output ) = commands.getstatusoutput( 'ldd -r %s' % file )
107  if ( status != 0 ):
108  print 'ERROR: ldd command returned with exit code %d' % ldd_ret
109  os.system( 'rm %s' % target[ 0 ] )
110  sys.exit(1)
111  lines = string.split( output, '\n' )
112  have_undef = 0
113  for i_line in lines:
114  #print repr(i_line)
115  regex = re.compile('undefined symbol: (.*)\t\\((.*)\\)')
116  if ( regex.match(i_line) ):
117  symbol = regex.sub('\\1', i_line)
118  try:
119  env['ALLOWED_SYMBOLS'].index(symbol)
120  except:
121  have_undef = 1
122  if ( have_undef ):
123  print output
124  print "ERROR: undefined symbols"
125  os.system('rm %s' % target[0])
126  sys.exit(1)
127 
128 def SharedLibrarySafe( env, target, source ):
129  ret = env.SharedLibrary( target, source )
130  env.AddPostAction( ret, checkLDD )
131  return ret
132 
133 def NotImplementedStub( *whatever ):
134  print 'Not Implemented'
135  sys.exit( 1 )
136 
137 # --------------------------------------------------------------------
138 
140 
141  def BuildGamePak( self, target = None, source = None, env = None ):
142  # NOTE: ew should have done with zipfile module
143  temp_dir = tempfile.mkdtemp( prefix = 'gamepak' )
144  self.SimpleCommand( 'cp %s %s' % ( source[0].abspath, os.path.join( temp_dir, 'gamex86.so' ) ) )
145  self.SimpleCommand( 'strip %s' % os.path.join( temp_dir, 'gamex86.so' ) )
146  self.SimpleCommand( 'echo 2 > %s' % ( os.path.join( temp_dir, 'binary.conf' ) ) )
147  self.SimpleCommand( 'cd %s ; zip %s gamex86.so binary.conf' % ( temp_dir, os.path.join( temp_dir, target[0].abspath ) ) )
148  self.SimpleCommand( 'rm -r %s' % temp_dir )
149  return None
150 
151 # --------------------------------------------------------------------
152 
153 # get a clean error output when running multiple jobs
154 def SetupBufferedOutput( env, silent ):
155  buf = idBuffering()
156  buf.silent = silent
157  buf.env = env
158  env['SPAWN'] = buf.buffered_spawn
159 
160 # setup utilities on an environement
161 def SetupUtils( env ):
162  gamepaks = idGamePaks()
163  env.BuildGamePak = gamepaks.BuildGamePak
164  env.SharedLibrarySafe = SharedLibrarySafe
165  try:
166  import SDK
167  sdk = SDK.idSDK()
168  env.PreBuildSDK = sdk.PreBuildSDK
169  env.BuildSDK = sdk.BuildSDK
170  except:
171  print 'SDK.py hookup failed'
172  env.PreBuildSDK = NotImplementedStub
173  env.BuildSDK = NotImplementedStub
174  try:
175  import Setup
176  setup = Setup.idSetup()
177  env.BuildSetup = setup.BuildSetup
178  except:
179  print 'Setup.py hookup failed'
180  env.BuildSetup = NotImplementedStub
181 
182 def BuildList( s_prefix, s_string ):
183  s_list = string.split( s_string )
184  for i in range( len( s_list ) ):
185  s_list[ i ] = s_prefix + '/' + s_list[ i ]
186  return s_list
def SharedLibrarySafe
Definition: scons_utils.py:128
def NotImplementedStub
Definition: scons_utils.py:133
Definition: SDK.py:5
def SetupBufferedOutput
Definition: scons_utils.py:154