944 lines
35 KiB
Python
944 lines
35 KiB
Python
""" 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'"
|
|
|
|
|
|
def is_debug_interpreter():
|
|
return hasattr(sys, 'gettotalrefcount')
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Copy files needed by lldb/macosx/heap.py to build libheap.dylib.
|
|
# Args: vDictArgs - (R) Program input parameters.
|
|
# vstrFrameworkPythonDir - (R) Python framework directory.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# Str - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
|
|
|
|
def macosx_copy_file_for_heap(vDictArgs, vstrFrameworkPythonDir):
|
|
dbg = utilsDebug.CDebugFnVerbose(
|
|
"Python script macosx_copy_file_for_heap()")
|
|
bOk = True
|
|
strMsg = ""
|
|
|
|
eOSType = utilsOsType.determine_os_type()
|
|
if eOSType != utilsOsType.EnumOsType.Darwin:
|
|
return (bOk, strMsg)
|
|
|
|
strHeapDir = os.path.join(vstrFrameworkPythonDir, "macosx", "heap")
|
|
strHeapDir = os.path.normcase(strHeapDir)
|
|
if os.path.exists(strHeapDir) and os.path.isdir(strHeapDir):
|
|
return (bOk, strMsg)
|
|
|
|
os.makedirs(strHeapDir)
|
|
|
|
strRoot = os.path.normpath(vDictArgs["--srcRoot"])
|
|
strSrc = os.path.join(
|
|
strRoot,
|
|
"examples",
|
|
"darwin",
|
|
"heap_find",
|
|
"heap",
|
|
"heap_find.cpp")
|
|
shutil.copy(strSrc, strHeapDir)
|
|
strSrc = os.path.join(
|
|
strRoot,
|
|
"examples",
|
|
"darwin",
|
|
"heap_find",
|
|
"heap",
|
|
"Makefile")
|
|
shutil.copy(strSrc, strHeapDir)
|
|
|
|
return (bOk, strMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# 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: Copy the lldb.py file into the lldb package directory and rename
|
|
# to __init_.py.
|
|
# Args: vDictArgs - (R) Program input parameters.
|
|
# vstrFrameworkPythonDir - (R) Python framework directory.
|
|
# vstrCfgBldDir - (R) Config directory path.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# Str - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
|
|
|
|
def copy_lldbpy_file_to_lldb_pkg_dir(
|
|
vDictArgs,
|
|
vstrFrameworkPythonDir,
|
|
vstrCfgBldDir):
|
|
dbg = utilsDebug.CDebugFnVerbose(
|
|
"Python script copy_lldbpy_file_to_lldb_pkg_dir()")
|
|
bOk = True
|
|
bDbg = "-d" in vDictArgs
|
|
strMsg = ""
|
|
|
|
strSrc = os.path.join(vstrCfgBldDir, "lldb.py")
|
|
strSrc = os.path.normcase(strSrc)
|
|
strDst = os.path.join(vstrFrameworkPythonDir, "__init__.py")
|
|
strDst = os.path.normcase(strDst)
|
|
|
|
if not os.path.exists(strSrc):
|
|
strMsg = strErrMsgLLDBPyFileNotNotFound % strSrc
|
|
return (bOk, strMsg)
|
|
|
|
try:
|
|
if bDbg:
|
|
print((strMsgCopyLLDBPy % (strSrc, strDst)))
|
|
shutil.copyfile(strSrc, strDst)
|
|
except IOError as e:
|
|
bOk = False
|
|
strMsg = "I/O error(%d): %s %s" % (e.errno,
|
|
e.strerror, strErrMsgCpLldbpy)
|
|
if e.errno == 2:
|
|
strMsg += " Src:'%s' Dst:'%s'" % (strSrc, strDst)
|
|
except:
|
|
bOk = False
|
|
strMsg = strErrMsgUnexpected % sys.exec_info()[0]
|
|
|
|
return (bOk, strMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Make the symbolic link on a Windows platform.
|
|
# Args: vstrSrcFile - (R) Source file name.
|
|
# vstrTargetFile - (R) Destination file name.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# Str - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
|
|
|
|
def make_symlink_windows(vstrSrcPath, vstrTargetPath):
|
|
print(("Making symlink from %s to %s" % (vstrSrcPath, vstrTargetPath)))
|
|
dbg = utilsDebug.CDebugFnVerbose("Python script make_symlink_windows()")
|
|
bOk = True
|
|
strErrMsg = ""
|
|
# If the src file doesn't exist, this is an error and we should throw.
|
|
src_stat = os.stat(vstrSrcPath)
|
|
|
|
try:
|
|
target_stat = os.stat(vstrTargetPath)
|
|
# If the target file exists but refers to a different file, delete it so that we can
|
|
# re-create the link. This can happen if you run this script once (creating a link)
|
|
# and then delete the source file (so that a brand new file gets created the next time
|
|
# you compile and link), and then re-run this script, so that both the target hardlink
|
|
# and the source file exist, but the target refers to an old copy of
|
|
# the source.
|
|
if (target_stat.st_ino == src_stat.st_ino) and (
|
|
target_stat.st_dev == src_stat.st_dev):
|
|
return (bOk, strErrMsg)
|
|
|
|
os.remove(vstrTargetPath)
|
|
except:
|
|
# If the target file don't exist, ignore this exception, we will link
|
|
# it shortly.
|
|
pass
|
|
|
|
try:
|
|
csl = ctypes.windll.kernel32.CreateHardLinkW
|
|
csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)
|
|
csl.restype = ctypes.c_ubyte
|
|
if csl(vstrTargetPath, vstrSrcPath, 0) == 0:
|
|
raise ctypes.WinError()
|
|
except Exception as e:
|
|
if e.errno != 17:
|
|
bOk = False
|
|
strErrMsg = "WinError(%d): %s %s" % (
|
|
e.errno, e.strerror, strErrMsgMakeSymlink)
|
|
strErrMsg += " Src:'%s' Target:'%s'" % (
|
|
vstrSrcPath, vstrTargetPath)
|
|
|
|
return (bOk, strErrMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Make the symbolic link on a UNIX style platform.
|
|
# Args: vstrSrcFile - (R) Source file name.
|
|
# vstrTargetFile - (R) Destination file name.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# Str - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
|
|
|
|
def make_symlink_other_platforms(vstrSrcPath, vstrTargetPath):
|
|
dbg = utilsDebug.CDebugFnVerbose(
|
|
"Python script make_symlink_other_platforms()")
|
|
bOk = True
|
|
strErrMsg = ""
|
|
|
|
try:
|
|
os.symlink(vstrSrcPath, vstrTargetPath)
|
|
except OSError as e:
|
|
bOk = False
|
|
strErrMsg = "OSError(%d): %s %s" % (
|
|
e.errno, e.strerror, strErrMsgMakeSymlink)
|
|
strErrMsg += " Src:'%s' Target:'%s'" % (vstrSrcPath, vstrTargetPath)
|
|
except:
|
|
bOk = False
|
|
strErrMsg = strErrMsgUnexpected % sys.exec_info()[0]
|
|
|
|
return (bOk, strErrMsg)
|
|
|
|
|
|
def make_symlink_native(vDictArgs, strSrc, strTarget):
|
|
eOSType = utilsOsType.determine_os_type()
|
|
bDbg = "-d" in vDictArgs
|
|
bOk = True
|
|
strErrMsg = ""
|
|
|
|
target_filename = os.path.basename(strTarget)
|
|
if eOSType == utilsOsType.EnumOsType.Unknown:
|
|
bOk = False
|
|
strErrMsg = strErrMsgOsTypeUnknown
|
|
elif eOSType == utilsOsType.EnumOsType.Windows:
|
|
if bDbg:
|
|
print((strMsgSymlinkMk % (target_filename, strSrc, strTarget)))
|
|
bOk, strErrMsg = make_symlink_windows(strSrc,
|
|
strTarget)
|
|
else:
|
|
if os.path.islink(strTarget):
|
|
if bDbg:
|
|
print((strMsgSymlinkExists % target_filename))
|
|
return (bOk, strErrMsg)
|
|
if bDbg:
|
|
print((strMsgSymlinkMk % (target_filename, strSrc, strTarget)))
|
|
bOk, strErrMsg = make_symlink_other_platforms(strSrc,
|
|
strTarget)
|
|
|
|
return (bOk, strErrMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Make the symbolic link.
|
|
# Args: vDictArgs - (R) Program input parameters.
|
|
# vstrFrameworkPythonDir - (R) Python framework directory.
|
|
# vstrSrcFile - (R) Source file name.
|
|
# vstrTargetFile - (R) Destination file name.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# Str - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
|
|
|
|
def make_symlink(
|
|
vDictArgs,
|
|
vstrFrameworkPythonDir,
|
|
vstrSrcFile,
|
|
vstrTargetFile):
|
|
dbg = utilsDebug.CDebugFnVerbose("Python script make_symlink()")
|
|
bOk = True
|
|
strErrMsg = ""
|
|
bDbg = "-d" in vDictArgs
|
|
strTarget = os.path.join(vstrFrameworkPythonDir, vstrTargetFile)
|
|
strTarget = os.path.normcase(strTarget)
|
|
strSrc = ""
|
|
|
|
os.chdir(vstrFrameworkPythonDir)
|
|
bMakeFileCalled = "-m" in vDictArgs
|
|
eOSType = utilsOsType.determine_os_type()
|
|
if not bMakeFileCalled:
|
|
strBuildDir = os.path.join("..", "..", "..")
|
|
else:
|
|
# Resolve vstrSrcFile path relatively the build directory
|
|
if eOSType == utilsOsType.EnumOsType.Windows:
|
|
# On a Windows platform the vstrFrameworkPythonDir looks like:
|
|
# llvm\\build\\Lib\\site-packages\\lldb
|
|
strBuildDir = os.path.join("..", "..", "..")
|
|
else:
|
|
# On a UNIX style platform the vstrFrameworkPythonDir looks like:
|
|
# llvm/build/lib/python2.7/site-packages/lldb
|
|
strBuildDir = os.path.join("..", "..", "..", "..")
|
|
strSrc = os.path.normcase(os.path.join(strBuildDir, vstrSrcFile))
|
|
|
|
return make_symlink_native(vDictArgs, strSrc, strTarget)
|
|
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Make the symbolic that the script bridge for Python will need in
|
|
# the Python framework directory.
|
|
# Args: vDictArgs - (R) Program input parameters.
|
|
# vstrFrameworkPythonDir - (R) Python framework directory.
|
|
# vstrLiblldbName - (R) File name for _lldb library.
|
|
# vstrLiblldbDir - (R) liblldb directory.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# Str - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
def make_symlink_liblldb(
|
|
vDictArgs,
|
|
vstrFrameworkPythonDir,
|
|
vstrLiblldbFileName,
|
|
vstrLldbLibDir):
|
|
dbg = utilsDebug.CDebugFnVerbose("Python script make_symlink_liblldb()")
|
|
bOk = True
|
|
strErrMsg = ""
|
|
strTarget = vstrLiblldbFileName
|
|
strSrc = ""
|
|
|
|
eOSType = utilsOsType.determine_os_type()
|
|
if eOSType == utilsOsType.EnumOsType.Windows:
|
|
# When importing an extension module using a debug version of python, you
|
|
# write, for example, "import foo", but the interpreter searches for
|
|
# "foo_d.pyd"
|
|
if is_debug_interpreter():
|
|
strTarget += "_d"
|
|
strTarget += ".pyd"
|
|
else:
|
|
strTarget += ".so"
|
|
|
|
bMakeFileCalled = "-m" in vDictArgs
|
|
if not bMakeFileCalled:
|
|
strSrc = "LLDB"
|
|
else:
|
|
strLibFileExtn = ""
|
|
if eOSType == utilsOsType.EnumOsType.Windows:
|
|
strSrc = os.path.join("bin", "liblldb.dll")
|
|
else:
|
|
if eOSType == utilsOsType.EnumOsType.Darwin:
|
|
strLibFileExtn = ".dylib"
|
|
else:
|
|
strLibFileExtn = ".so"
|
|
strSrc = os.path.join(vstrLldbLibDir, "liblldb" + strLibFileExtn)
|
|
|
|
bOk, strErrMsg = make_symlink(
|
|
vDictArgs, vstrFrameworkPythonDir, strSrc, strTarget)
|
|
|
|
return (bOk, strErrMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Make the symbolic link to the lldb-argdumper.
|
|
# Args: vDictArgs - (R) Program input parameters.
|
|
# vstrFrameworkPythonDir - (R) Python framework directory.
|
|
# vstrArgdumperFileName - (R) File name for lldb-argdumper.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# Str - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
|
|
|
|
def make_symlink_lldb_argdumper(
|
|
vDictArgs,
|
|
vstrFrameworkPythonDir,
|
|
vstrArgdumperFileName):
|
|
dbg = utilsDebug.CDebugFnVerbose(
|
|
"Python script make_symlink_lldb_argdumper()")
|
|
bOk = True
|
|
strErrMsg = ""
|
|
strTarget = vstrArgdumperFileName
|
|
strSrc = ""
|
|
|
|
eOSType = utilsOsType.determine_os_type()
|
|
if eOSType == utilsOsType.EnumOsType.Windows:
|
|
strTarget += ".exe"
|
|
|
|
bMakeFileCalled = "-m" in vDictArgs
|
|
if not bMakeFileCalled:
|
|
return (bOk, strErrMsg)
|
|
else:
|
|
strExeFileExtn = ""
|
|
if eOSType == utilsOsType.EnumOsType.Windows:
|
|
strExeFileExtn = ".exe"
|
|
strSrc = os.path.join("bin", "lldb-argdumper" + strExeFileExtn)
|
|
|
|
bOk, strErrMsg = make_symlink(
|
|
vDictArgs, vstrFrameworkPythonDir, strSrc, strTarget)
|
|
|
|
return (bOk, strErrMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Make the symlink that the script bridge for Python will need in
|
|
# the Python framework directory.
|
|
# Args: vDictArgs - (R) Program input parameters.
|
|
# vstrFrameworkPythonDir - (R) Python framework directory.
|
|
# vstrLldbLibDir - (R) liblldb directory.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# strErrMsg - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
|
|
|
|
def create_symlinks(vDictArgs, vstrFrameworkPythonDir, vstrLldbLibDir):
|
|
dbg = utilsDebug.CDebugFnVerbose("Python script create_symlinks()")
|
|
bOk = True
|
|
strErrMsg = ""
|
|
eOSType = utilsOsType.determine_os_type()
|
|
|
|
# Make symlink for _lldb
|
|
strLibLldbFileName = "_lldb"
|
|
if bOk:
|
|
bOk, strErrMsg = make_symlink_liblldb(vDictArgs,
|
|
vstrFrameworkPythonDir,
|
|
strLibLldbFileName,
|
|
vstrLldbLibDir)
|
|
|
|
# Make symlink for lldb-argdumper
|
|
strArgdumperFileName = "lldb-argdumper"
|
|
if bOk:
|
|
bOk, strErrMsg = make_symlink_lldb_argdumper(vDictArgs,
|
|
vstrFrameworkPythonDir,
|
|
strArgdumperFileName)
|
|
|
|
return (bOk, strErrMsg)
|
|
|
|
|
|
def copy_six(vDictArgs, vstrFrameworkPythonDir):
|
|
dbg = utilsDebug.CDebugFnVerbose("Python script copy_six()")
|
|
bDbg = "-d" in vDictArgs
|
|
bOk = True
|
|
strMsg = ""
|
|
site_packages_dir = os.path.dirname(vstrFrameworkPythonDir)
|
|
six_module_filename = "six.py"
|
|
src_file = os.path.join(
|
|
vDictArgs['--srcRoot'],
|
|
"third_party",
|
|
"Python",
|
|
"module",
|
|
"six",
|
|
six_module_filename)
|
|
src_file = os.path.normpath(src_file)
|
|
target = os.path.join(site_packages_dir, six_module_filename)
|
|
|
|
if bDbg:
|
|
print((strMsgCopySixPy % (src_file, target)))
|
|
try:
|
|
shutil.copyfile(src_file, target)
|
|
except:
|
|
bOk = False
|
|
strMsg = strErrMsgCopySixPyFailed % (src_file, target)
|
|
|
|
return (bOk, strMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Look for the directory in which to put the Python files if it
|
|
# does not already exist, attempt to make it.
|
|
# Args: vDictArgs - (R) Program input parameters.
|
|
# vstrFrameworkPythonDir - (R) Python framework directory.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# Str - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
|
|
|
|
def find_or_create_python_dir(vDictArgs, vstrFrameworkPythonDir):
|
|
dbg = utilsDebug.CDebugFnVerbose(
|
|
"Python script find_or_create_python_dir()")
|
|
bOk = True
|
|
strMsg = ""
|
|
bDbg = "-d" in vDictArgs
|
|
|
|
if os.path.isdir(vstrFrameworkPythonDir):
|
|
if bDbg:
|
|
print((strMsgFrameWkPyExists % vstrFrameworkPythonDir))
|
|
return (bOk, strMsg)
|
|
|
|
if bDbg:
|
|
print((strMsgFrameWkPyMkDir % vstrFrameworkPythonDir))
|
|
|
|
try:
|
|
os.makedirs(vstrFrameworkPythonDir)
|
|
except OSError as exception:
|
|
bOk = False
|
|
strMsg = strErrMsgCreateFrmWkPyDirFailed % (
|
|
vstrFrameworkPythonDir, os.strerror(exception.errno))
|
|
|
|
return (bOk, strMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Retrieve the configuration build path if present and valid (using
|
|
# parameter --cfgBlddir or copy the Python Framework directory.
|
|
# Args: vDictArgs - (R) Program input parameters.
|
|
# vstrFrameworkPythonDir - (R) Python framework directory.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# Str - Config directory path.
|
|
# strErrMsg - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
|
|
|
|
def get_config_build_dir(vDictArgs, vstrFrameworkPythonDir):
|
|
dbg = utilsDebug.CDebugFnVerbose("Python script get_config_build_dir()")
|
|
bOk = True
|
|
strErrMsg = ""
|
|
|
|
strConfigBldDir = ""
|
|
bHaveConfigBldDir = "--cfgBldDir" in vDictArgs
|
|
if bHaveConfigBldDir:
|
|
strConfigBldDir = vDictArgs["--cfgBldDir"]
|
|
if (bHaveConfigBldDir == False) or (strConfigBldDir.__len__() == 0):
|
|
strConfigBldDir = vstrFrameworkPythonDir
|
|
|
|
return (bOk, strConfigBldDir, strErrMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Determine where to put the files. Retrieve the directory path for
|
|
# Python's dist_packages/ site_package folder on a Windows platform.
|
|
# 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_windows(vDictArgs):
|
|
dbg = utilsDebug.CDebugFnVerbose(
|
|
"Python script get_framework_python_dir_windows()")
|
|
bOk = True
|
|
strWkDir = ""
|
|
strErrMsg = ""
|
|
|
|
# We are being built by LLVM, so use the PYTHON_INSTALL_DIR argument,
|
|
# and append the python version directory to the end of it. Depending
|
|
# on the system other stuff may need to be put here as well.
|
|
from distutils.sysconfig import get_python_lib
|
|
strPythonInstallDir = ""
|
|
bHaveArgPrefix = "--prefix" in vDictArgs
|
|
if bHaveArgPrefix:
|
|
strPythonInstallDir = os.path.normpath(vDictArgs["--prefix"])
|
|
|
|
bHaveArgCmakeBuildConfiguration = "--cmakeBuildConfiguration" in vDictArgs
|
|
if bHaveArgCmakeBuildConfiguration:
|
|
strPythonInstallDir = os.path.join(
|
|
strPythonInstallDir,
|
|
vDictArgs["--cmakeBuildConfiguration"])
|
|
|
|
if strPythonInstallDir.__len__() != 0:
|
|
strWkDir = get_python_lib(True, False, strPythonInstallDir)
|
|
else:
|
|
strWkDir = get_python_lib(True, False)
|
|
strWkDir = os.path.normcase(os.path.join(strWkDir, "lldb"))
|
|
|
|
return (bOk, strWkDir, strErrMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Retrieve the directory path for Python's dist_packages/
|
|
# site_package folder on a UNIX style platform.
|
|
# 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_other_platforms(vDictArgs):
|
|
dbg = utilsDebug.CDebugFnVerbose(
|
|
"Python script get_framework_python_dir_other_platform()")
|
|
bOk = True
|
|
strWkDir = ""
|
|
strErrMsg = ""
|
|
bDbg = "-d" in vDictArgs
|
|
|
|
bMakeFileCalled = "-m" in vDictArgs
|
|
if bMakeFileCalled:
|
|
dbg.dump_text("Built by LLVM")
|
|
return get_framework_python_dir_windows(vDictArgs)
|
|
else:
|
|
dbg.dump_text("Built by XCode")
|
|
# We are being built by XCode, so all the lldb Python files can go
|
|
# into the LLDB.framework/Resources/Python subdirectory.
|
|
strWkDir = vDictArgs["--targetDir"]
|
|
strWkDir = os.path.join(strWkDir, "LLDB.framework")
|
|
if os.path.exists(strWkDir):
|
|
if bDbg:
|
|
print((strMsgFoundLldbFrameWkDir % strWkDir))
|
|
strWkDir = os.path.join(strWkDir, "Resources", "Python", "lldb")
|
|
strWkDir = os.path.normcase(strWkDir)
|
|
else:
|
|
bOk = False
|
|
strErrMsg = strErrMsgFrameWkPyDirNotExist % strWkDir
|
|
|
|
return (bOk, strWkDir, strErrMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# 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
|
|
strWkDir = ""
|
|
strErrMsg = ""
|
|
|
|
eOSType = utilsOsType.determine_os_type()
|
|
if eOSType == utilsOsType.EnumOsType.Unknown:
|
|
bOk = False
|
|
strErrMsg = strErrMsgOsTypeUnknown
|
|
elif eOSType == utilsOsType.EnumOsType.Windows:
|
|
bOk, strWkDir, strErrMsg = get_framework_python_dir_windows(vDictArgs)
|
|
else:
|
|
bOk, strWkDir, strErrMsg = get_framework_python_dir_other_platforms(
|
|
vDictArgs)
|
|
|
|
return (bOk, strWkDir, strErrMsg)
|
|
|
|
#++---------------------------------------------------------------------------
|
|
# Details: Retrieve the liblldb directory path, if it exists and is valid.
|
|
# Args: vDictArgs - (R) Program input parameters.
|
|
# Returns: Bool - True = function success, False = failure.
|
|
# Str - liblldb directory path.
|
|
# strErrMsg - Error description on task failure.
|
|
# Throws: None.
|
|
#--
|
|
|
|
|
|
def get_liblldb_dir(vDictArgs):
|
|
dbg = utilsDebug.CDebugFnVerbose("Python script get_liblldb_dir()")
|
|
bOk = True
|
|
strErrMsg = ""
|
|
|
|
strLldbLibDir = ""
|
|
bHaveLldbLibDir = "--lldbLibDir" in vDictArgs
|
|
if bHaveLldbLibDir:
|
|
strLldbLibDir = vDictArgs["--lldbLibDir"]
|
|
if (bHaveLldbLibDir == False) or (strLldbLibDir.__len__() == 0):
|
|
strLldbLibDir = "lib"
|
|
|
|
return (bOk, strLldbLibDir, 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)
|
|
|
|
if bOk:
|
|
bOk, strCfgBldDir, strMsg = get_config_build_dir(
|
|
vDictArgs, strFrameworkPythonDir)
|
|
if bOk and bDbg:
|
|
print((strMsgPyFileLocatedHere % strFrameworkPythonDir))
|
|
print((strMsgConfigBuildDir % strCfgBldDir))
|
|
|
|
if bOk:
|
|
bOk, strLldbLibDir, strMsg = get_liblldb_dir(vDictArgs)
|
|
|
|
if bOk:
|
|
bOk, strMsg = find_or_create_python_dir(
|
|
vDictArgs, strFrameworkPythonDir)
|
|
|
|
if bOk:
|
|
bOk, strMsg = create_symlinks(
|
|
vDictArgs, strFrameworkPythonDir, strLldbLibDir)
|
|
|
|
if bOk:
|
|
bOk, strMsg = copy_six(vDictArgs, strFrameworkPythonDir)
|
|
|
|
if bOk:
|
|
bOk, strMsg = copy_lldbpy_file_to_lldb_pkg_dir(vDictArgs,
|
|
strFrameworkPythonDir,
|
|
strCfgBldDir)
|
|
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:
|
|
bOk, strMsg = macosx_copy_file_for_heap(
|
|
vDictArgs, strFrameworkPythonDir)
|
|
|
|
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")
|