Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -77,6 +77,7 @@ set(LLDB_BUILT_STANDALONE 1) endif() +set(LLDB_DISABLE_PYTHON 0 CACHE BOOL "Disables the Python scripting integration.") if (LLDB_DISABLE_PYTHON) add_definitions( -DLLDB_DISABLE_PYTHON ) endif() @@ -94,9 +95,14 @@ endmacro(add_lldb_definitions) if (NOT LLDB_DISABLE_PYTHON) - find_package(PythonLibs REQUIRED) - include_directories(${PYTHON_INCLUDE_DIRS}) + if (MSVC) + # this definition will stop python from auto linking python27_d.lib when Python.h is included + add_definitions( -DSWIG_PYTHON_INTERPRETER_NO_DEBUG ) + endif() + find_package(PythonLibs REQUIRED) + include_directories(${PYTHON_INCLUDE_DIRS}) endif() + include_directories(../clang/include) include_directories("${CMAKE_CURRENT_BINARY_DIR}/../clang/include") @@ -194,7 +200,7 @@ if (NOT MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") endif() - add_library(${name} ${libkind} ${srcs}) + llvm_add_library(${name} ${libkind} ${srcs}) #if (LLVM_COMMON_DEPENDS) ##add_dependencies(${name} ${LLVM_COMMON_DEPENDS}) #endif() @@ -229,14 +235,7 @@ endmacro(add_lldb_library) macro(add_lldb_executable name) - #add_llvm_executable(${name} ${ARGN}) - llvm_process_sources( ALL_FILES ${ARGN} ) - add_executable(${name} ${ALL_FILES}) - #target_link_libraries(${name} ${CLANG_USED_LIBS}) - #llvm_config( ${name} ${LLVM_LINK_COMPONENTS} ) - #if (LLVM_COMMON_DEPENDS) - #add_dependencies(${name} ${LLVM_COMMON_DEPENDS}) - #endif() + add_llvm_executable(${name} ${ARGN}) set_target_properties(${name} PROPERTIES FOLDER "lldb executables") endmacro(add_lldb_executable) @@ -286,9 +285,7 @@ #add_subdirectory(include) add_subdirectory(docs) -if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") - add_subdirectory(scripts) -endif() +add_subdirectory(scripts) add_subdirectory(source) add_subdirectory(test) add_subdirectory(tools) Index: include/lldb/API/SBHostOS.h =================================================================== --- include/lldb/API/SBHostOS.h +++ include/lldb/API/SBHostOS.h @@ -30,7 +30,7 @@ static lldb::thread_t ThreadCreate (const char *name, - thread_func_t thread_function, + lldb::thread_func_t thread_function, void *thread_arg, lldb::SBError *err); @@ -43,7 +43,7 @@ lldb::SBError *err); static bool ThreadJoin (lldb::thread_t thread, - thread_result_t *result, + lldb::thread_result_t *result, lldb::SBError *err); Index: include/lldb/Host/windows/win32.h =================================================================== --- include/lldb/Host/windows/win32.h +++ include/lldb/Host/windows/win32.h @@ -45,7 +45,10 @@ #include #include typedef unsigned short mode_t; + +#ifdef LLDB_DISABLE_PYTHON typedef uint32_t pid_t; +#endif int usleep(uint32_t useconds); Index: include/lldb/lldb-python.h =================================================================== --- include/lldb/lldb-python.h +++ include/lldb/lldb-python.h @@ -13,12 +13,40 @@ // Python.h needs to be included before any system headers in order to avoid redefinition of macros #ifdef LLDB_DISABLE_PYTHON - // Python is disabled in this build - #else +// If this is a visual studio build +# if defined( _MSC_VER ) +// Special case for debug build since python unfortunately +// adds library to the linker path through a #pragma directive +# if defined( _DEBUG ) +// Python forces a header link to python27_d.lib when building debug. +// To get around this (because most python packages for Windows +// don't come with debug python libraries), we undefine _DEBUG, include +// python.h and then restore _DEBUG. + +// The problem with this is that any system level headers included from +// python.h were also effectively included in 'release' mode when we undefined +// _DEBUG. To work around this we include headers that python includes +// before undefining _DEBUG. +# include +// Undefine to force python to link against the release distro +# undef _DEBUG +# include +# define _DEBUG + +// Normal operation +# else +# include +# endif + +# else + +// Include python for non windows machines +# include + +# endif -#include #endif // LLDB_DISABLE_PYTHON Index: scripts/CMakeLists.txt =================================================================== --- scripts/CMakeLists.txt +++ scripts/CMakeLists.txt @@ -1,13 +1,10 @@ set(LLVM_NO_RTTI 1) add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp - DEPENDS ${LLDB_SOURCE_DIR}/scripts/lldb.swig - # swig was directly invoked on Windows (where the Python API is not being generated) but on other platforms, we need to run the *swig-wrapper-classes.sh shell-scripts. - #COMMAND swig -c++ -shadow -python -I${LLDB_SOURCE_DIR}/include -I./. -outdir ${LLDB_SOURCE_DIR}/scripts/Python -o ${LLDB_SOURCE_DIR}/source/LLDBWrapPython.cpp ${LLDB_SOURCE_DIR}/scripts/lldb.swig - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/build-swig-wrapper-classes.sh ${LLDB_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR} -m - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/finish-swig-wrapper-classes.sh ${LLDB_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BINARY_DIR} -m - COMMENT "Building lldb python wrapper") + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp + DEPENDS ${LLDB_SOURCE_DIR}/scripts/lldb.swig + COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/buildSwigWrapperClasses.py "--srcRoot=${LLDB_SOURCE_DIR}" "--targetDir=${CMAKE_CURRENT_BINARY_DIR}" "--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}" "--prefix=${CMAKE_BINARY_DIR}" -m + COMMENT "Python script building LLDB Python wrapper") set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp PROPERTIES GENERATED 1) ADD_CUSTOM_TARGET(swig_wrapper ALL echo -n @@ -15,9 +12,7 @@ ) # Install the LLDB python module on all operating systems (except Windows) -if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") - install(SCRIPT lldb_python_module.cmake -DCMAKE_INSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\" -DCMAKE_BUILD_DIR=\"${CMAKE_BUILD_DIR}\") -endif() +install(SCRIPT lldb_python_module.cmake -DCMAKE_INSTALL_PREFIX=\"${CMAKE_INSTALL_PREFIX}\" -DCMAKE_BUILD_DIR=\"${CMAKE_BUILD_DIR}\") # build Python modules add_subdirectory(Python/modules) Index: scripts/Python/buildSwigPython.py =================================================================== --- /dev/null +++ scripts/Python/buildSwigPython.py @@ -0,0 +1,782 @@ +""" Python SWIG wrapper creation script Windows/LINUX/OSX platform + + -------------------------------------------------------------------------- + File: buildSwigPython.py + + Overview: Creates SWIG Python C++ Script Bridge wrapper code. This + script is called by build-swig-wrapper-classes.py in turn. + + Environment: OS: Windows Vista or newer, LINUX, OSX. + IDE: Visual Studio 2013 Plugin Python Tools (PTVS) + Script: Python 2.6/2.7.5 x64 + Other: SWIG 2.0.11 + + 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. + 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 time # Time access and conversions +import subprocess # Call external programs +import shutil # File handling + +# 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: +strMsgLldbDisablePythonEnv = "Python build aborted as LLDB_DISABLE_PYTHON \ +environmental variable is defined"; +strMsgLldbDisableGccEnv = "Python build aborted as GCC_PREPROCESSOR_DEFINITIONS \ +environmental variable is defined"; +strMsgHdrFiles = "Header files are:"; +strMsgIFaceFiles = "SWIG interface files are"; +strErrMsgProgFail = "Program failure: "; +strMsgFileNewrSwigOpFile = "\'%s\' is newer than \'%s\'\nSWIG file will need to be re-built"; +strMsgFileNotExist = "\'%s\' could not be found\nSWIG file will need to be re-built"; +strErrMsgOsTypeUnknown = "Unable to determine current OS type"; +strMsgNotNeedUpdate = "Everything is up-to-date"; +strMsgSwigNeedRebuild = "SWIG needs to be re-run"; +strErrMsgSwigParamsMissing = "This script was not passed either '--swigExePath \ +or the '--swigExeName' argument. Both are required."; +strMsgSwigExecute = "SWIG executing the following:\n\'%s'"; +strErrMsgSwigExecute = "SWIG failed: %s"; +strErrMsgPythonExecute = "Python script '%s' failed: %s"; +strMsgSwigNoGenDep = "SWIG ran with no generated dependencies, script exit early"; +strMsgSwigGenDep = "SWIG ran and generated dependencies, script exit early, deleted '%s'"; +strErrMsgFrameWkPyDirNotExist = "Unable to find the LLDB. Framework directory is '%s'"; +strMsgFoundLldbFrameWkDir = "Found '%s'"; +strErrMsgModifyPythonLldbPyFileNotFound = "Unable to find '%s' in '%s'"; + +#++--------------------------------------------------------------------------- +# Details: Retrieve the list of hard coded lldb header file names and +# put in the program's dictArgs map container. Make paths compatible +# with the current OS. +# Note this does not necessarily match the content of those +# directories. The resultant header string is inserted into the +# dictionary vDictArgs key "--headerFiles". +# Args: vDictArgs - (RW) Program input parameters. +# Returns: Bool - True = success, False = failure. +# Throws: None. +#-- +def get_header_files( vDictArgs ): + dbg = utilsDebug.CDebugFnVerbose( "Python script get_header_files()" ); + listHeaderFiles = [ "/include/lldb/API/lldb.h", # .sh has /include/lldb/lldb.h 21/11/2013 + "/include/lldb/lldb-defines.h", + "/include/lldb/lldb-enumerations.h", + "/include/lldb/lldb-forward.h", + "/include/lldb/lldb-forward-rtti.h", + "/include/lldb/lldb-types.h", + "/include/lldb/API/SBAddress.h", + "/include/lldb/API/SBBlock.h", + "/include/lldb/API/SBBreakpoint.h", + "/include/lldb/API/SBBreakpointLocation.h", + "/include/lldb/API/SBBroadcaster.h", + "/include/lldb/API/SBCommandInterpreter.h", + "/include/lldb/API/SBCommandReturnObject.h", + "/include/lldb/API/SBCommunication.h", + "/include/lldb/API/SBCompileUnit.h", + "/include/lldb/API/SBData.h", + "/include/lldb/API/SBDebugger.h", + "/include/lldb/API/SBError.h", + "/include/lldb/API/SBEvent.h", + "/include/lldb/API/SBExpressionOptions.h", + "/include/lldb/API/SBFileSpec.h", + "/include/lldb/API/SBFrame.h", + "/include/lldb/API/SBFunction.h", + "/include/lldb/API/SBHostOS.h", + "/include/lldb/API/SBInputReader.h", + "/include/lldb/API/SBInstruction.h", + "/include/lldb/API/SBInstructionList.h", + "/include/lldb/API/SBLineEntry.h", + "/include/lldb/API/SBListener.h", + "/include/lldb/API/SBModule.h", + "/include/lldb/API/SBModuleSpec.h", + "/include/lldb/API/SBProcess.h", + "/include/lldb/API/SBSourceManager.h", + "/include/lldb/API/SBStream.h", + "/include/lldb/API/SBStringList.h", + "/include/lldb/API/SBSymbol.h", + "/include/lldb/API/SBSymbolContext.h", + "/include/lldb/API/SBSymbolContextList.h", + "/include/lldb/API/SBTarget.h", + "/include/lldb/API/SBThread.h", + "/include/lldb/API/SBType.h", + "/include/lldb/API/SBTypeCategory.h", + "/include/lldb/API/SBTypeFilter.h", + "/include/lldb/API/SBTypeFormat.h", + "/include/lldb/API/SBTypeNameSpecifier.h", + "/include/lldb/API/SBTypeSummary.h", + "/include/lldb/API/SBTypeSynthetic.h", + "/include/lldb/API/SBValue.h", + "/include/lldb/API/SBValueList.h", + "/include/lldb/API/SBWatchpoint.h" ]; + bDebug = vDictArgs.has_key( "-d" ); + strRt = vDictArgs[ "--srcRoot" ]; + strRt = os.path.normcase( strRt ); + + strHeaderFiles = ""; + for strHdr in listHeaderFiles[ 0: len( listHeaderFiles ) ]: + strHdr = os.path.normcase( strHdr ); + strHeaderFiles += " %s%s" % (strRt, strHdr); + + if bDebug: + print strMsgHdrFiles; + print strHeaderFiles; + + vDictArgs[ "--headerFiles" ] = strHeaderFiles; + + return True; + +#++--------------------------------------------------------------------------- +# Details: Retrieve the list of hard coded lldb SWIG interface file names and +# put in the program's dictArgs map container. Make paths compatible +# with the current OS. +# Note this does not necessarily match the content of those +# directories. The resultant interface string is inserted into the +# dictionary vDictArgs key "--ifaceFiles". +# Args: vDictArgs - (RW) Program input parameters. +# Returns: Bool - True = success, False = failure. +# Throws: None. +#-- +def get_interface_files( vDictArgs ): + dbg = utilsDebug.CDebugFnVerbose( "Python script get_interface_files()" ); + listIFaceFiles = [ "/scripts/Python/interface/SBAddress.i", + "/scripts/Python/interface/SBBlock.i", + "/scripts/Python/interface/SBBreakpoint.i", + "/scripts/Python/interface/SBBreakpointLocation.i", + "/scripts/Python/interface/SBBroadcaster.i", + "/scripts/Python/interface/SBCommandInterpreter.i", + "/scripts/Python/interface/SBCommandReturnObject.i", + "/scripts/Python/interface/SBCommunication.i", + "/scripts/Python/interface/SBCompileUnit.i", + "/scripts/Python/interface/SBData.i", + "/scripts/Python/interface/SBDebugger.i", + "/scripts/Python/interface/SBDeclaration.i", + "/scripts/Python/interface/SBError.i", + "/scripts/Python/interface/SBEvent.i", + "/scripts/Python/interface/SBExpressionOptions.i", + "/scripts/Python/interface/SBFileSpec.i", + "/scripts/Python/interface/SBFrame.i", + "/scripts/Python/interface/SBFunction.i", + "/scripts/Python/interface/SBHostOS.i", + "/scripts/Python/interface/SBInputReader.i", + "/scripts/Python/interface/SBInstruction.i", + "/scripts/Python/interface/SBInstructionList.i", + "/scripts/Python/interface/SBLineEntry.i", + "/scripts/Python/interface/SBListener.i", + "/scripts/Python/interface/SBModule.i", + "/scripts/Python/interface/SBModuleSpec.i", + "/scripts/Python/interface/SBProcess.i", + "/scripts/Python/interface/SBSourceManager.i", + "/scripts/Python/interface/SBStream.i", + "/scripts/Python/interface/SBStringList.i", + "/scripts/Python/interface/SBSymbol.i", + "/scripts/Python/interface/SBSymbolContext.i", + "/scripts/Python/interface/SBTarget.i", + "/scripts/Python/interface/SBThread.i", + "/scripts/Python/interface/SBType.i", + "/scripts/Python/interface/SBTypeCategory.i", + "/scripts/Python/interface/SBTypeFilter.i", + "/scripts/Python/interface/SBTypeFormat.i", + "/scripts/Python/interface/SBTypeNameSpecifier.i", + "/scripts/Python/interface/SBTypeSummary.i", + "/scripts/Python/interface/SBTypeSynthetic.i", + "/scripts/Python/interface/SBValue.i", + "/scripts/Python/interface/SBValueList.i", + "/scripts/Python/interface/SBWatchpoint.i" ]; + bDebug = vDictArgs.has_key( "-d" ); + strRt = vDictArgs[ "--srcRoot" ]; + strRt = os.path.normcase( strRt ); + + strInterfaceFiles = ""; + for strIFace in listIFaceFiles[ 0: len( listIFaceFiles ) ]: + strIFace = os.path.normcase( strIFace ); + strInterfaceFiles += " %s%s" % (strRt, strIFace); + + if bDebug: + print strMsgIFaceFiles; + print strInterfaceFiles; + + vDictArgs[ "--ifaceFiles" ] = strInterfaceFiles; + + return True; + +#++--------------------------------------------------------------------------- +# Details: Compare which file is newer. +# Args: vFile1 - (R) File name path. +# vFile2 - (R) File name path. +# Returns: Int - 0 = both not exist, 1 = file 1 newer, 2 = file 2 newer, +# 3 = file 1 not exist. +# Throws: None. +#-- +def which_file_is_newer( vFile1, vFile2 ): + bF1 = os.path.exists( vFile1 ); + bF2 = os.path.exists( vFile2 ); + if bF1 == False and bF2 == False: + return 0; # Both files not exist + if bF1 == False: + return 3; # File 1 not exist + if bF2 == False: + return 1; # File 1 is newer / file 2 not exist + f1Stamp = os.path.getmtime( vFile1 ); + f2Stamp = os.path.getmtime( vFile2 ); + if f1Stamp > f2Stamp: + return 1; # File 1 is newer + + return 2; # File 2 is newer than file 1 + +#++--------------------------------------------------------------------------- +# Details: Determine whether the specified file exists. +# Args: vDictArgs - (R) Program input parameters. +# vstrFileNamePath - (R) Check this file exists. +# Returns: Bool - True = Files exists, false = not found. +# Throws: None. +#-- +def check_file_exists( vDictArgs, vstrFileNamePath ): + bExists = False; + bDebug = vDictArgs.has_key( "-d" ); + + if os.path.exists( vstrFileNamePath ): + bExists = True; + elif bDebug: + print strMsgFileNotExist % vstrFileNamePath; + + return bExists; + +#++--------------------------------------------------------------------------- +# Details: Determine whether the specified file is newer than the +# LLDBWrapPython.cpp file. +# Args: vDictArgs - (R) Program input parameters. +# vstrSwigOpFileNamePath - (R) LLDBWrapPython.cpp file. +# vstrFileNamePath - (R) Specific file. +# Returns: Bool - True = SWIG update required, false = no update required. +# Throws: None. +#-- +def check_newer_file( vDictArgs, vstrSwigOpFileNamePath, vstrFileNamePath ): + bNeedUpdate = False; + bDebug = vDictArgs.has_key( "-d" ); + + strMsg = ""; + nResult = which_file_is_newer( vstrFileNamePath, vstrSwigOpFileNamePath ); + if nResult == 1: + strMsg = strMsgFileNewrSwigOpFile % (vstrFileNamePath, + vstrSwigOpFileNamePath); + bNeedUpdate = True; + elif nResult == 3: + strMsg = strMsgFileNotExist % vstrFileNamePath; + bNeedUpdate = True; + + if bNeedUpdate and bDebug: + print strMsg; + + return bNeedUpdate; + +#++--------------------------------------------------------------------------- +# Details: Determine whether the any files in the list are newer than the +# LLDBWrapPython.cpp file. +# Args: vDictArgs - (R) Program input parameters. +# vstrSwigOpFileNamePath - (R) LLDBWrapPython.cpp file. +# vstrFiles - (R) Multi string file names ' ' delimiter. +# Returns: Bool - True = SWIG update required, false = no update required. +# Throws: None. +#-- +def check_newer_files( vDictArgs, vstrSwigOpFileNamePath, vstrFiles ): + bNeedUpdate = False; + + listFiles = vstrFiles.split(); + for strFile in listFiles: + if check_newer_file( vDictArgs, vstrSwigOpFileNamePath, strFile ): + bNeedUpdate = True; + break; + + return bNeedUpdate; + +#++--------------------------------------------------------------------------- +# Details: 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 = vDictArgs.has_key( "--prefix" ); + if bHaveArgPrefix: + strPythonInstallDir = vDictArgs[ "--prefix" ]; + if strPythonInstallDir.__len__() != 0: + strWkDir = get_python_lib( True, False, strPythonInstallDir ); + else: + strWkDir = get_python_lib( True, False ); + strWkDir += "/lldb"; + strWkDir = os.path.normcase( strWkDir ); + + 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 = vDictArgs.has_key( "-d" ); + + bMakeFileCalled = vDictArgs.has_key( "-m" ); + 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 += "/LLDB.framework"; + if os.path.exists( strWkDir ): + if bDbg: + print strMsgFoundLldbFrameWkDir % strWkDir; + 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 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 = vDictArgs.has_key( "--cfgBldDir" ); + if bHaveConfigBldDir: + strConfigBldDir = vDictArgs[ "--cfgBldDir" ]; + if (bHaveConfigBldDir == False) or (strConfigBldDir.__len__() == 0): + strConfigBldDir = vstrFrameworkPythonDir; + + return (bOk, strConfigBldDir, strErrMsg); + +#++--------------------------------------------------------------------------- +# Details: Do a SWIG code rebuild. Any number returned by SWIG which is not +# zero is treated as an error. The generate dependencies flag decides +# how SWIG is rebuilt and if set false will cause the script to exit +# immediately with the exit status + 200 if status is not zero. +# Args: vDictArgs - (R) Program input parameters. +# vstrSwigDepFile - (R) SWIG dependency file. +# vstrCfgBldDir - (R) Configuration build directory. +# vstrSwigOpFile - (R) SWIG output file. +# vstrSwigIpFile - (R) SWIG input file. +# Returns: Bool - True = function success, False = failure. +# strMsg - Error or status message. +# nExitResult - Exit result of SWIG executable. +# - 0 = Success. +# - 1 = Success, exit this script and parent script. +# - +200 = A SWIG error status result. +# Throws: None. +#-- +def do_swig_rebuild( vDictArgs, vstrSwigDepFile, vstrCfgBldDir, + vstrSwigOpFile, vstrSwigIpFile ): + dbg = utilsDebug.CDebugFnVerbose( "Python script do_swig_rebuild()" ); + bOk = True; + strMsg = ""; + bDbg = vDictArgs.has_key( "-d" ); + bGenDependencies = vDictArgs.has_key( "-M" ); + strSwigExePath = vDictArgs[ "--swigExePath" ]; + strSwigExeName = vDictArgs[ "--swigExeName" ]; + strSrcRoot = vDictArgs[ "--srcRoot" ]; + + # Build SWIG path to executable + if strSwigExePath != "": + strSwig = "%s/%s" % (strSwigExePath, strSwigExeName); + strSwig = os.path.normcase( strSwig ); + else: + strSwig = strSwigExeName; + + strCfg = vstrCfgBldDir; + strOp = vstrSwigOpFile; + strIp = vstrSwigIpFile; + strSi = os.path.normcase( "./." ); + strRoot = strSrcRoot + "/include"; + strRoot = os.path.normcase( strRoot ); + strDep = ""; + if bGenDependencies: + strDep = vstrSwigDepFile + ".tmp"; + + # Build the SWIG args list + strCmd = "%s " % strSwig; + strCmd += "-c++ "; + strCmd += "-shadow "; + strCmd += "-python "; + strCmd += "-threads "; + strCmd += "-I\"%s\" " % strRoot; + strCmd += "-I\"%s\" " % strSi; + strCmd += "-D__STDC_LIMIT_MACROS "; + strCmd += "-D__STDC_CONSTANT_MACROS "; + if bGenDependencies: + strCmd += "-MMD -MF \"%s\" " % strDep; + strCmd += "-outdir \"%s\" " % strCfg; + strCmd += "-o \"%s\" " % strOp; + strCmd += "\"%s\" " % strIp; + if bDbg: + print strMsgSwigExecute % strCmd; + + # Execute SWIG + process = subprocess.Popen( strCmd, stdout=subprocess.PIPE, + stderr=subprocess.PIPE, shell=True ); + # Wait for SWIG process to terminate + strStdOut, strStdErr = process.communicate(); + nResult = process.returncode; + if nResult != 0: + bOk = False; + nResult += 200; + strMsg = strErrMsgSwigExecute % strStdErr; + else: + if bDbg and (strStdOut.__len__() != 0): + strMsg = strStdOut; + + if bGenDependencies: + if bOk: + if os.path.exists( strDep ): + shutil.move( strDep, vstrSwigDepFile ); + else: + os.remove( strDep ); + nResult = 1; # Exit this script and parent script + if bDbg: + strMsg = strMsgSwigGenDep % strDep; + else: + strMsg = strMsgSwigNoGenDep + strMsg; + + return bOk, strMsg, nResult; + +#++--------------------------------------------------------------------------- +# Details: Execute another Python script from this script in a separate +# process. No data is passed back to the caller script. It is +# assumed should any exit result be returned that -ve numbers are +# error conditions. A zero or +ve numbers mean ok/warning/status. +# Args: vDictArgs - (R) Program input parameters. +# vstrArgs - (R) Space separated parameters passed to python. +# Returns: Bool - True = function success, False = failure. +# strMsg - Error or status message. +# Throws: None. +#-- +def run_python_script( vDictArgs, vstrArgs ): + dbg = utilsDebug.CDebugFnVerbose( "Python script run_python_script()" ); + bOk = True; + strMsg = ""; + bDbg = vDictArgs.has_key( "-d" ); + + strPy = "python %s" % vstrArgs; + process = subprocess.Popen( strPy, shell=True ); + strStdOut, strStdErr = process.communicate(); + nResult = process.returncode; + if nResult < 0: + bOk = False; + strErr = strStdErr; + if strErr == None: + strErr = "No error given"; + strMsg = strErrMsgPythonExecute % (vstrArgs, strErr); + else: + if bDbg: + strOut = strStdOut; + if strOut == None: + strOut = "No status given"; + strMsg = strOut; + + return bOk, strMsg; + +#++--------------------------------------------------------------------------- +# Details: Implement the iterator protocol and/or eq/ne operators for some +# lldb objects. +# Append global variable to lldb Python module. +# And initialize the lldb debugger subsystem. +# Args: vDictArgs - (R) Program input parameters. +# vstrCfgBldDir - (R) Configuration build directory. +# Returns: Bool - True = function success, False = failure. +# strMsg - Error or status message. +# Throws: None. +#-- +def do_modify_python_lldb( vDictArgs, vstrCfgBldDir ): + dbg = utilsDebug.CDebugFnVerbose( "Python script do_modify_python_lldb()" ); + bOk = True; + strMsg = ""; + bDbg = vDictArgs.has_key( "-d" ); + strCwd = vDictArgs[ "--srcRoot" ]; # /llvm/tools/lldb + strCwd += "/scripts/Python"; + strPyScript = "modify-python-lldb.py"; + strPath = "%s/%s" % (strCwd, strPyScript); + strPath = os.path.normcase( strPath ); + + bOk = os.path.exists( strPath ); + if not bOk: + strMsg = strErrMsgModifyPythonLldbPyFileNotFound % (strPyScript, strPath); + return bOk, strMsg; + + strPyArgs = "%s %s" % (strPath, vstrCfgBldDir); + bOk, strMsg = run_python_script( vDictArgs, strPyArgs ); + + return bOk, strMsg; + +#----------------------------------------------------------------------------- +#----------------------------------------------------------------------------- +#----------------------------------------------------------------------------- + +""" 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. + If environmental variable "LLDB_DISABLE_PYTHON" is defined/exists + it will cause the script to end early creating nothing. + If environmental variable "GCC_PREPROCESSOR_DEFINITIONS" is + defined/exists it will cause the script to end early creating + nothing. + Args: vDictArgs - (R) Map of parameter names to values. Used to for the + the SWIG required parameters to create code. Note + this container does get amended with more data. + -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. + -M (optional) Specify want SWIG to generate a dependency file. + --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. + --swigExePath File path the SWIG executable. (Determined and + passed by buildSwigWrapperClasses.py to here) + --swigExeName The file name of the SWIG executable. (Determined + and passed by buildSwigWrapperClasses.py to + here) + Results: 0 Success + 1 Success, generated dependencies removed + LLDBWrapPython.cpp.d. + -100+ Error from this script to the caller script. + -100 Error program failure with optional message. + -200+ - 200 +- the SWIG exit result. + + -------------------------------------------------------------------------- + +""" +def main( vDictArgs ): + dbg = utilsDebug.CDebugFnVerbose( "Python script main()" ); + bOk = True; + strMsg = ""; + strErrMsgProgFail = ""; + + if not( vDictArgs.has_key( "--swigExePath" ) and vDictArgs.has_key( "--swigExeName" ) ): + strErrMsgProgFail += strErrMsgSwigParamsMissing; + return (-100, strErrMsgProgFail ); + + bDebug = vDictArgs.has_key( "-d" ); + + strSwigDepFile = ""; + strSwigDepOptions = ""; + bGenDependencies = vDictArgs.has_key( "-M" ); + if bGenDependencies: + strSwigDepFile = vDictArgs[ "--targetDir" ] + "/LLDBWrapPython.cpp.d"; + strSwigDepOptions = "-MMD -MF \"%s.tmp\"" % strSwigDepFile; + strSwigDepFile = os.path.normcase( strSwigDepFile ); + strSwigDepOptions = os.path.normcase( strSwigDepOptions ); + + bMakeFileCalled = vDictArgs.has_key( "-m" ); + strSwigOutputFile = "" + if bMakeFileCalled: + strSwigOutputFile = vDictArgs[ "--targetDir" ] + "/LLDBWrapPython.cpp"; + else: + strSwigOutputFile = vDictArgs[ "--srcRoot" ] + "/source/LLDBWrapPython.cpp"; + strSwigOutputFile = os.path.normcase( strSwigOutputFile ); + + strRt = vDictArgs[ "--srcRoot" ]; + strSwigInputFile = strRt + "/scripts/lldb.swig"; + strSwigPythonExtensions = strRt + "/scripts/Python/python-extensions.swig"; + strSwigPythonWrapper = strRt + "/scripts/Python/python-wrapper.swig"; + strSwigPythonTypemaps = strRt + "/scripts/Python/python-typemaps.swig"; + strSwigPythonSwigsafecast = strRt + "/scripts/Python/python-swigsafecast.swig"; + strSwigInputFile = os.path.normcase( strSwigInputFile ); + strSwigPythonExtensions = os.path.normcase( strSwigPythonExtensions ); + strSwigPythonWrapper = os.path.normcase( strSwigPythonWrapper ); + strSwigPythonTypemaps = os.path.normcase( strSwigPythonTypemaps ); + strSwigPythonSwigsafecast = os.path.normcase( strSwigPythonSwigsafecast ); + + strEnvVarLLDBDisablePython = os.getenv( "LLDB_DISABLE_PYTHON", None ); + # We don't want Python for this build, but touch the output file so we + # don't have to conditionalize the build on this as well. + # Note, at present iOS doesn't have Python, so if you're building for + # iOS be sure to set LLDB_DISABLE_PYTHON to 1. + if (strEnvVarLLDBDisablePython != None) and \ + (strEnvVarLLDBDisablePython == "1"): + os.remove( strSwigOutputFile ); + open( strSwigOutputFile, 'w' ).close(); # Touch the file + if bDebug: + strMsg = strMsgLldbDisablePython; + return (0, strMsg ); + + # If this project is being built with LLDB_DISABLE_PYTHON defined, + # don't bother generating Python swig bindings -- we don't have + # Python available. + strEnvVarGccPreprocessDefs = os.getenv( "GCC_PREPROCESSOR_DEFINITIONS", + None ); + if (strEnvVarGccPreprocessDefs != None) or \ + (strEnvVarLLDBDisablePython != None): + os.remove( strSwigOutputFile ); + open( strSwigOutputFile, 'w' ).close(); # Touch the file + if bDebug: + strMsg = strMsgLldbDisableGccEnv; + return (0, strMsg); + + bOk = bOk and get_header_files( vDictArgs ); + bOk = bOk and get_interface_files( vDictArgs ); + + strFrameworkPythonDir = ""; + if bOk: + bNeedUpdate = (check_file_exists( vDictArgs, strSwigOutputFile ) == False); + dbg.dump_object( "check_file_exists strSwigOutputFile, bNeedUpdate =", bNeedUpdate); + if bNeedUpdate == False: + bNeedUpdate = check_newer_files( vDictArgs, strSwigOutputFile, vDictArgs[ "--headerFiles" ] ); + dbg.dump_object( "check_newer_files header files than strSwigOutputFile, bNeedUpdate =", bNeedUpdate); + if bNeedUpdate == False: + bNeedUpdate = check_newer_files( vDictArgs, strSwigOutputFile, vDictArgs[ "--ifaceFiles" ] ); + dbg.dump_object( "check_newer_files iface files than strSwigOutputFile, bNeedUpdate =", bNeedUpdate); + if bNeedUpdate == False: + bNeedUpdate = check_newer_file( vDictArgs, strSwigOutputFile, strSwigInputFile ); + dbg.dump_object( "check_newer_files strSwigInputFile than strSwigOutputFile, bNeedUpdate =", bNeedUpdate); + if bNeedUpdate == False: + bNeedUpdate = check_newer_file( vDictArgs, strSwigOutputFile, strSwigPythonExtensions ); + dbg.dump_object( "check_newer_files strSwigPythonExtensions than strSwigOutputFile, bNeedUpdate =", bNeedUpdate); + if bNeedUpdate == False: + bNeedUpdate = check_newer_file( vDictArgs, strSwigOutputFile, strSwigPythonWrapper ); + dbg.dump_object( "check_newer_files strSwigPythonWrapper than strSwigOutputFile, bNeedUpdate =", bNeedUpdate); + if bNeedUpdate == False: + bNeedUpdate = check_newer_file( vDictArgs, strSwigOutputFile, strSwigPythonTypemaps ); + dbg.dump_object( "check_newer_files strSwigPythonTypemaps than strSwigOutputFile, bNeedUpdate =", bNeedUpdate); + if bNeedUpdate == False: + bNeedUpdate = check_newer_file( vDictArgs, strSwigOutputFile, strSwigPythonSwigsafecast ); + dbg.dump_object( "check_newer_files strSwigPythonSwigsafecast than strSwigOutputFile, bNeedUpdate =", bNeedUpdate); + + # Determine where to put the files + bOk, strFrameworkPythonDir, strMsg = get_framework_python_dir( vDictArgs ); + + if bOk: + bOk, strCfgBldDir, strMsg = get_config_build_dir( vDictArgs, strFrameworkPythonDir ); + + if bOk and (bNeedUpdate == False): + strDllPath = strFrameworkPythonDir + "/_lldb.so"; + strDllPath = os.path.normcase( strDllPath ); + bSymbolicLink = check_file_exists( vDictArgs, strDllPath ) and os.path.islink( strDllPath ); + bNeedUpdate = not bSymbolicLink; + dbg.dump_object( "check_file_exists( vDictArgs, strDllPath ) and os.path.islink( strDllPath ), bNeedUpdate =", bNeedUpdate); + + if bOk and (bNeedUpdate == False): + strInitPiPath = strFrameworkPythonDir + "/__init__.py"; + strInitPiPath = os.path.normcase( strInitPiPath ); + print strInitPiPath + bNeedUpdate = not check_file_exists( vDictArgs, strInitPiPath ); + dbg.dump_object( "check_file_exists( vDictArgs, strInitPiPath ), bNeedUpdate =", bNeedUpdate); + + if bOk: + if (bNeedUpdate == False): + strMsg = strMsgNotNeedUpdate; + return (0, strMsg ); + else: + print strMsgSwigNeedRebuild; + bOk, strMsg, nExitResult = do_swig_rebuild( vDictArgs, strSwigDepFile, + strCfgBldDir, + strSwigOutputFile, + strSwigInputFile ); + bGenDependencies = vDictArgs.has_key( "-M" ); + if bGenDependencies == True: + return (nExitResult, strMsg); + + if bOk: + bOk, strMsg = do_modify_python_lldb( vDictArgs, strCfgBldDir ); + + 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 buildSwigWrapperClasses.py"; + Index: scripts/Python/finish-swig-Python-LLDB.sh =================================================================== --- scripts/Python/finish-swig-Python-LLDB.sh +++ scripts/Python/finish-swig-Python-LLDB.sh @@ -156,7 +156,7 @@ if [ $MakefileCalled -eq 0 ] then ln -s "../../../LLDB" _lldb.so - else + else ln -s "../../../liblldb${SOEXT}" _lldb.so fi else Index: scripts/Python/finishSwigPythonLLDB.py =================================================================== --- /dev/null +++ scripts/Python/finishSwigPythonLLDB.py @@ -0,0 +1,624 @@ +""" 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. + + Environment: OS: Windows Vista or newer, LINUX, OSX. + IDE: Visual Studio 2013 Plugin Python Tools (PTVS) + Script: Python 2.6/2.7.5 x64 + Other: None. + + 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 errno # OS error results +import shutil # High-level operations on files and collections of files +import subprocess # Call external programs +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: "; +strErrMsgFrameWkPyDirNotExist = "Unable to find the LLDB.framework directory '%s'"; +strMsgFoundLldbFrameWkDir = "Found '%s'"; +strMsgPyFileLocatedHere = "Python file will be put in '%s'"; +strMsgFrameWkPyExists = "'%s' already exists"; +strMsgFrameWkPyMkDir = "Making directory '%s'"; +strErrMsgCreateFrmWkPyDirFailed = "Unable to create directory '%s' error: %s"; +strMsglldbsoExists = "'%s' already exists"; +strMsglldbsoMk = "Creating symlink for _lldb.so"; +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"; + +#++--------------------------------------------------------------------------- +# 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 = 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 = vDictArgs[ "--srcRoot" ]; + strSrc = strRoot + "/examples/darwin/heap_find/heap/heap_find.cpp"; + shutil.copy( strSrc, strHeapDir ); + strSrc = 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 ); + + bOk = True; + strMsg = ""; + + if vstrPkgDir.__len__() != 0 and vstrPkgDir[ 0 ] != "/": + bOk = False; + strMsg = strErrMsgCreatePyPkgMissingSlash; + return (bOk, strMsg); + + strPkgName = vstrPkgDir; + strPkgName = "lldb" + strPkgName.replace( "/", "." ); + strPkgName = os.path.normcase( strPkgName ); + + strPkgDir = vstrFrameworkPythonDir; + strPkgDir += vstrPkgDir; + strPkgDir = os.path.normcase( strPkgDir ); + + if not(os.path.exists( strPkgDir ) and os.path.isdir( strPkgDir )): + os.makedirs( strPkgDir ); + + for strPkgFile in vListPkgFiles: + if os.path.exists( strPkgFile ) and os.path.isfile( strPkgFile ): + strPyFile = os.path.normcase( strPkgFile ); + shutil.copy( strPyFile, strPkgDir ); + + # Create a packet init files if there wasn't one + strPkgIniFile = strPkgDir + "/__init__.py"; + strPkgIniFile = os.path.normcase( strPkgIniFile ); + if os.path.exists( strPkgIniFile ) and os.path.isfile( strPkgIniFile ): + return (bOk, strMsg); + + strPyScript = "__all__ = ["; + strDelimiter = ""; + for strPkgFile in vListPkgFiles: + strPyFile = os.path.normcase( strPkgFile ); + if os.path.exists( strPyFile ) and os.path.isfile( strPyFile ): + 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; + + 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: 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( vstrFrameworkPythonDir, vstrCfgBldDir ): + dbg = utilsDebug.CDebugFnVerbose( "Python script copy_lldbpy_file_to_lldb_pkg_dir()" ); + bOk = True; + strMsg = ""; + + strSrc = vstrCfgBldDir + "/lldb.py"; + strSrc = os.path.normcase( strSrc ); + strDst = vstrFrameworkPythonDir + "/__init__.py"; + strDst = os.path.normcase( strDst ); + + if not os.path.exists( strSrc ): + return (bOk, strMsg); + + try: + 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 that the script bridge for Python will need in +# the Python framework directory. Code for specific to Windows. +# Args: vDictArgs - (R) Program input parameters. +# vstrFrameworkPythonDir - (R) Python framework directory. +# vstrDllName - (R) File name for _lldb.dll. +# Returns: Bool - True = function success, False = failure. +# Str - Error description on task failure. +# Throws: None. +#-- +def make_symlink_windows( vDictArgs, vstrFrameworkPythonDir, vstrDllName ): + dbg = utilsDebug.CDebugFnVerbose( "Python script make_symlink_windows()" ); + bOk = True; + strMsg = ""; + + bDbg = vDictArgs.has_key( "-d" ); + strTarget = vstrDllName + ".pyd"; + strDLLPath = "%s\\%s" % (vstrFrameworkPythonDir, strTarget); + strTarget = os.path.normcase( strDLLPath ); + strSrc = ""; + + os.chdir( vstrFrameworkPythonDir ); + bMakeFileCalled = vDictArgs.has_key( "-m" ); + if not bMakeFileCalled: + strSrc = os.path.normcase( "../../../LLDB" ); + else: + strLibFileExtn = ".dll"; + strSrc = os.path.normcase( "../../../bin/liblldb%s" % strLibFileExtn ); + + if os.path.isfile( strTarget ): + if bDbg: + print strMsglldbsoExists % strTarget; + return (bOk, strMsg); + + if bDbg: + print strMsglldbsoMk; + + 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(strTarget, strSrc, 0) == 0: + raise ctypes.WinError() + except Exception as e: + bOk = False; + strMsg = "WinError( %d ): %s %s" % (e.errno, e.strerror, strErrMsgMakeSymlink); + strMsg += " Src:'%s' Target:'%s'" % (strSrc, strTarget); + + return (bOk, strMsg); + +#++--------------------------------------------------------------------------- +# Details: Make the symbolic link that the script bridge for Python will need in +# the Python framework directory. Code for all platforms apart from +# Windows. +# Args: vDictArgs - (R) Program input parameters. +# vstrFrameworkPythonDir - (R) Python framework directory. +# vstrSoName - (R) File name for _lldb.so. +# Returns: Bool - True = function success, False = failure. +# Str - Error description on task failure. +# Throws: None. +#-- +def make_symlink_other_platforms( vDictArgs, vstrFrameworkPythonDir, vstrSoPath ): + dbg = utilsDebug.CDebugFnVerbose( "Python script make_symlink_other_platforms()" ); + bOk = True; + strMsg = ""; + bDbg = vDictArgs.has_key( "-d" ); + strTarget = vstrSoPath + ".so"; + strSoPath = "%s/%s" % (vstrFrameworkPythonDir, strTarget); + strTarget = os.path.normcase( strSoPath ); + strSrc = ""; + + os.chdir( vstrFrameworkPythonDir ); + bMakeFileCalled = vDictArgs.has_key( "-m" ); + if not bMakeFileCalled: + strSrc = os.path.normcase( "../../../LLDB" ); + else: + strLibFileExtn = ""; + eOSType = utilsOsType.determine_os_type(); + if eOSType == utilsOsType.EnumOsType.Linux: + strLibFileExtn = ".so"; + elif eOSType == utilsOsType.EnumOsType.Darwin: + strLibFileExtn = ".dylib"; + strSrc = os.path.normcase( "../../../liblldb%s" % strLibFileExtn ); + + if os.path.islink( strTarget ): + if bDbg: + print strMsglldbsoExists % strTarget; + return (bOk, strMsg); + + if bDbg: + print strMsglldbsoMk; + + try: + os.symlink( strSrc, strTarget ); + except OSError as e: + bOk = False; + strMsg = "OSError( %d ): %s %s" % (e.errno, e.strerror, strErrMsgMakeSymlink); + strMsg += " Src:'%s' Target:'%s'" % (strSrc, strTarget); + except: + bOk = False; + strMsg = strErrMsgUnexpected % sys.exec_info()[ 0 ]; + + return (bOk, strMsg); + +#++--------------------------------------------------------------------------- +# 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. +# Returns: Bool - True = function success, False = failure. +# strErrMsg - Error description on task failure. +# Throws: None. +#-- +def make_symlink( vDictArgs, vstrFrameworkPythonDir ): + dbg = utilsDebug.CDebugFnVerbose( "Python script make_symlink()" ); + bOk = True; + strWkDir = ""; + strErrMsg = ""; + strSoFileName = "_lldb"; + + eOSType = utilsOsType.determine_os_type(); + if eOSType == utilsOsType.EnumOsType.Unknown: + bOk = False; + strErrMsg = strErrMsgOsTypeUnknown; + elif eOSType == utilsOsType.EnumOsType.Windows: + bOk, strErrMsg = make_symlink_windows( vDictArgs, + vstrFrameworkPythonDir, + strSoFileName ); + else: + bOk, strErrMsg = make_symlink_other_platforms( vDictArgs, + vstrFrameworkPythonDir, + strSoFileName ); + return (bOk, strErrMsg); + +#++--------------------------------------------------------------------------- +# 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 = vDictArgs.has_key( "-d" ); + + 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 = vDictArgs.has_key( "--cfgBldDir" ); + 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 = vDictArgs.has_key( "--prefix" ); + if bHaveArgPrefix: + strPythonInstallDir = vDictArgs[ "--prefix" ]; + + bHaveArgCmakeBuildConfiguration = vDictArgs.has_key( "--cmakeBuildConfiguration" ); + if bHaveArgCmakeBuildConfiguration: + strPythonInstallDir += '/' + vDictArgs[ "--cmakeBuildConfiguration" ]; + + if strPythonInstallDir.__len__() != 0: + strWkDir = get_python_lib( True, False, strPythonInstallDir ); + else: + strWkDir = get_python_lib( True, False ); + strWkDir += "/lldb"; + strWkDir = os.path.normcase( strWkDir ); + + 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 = vDictArgs.has_key( "-d" ); + + bMakeFileCalled = vDictArgs.has_key( "-m" ); + 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 += "/LLDB.framework"; + if os.path.exists( strWkDir ): + if bDbg: + print strMsgFoundLldbFrameWkDir % strWkDir; + 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: 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. + 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 = vDictArgs.has_key( "-d" ); + + 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; + + if bOk: + bOk, strMsg = find_or_create_python_dir( vDictArgs, strFrameworkPythonDir ); + + if bOk: + bOk, strMsg = make_symlink( vDictArgs, strFrameworkPythonDir ); + + if bOk: + bOk, strMsg = copy_lldbpy_file_to_lldb_pkg_dir( strFrameworkPythonDir, + strCfgBldDir ); + strRoot = vDictArgs[ "--srcRoot" ]; + if bOk: + # lldb + listPkgFiles = [ strRoot + "/source/Interpreter/embedded_interpreter.py" ]; + bOk, strMsg = create_py_pkg( vDictArgs, strFrameworkPythonDir, "", listPkgFiles ); + + if bOk: + # lldb/formatters/cpp + listPkgFiles = [ strRoot + "/examples/synthetic/gnu_libstdcpp.py", + 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 = [ strRoot + "/examples/summaries/cocoa/cache.py", + strRoot + "/examples/summaries/cocoa/metrics.py", + strRoot + "/examples/summaries/cocoa/attrib_fromdict.py", + strRoot + "/examples/summaries/cocoa/Logger.py" ]; + bOk, strMsg = create_py_pkg( vDictArgs, strFrameworkPythonDir, "/formatters", listPkgFiles ); + + if bOk: + # lldb/utils + listPkgFiles = [ strRoot + "/examples/python/symbolication.py" ]; + bOk, strMsg = create_py_pkg( vDictArgs, strFrameworkPythonDir, "/utils", listPkgFiles ); + + if bOk and (eOSType == utilsOsType.EnumOsType.Darwin): + # lldb/macosx + listPkgFiles = [ strRoot + "/examples/python/crashlog.py", + 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 = [ strRoot + "/examples/python/diagnose_unwind.py", + 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"; + Index: scripts/Python/interface/SBHostOS.i =================================================================== --- scripts/Python/interface/SBHostOS.i +++ scripts/Python/interface/SBHostOS.i @@ -21,7 +21,7 @@ static lldb::thread_t ThreadCreate (const char *name, - void *(*thread_function)(void *), + lldb::thread_func_t, void *thread_arg, lldb::SBError *err); @@ -34,7 +34,7 @@ lldb::SBError *err); static bool ThreadJoin (lldb::thread_t thread, - void **result, + lldb::thread_result_t *result, lldb::SBError *err); }; Index: scripts/buildSwigWrapperClasses.py =================================================================== --- /dev/null +++ scripts/buildSwigWrapperClasses.py @@ -0,0 +1,561 @@ +""" SWIG creates Python C++ Script Bridge wrapper code Windows/LINUX/OSX platform + + -------------------------------------------------------------------------- + File: buildSwigWrapperClasses.py + + Overview: Python script(s) to build 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. + For each scripting language lib lldb supports, we need to + create the appropriate Script Bridge wrapper classes for + that language so that users can call Script Bridge + functions from within the script interpreter. + We use SWIG to help create the appropriate wrapper + classes/functions for the scripting language. In some + cases the file generated by SWIG may need some tweaking + before it is completely ready to use. + + Environment: OS: Windows Vista or newer,LINUX,OSX. + IDE: Visual Studio 2013 Plugin Python Tools (PTVS) + Script: Python 2.6/2.7.5 x64 + Other: SWIG 2.0.11 + + Gotchas: For Windows OS it is assumed the SWIG executable can be + found in the %PATH% environmental variable. + + 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: +gbDbgVerbose = False; # True = Turn on script function tracing, False = off. +gbDbgFlag = False; # Global debug mode flag, set by input parameter + # --dbgFlag. True = operate in debug mode. +gbMakeFileFlag = False; # True = yes called from makefile system, False = not. +gbSwigGenDepFileFlag = False; # True = SWIG generate a dependency file. + +# 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" +strSwigFileFound = "Found the \'lldb.swig\' file\n"; +strSwigFileFoundNotFound = "Unable to locate the file \'%s\'" +strSwigExeFileNotFound = "Unable to locate the SWIG executable file \'swig\'"; +strSwigScriptDirNotFound = "Unable to locate the SWIG script directory \'/script\'"; +strSwigScriptNotFound = "Unable to locate the SWIG script file \'%s\' in \'%s\'. Is it a script directory?"; +strSwigScriptLangFound = "Found \'%s\' build script."; +strSwigScriptLangsFound = "Found the following script languages:"; +strSwigExecuteMsg = "Executing \'%s\' build script..."; +strSwigExecuteError = "Executing \'%s\' build script failed: "; +strHelpInfo = "\ +Python script(s) to build the SWIG Python C++ Script \n\ +Bridge wrapper code on various platforms. 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\ + -M (optional) Specify want SWIG to generate a dependency \n\ + file.\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\ + --argsFile= The args are read from a file instead of the\n\ + command line. Other command line args are ignored.\n\ +\n\ +Usage:\n\ + buildSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath\n\ + --cfgBldDir=ADirPath --prefix=ADirPath -m -d\n\ +\n\ +"; #TAG_PROGRAM_HELP_INFO +strHelpInfoExtraWindows = "\ +On the Windows platform the PATH environmental variable needs to be \n\ +extended to include the installed SWIG executable path so it can be \n\ +be found by this Python script. The SWIG executable name is 'swig'." +strHelpInfoExtraNonWindows = "\ +This Python script looks for the SWIG executable 'swig' in the following \n\ +directories '/usr/bin', '/usr/local/bin'. If not found the script will \n\ +abort."; + +#++--------------------------------------------------------------------------- +# Details: Retrieve the script -h help information based on the OS currently. +# Args: None. +# Returns: Str - Help Text. +# Throws: None. +#-- +def get_help_information(): + strHelpMsg = strHelpInfo; + + eOSType = utilsOsType.determine_os_type(); + if eOSType == utilsOsType.EnumOsType.Windows: + strHelpMsg += strHelpInfoExtraWindows; + else: + strHelpMsg += strHelpInfoExtraNonWindows; + + return strHelpMsg; + +#++--------------------------------------------------------------------------- +# 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 (%d)" % (strExitMsgSuccess, vnResult); + else: + 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 vDictArgs.iteritems(): + strEqs = ""; + strQ = ""; + if val.__len__() != 0: + strEqs = " ="; + strQ = "\""; + print "%s%s%s %s%s%s\n" % (strParameter, arg, strEqs, strQ, val, strQ); + +#++--------------------------------------------------------------------------- +# Details: Locate the lldb.swig file. No checking for path correctness is +# done here as assumed all values checked already. Path is adapted +# to be compatible with the platform file system. +# Args: vstrSrcRoot - (R) Directory path to the lldb source root. +# veOSType - (R) Current OS type enumeration. +# Returns: Bool - True = Success. +# - False = Failure file not found. +# Str - Error message. +# Throws: None. +#-- +def check_lldb_swig_file_exists( vstrSrcRoot, veOSType ): + dbg = utilsDebug.CDebugFnVerbose( "check_lldb_swig_file_exists()" ); + bOk = True; + strStatusMsg = ""; + strSwigFilePathName = "/scripts/lldb.swig"; + + strFullPath = os.path.normcase( vstrSrcRoot + strSwigFilePathName ); + bOk = os.path.isfile( strFullPath ); + if bOk: + if gbDbgFlag: + print strSwigFileFound; + else: + strStatusMsg = strSwigFileFoundNotFound % strFullPath; + + return (bOk, strStatusMsg); + +#++--------------------------------------------------------------------------- +# Details: Locate SWIG sub script language directory and the script within +# and execute SWIG for that script language. +# Args: vStrScriptLang - (R) Name of the script language to build. +# vSwigBuildFileName - (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_swig( vStrScriptLang, vSwigBuildFileName, vDictArgs ): + dbg = utilsDebug.CDebugFnVerbose( "run_swig()" ); + nResult = 0; + strStatusMsg = ""; + strScriptFile = vSwigBuildFileName % vStrScriptLang; + strScriptFileDir = "%s%s/%s" % (vDictArgs[ "--srcRoot" ], "/scripts", + vStrScriptLang); + strScriptFilePath = "%s/%s" % (strScriptFileDir, strScriptFile); + + # Check for the existence of the script file + strPath = os.path.normcase( strScriptFilePath ); + bOk = os.path.exists( strPath ); + if bOk == False: + strDir = os.path.normcase( strScriptFileDir ); + strStatusMsg = strSwigScriptNotFound % (strScriptFile, strDir); + return (-9, strStatusMsg); + + if gbDbgFlag: + print strSwigScriptLangFound % vStrScriptLang; + print strSwigExecuteMsg % 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 SWIG sub directory script language supported +# type and execute SWIG to build wrapper code based on that language. +# If an error occurs for a build this function will return with an +# error and not continue with proceed script builds. +# 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_swig_for_each_script_supported( vDictArgs ): + dbg = utilsDebug.CDebugFnVerbose( "run_swig_for_each_script_supported()" ); + nResult = 0; + strStatusMsg = ""; + strSwigScriptDir = vDictArgs[ "--srcRoot" ] + "/scripts"; + strSwigBuildFileName = "buildSwig%s.py"; + + # Check for the existence of the SWIG scripts folder + strScriptsDir = os.path.normcase( strSwigScriptDir ); + bOk = os.path.exists( strScriptsDir ); + if bOk == False: + return (-8, strSwigScriptDirNotFound); + + # Look for any script language directories to build for + listDirs = []; + nDepth = 1; + for strPath, listDirs, listFiles in os.walk( strSwigScriptDir ): + nDepth = nDepth - 1; + if nDepth == 0: + break; + + if gbDbgFlag: + print strSwigScriptLangsFound, + for dir in listDirs: + print dir, + print "\n"; + + # Iterate script directory find any script language directories + for scriptLang in listDirs: + dbg.dump_text( "Executing language script for \'%s\'" % scriptLang ); + nResult, strStatusMsg = run_swig( scriptLang, strSwigBuildFileName, + vDictArgs ); + if nResult < 0: + break; + + if nResult < 0: + strTmp = strSwigExecuteError % scriptLang; + strTmp += strStatusMsg; + strStatusMsg = strTmp; + + return (nResult, strStatusMsg); + +#++--------------------------------------------------------------------------- +# Details: Dummy function - system unknown. Function should not be called. +# Args: vDictArgs - (R) Program input parameters. +# Returns: Bool - False = Program logic error. +# Str - Error message. +# Throws: None. +#-- +def check_lldb_swig_executable_file_exists_Unknown( vDictArgs ): + dbg = utilsDebug.CDebugFnVerbose( "check_lldb_swig_executable_file_exists_Unknown()" ); + # Do nothing + return (False, strMsgErrorOsTypeUnknown); + +#++--------------------------------------------------------------------------- +# Details: Locate the SWIG executable file in a Windows system. Several hard +# coded predetermined possible file path locations are searched. +# (This is good candidate for a derived class object) +# Args: vDictArgs - (W) Program input parameters. +# Returns: Bool - True = Success. +# - False = Failure file not found. +# Str - Error message. +# Throws: None. +#-- +def check_lldb_swig_executable_file_exists_windows( vDictArgs ): + dbg = utilsDebug.CDebugFnVerbose( "check_lldb_swig_executable_file_exists_windows()" ); + + # Will always be true as it assumed the path to SWIG executable will be + # in the OS system environmental variable %PATH%. Easier this way as the + # user may have renamed the directory and or custom path installation. + bExeFileFound = True; + vDictArgs[ "--swigExePath" ] = ""; + vDictArgs[ "--swigExeName" ] = "swig.exe"; + return (bExeFileFound, None); + +#++--------------------------------------------------------------------------- +# Details: Locate the SWIG executable file in a Linux system. Several hard +# coded predetermined possible file path locations are searched. +# (This is good candidate for a derived class object) +# Args: vDictArgs - (W) Program input parameters. +# Returns: Bool - True = Success. +# - False = Failure file not found. +# Str - Error message. +# Throws: None. +#-- +def check_lldb_swig_executable_file_exists_Linux( vDictArgs ): + dbg = utilsDebug.CDebugFnVerbose( "check_lldb_swig_executable_file_exists_Linux()" ); + bExeFileFound = False; + + strSwigExe = "swig"; + strSwigExePath = "/usr/bin"; + strExe = os.path.normcase( "%s/%s" % (strSwigExePath, strSwigExe) ); + if os.path.isfile( strExe ) and os.access( strExe, os.X_OK ): + bExeFileFound = True; + vDictArgs[ "--swigExePath" ] = os.path.normcase( strSwigExePath ); + vDictArgs[ "--swigExeName" ] = strSwigExe; + return (bExeFileFound, None); + + strSwigExePath = "/usr/local/bin"; + strExe = os.path.normcase( "%s/%s" % (strSwigExePath, strSwigExe) ); + if os.path.isfile( strExe ) and os.access( strExe, os.X_OK ): + bExeFileFound = True; + vDictArgs[ "--swigExePath" ] = os.path.normcase( strSwigExePath ); + vDictArgs[ "--swigExeName" ] = strSwigExe; + return (bExeFileFound, None); + + return (bExeFileFound, strSwigExeFileNotFound); + +#++--------------------------------------------------------------------------- +# Details: Locate the SWIG executable file in a OSX system. Several hard +# coded predetermined possible file path locations are searched. +# (This is good candidate for a derived class object) +# Args: vDictArgs - (W) Program input parameters. +# Returns: Bool - True = Success. +# - False = Failure file not found. +# Str - Error message. +# Throws: None. +#-- +def check_lldb_swig_executable_file_exists_Darwin( vDictArgs ): + dbg = utilsDebug.CDebugFnVerbose( "check_lldb_swig_executable_file_exists_Darwin()" ); + bExeFileFound = False; + # ToDo: Find the SWIG executable and add the path to the args dictionary + #vDictArgs.[ "--swigExePath" ] = "/usr/bin/swig"; + strStatusMsg = "Sorry function 'check_lldb_swig_executable_file_exists_Darwin()' is not implemented"; + + return (bExeFileFound, strStatusMsg); + +#++--------------------------------------------------------------------------- +# Details: Locate the SWIG executable file. Several hard coded predetermined +# possible file path locations are searched. +# Args: vDictArgs - (RW) Program input parameters. +# veOSType - (R) Current OS type enumeration. +# Returns: Bool - True = Success. +# - False = Failure file not found. +# Str - Error message. +# Throws: None. +#-- +def check_lldb_swig_executable_file_exists( vDictArgs, veOSType ): + dbg = utilsDebug.CDebugFnVerbose( "check_lldb_swig_executable_file_exists()" ); + bExeFileFound = False; + strStatusMsg = ""; + + switch = { 0 : check_lldb_swig_executable_file_exists_Unknown, + 1 : check_lldb_swig_executable_file_exists_windows, + 2 : check_lldb_swig_executable_file_exists_Linux, + 3 : check_lldb_swig_executable_file_exists_Darwin } + bExeFileFound, strStatusMsg = switch[ veOSType ]( vDictArgs ); + + return (bExeFileFound, strStatusMsg); + +#++--------------------------------------------------------------------------- +# 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 = "hdmM"; # Format "hiox:" = -h -i -o -x + listLongArgs = ["srcRoot=", "targetDir=", "cfgBldDir=", "prefix=", + "argsFile"]; + dictArgReq = { "-h": "o", # o = optional, m = mandatory + "-d": "o", + "-m": "o", + "-M": "o", + "--srcRoot": "m", + "--targetDir": "m", + "--cfgBldDir": "o", + "--prefix": "o", + "--argsFile": "o" }; + strHelpInfo = get_help_information(); + + # 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: 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 = dictArgs.has_key( "-d" ); + if gbDbgFlag: + print_out_input_parameters( dictArgs ); + + # Check to see if we were called from the Makefile system. If we were, check + # if the caller wants SWIG to generate a dependency file. + # Not used in this program, but passed through to the language script file + # called by this program + global gbMakeFileFlag; + global gbSwigGenDepFileFlag; + gbMakeFileFlag = dictArgs.has_key( "-m" ); + gbSwigGenDepFileFlag = dictArgs.has_key( "-M" ); + + bOk, strMsg = check_lldb_swig_file_exists( dictArgs[ "--srcRoot" ], eOSType ); + if bOk == False: + program_exit( -3, strMsg ); + + bOk, strMsg = check_lldb_swig_executable_file_exists( dictArgs, eOSType ); + if bOk == False: + program_exit( -6, strMsg ); + + nResult, strMsg = run_swig_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. + -M (optional) Specify want SWIG to generate a dependency file. + --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. + --argsFile= The args are read from a file instead of the + command line. Other command line args are ignored. + Usage: + buildSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath + --cfgBldDir=ADirPath --prefix=ADirPath -m -d + + Results: 0 Success + -1 Error - invalid parameters passed. + -2 Error - incorrect number of mandatory parameters passed. + -3 Error - unable to locate lldb.swig file. + -4 Error - unable to determine OS type. + -5 Error - program called by another Python script not allowed. + -6 Error - unable to locate the swig executable file. + -7 Error - SWIG script execution failed. + -8 Error - unable to locate the SWIG scripts folder. + -9 Error - unable to locate the SWIG language script file. + -100+ - Error messages from the SWIG language script file. + -200+ - 200 +- the SWIG exit result. + -------------------------------------------------------------------------- + +""" + +# 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 ); + \ No newline at end of file Index: scripts/finishSwigWrapperClasses.py =================================================================== --- /dev/null +++ scripts/finishSwigWrapperClasses.py @@ -0,0 +1,386 @@ +""" 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. + + Environment: OS: Windows Vista or newer,LINUX,OSX. + IDE: Visual Studio 2013 Plugin Python Tools (PTVS) + Script: Python 2.6/2.7.5 x64 + Other: None. + + 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: +gbDbgVerbose = False; # True = Turn on script function tracing, False = off. +gbDbgFlag = False; # Global debug mode flag, set by input parameter + # --dbgFlag. True = operate in debug mode. +gbMakeFileFlag = False; # True = yes called from makefile system, False = not. + +# 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\ + --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\ +\n\ +Usage:\n\ + finishSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath\n\ + --cfgBldDir=ADirPath --prefix=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 (%d)" % (strExitMsgSuccess, vnResult); + else: + 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 vDictArgs.iteritems(): + 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 + listLongArgs = ["srcRoot=", "targetDir=", "cfgBldDir=", "prefix=", "cmakeBuildConfiguration=", + "argsFile"]; + dictArgReq = { "-h": "o", # o = optional, m = mandatory + "-d": "o", + "-m": "o", + "--srcRoot": "m", + "--targetDir": "m", + "--cfgBldDir": "o", + "--prefix": "o", + "--cmakeBuildConfiguration": "o", + "--argsFile": "o" }; + + # 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 = "%s%s/%s" % (vDictArgs[ "--srcRoot" ], "/scripts", + vStrScriptLang); + strScriptFilePath = "%s/%s" % (strScriptFileDir, strScriptFile); + + # Check for the existence of the script file + strPath = os.path.normcase( strScriptFilePath ); + bOk = os.path.exists( strPath ); + if bOk == False: + 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 = 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 bOk == False: + return (-8, strScriptDirNotFound); + + # Look for any script language directories to build for + listDirs = []; + nDepth = 1; + for strPath, listDirs, listFiles in os.walk( strScriptDir ): + nDepth = nDepth - 1; + if nDepth == 0: + break; + + if gbDbgFlag: + print strScriptLangsFound, + for dir in listDirs: + print dir, + print "\n"; + + # 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 = dictArgs.has_key( "-d" ); + if gbDbgFlag: + print_out_input_parameters( dictArgs ); + + # Check to see if we were called from the Makefile system. If we were, check + # if the caller wants SWIG to generate a dependency file. + # Not used in this program, but passed through to the language script file + # called by this program + global gbMakeFileFlag; + gbMakeFileFlag = dictArgs.has_key( "-m" ); + + 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\ + --argsFile= The args are read from a file instead of the + command line. Other command line args are ignored. + Usage: + finishSwigWrapperClasses.py --srcRoot=ADirPath --targetDir=ADirPath + --cfgBldDir=ADirPath --prefix=ADirPath -m -d + + 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 ); + Index: scripts/utilsArgsParse.py =================================================================== --- /dev/null +++ scripts/utilsArgsParse.py @@ -0,0 +1,146 @@ +""" 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. + + Environment: OS: Windows/LINUX/OSX + IDE: Visual Studio 2013 Plugin Python Tools (PTVS) + Script: Python 2.6 x64 + + Gotchas: None. + + Copyright: None. + -------------------------------------------------------------------------- + +""" + +# Python modules: +import sys # Provide argument parsing +import getopt # Parse command line arguments + +# Third party modules: + +# In-house modules: +import utilsOsType # Determine the OS type this script is running on + +# 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 vDictArgReq.iteritems(): + 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[:arg.__len__() - 1]; + if opt == argg: + if "m" == vDictArgReq[ opt ]: + countMandatoryOpts = countMandatoryOpts + 1; + dictArgs[ opt ] = val; + if 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); + Index: scripts/utilsDebug.py =================================================================== --- /dev/null +++ scripts/utilsDebug.py @@ -0,0 +1,133 @@ +""" Utility module to help debug Python scripts + + -------------------------------------------------------------------------- + File: utilsDebug.py + + Overview: Python module to supply functions to help debug Python + scripts. + + Environment: OS: Windows/LINUX/OSX + IDE: Visual Studio 2013 Plugin Python Tools (PTVS) + Script: Python 2.6 x64 + + Gotchas: None. + + Copyright: None. + -------------------------------------------------------------------------- + +""" + +# Python modules: + +# 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: + # 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 CDebugFnVerbose.bVerboseOn == False: + return; + print "%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 CDebugFnVerbose.bVerboseOn == False: + return; + print "%d%s> Dp: %s" % (CDebugFnVerbose.__nLevel, self.__get_dots(), + vstrText); + + # Private methods: + def __init__( self, vstrFnName ): + self.__indent_out( vstrFnName ); + + # Class destructor + def __del__( self ): + self.__indent_back(); + + #++------------------------------------------------------------------------ + # 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 = ""; + + + \ No newline at end of file Index: scripts/utilsOsType.py =================================================================== --- /dev/null +++ scripts/utilsOsType.py @@ -0,0 +1,82 @@ +""" 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. + + Environment: OS: Windows/LINUX/OSX + IDE: Visual Studio 2013 Plugin Python Tools (PTVS) + Script: Python 2.6 x64 + + Gotchas: None. + + Copyright: None. + -------------------------------------------------------------------------- + +""" + +# 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. +#-- +class EnumOsType( object ): + values = [ "Unknown", + "Windows", + "Linux", + "Darwin" ]; # OSX + class __metaclass__( type ): +#++--------------------------------------------------------------------------- +# Details: Fn acts as an enumeration. +# Args: vName - (R) Enumeration to match. +# Returns: Int - Matching enumeration/index. +# Throws: None. +#-- + def __getattr__( self, vName ): + return self.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( self, 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 == "win32": + eOSType = EnumOsType.Windows; + elif (strOS == "linux") or (strOS == "linux2"): + eOSType = EnumOsType.Linux; + elif strOS == "darwin": + eOSType == EnumOsType.Darwin; + + return eOSType; Index: source/CMakeLists.txt =================================================================== --- source/CMakeLists.txt +++ source/CMakeLists.txt @@ -312,6 +312,13 @@ # FIXME: implement svn/git revision and repository parsing solution on Windows. There is an SVN-only # revision parsing solution in tools/clang/lib/Basic/CMakelists.txt. +# Add a Post-Build Event to copy over Python files and create the symlink to liblldb.so for the Python API(hardlink on Windows) +if ( NOT LLDB_DISABLE_PYTHON ) +add_custom_command( TARGET liblldb + POST_BUILD + COMMAND python ${CMAKE_CURRENT_SOURCE_DIR}/../scripts/finishSwigWrapperClasses.py "--srcRoot=${LLDB_SOURCE_DIR}" "--targetDir=${CMAKE_CURRENT_BINARY_DIR}" "--cfgBldDir=${CMAKE_CURRENT_BINARY_DIR}" "--prefix=${CMAKE_BINARY_DIR}" "--cmakeBuildConfiguration=${CMAKE_CFG_INTDIR}" -m + COMMENT "Python script sym-linking LLDB Python API") +endif () install(TARGETS liblldb RUNTIME DESTINATION bin Index: source/Interpreter/ScriptInterpreterPython.cpp =================================================================== --- source/Interpreter/ScriptInterpreterPython.cpp +++ source/Interpreter/ScriptInterpreterPython.cpp @@ -388,12 +388,12 @@ if (m_session_is_active) { if (log) - log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ") session is already active, returning without doing anything", on_entry_flags); + log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx64 ") session is already active, returning without doing anything", (uint64_t)on_entry_flags); return false; } if (log) - log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx16 ")", on_entry_flags); + log->Printf("ScriptInterpreterPython::EnterSession(on_entry_flags=0x%" PRIx64 ")", (uint64_t)on_entry_flags); m_session_is_active = true; @@ -589,7 +589,12 @@ input_file_sp = debugger.GetInputFile(); // Set output to a temporary file so we can forward the results on to the result object +#ifdef _MSC_VER + // pipe is not supported on windows so default to a fail condition + int err = 1; +#else int err = pipe(pipe_fds); +#endif if (err == 0) { std::unique_ptr conn_ap(new ConnectionFileDescriptor(pipe_fds[0], true)); @@ -695,114 +700,115 @@ return false; } - -class IOHandlerPythonInterpreter : - public IOHandler +namespace lldb_private { -public: - - IOHandlerPythonInterpreter (Debugger &debugger, - ScriptInterpreterPython *python) : - IOHandler (debugger), - m_python(python) + class IOHandlerPythonInterpreter : + public IOHandler { - - } - - virtual - ~IOHandlerPythonInterpreter() - { - - } - - virtual ConstString - GetControlSequence (char ch) - { - if (ch == 'd') - return ConstString("quit()\n"); - return ConstString(); - } + public: - virtual void - Run () - { - if (m_python) + IOHandlerPythonInterpreter (Debugger &debugger, + ScriptInterpreterPython *python) : + IOHandler (debugger), + m_python(python) + { + + } + + virtual + ~IOHandlerPythonInterpreter() { - int stdin_fd = GetInputFD(); - if (stdin_fd >= 0) + + } + + virtual ConstString + GetControlSequence (char ch) + { + if (ch == 'd') + return ConstString("quit()\n"); + return ConstString(); + } + + virtual void + Run () + { + if (m_python) { - Terminal terminal(stdin_fd); - TerminalState terminal_state; - const bool is_a_tty = terminal.IsATerminal(); - - if (is_a_tty) + int stdin_fd = GetInputFD(); + if (stdin_fd >= 0) { - terminal_state.Save (stdin_fd, false); - terminal.SetCanonical(false); - terminal.SetEcho(true); + Terminal terminal(stdin_fd); + TerminalState terminal_state; + const bool is_a_tty = terminal.IsATerminal(); + + if (is_a_tty) + { + terminal_state.Save (stdin_fd, false); + terminal.SetCanonical(false); + terminal.SetEcho(true); + } + + ScriptInterpreterPython::Locker locker (m_python, + ScriptInterpreterPython::Locker::AcquireLock | + ScriptInterpreterPython::Locker::InitSession | + ScriptInterpreterPython::Locker::InitGlobals, + ScriptInterpreterPython::Locker::FreeAcquiredLock | + ScriptInterpreterPython::Locker::TearDownSession); + + // The following call drops into the embedded interpreter loop and stays there until the + // user chooses to exit from the Python interpreter. + // This embedded interpreter will, as any Python code that performs I/O, unlock the GIL before + // a system call that can hang, and lock it when the syscall has returned. + + // We need to surround the call to the embedded interpreter with calls to PyGILState_Ensure and + // PyGILState_Release (using the Locker above). This is because Python has a global lock which must be held whenever we want + // to touch any Python objects. Otherwise, if the user calls Python code, the interpreter state will be off, + // and things could hang (it's happened before). + + StreamString run_string; + run_string.Printf ("run_python_interpreter (%s)", m_python->GetDictionaryName ()); + PyRun_SimpleString (run_string.GetData()); + + if (is_a_tty) + terminal_state.Restore(); } - - ScriptInterpreterPython::Locker locker (m_python, - ScriptInterpreterPython::Locker::AcquireLock | - ScriptInterpreterPython::Locker::InitSession | - ScriptInterpreterPython::Locker::InitGlobals, - ScriptInterpreterPython::Locker::FreeAcquiredLock | - ScriptInterpreterPython::Locker::TearDownSession); - - // The following call drops into the embedded interpreter loop and stays there until the - // user chooses to exit from the Python interpreter. - // This embedded interpreter will, as any Python code that performs I/O, unlock the GIL before - // a system call that can hang, and lock it when the syscall has returned. - - // We need to surround the call to the embedded interpreter with calls to PyGILState_Ensure and - // PyGILState_Release (using the Locker above). This is because Python has a global lock which must be held whenever we want - // to touch any Python objects. Otherwise, if the user calls Python code, the interpreter state will be off, - // and things could hang (it's happened before). - - StreamString run_string; - run_string.Printf ("run_python_interpreter (%s)", m_python->GetDictionaryName ()); - PyRun_SimpleString (run_string.GetData()); - - if (is_a_tty) - terminal_state.Restore(); } + SetIsDone(true); } - SetIsDone(true); - } - virtual void - Hide () - { - - } - - virtual void - Refresh () - { - - } + virtual void + Hide () + { - virtual void - Cancel () - { - - } + } - virtual void - Interrupt () - { - - } - - virtual void - GotEOF() - { - - } -protected: - ScriptInterpreterPython *m_python; -}; + virtual void + Refresh () + { + + } + + virtual void + Cancel () + { + + } + virtual void + Interrupt () + { + + } + + virtual void + GotEOF() + { + + } + protected: + ScriptInterpreterPython *m_python; + }; +} void ScriptInterpreterPython::ExecuteInterpreterLoop () Index: source/Symbol/ClangASTType.cpp =================================================================== --- source/Symbol/ClangASTType.cpp +++ source/Symbol/ClangASTType.cpp @@ -3253,7 +3253,7 @@ if (element_type.GetCompleteType()) { char element_name[64]; - ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); + ::snprintf(element_name, sizeof (element_name), "[%" PRIu64 "]", (uint64_t)idx); child_name.assign(element_name); child_byte_size = element_type.GetByteSize(); child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; @@ -3274,7 +3274,7 @@ if (element_type.GetCompleteType()) { char element_name[64]; - ::snprintf (element_name, sizeof (element_name), "[%zu]", idx); + ::snprintf(element_name, sizeof (element_name), "[%" PRIu64 "]", (uint64_t)idx); child_name.assign(element_name); child_byte_size = element_type.GetByteSize(); child_byte_offset = (int32_t)idx * (int32_t)child_byte_size; Index: source/Utility/PseudoTerminal.cpp =================================================================== --- source/Utility/PseudoTerminal.cpp +++ source/Utility/PseudoTerminal.cpp @@ -19,6 +19,7 @@ #ifdef _WIN32 #include "lldb/Host/windows/win32.h" +typedef uint32_t pid_t; // empty functions int posix_openpt(int flag) { return 0; }