blob: 8b9552bfe49e281754888d7bbe2a09c6c5b3177e [file] [log] [blame]
Deepak Panickal9b35cf52014-07-01 17:57:19 +00001""" Post process SWIG Bridge wrapper code Python script for Windows/LINUX/OSX platform
2
3 --------------------------------------------------------------------------
4 File: finishSwigWrapperClasses.py
5
6 Overview: Python script(s) to finish off the SWIG Python C++ Script
7 Bridge wrapper code on the Windows/LINUX/OSX platform.
8 The Python scripts are equivalent to the shell script (.sh)
9 files.
10 We use SWIG to create a C++ file containing the appropriate
11 wrapper classes and functions for each scripting language,
12 before liblldb is built (thus the C++ file can be compiled
13 into liblldb. In some cases, additional work may need to be
14 done after liblldb has been compiled, to make the scripting
15 language stuff fully functional. Any such post-processing
16 is handled through the Python scripts called here.
17
18 Environment: OS: Windows Vista or newer,LINUX,OSX.
19 IDE: Visual Studio 2013 Plugin Python Tools (PTVS)
20 Script: Python 2.6/2.7.5 x64
21 Other: None.
22
23 Gotchas: None.
24
25 Copyright: None.
26 --------------------------------------------------------------------------
27
28"""
29
30# Python modules:
31import sys # Provide argument parsing
32import os # Provide directory and file handling
33
34# Third party modules:
35
36# In-house modules:
37import utilsArgsParse # Parse and validate this script's input arguments
38import utilsOsType # Determine the OS type this script is running on
39import utilsDebug # Debug Python scripts
40
41# Instantiations:
42gbDbgVerbose = False; # True = Turn on script function tracing, False = off.
43gbDbgFlag = False; # Global debug mode flag, set by input parameter
44 # --dbgFlag. True = operate in debug mode.
45gbMakeFileFlag = False; # True = yes called from makefile system, False = not.
46
47# User facing text:
48strMsgErrorNoMain = "Program called by another Python script not allowed";
49strExitMsgSuccess = "Program successful";
50strExitMsgError = "Program error: ";
51strParameter = "Parameter: ";
52strMsgErrorOsTypeUnknown = "Unable to determine OS type"
53strScriptDirNotFound = "Unable to locate the script directory \'/script\'";
54strScriptLangsFound = "Found the following script languages:";
55strPostProcessError = "Executing \'%s\' post process script failed: ";
56strScriptNotFound = "Unable to locate the post process script file \'%s\' in \'%s\'";
57strScriptLangFound = "Found \'%s\' build script.";
58strScriptLangsFound = "Found the following script languages:";
59strExecuteMsg = "Executing \'%s\' build script...";
60strExecuteError = "Executing \'%s\' build script failed: ";
61strHelpInfo = "\
62Python script(s) to finish off the SWIG Python C++ Script \n\
63Bridge wrapper code on the Windows/LINUX/OSX platform. The Python \n\
64scripts are equivalent to the shell script (.sh) files \n\
65run on others platforms.\n\
66Args: -h (optional) Print help information on this program.\n\
67 -d (optional) Determines whether or not this script\n\
68 outputs additional information when running.\n\
69 -m (optional) Specify called from Makefile system.\n\
70 --srcRoot= The root of the lldb source tree.\n\
71 --targetDir= Where the lldb framework/shared library gets put.\n\
72 --cfgBldDir= (optional) Where the build-swig-Python-LLDB.py program \n\
73 will put the lldb.py file it generated from running\n\
74 SWIG.\n\
75 --prefix= (optional) Is the root directory used to determine where\n\
76 third-party modules for scripting languages should\n\
77 be installed. Where non-Darwin systems want to put\n\
78 the .py and .so files so that Python can find them\n\
79 automatically. Python install directory.\n\
80 --cmakeBuildConfiguration= (optional) Is the build configuration(Debug, Release, RelWithDebugInfo)\n\
81 used to determine where the bin and lib directories are \n\
82 created for a Windows build.\n\
83 --argsFile= The args are read from a file instead of the\n\
84 command line. Other command line args are ignored.\n\
85\n\
86Usage:\n\
87 finishSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath\n\
88 --cfgBldDir=ADirPath --prefix=ADirPath -m -d\n\
89\n\
90"; #TAG_PROGRAM_HELP_INFO
91
92#++---------------------------------------------------------------------------
93# Details: Exit the program on success. Called on program successfully done
94# its work. Returns a status result to the caller.
95# Args: vnResult - (R) 0 or greater indicating success.
96# vMsg - (R) Success message if any to show success to user.
97# Returns: None.
98# Throws: None.
99#--
100def program_exit_success( vnResult, vMsg ):
101 strMsg = "";
102
103 if vMsg.__len__() == 0:
104 strMsg = "%s (%d)" % (strExitMsgSuccess, vnResult);
105 else:
106 strMsg = "%s: %s (%d)" % (strExitMsgSuccess, vMsg, vnResult);
107 print strMsg;
108
109 sys.exit( vnResult );
110
111#++---------------------------------------------------------------------------
112# Details: Exit the program with error. Called on exit program failed its
113# task. Returns a status result to the caller.
114# Args: vnResult - (R) A negative number indicating error condition.
115# vMsg - (R) Error message to show to user.
116# Returns: None.
117# Throws: None.
118#--
119def program_exit_on_failure( vnResult, vMsg ):
120 print "%s%s (%d)" % (strExitMsgError, vMsg, vnResult);
121 sys.exit( vnResult );
122
123#++---------------------------------------------------------------------------
124# Details: Exit the program return a exit result number and print a message.
125# Positive numbers and zero are returned for success other error
126# occurred.
127# Args: vnResult - (R) A -ve (an error), 0 or +ve number (ok or status).
128# vMsg - (R) Error message to show to user.
129# Returns: None.
130# Throws: None.
131#--
132def program_exit( vnResult, vMsg ):
133 if vnResult >= 0:
134 program_exit_success( vnResult, vMsg );
135 else:
136 program_exit_on_failure( vnResult, vMsg );
137
138#++---------------------------------------------------------------------------
139# Details: Dump input parameters.
140# Args: vDictArgs - (R) Map of input args to value.
141# Returns: None.
142# Throws: None.
143#--
144def print_out_input_parameters( vDictArgs ):
145 for arg, val in vDictArgs.iteritems():
146 strEqs = "";
147 strQ = "";
148 if val.__len__() != 0:
149 strEqs = " =";
150 strQ = "\"";
151 print "%s%s%s %s%s%s\n" % (strParameter, arg, strEqs, strQ, val, strQ);
152
153#++---------------------------------------------------------------------------
154# Details: Validate the arguments passed to the program. This function exits
155# the program should error with the arguments be found.
156# Args: vArgv - (R) List of arguments and values.
157# Returns: Int - 0 = success, -ve = some failure.
158# Dict - Map of arguments names to argument values
159# Throws: None.
160#--
161def validate_arguments( vArgv ):
162 dbg = utilsDebug.CDebugFnVerbose( "validate_arguments()" );
163 strMsg = "";
164 dictArgs = {};
165 nResult = 0;
166 strListArgs = "hdm"; # Format "hiox:" = -h -i -o -x <arg>
167 listLongArgs = ["srcRoot=", "targetDir=", "cfgBldDir=", "prefix=", "cmakeBuildConfiguration=",
168 "argsFile"];
169 dictArgReq = { "-h": "o", # o = optional, m = mandatory
170 "-d": "o",
171 "-m": "o",
172 "--srcRoot": "m",
173 "--targetDir": "m",
174 "--cfgBldDir": "o",
175 "--prefix": "o",
176 "--cmakeBuildConfiguration": "o",
177 "--argsFile": "o" };
178
179 # Check for mandatory parameters
180 nResult, dictArgs, strMsg = utilsArgsParse.parse( vArgv, strListArgs,
181 listLongArgs,
182 dictArgReq,
183 strHelpInfo );
184 if nResult < 0:
185 program_exit_on_failure( nResult, strMsg );
186
187 # User input -h for help
188 if nResult == 1:
189 program_exit_success( 0, strMsg );
190
191 return (nResult, dictArgs);
192
193#++---------------------------------------------------------------------------
194# Details: Locate post process script language directory and the script within
195# and execute.
196# Args: vStrScriptLang - (R) Name of the script language to build.
197# vstrFinishFileName - (R) Prefix file name to build full name.
198# vDictArgs - (R) Program input parameters.
199# Returns: Int - 0 = Success, < 0 some error condition.
200# Str - Error message.
201# Throws: None.
202#--
203def run_post_process( vStrScriptLang, vstrFinishFileName, vDictArgs ):
204 dbg = utilsDebug.CDebugFnVerbose( "run_post_process()" );
205 nResult = 0;
206 strStatusMsg = "";
207 strScriptFile = vstrFinishFileName % vStrScriptLang;
208 strScriptFileDir = "%s%s/%s" % (vDictArgs[ "--srcRoot" ], "/scripts",
209 vStrScriptLang);
210 strScriptFilePath = "%s/%s" % (strScriptFileDir, strScriptFile);
211
212 # Check for the existence of the script file
213 strPath = os.path.normcase( strScriptFilePath );
214 bOk = os.path.exists( strPath );
215 if bOk == False:
216 strDir = os.path.normcase( strScriptFileDir );
217 strStatusMsg = strScriptNotFound % (strScriptFile, strDir);
218 return (-9, strStatusMsg);
219
220 if gbDbgFlag:
221 print strScriptLangFound % vStrScriptLang;
222 print strExecuteMsg % vStrScriptLang;
223
224 # Change where Python looks for our modules
225 strDir = os.path.normcase( strScriptFileDir );
226 sys.path.append( strDir );
227
228 # Execute the specific language script
229 dictArgs = vDictArgs; # Remove any args not required before passing on
230 strModuleName = strScriptFile[ : strScriptFile.__len__() - 3 ];
231 module = __import__( strModuleName );
232 nResult, strStatusMsg = module.main( dictArgs );
233
234 # Revert sys path
235 sys.path.remove( strDir );
236
237 return (nResult, strStatusMsg);
238
239#++---------------------------------------------------------------------------
240# Details: Step through each script language sub directory supported
241# and execute post processing script for each scripting language,
242# make sure the build script for that language exists.
243# For now the only language we support is Python, but we expect this
244# to change.
245# Args: vDictArgs - (R) Program input parameters.
246# Returns: Int - 0 = Success, < 0 some error condition.
247# Str - Error message.
248# Throws: None.
249#--
250def run_post_process_for_each_script_supported( vDictArgs ):
251 dbg = utilsDebug.CDebugFnVerbose( "run_post_process_for_each_script_supported()" );
252 nResult = 0;
253 strStatusMsg = "";
254 strScriptDir = vDictArgs[ "--srcRoot" ] + "/scripts";
255 strFinishFileName = "finishSwig%sLLDB.py";
256
257 # Check for the existence of the scripts folder
258 strScriptsDir = os.path.normcase( strScriptDir );
259 bOk = os.path.exists( strScriptsDir );
260 if bOk == False:
261 return (-8, strScriptDirNotFound);
262
263 # Look for any script language directories to build for
264 listDirs = [];
265 nDepth = 1;
266 for strPath, listDirs, listFiles in os.walk( strScriptDir ):
267 nDepth = nDepth - 1;
268 if nDepth == 0:
269 break;
270
271 if gbDbgFlag:
272 print strScriptLangsFound,
273 for dir in listDirs:
274 print dir,
275 print "\n";
276
277 # Iterate script directory find any script language directories
278 for scriptLang in listDirs:
279 dbg.dump_text( "Executing language script for \'%s\'" % scriptLang );
280 nResult, strStatusMsg = run_post_process( scriptLang, strFinishFileName,
281 vDictArgs );
282 if nResult < 0:
283 break;
284
285 if nResult < 0:
286 strTmp = strPostProcessError % scriptLang;
287 strTmp += strStatusMsg;
288 strStatusMsg = strTmp;
289
290 return (nResult, strStatusMsg);
291
292#++---------------------------------------------------------------------------
293# Details: Program's main() with arguments passed in from the command line.
294# Program either exits normally or with error from this function -
295# top most level function.
296# Args: vArgv - (R) List of arguments and values.
297# Returns: None
298# Throws: None.
299#--
300def main( vArgv ):
301 dbg = utilsDebug.CDebugFnVerbose( "main()" );
302 bOk = False;
303 dictArgs = {};
304 nResult = 0;
305 strMsg = "";
306
307 # The validate arguments fn will exit the program if tests fail
308 nResult, dictArgs = validate_arguments( vArgv );
309
310 eOSType = utilsOsType.determine_os_type();
311 if eOSType == utilsOsType.EnumOsType.Unknown:
312 program_exit( -4, strMsgErrorOsTypeUnknown );
313
314 global gbDbgFlag;
315 gbDbgFlag = dictArgs.has_key( "-d" );
316 if gbDbgFlag:
317 print_out_input_parameters( dictArgs );
318
319 # Check to see if we were called from the Makefile system. If we were, check
320 # if the caller wants SWIG to generate a dependency file.
321 # Not used in this program, but passed through to the language script file
322 # called by this program
323 global gbMakeFileFlag;
324 gbMakeFileFlag = dictArgs.has_key( "-m" );
325
326 nResult, strMsg = run_post_process_for_each_script_supported( dictArgs );
327
328 program_exit( nResult, strMsg );
329
330#-----------------------------------------------------------------------------
331#-----------------------------------------------------------------------------
332#-----------------------------------------------------------------------------
333
334#TAG_PROGRAM_HELP_INFO
335""" Details: Program main entry point.
336
337 --------------------------------------------------------------------------
338 Args: -h (optional) Print help information on this program.
339 -d (optional) Determines whether or not this script
340 outputs additional information when running.
341 -m (optional) Specify called from Makefile system. If given locate
342 the LLDBWrapPython.cpp in --srcRoot/source folder
343 else in the --targetDir folder.
344 --srcRoot= The root of the lldb source tree.
345 --targetDir= Where the lldb framework/shared library gets put.
346 --cfgBldDir= Where the buildSwigPythonLLDB.py program will
347 (optional) put the lldb.py file it generated from running
348 SWIG.
349 --prefix= Is the root directory used to determine where
350 (optional) third-party modules for scripting languages should
351 be installed. Where non-Darwin systems want to put
352 the .py and .so files so that Python can find them
353 automatically. Python install directory.
354 --cmakeBuildConfiguration= (optional) Is the build configuration(Debug, Release, RelWithDebugInfo)\n\
355 used to determine where the bin and lib directories are \n\
356 created for a Windows build.\n\
357 --argsFile= The args are read from a file instead of the
358 command line. Other command line args are ignored.
359 Usage:
360 finishSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath
361 --cfgBldDir=ADirPath --prefix=ADirPath -m -d
362
363 Results: 0 Success
364 -1 Error - invalid parameters passed.
365 -2 Error - incorrect number of mandatory parameters passed.
366
367 -4 Error - unable to determine OS type.
368 -5 Error - program not run with name of "__main__".
369 -8 Error - unable to locate the scripts folder.
370 -9 Error - unable to locate the post process language script
371 file.
372
373 -100+ - Error messages from the child language script file.
374
375 --------------------------------------------------------------------------
376
377"""
378
379# Called using "__main__" when not imported i.e. from the command line
380if __name__ == "__main__":
381 utilsDebug.CDebugFnVerbose.bVerboseOn = gbDbgVerbose;
382 dbg = utilsDebug.CDebugFnVerbose( "__main__" );
383 main( sys.argv[ 1: ] );
384else:
385 program_exit( -5, strMsgErrorNoMain );
386