[lldb] move package generation from python to cmake

Summary: This is the last part. And we can remove the python script.

Subscribers: lldb-commits, mgorny

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D69019
This commit is contained in:
Haibo Huang 2019-10-15 22:22:53 -07:00
parent 651b5e725e
commit 99046b873f
7 changed files with 61 additions and 1124 deletions

View File

@ -88,12 +88,6 @@ if(LLDB_INCLUDE_TESTS)
endif()
if (NOT LLDB_DISABLE_PYTHON)
if(NOT LLDB_BUILD_FRAMEWORK)
set(use_python_wrapper_from_src_dir -m)
endif()
if(LLDB_USE_SYSTEM_SIX)
set(use_six_py_from_system --useSystemSix)
endif()
get_target_property(lldb_scripts_dir swig_wrapper BINARY_DIR)
get_target_property(liblldb_build_dir liblldb LIBRARY_OUTPUT_DIRECTORY)
@ -105,21 +99,8 @@ if (NOT LLDB_DISABLE_PYTHON)
# Add a Post-Build Event to copy over Python files and create the symlink
# to liblldb.so for the Python API(hardlink on Windows).
add_custom_target(finish_swig ALL
add_custom_target(finish_swig ALL VERBATIM
COMMAND ${CMAKE_COMMAND} -E make_directory ${lldb_python_build_path}
COMMAND
${PYTHON_EXECUTABLE} ${LLDB_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py
--srcRoot=${LLDB_SOURCE_DIR}
--targetDir=${liblldb_build_dir}
--cfgBldDir=${lldb_scripts_dir}
--prefix=${CMAKE_BINARY_DIR}
--cmakeBuildConfiguration=${CMAKE_CFG_INTDIR}
--lldbLibDir=lib${LLVM_LIBDIR_SUFFIX}
--lldbPythonPath=${lldb_python_build_path}
${use_python_wrapper_from_src_dir}
${use_six_py_from_system}
VERBATIM
DEPENDS ${LLDB_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py
DEPENDS ${lldb_scripts_dir}/lldb.py
COMMENT "Python script sym-linking LLDB Python API")
@ -145,6 +126,49 @@ if (NOT LLDB_DISABLE_PYTHON)
${lldb_python_heap_dir})
endif()
function(create_python_package target pkg_dir)
cmake_parse_arguments(ARG "" "" "FILES" ${ARGN})
if(ARG_FILES)
set(copy_cmd COMMAND ${CMAKE_COMMAND} -E copy ${ARG_FILES} ${pkg_dir})
endif()
add_custom_command(TARGET ${target} POST_BUILD VERBATIM
COMMAND ${CMAKE_COMMAND} -E make_directory ${pkg_dir}
${copy_cmd}
COMMAND ${PYTHON_EXECUTABLE} "${LLDB_SOURCE_DIR}/scripts/Python/createPythonInit.py"
${pkg_dir} ${ARG_FILES}
WORKING_DIRECTORY ${lldb_python_build_path})
endfunction()
add_custom_command(TARGET finish_swig POST_BUILD VERBATIM
COMMAND ${CMAKE_COMMAND} -E copy
"${LLDB_SOURCE_DIR}/source/Interpreter/embedded_interpreter.py" ${lldb_python_build_path})
create_python_package(finish_swig "formatters/cpp"
FILES "${LLDB_SOURCE_DIR}/examples/synthetic/gnu_libstdcpp.py"
"${LLDB_SOURCE_DIR}/examples/synthetic/libcxx.py")
# Make an empty __init__.py in lldb/runtime as this is required for
# Python to recognize lldb.runtime as a valid package (and hence,
# lldb.runtime.objc as a valid contained package)
create_python_package(finish_swig "runtime")
# Having these files copied here ensure that lldb/formatters is a
# valid package itself
create_python_package(finish_swig "formatters"
FILES "${LLDB_SOURCE_DIR}/examples/summaries/cocoa/cache.py"
"${LLDB_SOURCE_DIR}/examples/summaries/synth.py"
"${LLDB_SOURCE_DIR}/examples/summaries/cocoa/metrics.py"
"${LLDB_SOURCE_DIR}/examples/summaries/cocoa/attrib_fromdict.py"
"${LLDB_SOURCE_DIR}/examples/summaries/cocoa/Logger.py")
create_python_package(finish_swig "utils"
FILES "${LLDB_SOURCE_DIR}/examples/python/symbolication.py")
if(APPLE)
create_python_package(finish_swig "macosx"
FILES "${LLDB_SOURCE_DIR}/examples/python/crashlog.py"
"${LLDB_SOURCE_DIR}/examples/darwin/heap_find/heap.py")
create_python_package(finish_swig "diagnose"
FILES "${LLDB_SOURCE_DIR}/examples/python/diagnose_unwind.py"
"${LLDB_SOURCE_DIR}/examples/python/diagnose_nsstring.py")
endif()
function(create_relative_symlink target dest_file output_dir output_name)
get_filename_component(dest_file ${dest_file} ABSOLUTE)
get_filename_component(output_dir ${output_dir} ABSOLUTE)

View File

@ -0,0 +1,17 @@
import os
import sys
pkgRelDir = sys.argv[1]
pkgFiles = sys.argv[2:]
getFileName = lambda f: os.path.splitext(os.path.basename(f))[0]
importNames = ', '.join('"{}"'.format(getFileName(f)) for f in pkgFiles)
script = """__all__ = [{import_names}]
for x in __all__:
__import__('lldb.{pkg_name}.' + x)
""".format(import_names=importNames, pkg_name=pkgRelDir.replace("/", "."))
pkgIniFile = os.path.normpath(os.path.join(pkgRelDir, "__init__.py"))
with open(pkgIniFile, "w") as f:
f.write(script)

View File

@ -1,332 +0,0 @@
""" Python SWIG post process script for each language
--------------------------------------------------------------------------
File: finishSwigPythonLLDB.py
Overview: Python script(s) to post process SWIG Python C++ Script
Bridge wrapper code on the Windows/LINUX/OSX platform.
The Python scripts are equivalent to the shell script (.sh)
files.
For the Python script interpreter (external to liblldb) to
be able to import and use the lldb module, there must be
two files, lldb.py and _lldb.so, that it can find. lldb.py
is generated by SWIG at the same time it generates the C++
file. _lldb.so is actually a symlink file that points to
the LLDB shared library/framework.
The Python script interpreter needs to be able to
automatically find these two files. On Darwin systems it
searches in the LLDB.framework, as well as in all the normal
Python search paths. On non-Darwin systems these files will
need to be put some place where Python will find them.
This shell script creates the _lldb.so symlink in the
appropriate place, and copies the lldb.py (and
embedded_interpreter.py) file to the correct directory.
Gotchas: Python debug complied pythonXX_d.lib is required for SWIG
to build correct LLDBWrapperPython.cpp in order for Visual
Studio to compile successfully. The release version of the
Python lib will not work (20/12/2013).
LLDB (dir) CMakeLists.txt uses windows environmental
variables $PYTHON_INCLUDE and $PYTHON_LIB to locate
Python files required for the build.
Copyright: None.
--------------------------------------------------------------------------
"""
# Python modules:
import os # Provide directory and file handling, determine OS information
import sys # System specific parameters and functions
import shutil # High-level operations on files and collections of files
import ctypes # Invoke Windows API for creating symlinks
# Third party modules:
# In-house modules:
import utilsOsType # Determine the OS type this script is running on
import utilsDebug # Debug Python scripts
# User facing text:
strMsgOsVersion = "The current OS is %s"
strMsgPyVersion = "The Python version is %d.%d"
strErrMsgProgFail = "Program failure: "
strErrMsgLLDBPyFileNotNotFound = "Unable to locate lldb.py at path '%s'"
strMsgCopyLLDBPy = "Copying lldb.py from '%s' to '%s'"
strErrMsgFrameWkPyDirNotExist = "Unable to find the LLDB.framework directory '%s'"
strMsgCreatePyPkgCopyPkgFile = "create_py_pkg: Copied file '%s' to folder '%s'"
strMsgCreatePyPkgInitFile = "create_py_pkg: Creating pakage init file '%s'"
strMsgCreatePyPkgMkDir = "create_py_pkg: Created folder '%s'"
strMsgConfigBuildDir = "Configuration build directory located at '%s'"
strMsgFoundLldbFrameWkDir = "Found '%s'"
strMsgPyFileLocatedHere = "Python file will be put in '%s'"
strMsgFrameWkPyExists = "Python output folder '%s' already exists"
strMsgFrameWkPyMkDir = "Python output folder '%s' will be created"
strErrMsgCreateFrmWkPyDirFailed = "Unable to create directory '%s' error: %s"
strMsgSymlinkExists = "Symlink for '%s' already exists"
strMsgSymlinkMk = "Creating symlink for %s (%s -> %s)"
strErrMsgCpLldbpy = "copying lldb to lldb package directory"
strErrMsgCreatePyPkgMissingSlash = "Parameter 3 fn create_py_pkg() missing slash"
strErrMsgMkLinkExecute = "Command mklink failed: %s"
strErrMsgMakeSymlink = "creating symbolic link"
strErrMsgUnexpected = "Unexpected error: %s"
strMsgCopySixPy = "Copying six.py from '%s' to '%s'"
strErrMsgCopySixPyFailed = "Unable to copy '%s' to '%s'"
#++---------------------------------------------------------------------------
# Details: Create Python packages and Python __init__ files.
# Args: vDictArgs - (R) Program input parameters.
# vstrFrameworkPythonDir - (R) Python framework directory.
# vstrPkgDir - (R) Destination for copied Python files.
# vListPkgFiles - (R) List of source Python files.
# Returns: Bool - True = function success, False = failure.
# Str - Error description on task failure.
# Throws: None.
#--
def create_py_pkg(
vDictArgs,
vstrFrameworkPythonDir,
vstrPkgDir,
vListPkgFiles):
dbg = utilsDebug.CDebugFnVerbose("Python script create_py_pkg()")
dbg.dump_object("Package file(s):", vListPkgFiles)
bDbg = "-d" in vDictArgs
bOk = True
strMsg = ""
if vstrPkgDir.__len__() != 0 and vstrPkgDir[0] != "/":
bOk = False
strMsg = strErrMsgCreatePyPkgMissingSlash
return (bOk, strMsg)
strPkgName = vstrPkgDir
strPkgName = "lldb" + strPkgName.replace("/", ".")
strPkgDir = vstrFrameworkPythonDir
strPkgDir += vstrPkgDir
strPkgDir = os.path.normcase(strPkgDir)
if not(os.path.exists(strPkgDir) and os.path.isdir(strPkgDir)):
if bDbg:
print((strMsgCreatePyPkgMkDir % strPkgDir))
os.makedirs(strPkgDir)
for strPkgFile in vListPkgFiles:
if os.path.exists(strPkgFile) and os.path.isfile(strPkgFile):
if bDbg:
print((strMsgCreatePyPkgCopyPkgFile % (strPkgFile, strPkgDir)))
shutil.copy(strPkgFile, strPkgDir)
# Create a packet init files if there wasn't one
strPkgIniFile = os.path.normpath(os.path.join(strPkgDir, "__init__.py"))
if os.path.exists(strPkgIniFile) and os.path.isfile(strPkgIniFile):
return (bOk, strMsg)
strPyScript = "__all__ = ["
strDelimiter = ""
for strPkgFile in vListPkgFiles:
if os.path.exists(strPkgFile) and os.path.isfile(strPkgFile):
strBaseName = os.path.basename(strPkgFile)
nPos = strBaseName.find(".")
if nPos != -1:
strBaseName = strBaseName[0: nPos]
strPyScript += "%s\"%s\"" % (strDelimiter, strBaseName)
strDelimiter = ","
strPyScript += "]\n"
strPyScript += "for x in __all__:\n"
strPyScript += "\t__import__('%s.' + x)" % strPkgName
if bDbg:
print((strMsgCreatePyPkgInitFile % strPkgIniFile))
file = open(strPkgIniFile, "w")
file.write(strPyScript)
file.close()
return (bOk, strMsg)
#++---------------------------------------------------------------------------
# Details: Retrieve the directory path for Python's dist_packages/
# site_package folder depending on the type of OS platform being
# used.
# Args: vDictArgs - (R) Program input parameters.
# Returns: Bool - True = function success, False = failure.
# Str - Python Framework directory path.
# strErrMsg - Error description on task failure.
# Throws: None.
#--
def get_framework_python_dir(vDictArgs):
dbg = utilsDebug.CDebugFnVerbose(
"Python script get_framework_python_dir()")
bOk = True
strErrMsg = ""
strWkDir = os.path.normpath(vDictArgs["--lldbPythonPath"])
return (bOk, strWkDir, strErrMsg)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
""" Details: Program main entry point fn. Called by another Python script.
--------------------------------------------------------------------------
Details: This script is to be called by another Python script. It is not
intended to be called directly i.e from the command line.
Args: vDictArgs - (R) Map of parameter names to values.
-d (optional) Determines whether or not this script
outputs additional information when running.
-m (optional) Specify called from Makefile system. If given locate
the LLDBWrapPython.cpp in --srcRoot/source folder
else in the --targetDir folder.
--srcRoot The root of the lldb source tree.
--targetDir Where the lldb framework/shared library gets put.
--cfgBlddir Where the buildSwigPythonLLDB.py program will
(optional) put the lldb.py file it generated from running
SWIG.
--prefix Is the root directory used to determine where
(optional) third-party modules for scripting languages should
be installed. Where non-Darwin systems want to put
the .py and .so files so that Python can find them
automatically. Python install directory.
--lldbLibDir The name of the directory containing liblldb.so.
(optional) "lib" by default.
Results: 0 Success
-100+ Error from this script to the caller script.
-100 Error program failure with optional message.
--------------------------------------------------------------------------
"""
def main(vDictArgs):
dbg = utilsDebug.CDebugFnVerbose("Python script main()")
bOk = True
strMsg = ""
strErrMsgProgFail = ""
bDbg = "-d" in vDictArgs
eOSType = utilsOsType.determine_os_type()
if bDbg:
pyVersion = sys.version_info
print((strMsgOsVersion % utilsOsType.EnumOsType.name_of(eOSType)))
print((strMsgPyVersion % (pyVersion[0], pyVersion[1])))
bOk, strFrameworkPythonDir, strMsg = get_framework_python_dir(vDictArgs)
strRoot = os.path.normpath(vDictArgs["--srcRoot"])
if bOk:
# lldb
listPkgFiles = [
os.path.join(
strRoot,
"source",
"Interpreter",
"embedded_interpreter.py")]
bOk, strMsg = create_py_pkg(
vDictArgs, strFrameworkPythonDir, "", listPkgFiles)
if bOk:
# lldb/formatters/cpp
listPkgFiles = [
os.path.join(
strRoot,
"examples",
"synthetic",
"gnu_libstdcpp.py"),
os.path.join(
strRoot,
"examples",
"synthetic",
"libcxx.py")]
bOk, strMsg = create_py_pkg(
vDictArgs, strFrameworkPythonDir, "/formatters/cpp", listPkgFiles)
if bOk:
# Make an empty __init__.py in lldb/runtime as this is required for
# Python to recognize lldb.runtime as a valid package (and hence,
# lldb.runtime.objc as a valid contained package)
listPkgFiles = []
bOk, strMsg = create_py_pkg(
vDictArgs, strFrameworkPythonDir, "/runtime", listPkgFiles)
if bOk:
# lldb/formatters
# Having these files copied here ensure that lldb/formatters is a
# valid package itself
listPkgFiles = [
os.path.join(
strRoot, "examples", "summaries", "cocoa", "cache.py"), os.path.join(
strRoot, "examples", "summaries", "synth.py"), os.path.join(
strRoot, "examples", "summaries", "cocoa", "metrics.py"), os.path.join(
strRoot, "examples", "summaries", "cocoa", "attrib_fromdict.py"), os.path.join(
strRoot, "examples", "summaries", "cocoa", "Logger.py")]
bOk, strMsg = create_py_pkg(
vDictArgs, strFrameworkPythonDir, "/formatters", listPkgFiles)
if bOk:
# lldb/utils
listPkgFiles = [
os.path.join(
strRoot,
"examples",
"python",
"symbolication.py")]
bOk, strMsg = create_py_pkg(
vDictArgs, strFrameworkPythonDir, "/utils", listPkgFiles)
if bOk and (eOSType == utilsOsType.EnumOsType.Darwin):
# lldb/macosx
listPkgFiles = [
os.path.join(
strRoot,
"examples",
"python",
"crashlog.py"),
os.path.join(
strRoot,
"examples",
"darwin",
"heap_find",
"heap.py")]
bOk, strMsg = create_py_pkg(
vDictArgs, strFrameworkPythonDir, "/macosx", listPkgFiles)
if bOk and (eOSType == utilsOsType.EnumOsType.Darwin):
# lldb/diagnose
listPkgFiles = [
os.path.join(
strRoot,
"examples",
"python",
"diagnose_unwind.py"),
os.path.join(
strRoot,
"examples",
"python",
"diagnose_nsstring.py")]
bOk, strMsg = create_py_pkg(
vDictArgs, strFrameworkPythonDir, "/diagnose", listPkgFiles)
if bOk:
return (0, strMsg)
else:
strErrMsgProgFail += strMsg
return (-100, strErrMsgProgFail)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# This script can be called by another Python script by calling the main()
# function directly
if __name__ == "__main__":
print("Script cannot be called directly, called by finishSwigWrapperClasses.py")

View File

@ -1,403 +0,0 @@
""" Post process SWIG Bridge wrapper code Python script for Windows/LINUX/OSX platform
--------------------------------------------------------------------------
File: finishSwigWrapperClasses.py
Overview: Python script(s) to finish off the SWIG Python C++ Script
Bridge wrapper code on the Windows/LINUX/OSX platform.
The Python scripts are equivalent to the shell script (.sh)
files.
We use SWIG to create a C++ file containing the appropriate
wrapper classes and functions for each scripting language,
before liblldb is built (thus the C++ file can be compiled
into liblldb. In some cases, additional work may need to be
done after liblldb has been compiled, to make the scripting
language stuff fully functional. Any such post-processing
is handled through the Python scripts called here.
Gotchas: None.
Copyright: None.
--------------------------------------------------------------------------
"""
# Python modules:
import sys # Provide argument parsing
import os # Provide directory and file handling
# Third party modules:
# In-house modules:
import utilsArgsParse # Parse and validate this script's input arguments
import utilsOsType # Determine the OS type this script is running on
import utilsDebug # Debug Python scripts
# Instantiations:
# True = Turn on script function tracing, False = off.
gbDbgVerbose = False
gbDbgFlag = False # Global debug mode flag, set by input parameter
# --dbgFlag. True = operate in debug mode.
# True = yes called from makefile system, False = not.
gbMakeFileFlag = False
# User facing text:
strMsgErrorNoMain = "Program called by another Python script not allowed"
strExitMsgSuccess = "Program successful"
strExitMsgError = "Program error: "
strParameter = "Parameter: "
strMsgErrorOsTypeUnknown = "Unable to determine OS type"
strScriptDirNotFound = "Unable to locate the script directory \'/script\'"
strScriptLangsFound = "Found the following script languages:"
strPostProcessError = "Executing \'%s\' post process script failed: "
strScriptNotFound = "Unable to locate the post process script file \'%s\' in \'%s\'"
strScriptLangFound = "Found \'%s\' build script."
strScriptLangsFound = "Found the following script languages:"
strExecuteMsg = "Executing \'%s\' build script..."
strExecuteError = "Executing \'%s\' build script failed: "
strHelpInfo = "\
Python script(s) to finish off the SWIG Python C++ Script \n\
Bridge wrapper code on the Windows/LINUX/OSX platform. The Python \n\
scripts are equivalent to the shell script (.sh) files \n\
run on others platforms.\n\
Args: -h (optional) Print help information on this program.\n\
-d (optional) Determines whether or not this script\n\
outputs additional information when running.\n\
-m (optional) Specify called from Makefile system.\n\
--srcRoot= The root of the lldb source tree.\n\
--targetDir= Where the lldb framework/shared library gets put.\n\
--cfgBldDir= (optional) Where the build-swig-Python-LLDB.py program \n\
will put the lldb.py file it generated from running\n\
SWIG.\n\
--prefix= (optional) Is the root directory used to determine where\n\
third-party modules for scripting languages should\n\
be installed. Where non-Darwin systems want to put\n\
the .py and .so files so that Python can find them\n\
automatically. Python install directory.\n\
--lldbLibDir (optional) The name of the directory containing liblldb.so.\n\
\"lib\" by default.\n\
--cmakeBuildConfiguration= (optional) Is the build configuration(Debug, Release, RelWithDebugInfo)\n\
used to determine where the bin and lib directories are \n\
created for a Windows build.\n\
--argsFile= The args are read from a file instead of the\n\
command line. Other command line args are ignored.\n\
--useSystemSix Use system six.py version.\n\
\n\
Usage:\n\
finishSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath\n\
--cfgBldDir=ADirPath --prefix=ADirPath --lldbLibDir=ADirPath -m -d\n\
\n\
" # TAG_PROGRAM_HELP_INFO
#++---------------------------------------------------------------------------
# Details: Exit the program on success. Called on program successfully done
# its work. Returns a status result to the caller.
# Args: vnResult - (R) 0 or greater indicating success.
# vMsg - (R) Success message if any to show success to user.
# Returns: None.
# Throws: None.
#--
def program_exit_success(vnResult, vMsg):
strMsg = ""
if vMsg.__len__() != 0:
strMsg = "%s: %s (%d)" % (strExitMsgSuccess, vMsg, vnResult)
print(strMsg)
sys.exit(vnResult)
#++---------------------------------------------------------------------------
# Details: Exit the program with error. Called on exit program failed its
# task. Returns a status result to the caller.
# Args: vnResult - (R) A negative number indicating error condition.
# vMsg - (R) Error message to show to user.
# Returns: None.
# Throws: None.
#--
def program_exit_on_failure(vnResult, vMsg):
print(("%s%s (%d)" % (strExitMsgError, vMsg, vnResult)))
sys.exit(vnResult)
#++---------------------------------------------------------------------------
# Details: Exit the program return a exit result number and print a message.
# Positive numbers and zero are returned for success other error
# occurred.
# Args: vnResult - (R) A -ve (an error), 0 or +ve number (ok or status).
# vMsg - (R) Error message to show to user.
# Returns: None.
# Throws: None.
#--
def program_exit(vnResult, vMsg):
if vnResult >= 0:
program_exit_success(vnResult, vMsg)
else:
program_exit_on_failure(vnResult, vMsg)
#++---------------------------------------------------------------------------
# Details: Dump input parameters.
# Args: vDictArgs - (R) Map of input args to value.
# Returns: None.
# Throws: None.
#--
def print_out_input_parameters(vDictArgs):
for arg, val in list(vDictArgs.items()):
strEqs = ""
strQ = ""
if val.__len__() != 0:
strEqs = " ="
strQ = "\""
print(("%s%s%s %s%s%s\n" % (strParameter, arg, strEqs, strQ, val, strQ)))
#++---------------------------------------------------------------------------
# Details: Validate the arguments passed to the program. This function exits
# the program should error with the arguments be found.
# Args: vArgv - (R) List of arguments and values.
# Returns: Int - 0 = success, -ve = some failure.
# Dict - Map of arguments names to argument values
# Throws: None.
#--
def validate_arguments(vArgv):
dbg = utilsDebug.CDebugFnVerbose("validate_arguments()")
strMsg = ""
dictArgs = {}
nResult = 0
strListArgs = "hdm" # Format "hiox:" = -h -i -o -x <arg>
listLongArgs = [
"srcRoot=",
"targetDir=",
"cfgBldDir=",
"prefix=",
"cmakeBuildConfiguration=",
"lldbLibDir=",
"lldbPythonPath=",
"argsFile",
"useSystemSix"]
dictArgReq = {"-h": "o", # o = optional, m = mandatory
"-d": "o",
"-m": "o",
"--srcRoot": "m",
"--targetDir": "m",
"--cfgBldDir": "o",
"--prefix": "o",
"--cmakeBuildConfiguration": "o",
"--lldbLibDir": "o",
"--argsFile": "o",
"--useSystemSix": "o",
"--lldbPythonPath": "m"}
# Check for mandatory parameters
nResult, dictArgs, strMsg = utilsArgsParse.parse(vArgv, strListArgs,
listLongArgs,
dictArgReq,
strHelpInfo)
if nResult < 0:
program_exit_on_failure(nResult, strMsg)
# User input -h for help
if nResult == 1:
program_exit_success(0, strMsg)
return (nResult, dictArgs)
#++---------------------------------------------------------------------------
# Details: Locate post process script language directory and the script within
# and execute.
# Args: vStrScriptLang - (R) Name of the script language to build.
# vstrFinishFileName - (R) Prefix file name to build full name.
# vDictArgs - (R) Program input parameters.
# Returns: Int - 0 = Success, < 0 some error condition.
# Str - Error message.
# Throws: None.
#--
def run_post_process(vStrScriptLang, vstrFinishFileName, vDictArgs):
dbg = utilsDebug.CDebugFnVerbose("run_post_process()")
nResult = 0
strStatusMsg = ""
strScriptFile = vstrFinishFileName % vStrScriptLang
strScriptFileDir = os.path.normpath(
os.path.join(
vDictArgs["--srcRoot"],
"scripts",
vStrScriptLang))
strScriptFilePath = os.path.join(strScriptFileDir, strScriptFile)
# Check for the existence of the script file
strPath = os.path.normcase(strScriptFilePath)
bOk = os.path.exists(strPath)
if not bOk:
strDir = os.path.normcase(strScriptFileDir)
strStatusMsg = strScriptNotFound % (strScriptFile, strDir)
return (-9, strStatusMsg)
if gbDbgFlag:
print((strScriptLangFound % vStrScriptLang))
print((strExecuteMsg % vStrScriptLang))
# Change where Python looks for our modules
strDir = os.path.normcase(strScriptFileDir)
sys.path.append(strDir)
# Execute the specific language script
dictArgs = vDictArgs # Remove any args not required before passing on
strModuleName = strScriptFile[: strScriptFile.__len__() - 3]
module = __import__(strModuleName)
nResult, strStatusMsg = module.main(dictArgs)
# Revert sys path
sys.path.remove(strDir)
return (nResult, strStatusMsg)
#++---------------------------------------------------------------------------
# Details: Step through each script language sub directory supported
# and execute post processing script for each scripting language,
# make sure the build script for that language exists.
# For now the only language we support is Python, but we expect this
# to change.
# Args: vDictArgs - (R) Program input parameters.
# Returns: Int - 0 = Success, < 0 some error condition.
# Str - Error message.
# Throws: None.
#--
def run_post_process_for_each_script_supported(vDictArgs):
dbg = utilsDebug.CDebugFnVerbose(
"run_post_process_for_each_script_supported()")
nResult = 0
strStatusMsg = ""
strScriptDir = os.path.normpath(
os.path.join(
vDictArgs["--srcRoot"],
"scripts"))
strFinishFileName = "finishSwig%sLLDB.py"
# Check for the existence of the scripts folder
strScriptsDir = os.path.normcase(strScriptDir)
bOk = os.path.exists(strScriptsDir)
if not bOk:
return (-8, strScriptDirNotFound)
# Look for any script language directories to build for
listDirs = ["Python"]
# Iterate script directory find any script language directories
for scriptLang in listDirs:
dbg.dump_text("Executing language script for \'%s\'" % scriptLang)
nResult, strStatusMsg = run_post_process(
scriptLang, strFinishFileName, vDictArgs)
if nResult < 0:
break
if nResult < 0:
strTmp = strPostProcessError % scriptLang
strTmp += strStatusMsg
strStatusMsg = strTmp
return (nResult, strStatusMsg)
#++---------------------------------------------------------------------------
# Details: Program's main() with arguments passed in from the command line.
# Program either exits normally or with error from this function -
# top most level function.
# Args: vArgv - (R) List of arguments and values.
# Returns: None
# Throws: None.
#--
def main(vArgv):
dbg = utilsDebug.CDebugFnVerbose("main()")
bOk = False
dictArgs = {}
nResult = 0
strMsg = ""
# The validate arguments fn will exit the program if tests fail
nResult, dictArgs = validate_arguments(vArgv)
eOSType = utilsOsType.determine_os_type()
if eOSType == utilsOsType.EnumOsType.Unknown:
program_exit(-4, strMsgErrorOsTypeUnknown)
global gbDbgFlag
gbDbgFlag = "-d" in dictArgs
if gbDbgFlag:
print_out_input_parameters(dictArgs)
nResult, strMsg = run_post_process_for_each_script_supported(dictArgs)
program_exit(nResult, strMsg)
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
# TAG_PROGRAM_HELP_INFO
""" Details: Program main entry point.
--------------------------------------------------------------------------
Args: -h (optional) Print help information on this program.
-d (optional) Determines whether or not this script
outputs additional information when running.
-m (optional) Specify called from Makefile system. If given locate
the LLDBWrapPython.cpp in --srcRoot/source folder
else in the --targetDir folder.
--srcRoot= The root of the lldb source tree.
--targetDir= Where the lldb framework/shared library gets put.
--cfgBldDir= Where the buildSwigPythonLLDB.py program will
(optional) put the lldb.py file it generated from running
SWIG.
--prefix= Is the root directory used to determine where
(optional) third-party modules for scripting languages should
be installed. Where non-Darwin systems want to put
the .py and .so files so that Python can find them
automatically. Python install directory.
--cmakeBuildConfiguration= (optional) Is the build configuration(Debug, Release, RelWithDebugInfo)\n\
used to determine where the bin and lib directories are \n\
created for a Windows build.\n\
--lldbLibDir= The name of the directory containing liblldb.so.
(optional) "lib" by default.
--argsFile= The args are read from a file instead of the
command line. Other command line args are ignored.
--useSystemSix Use system six.py version.
Usage:
finishSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath
--cfgBldDir=ADirPath --prefix=ADirPath --lldbLibDir=ADirPath -m -d
--useSystemSix
Results: 0 Success
-1 Error - invalid parameters passed.
-2 Error - incorrect number of mandatory parameters passed.
-4 Error - unable to determine OS type.
-5 Error - program not run with name of "__main__".
-8 Error - unable to locate the scripts folder.
-9 Error - unable to locate the post process language script
file.
-100+ - Error messages from the child language script file.
--------------------------------------------------------------------------
"""
# Called using "__main__" when not imported i.e. from the command line
if __name__ == "__main__":
utilsDebug.CDebugFnVerbose.bVerboseOn = gbDbgVerbose
dbg = utilsDebug.CDebugFnVerbose("__main__")
main(sys.argv[1:])
else:
program_exit(-5, strMsgErrorNoMain)

View File

@ -1,141 +0,0 @@
""" Utility module handle program args and give help
--------------------------------------------------------------------------
File: utilsArgsParse.py
Overview: Python module to parse and validate program parameters
against those required by the program whether mandatory
or optional.
Also give help information on arguments required by the
program.
Gotchas: None.
Copyright: None.
--------------------------------------------------------------------------
"""
# Python modules:
import getopt # Parse command line arguments
# Third party modules:
# In-house modules:
# Instantiations:
# User facing text:
strMsgErrorInvalidParameters = "Invalid parameters entered, -h for help. \nYou entered:\n"
strMsgErrorInvalidNoParams = "No parameters entered, -h for help\n"
strMsgErrorNumberParameters = "Number of parameters entered incorrect, %d parameters required. You entered:\n"
strMsgArgFileNotImplemented = "Sorry the --argFile is not implemented"
#++---------------------------------------------------------------------------
# Details: Validate the arguments passed in against the mandatory and
# optional arguments specified. The argument format for the parameters
# is required to work with the module getopt function getopt().
# Parameter vDictArgReq specifies which parameters are mandatory and
# which are optional. The format is for example:
# dictArgReq = {"-h": "o", # o = optional, m = mandatory
# "-m": "m",
# "--targetDir": "m",
# "--cfgBldDir": "o" }
# Args: vArgv - (R) List of arguments and values.
# vstrListArgs - (R) List of small arguments.
# vListLongArgs - (R) List of long arguments.
# vDictArgReq - (R) Map of arguments required.
# vstrHelpInfo - (R) Formatted help text.
# Returns: Int - 0 success.
# 1 success display information, do nothing else.
# -1 error invalid parameters.
# -2 error incorrect number of mandatory parameters.
# Dict - Map of arguments names to argument values
# Str - Error message.
# Throws: None.
#--
def parse(vArgv, vstrListArgs, vListLongArgs, vDictArgReq, vstrHelpInfo):
dictArgs = {}
dictDummy = {}
strDummy = ""
# Validate parameters above and error on not recognised
try:
dictOptsNeeded, dictArgsLeftOver = getopt.getopt(vArgv,
vstrListArgs,
vListLongArgs)
except getopt.GetoptError:
strMsg = strMsgErrorInvalidParameters
strMsg += str(vArgv)
return (-1, dictDummy, strMsg)
if len(dictOptsNeeded) == 0:
strMsg = strMsgErrorInvalidNoParams
return (-1, dictDummy, strMsg)
# Look for help -h before anything else
for opt, arg in dictOptsNeeded:
if opt == '-h':
return (1, dictDummy, vstrHelpInfo)
# Look for the --argFile if found ignore other command line arguments
for opt, arg in dictOptsNeeded:
if opt == '--argsFile':
return (1, dictDummy, strMsgArgFileNotImplemented)
# Count the number of mandatory args required (if any one found)
countMandatory = 0
for opt, man in list(vDictArgReq.items()):
if man == "m":
countMandatory = countMandatory + 1
# Extract short args
listArgs = []
for arg in vstrListArgs:
if (arg == '-h') or (arg == ':'):
continue
listArgs.append(arg)
# Append to arg dictionary the option and its value
bFoundNoInputValue = False
countMandatoryOpts = 0
for opt, val in dictOptsNeeded:
match = 0
for arg in listArgs:
argg = "-" + arg
if opt == argg:
if "m" == vDictArgReq[opt]:
countMandatoryOpts = countMandatoryOpts + 1
dictArgs[opt] = val
match = 1
break
if match == 0:
for arg in vListLongArgs:
argg = "--" + arg.rstrip('=')
if opt == argg:
if "m" == vDictArgReq[opt]:
countMandatoryOpts = countMandatoryOpts + 1
dictArgs[opt] = val
if arg[-1:] == '=' and val.__len__() == 0:
bFoundNoInputValue = True
break
# Do any of the long arguments not have a value attached
if bFoundNoInputValue:
strMsg = strMsgErrorInvalidParameters
strMsg += str(vArgv)
return (-1, dictDummy, strMsg)
# Debug only
# print countMandatoryOpts
# print countMandatory
# Do we have the exact number of mandatory arguments
if (countMandatoryOpts > 0) and (countMandatory != countMandatoryOpts):
strMsg = strMsgErrorNumberParameters % countMandatory
strMsg += str(vArgv)
return (-2, dictDummy, strMsg)
return (0, dictArgs, strDummy)

View File

@ -1,125 +0,0 @@
""" Utility module to help debug Python scripts
--------------------------------------------------------------------------
File: utilsDebug.py
Overview: Python module to supply functions to help debug Python
scripts.
Gotchas: None.
Copyright: None.
--------------------------------------------------------------------------
"""
# Python modules:
import sys
# Third party modules:
# In-house modules:
# Instantiations:
#-----------------------------------------------------------------------------
# Details: Class to implement simple stack function trace. Instantiation the
# class as the first function you want to trace. Example:
# obj = utilsDebug.CDebugFnVerbose("validate_arguments()")
# Gotchas: This class will not work in properly in a multi-threaded
# environment.
# Authors: Illya Rudkin 28/11/2013.
# Changes: None.
#--
class CDebugFnVerbose(object):
# Public static properties:
bVerboseOn = False # True = turn on function tracing, False = turn off.
# Public:
#++------------------------------------------------------------------------
# Details: CDebugFnVerbose constructor.
# Type: Method.
# Args: vstrFnName - (R) Text description i.e. a function name.
# Return: None.
# Throws: None.
#--
# CDebugFnVerbose(vstrFnName)
#++------------------------------------------------------------------------
# Details: Print out information on the object specified.
# Type: Method.
# Args: vstrText - (R) Some helper text description.
# vObject - (R) Some Python type object.
# Return: None.
# Throws: None.
#--
def dump_object(self, vstrText, vObject):
if not CDebugFnVerbose.bVerboseOn:
return
sys.stdout.write(
"%d%s> Dp: %s" %
(CDebugFnVerbose.__nLevel,
self.__get_dots(),
vstrText))
print(vObject)
#++------------------------------------------------------------------------
# Details: Print out some progress text given by the client.
# Type: Method.
# Args: vstrText - (R) Some helper text description.
# Return: None.
# Throws: None.
#--
def dump_text(self, vstrText):
if not CDebugFnVerbose.bVerboseOn:
return
print(("%d%s> Dp: %s" % (CDebugFnVerbose.__nLevel, self.__get_dots(),
vstrText)))
# Private methods:
def __init__(self, vstrFnName):
self.__indent_out(vstrFnName)
#++------------------------------------------------------------------------
# Details: Build an indentation string of dots based on the __nLevel.
# Type: Method.
# Args: None.
# Return: Str - variable length string.
# Throws: None.
#--
def __get_dots(self):
return "".join("." for i in range(0, CDebugFnVerbose.__nLevel))
#++------------------------------------------------------------------------
# Details: Build and print out debug verbosity text indicating the function
# just exited from.
# Type: Method.
# Args: None.
# Return: None.
# Throws: None.
#--
def __indent_back(self):
if CDebugFnVerbose.bVerboseOn:
print(("%d%s< fn: %s" % (CDebugFnVerbose.__nLevel,
self.__get_dots(), self.__strFnName)))
CDebugFnVerbose.__nLevel -= 1
#++------------------------------------------------------------------------
# Details: Build and print out debug verbosity text indicating the function
# just entered.
# Type: Method.
# Args: vstrFnName - (R) Name of the function entered.
# Return: None.
# Throws: None.
#--
def __indent_out(self, vstrFnName):
CDebugFnVerbose.__nLevel += 1
self.__strFnName = vstrFnName
if CDebugFnVerbose.bVerboseOn:
print(("%d%s> fn: %s" % (CDebugFnVerbose.__nLevel,
self.__get_dots(), self.__strFnName)))
# Private statics attributes:
__nLevel = 0 # Indentation level counter
# Private attributes:
__strFnName = ""

View File

@ -1,103 +0,0 @@
""" Utility module to determine the OS Python running on
--------------------------------------------------------------------------
File: utilsOsType.py
Overview: Python module to supply functions and an enumeration to
help determine the platform type, bit size and OS currently
being used.
--------------------------------------------------------------------------
"""
# Python modules:
import sys # Provide system information
# Third party modules:
# In-house modules:
# Instantiations:
# Enumerations:
#-----------------------------------------------------------------------------
# Details: Class to implement a 'C' style enumeration type.
# Gotchas: None.
# Authors: Illya Rudkin 28/11/2013.
# Changes: None.
#--
if sys.version_info.major >= 3:
from enum import Enum
class EnumOsType(Enum):
Unknown = 0
Darwin = 1
FreeBSD = 2
Linux = 3
NetBSD = 4
OpenBSD = 5
Windows = 6
kFreeBSD = 7
else:
class EnumOsType(object):
values = ["Unknown",
"Darwin",
"FreeBSD",
"Linux",
"NetBSD",
"OpenBSD",
"Windows",
"kFreeBSD"]
class __metaclass__(type):
#++----------------------------------------------------------------
# Details: Fn acts as an enumeration.
# Args: vName - (R) Enumeration to match.
# Returns: Int - Matching enumeration/index.
# Throws: None.
#--
def __getattr__(cls, vName):
return cls.values.index(vName)
#++---------------------------------------------------------------------------
# Details: Reverse fast lookup of the values list.
# Args: vI - (R) Index / enumeration.
# Returns: Str - text description matching enumeration.
# Throws: None.
#--
def name_of(cls, vI):
return EnumOsType.values[vI]
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
#-----------------------------------------------------------------------------
#++---------------------------------------------------------------------------
# Details: Determine what operating system is currently running on.
# Args: None.
# Returns: EnumOsType - The OS type being used ATM.
# Throws: None.
#--
def determine_os_type():
eOSType = EnumOsType.Unknown
strOS = sys.platform
if strOS == "darwin":
eOSType = EnumOsType.Darwin
elif strOS.startswith("freebsd"):
eOSType = EnumOsType.FreeBSD
elif strOS.startswith("linux"):
eOSType = EnumOsType.Linux
elif strOS.startswith("netbsd"):
eOSType = EnumOsType.NetBSD
elif strOS.startswith("openbsd"):
eOSType = EnumOsType.OpenBSD
elif strOS == "win32":
eOSType = EnumOsType.Windows
elif strOS.startswith("gnukfreebsd"):
eOSType = EnumOsType.kFreeBSD
return eOSType