Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

View File

@ -0,0 +1,237 @@
# Usage:
# art/test/run-test --host --gdb [--64] [--interpreter] 004-JniTest
# 'b Java_Main_shortMethod'
# 'r'
# 'command script import host_art_bt.py'
# 'host_art_bt'
import sys
import re
import lldb
def host_art_bt(debugger, command, result, internal_dict):
prettified_frames = []
lldb_frame_index = 0
art_frame_index = 0
target = debugger.GetSelectedTarget()
process = target.GetProcess()
thread = process.GetSelectedThread()
while lldb_frame_index < thread.GetNumFrames():
frame = thread.GetFrameAtIndex(lldb_frame_index)
if frame.GetModule() and re.match(r'JIT\(.*?\)',
frame.GetModule().GetFileSpec().GetFilename()):
# Compiled Java frame
# Get function/filename/lineno from symbol context
symbol = frame.GetSymbol()
if not symbol:
print 'No symbol info for compiled Java frame: ', frame
sys.exit(1)
line_entry = frame.GetLineEntry()
prettified_frames.append({
'function': symbol.GetName(),
'file': str(line_entry.GetFileSpec()) if line_entry else None,
'line': line_entry.GetLine() if line_entry else -1
})
# Skip art frames
while True:
art_stack_visitor = frame.EvaluateExpression(
"""struct GetStackVisitor : public StackVisitor { GetStackVisitor(int depth_) : StackVisitor(Thread::Current(), NULL), depth(depth_) {} bool VisitFrame() { if (cur_depth_ == depth) { return false; } else { return true; } } int depth; }; GetStackVisitor visitor(""" +
str(art_frame_index) +
"""); visitor.WalkStack(true); visitor""")
art_method = frame.EvaluateExpression(
art_stack_visitor.GetName() + """.GetMethod()""")
if art_method.GetValueAsUnsigned() != 0:
art_method_name = frame.EvaluateExpression(
"""art::PrettyMethod(""" + art_method.GetName() + """, true)""")
art_method_name_data = frame.EvaluateExpression(
art_method_name.GetName() + """.c_str()""").GetValueAsUnsigned()
art_method_name_size = frame.EvaluateExpression(
art_method_name.GetName() + """.length()""").GetValueAsUnsigned()
error = lldb.SBError()
art_method_name = process.ReadCStringFromMemory(
art_method_name_data, art_method_name_size + 1, error)
if not error.Success:
print 'Failed to read method name'
sys.exit(1)
if art_method_name != symbol.GetName():
print 'Function names in native symbol and art runtime stack do not match: ', symbol.GetName(), ' != ', art_method_name
art_frame_index = art_frame_index + 1
break
art_frame_index = art_frame_index + 1
# Skip native frames
lldb_frame_index = lldb_frame_index + 1
if lldb_frame_index < thread.GetNumFrames():
frame = thread.GetFrameAtIndex(lldb_frame_index)
if frame.GetModule() and re.match(
r'JIT\(.*?\)', frame.GetModule().GetFileSpec().GetFilename()):
# Another compile Java frame
# Don't skip; leave it to the next iteration
continue
elif frame.GetSymbol() and (frame.GetSymbol().GetName() == 'art_quick_invoke_stub' or frame.GetSymbol().GetName() == 'art_quick_invoke_static_stub'):
# art_quick_invoke_stub / art_quick_invoke_static_stub
# Skip until we get past the next ArtMethod::Invoke()
while True:
lldb_frame_index = lldb_frame_index + 1
if lldb_frame_index >= thread.GetNumFrames():
print 'ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub'
sys.exit(1)
frame = thread.GetFrameAtIndex(lldb_frame_index)
if frame.GetSymbol() and frame.GetSymbol().GetName(
) == 'art::mirror::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)':
lldb_frame_index = lldb_frame_index + 1
break
else:
print 'Invalid frame below compiled Java frame: ', frame
elif frame.GetSymbol() and frame.GetSymbol().GetName() == 'art_quick_generic_jni_trampoline':
# Interpreted JNI frame for x86_64
# Skip art frames
while True:
art_stack_visitor = frame.EvaluateExpression(
"""struct GetStackVisitor : public StackVisitor { GetStackVisitor(int depth_) : StackVisitor(Thread::Current(), NULL), depth(depth_) {} bool VisitFrame() { if (cur_depth_ == depth) { return false; } else { return true; } } int depth; }; GetStackVisitor visitor(""" +
str(art_frame_index) +
"""); visitor.WalkStack(true); visitor""")
art_method = frame.EvaluateExpression(
art_stack_visitor.GetName() + """.GetMethod()""")
if art_method.GetValueAsUnsigned() != 0:
# Get function/filename/lineno from ART runtime
art_method_name = frame.EvaluateExpression(
"""art::PrettyMethod(""" + art_method.GetName() + """, true)""")
art_method_name_data = frame.EvaluateExpression(
art_method_name.GetName() + """.c_str()""").GetValueAsUnsigned()
art_method_name_size = frame.EvaluateExpression(
art_method_name.GetName() + """.length()""").GetValueAsUnsigned()
error = lldb.SBError()
function = process.ReadCStringFromMemory(
art_method_name_data, art_method_name_size + 1, error)
prettified_frames.append({
'function': function,
'file': None,
'line': -1
})
art_frame_index = art_frame_index + 1
break
art_frame_index = art_frame_index + 1
# Skip native frames
lldb_frame_index = lldb_frame_index + 1
if lldb_frame_index < thread.GetNumFrames():
frame = thread.GetFrameAtIndex(lldb_frame_index)
if frame.GetSymbol() and (frame.GetSymbol().GetName() ==
'art_quick_invoke_stub' or frame.GetSymbol().GetName() == 'art_quick_invoke_static_stub'):
# art_quick_invoke_stub / art_quick_invoke_static_stub
# Skip until we get past the next ArtMethod::Invoke()
while True:
lldb_frame_index = lldb_frame_index + 1
if lldb_frame_index >= thread.GetNumFrames():
print 'ArtMethod::Invoke not found below art_quick_invoke_stub/art_quick_invoke_static_stub'
sys.exit(1)
frame = thread.GetFrameAtIndex(lldb_frame_index)
if frame.GetSymbol() and frame.GetSymbol().GetName(
) == 'art::mirror::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)':
lldb_frame_index = lldb_frame_index + 1
break
else:
print 'Invalid frame below compiled Java frame: ', frame
elif frame.GetSymbol() and re.search(r'art::interpreter::', frame.GetSymbol().GetName()):
# Interpreted Java frame
while True:
lldb_frame_index = lldb_frame_index + 1
if lldb_frame_index >= thread.GetNumFrames():
print 'art::interpreter::Execute not found in interpreter frame'
sys.exit(1)
frame = thread.GetFrameAtIndex(lldb_frame_index)
if frame.GetSymbol() and frame.GetSymbol().GetName(
) == 'art::interpreter::Execute(art::Thread*, art::MethodHelper&, art::DexFile::CodeItem const*, art::ShadowFrame&, art::JValue)':
break
# Skip art frames
while True:
art_stack_visitor = frame.EvaluateExpression(
"""struct GetStackVisitor : public StackVisitor { GetStackVisitor(int depth_) : StackVisitor(Thread::Current(), NULL), depth(depth_) {} bool VisitFrame() { if (cur_depth_ == depth) { return false; } else { return true; } } int depth; }; GetStackVisitor visitor(""" +
str(art_frame_index) +
"""); visitor.WalkStack(true); visitor""")
art_method = frame.EvaluateExpression(
art_stack_visitor.GetName() + """.GetMethod()""")
if art_method.GetValueAsUnsigned() != 0:
# Get function/filename/lineno from ART runtime
art_method_name = frame.EvaluateExpression(
"""art::PrettyMethod(""" + art_method.GetName() + """, true)""")
art_method_name_data = frame.EvaluateExpression(
art_method_name.GetName() + """.c_str()""").GetValueAsUnsigned()
art_method_name_size = frame.EvaluateExpression(
art_method_name.GetName() + """.length()""").GetValueAsUnsigned()
error = lldb.SBError()
function = process.ReadCStringFromMemory(
art_method_name_data, art_method_name_size + 1, error)
line = frame.EvaluateExpression(
art_stack_visitor.GetName() +
""".GetMethod()->GetLineNumFromDexPC(""" +
art_stack_visitor.GetName() +
""".GetDexPc(true))""").GetValueAsUnsigned()
file_name = frame.EvaluateExpression(
art_method.GetName() + """->GetDeclaringClassSourceFile()""")
file_name_data = file_name.GetValueAsUnsigned()
file_name_size = frame.EvaluateExpression(
"""(size_t)strlen(""" + file_name.GetName() + """)""").GetValueAsUnsigned()
error = lldb.SBError()
file_name = process.ReadCStringFromMemory(
file_name_data, file_name_size + 1, error)
if not error.Success():
print 'Failed to read source file name'
sys.exit(1)
prettified_frames.append({
'function': function,
'file': file_name,
'line': line
})
art_frame_index = art_frame_index + 1
break
art_frame_index = art_frame_index + 1
# Skip native frames
while True:
lldb_frame_index = lldb_frame_index + 1
if lldb_frame_index >= thread.GetNumFrames():
print 'Can not get past interpreter native frames'
sys.exit(1)
frame = thread.GetFrameAtIndex(lldb_frame_index)
if frame.GetSymbol() and not re.search(
r'art::interpreter::', frame.GetSymbol().GetName()):
break
else:
# Other frames. Add them as-is.
frame = thread.GetFrameAtIndex(lldb_frame_index)
lldb_frame_index = lldb_frame_index + 1
if frame.GetModule():
module_name = frame.GetModule().GetFileSpec().GetFilename()
if not module_name in [
'libartd.so',
'dalvikvm32',
'dalvikvm64',
'libc.so.6']:
prettified_frames.append({
'function': frame.GetSymbol().GetName() if frame.GetSymbol() else None,
'file': str(frame.GetLineEntry().GetFileSpec()) if frame.GetLineEntry() else None,
'line': frame.GetLineEntry().GetLine() if frame.GetLineEntry() else -1
})
for prettified_frame in prettified_frames:
print prettified_frame['function'], prettified_frame['file'], prettified_frame['line']
def __lldb_init_module(debugger, internal_dict):
debugger.HandleCommand(
'command script add -f host_art_bt.host_art_bt host_art_bt')

View File

@ -0,0 +1,310 @@
#!/bin/sh
# finish-swig-Python.sh
#
# 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 someplace 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.
#
# SRC_ROOT is the root of the lldb source tree.
# TARGET_DIR is where the lldb framework/shared library gets put.
# CONFIG_BUILD_DIR is where the build-swig-Python-LLDB.sh shell script
# put the lldb.py file it was generated from running SWIG.
# PYTHON_INSTALL_DIR is where non-Darwin systems want to put the .py and .so
# files so that Python can find them automatically.
# debug_flag (optional) determines whether or not this script outputs
# additional information when running.
SRC_ROOT=$1
TARGET_DIR=$2
CONFIG_BUILD_DIR=$3
PYTHON_INSTALL_DIR=$4
debug_flag=$5
makefile_flag=$6
# If we don't want Python, then just do nothing here.
# 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 [ ! "$LLDB_DISABLE_PYTHON" = "1" ] ; then
if [ -n "$debug_flag" -a "$debug_flag" = "-debug" ]
then
Debug=1
else
Debug=0
fi
if [ -n "$makefile_flag" -a "$makefile_flag" = "-m" ]
then
MakefileCalled=1
else
MakefileCalled=0
fi
OS_NAME=`uname -s`
PYTHON=${PYTHON_EXECUTABLE:-/usr/bin/env python}
PYTHON_VERSION=`${PYTHON} --version 2>&1 | sed -e 's,Python ,,' -e 's,[.][0-9],,2' -e 's,[a-z][a-z][0-9],,'`
if [ $Debug -eq 1 ]
then
echo "The current OS is $OS_NAME"
echo "The Python version is $PYTHON_VERSION"
fi
if [ ${OS_NAME} = "Darwin" ]
then
SOEXT=".dylib"
else
SOEXT=".so"
fi
#
# Determine where to put the files.
if [ $MakefileCalled -eq 0 ]
then
# We are being built by Xcode, so all the lldb Python files can go
# into the LLDB.framework/Resources/Python subdirectory.
if [ ! -d "${TARGET_DIR}/LLDB.framework" ]
then
echo "Error: Unable to find LLDB.framework" >&2
exit 1
else
if [ $Debug -eq 1 ]
then
echo "Found ${TARGET_DIR}/LLDB.framework."
fi
fi
# Make the Python directory in the framework if it doesn't already exist
framework_python_dir="${TARGET_DIR}/LLDB.framework/Resources/Python/lldb"
else
# 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.
if [ -n "${PYTHON_INSTALL_DIR}" ]
then
framework_python_dir=`${PYTHON} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(True, False, \"${PYTHON_INSTALL_DIR}\");"`/lldb
else
framework_python_dir=`${PYTHON} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(True, False);"`/lldb
fi
fi
[ -n "${CONFIG_BUILD_DIR}" ] || CONFIG_BUILD_DIR=${framework_python_dir}
#
# Look for the directory in which to put the Python files; if it does not
# already exist, attempt to make it.
#
if [ $Debug -eq 1 ]
then
echo "Python files will be put in ${framework_python_dir}"
fi
python_dirs="${framework_python_dir}"
for python_dir in $python_dirs
do
if [ ! -d "${python_dir}" ]
then
if [ $Debug -eq 1 ]
then
echo "Making directory ${python_dir}"
fi
mkdir -p "${python_dir}"
else
if [ $Debug -eq 1 ]
then
echo "${python_dir} already exists."
fi
fi
if [ ! -d "${python_dir}" ]
then
echo "Error: Unable to find or create ${python_dir}" >&2
exit 1
fi
done
# Make the symlink that the script bridge for Python will need in the
# Python framework directory
if [ ! -L "${framework_python_dir}/_lldb.so" ]
then
if [ $Debug -eq 1 ]
then
echo "Creating symlink for _lldb.so"
fi
cd "${framework_python_dir}"
if [ $MakefileCalled -eq 0 ]
then
ln -s "../../../LLDB" _lldb.so
else
ln -s "../../../liblldb${SOEXT}" _lldb.so
fi
else
if [ $Debug -eq 1 ]
then
echo "${framework_python_dir}/_lldb.so already exists."
fi
fi
# Make symlink for darwin-debug on Darwin
if [ ${OS_NAME} = "Darwin" ] && [ $MakefileCalled -ne 0 ]
then
# We are being built by CMake on Darwin
if [ ! -L "${framework_python_dir}/darwin-debug" ]
then
if [ $Debug -eq 1 ]
then
echo "Creating symlink for darwin-debug"
fi
cd "${framework_python_dir}"
else
if [ $Debug -eq 1 ]
then
echo "${framework_python_dir}/darwin-debug already exists."
fi
fi
fi
# Make symlink for lldb-argdumper on any platform
if [ $MakefileCalled -ne 0 ]
then
# We are being built by CMake
if [ ! -L "${framework_python_dir}/lldb-argdumper" ]
then
if [ $Debug -eq 1 ]
then
echo "Creating symlink for lldb-argdumper"
fi
cd "${framework_python_dir}"
ln -s "../../../../bin/lldb-argdumper" lldb-argdumper
else
if [ $Debug -eq 1 ]
then
echo "${framework_python_dir}/lldb-argdumper already exists."
fi
fi
fi
create_python_package () {
package_dir="${framework_python_dir}$1"
package_files="$2"
package_name=`echo $1 | tr '/' '.'`
package_name="lldb${package_name}"
if [ ! -d "${package_dir}" ]
then
mkdir -p "${package_dir}"
fi
for package_file in $package_files
do
if [ -f "${package_file}" ]
then
cp "${package_file}" "${package_dir}"
package_file_basename=$(basename "${package_file}")
fi
done
# Create a packate init file if there wasn't one
package_init_file="${package_dir}/__init__.py"
if [ ! -f "${package_init_file}" ]
then
printf "__all__ = [" > "${package_init_file}"
python_module_separator=""
for package_file in $package_files
do
if [ -f "${package_file}" ]
then
package_file_basename=$(basename "${package_file}")
printf "${python_module_separator}\"${package_file_basename%.*}\"" >> "${package_init_file}"
python_module_separator=", "
fi
done
echo "]" >> "${package_init_file}"
echo "for x in __all__:" >> "${package_init_file}"
echo " __import__('${package_name}.'+x)" >> "${package_init_file}"
fi
}
# Copy the lldb.py file into the lldb package directory and rename to __init_.py
cp "${CONFIG_BUILD_DIR}/lldb.py" "${framework_python_dir}/__init__.py"
# lldb
package_files="${SRC_ROOT}/source/Interpreter/embedded_interpreter.py"
create_python_package "" "${package_files}"
# lldb/formatters/cpp
package_files="${SRC_ROOT}/examples/synthetic/gnu_libstdcpp.py
${SRC_ROOT}/examples/synthetic/libcxx.py"
create_python_package "/formatters/cpp" "${package_files}"
# make an empty __init__.py in lldb/runtime
# this is required for Python to recognize lldb.runtime as a valid package
# (and hence, lldb.runtime.objc as a valid contained package)
create_python_package "/runtime" ""
# lldb/formatters
# having these files copied here ensures that lldb/formatters is a valid package itself
package_files="${SRC_ROOT}/examples/summaries/cocoa/cache.py
${SRC_ROOT}/examples/summaries/synth.py
${SRC_ROOT}/examples/summaries/cocoa/metrics.py
${SRC_ROOT}/examples/summaries/cocoa/attrib_fromdict.py
${SRC_ROOT}/examples/summaries/cocoa/Logger.py"
create_python_package "/formatters" "${package_files}"
# lldb/utils
package_files="${SRC_ROOT}/examples/python/symbolication.py"
create_python_package "/utils" "${package_files}"
if [ ${OS_NAME} = "Darwin" ]
then
# lldb/macosx
package_files="${SRC_ROOT}/examples/python/crashlog.py
${SRC_ROOT}/examples/darwin/heap_find/heap.py"
create_python_package "/macosx" "${package_files}"
# lldb/diagnose
package_files="${SRC_ROOT}/examples/python/diagnose_unwind.py
${SRC_ROOT}/examples/python/diagnose_nsstring.py"
create_python_package "/diagnose" "${package_files}"
# Copy files needed by lldb/macosx/heap.py to build libheap.dylib
heap_dir="${framework_python_dir}/macosx/heap"
if [ ! -d "${heap_dir}" ]
then
mkdir -p "${heap_dir}"
cp "${SRC_ROOT}/examples/darwin/heap_find/heap/heap_find.cpp" "${heap_dir}"
cp "${SRC_ROOT}/examples/darwin/heap_find/heap/Makefile" "${heap_dir}"
fi
fi
fi
exit 0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
# Disable some warnings triggered by Python's headers.
check_cxx_compiler_flag("-Wno-macro-redefined"
CXX_SUPPORTS_NO_MACRO_REDEFINED)
if (CXX_SUPPORTS_NO_MACRO_REDEFINED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-macro-redefined")
endif ()
# build the Python readline suppression module only on Linux
if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "GNU" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "kFreeBSD")
add_subdirectory(readline)
endif()

View File

@ -0,0 +1,25 @@
# FIXME: if a non-standard version of python is requested, the cmake macro
# below will need Python_ADDITIONAL_VERSIONS set in order to find it.
include(FindPythonInterp)
SET(PYTHON_DIRECTORY python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages)
# Build the readline python module
include_directories(${PYTHON_INCLUDE_DIR})
add_library(readline SHARED readline.cpp)
if (NOT LLDB_DISABLE_LIBEDIT)
target_link_libraries(readline ${PYTHON_LIBRARY} edit)
else()
target_link_libraries(readline ${PYTHON_LIBRARY})
endif()
# FIXME: the LIBRARY_OUTPUT_PATH seems to be ignored - this is not a
# functional issue for the build dir, though, since the shared lib dir
# for the build is in the python shared library load path, and thus
# python finds it when loading the python readline module.
set_target_properties(readline PROPERTIES
PREFIX ""
LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/${PYTHON_DIRECTORY})
# Install the readline module.
install(TARGETS readline LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib${LLVM_LIBDIR_SUFFIX}/${PYTHON_DIRECTORY})

View File

@ -0,0 +1,87 @@
// NOTE: Since Python may define some pre-processor definitions which affect the
// standard headers on some systems, you must include Python.h before any
// standard headers are included.
#include "Python.h"
#include <stdio.h>
#ifndef LLDB_DISABLE_LIBEDIT
#include <editline/readline.h>
#endif
// Simple implementation of the Python readline module using libedit.
// In the event that libedit is excluded from the build, this turns
// back into a null implementation that blocks the module from pulling
// in the GNU readline shared lib, which causes linkage confusion when
// both readline and libedit's readline compatibility symbols collide.
//
// Currently it only installs a PyOS_ReadlineFunctionPointer, without
// implementing any of the readline module methods. This is meant to
// work around LLVM pr18841 to avoid seg faults in the stock Python
// readline.so linked against GNU readline.
#ifndef LLDB_DISABLE_LIBEDIT
PyDoc_STRVAR(moduleDocumentation,
"Simple readline module implementation based on libedit.");
#else
PyDoc_STRVAR(moduleDocumentation,
"Stub module meant to avoid linking GNU readline.");
#endif
#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef readline_module = {
PyModuleDef_HEAD_INIT, // m_base
"readline", // m_name
moduleDocumentation, // m_doc
-1, // m_size
nullptr, // m_methods
nullptr, // m_reload
nullptr, // m_traverse
nullptr, // m_clear
nullptr, // m_free
};
#else
static struct PyMethodDef moduleMethods[] = {{nullptr, nullptr, 0, nullptr}};
#endif
#ifndef LLDB_DISABLE_LIBEDIT
static char *
#if PY_MAJOR_VERSION >= 3
simple_readline(FILE *stdin, FILE *stdout, const char *prompt)
#else
simple_readline(FILE *stdin, FILE *stdout, char *prompt)
#endif
{
rl_instream = stdin;
rl_outstream = stdout;
char *line = readline(prompt);
if (!line) {
char *ret = (char *)PyMem_Malloc(1);
if (ret != NULL)
*ret = '\0';
return ret;
}
if (*line)
add_history(line);
int n = strlen(line);
char *ret = (char *)PyMem_Malloc(n + 2);
strncpy(ret, line, n);
free(line);
ret[n] = '\n';
ret[n + 1] = '\0';
return ret;
}
#endif
PyMODINIT_FUNC initreadline(void) {
#ifndef LLDB_DISABLE_LIBEDIT
PyOS_ReadlineFunctionPointer = simple_readline;
#endif
#if PY_MAJOR_VERSION >= 3
return PyModule_Create(&readline_module);
#else
Py_InitModule4("readline", moduleMethods, moduleDocumentation,
static_cast<PyObject *>(NULL), PYTHON_API_VERSION);
#endif
}

View File

@ -0,0 +1,441 @@
"""
The LLVM Compiler Infrastructure
This file is distributed under the University of Illinois Open Source
License. See LICENSE.TXT for details.
Python binding preparation script.
"""
# Python modules:
from __future__ import print_function
import logging
import os
import re
import shutil
import subprocess
import sys
import platform
class SwigSettings(object):
"""Provides a single object to represent swig files and settings."""
def __init__(self):
self.extensions_file = None
self.header_files = None
self.input_file = None
self.interface_files = None
self.output_file = None
self.safecast_file = None
self.typemaps_file = None
self.wrapper_file = None
@classmethod
def _any_files_newer(cls, files, check_mtime):
"""Returns if any of the given files has a newer modified time.
@param cls the class
@param files a list of zero or more file paths to check
@param check_mtime the modification time to use as a reference.
@return True if any file's modified time is newer than check_mtime.
"""
for path in files:
path_mtime = os.path.getmtime(path)
if path_mtime > check_mtime:
# This path was modified more recently than the
# check_mtime.
return True
# If we made it here, nothing was newer than the check_mtime
return False
@classmethod
def _file_newer(cls, path, check_mtime):
"""Tests how recently a file has been modified.
@param cls the class
@param path a file path to check
@param check_mtime the modification time to use as a reference.
@return True if the file's modified time is newer than check_mtime.
"""
path_mtime = os.path.getmtime(path)
return path_mtime > check_mtime
def output_out_of_date(self):
"""Returns whether the output file is out of date.
Compares output file time to all the input files.
@return True if any of the input files are newer than
the output file, or if the output file doesn't exist;
False otherwise.
"""
if not os.path.exists(self.output_file):
logging.info("will generate, missing binding output file")
return True
output_mtime = os.path.getmtime(self.output_file)
if self._any_files_newer(self.header_files, output_mtime):
logging.info("will generate, header files newer")
return True
if self._any_files_newer(self.interface_files, output_mtime):
logging.info("will generate, interface files newer")
return True
if self._file_newer(self.input_file, output_mtime):
logging.info("will generate, swig input file newer")
return True
if self._file_newer(self.extensions_file, output_mtime):
logging.info("will generate, swig extensions file newer")
return True
if self._file_newer(self.wrapper_file, output_mtime):
logging.info("will generate, swig wrapper file newer")
return True
if self._file_newer(self.typemaps_file, output_mtime):
logging.info("will generate, swig typemaps file newer")
return True
if self._file_newer(self.safecast_file, output_mtime):
logging.info("will generate, swig safecast file newer")
return True
# If we made it here, nothing is newer than the output file.
# Thus, the output file is not out of date.
return False
def get_header_files(options):
"""Returns a list of paths to C++ header files for the LLDB API.
These are the files that define the C++ API that will be wrapped by Python.
@param options the dictionary of options parsed from the command line.
@return a list of full paths to the include files used to define the public
LLDB C++ API.
"""
header_file_paths = []
header_base_dir = os.path.join(options.src_root, "include", "lldb")
# Specify the include files in include/lldb that are not easy to
# grab programatically.
for header in [
"lldb-defines.h",
"lldb-enumerations.h",
"lldb-forward.h",
"lldb-types.h"]:
header_file_paths.append(os.path.normcase(
os.path.join(header_base_dir, header)))
# Include the main LLDB.h file.
api_dir = os.path.join(header_base_dir, "API")
header_file_paths.append(os.path.normcase(
os.path.join(api_dir, "LLDB.h")))
filename_regex = re.compile(r"^SB.+\.h$")
# Include all the SB*.h files in the API dir.
for filename in os.listdir(api_dir):
if filename_regex.match(filename):
header_file_paths.append(
os.path.normcase(os.path.join(api_dir, filename)))
logging.debug("found public API header file paths: %s", header_file_paths)
return header_file_paths
def get_interface_files(options):
"""Returns a list of interface files used as input to swig.
@param options the options dictionary parsed from the command line args.
@return a list of full paths to the interface (.i) files used to describe
the public API language binding.
"""
interface_file_paths = []
interface_dir = os.path.join(options.src_root, "scripts", "interface")
for filepath in [f for f in os.listdir(interface_dir)
if os.path.splitext(f)[1] == ".i"]:
interface_file_paths.append(
os.path.normcase(os.path.join(interface_dir, filepath)))
logging.debug("found swig interface files: %s", interface_file_paths)
return interface_file_paths
def remove_ignore_enoent(filename):
"""Removes given file, ignoring error if it doesn't exist.
@param filename the path of the file to remove.
"""
try:
os.remove(filename)
except OSError as error:
import errno
if error.errno != errno.ENOENT:
raise
def do_swig_rebuild(options, dependency_file, config_build_dir, settings):
"""Generates Python bindings file from swig.
This method will do a sys.exit() if something fails. If it returns to
the caller, it succeeded.
@param options the parsed command line options structure.
@param dependency_file path to the bindings dependency file
to be generated; otherwise, None if a dependency file is not
to be generated.
@param config_build_dir used as the output directory used by swig
@param settings the SwigSettings that specify a number of aspects used
to configure building the Python binding with swig (mostly paths)
"""
if options.generate_dependency_file:
temp_dep_file_path = dependency_file + ".tmp"
# Build the SWIG args list
is_darwin = options.target_platform == "Darwin"
gen_deps = options.generate_dependency_file
darwin_extras = ["-D__APPLE__"] if is_darwin else []
deps_args = ["-MMD", "-MF", temp_dep_file_path] if gen_deps else []
command = ([
options.swig_executable,
"-c++",
"-shadow",
"-python",
"-threads",
"-I" + os.path.normpath(os.path.join(options.src_root, "include")),
"-I" + os.path.curdir,
"-D__STDC_LIMIT_MACROS",
"-D__STDC_CONSTANT_MACROS"
]
+ darwin_extras
+ deps_args
+ [
"-outdir", config_build_dir,
"-o", settings.output_file,
settings.input_file
]
)
logging.info("running swig with: %r", command)
# Execute swig
process = subprocess.Popen(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
# Wait for SWIG process to terminate
swig_stdout, swig_stderr = process.communicate()
return_code = process.returncode
if return_code != 0:
logging.error(
"swig failed with error code %d: stdout=%s, stderr=%s",
return_code,
swig_stdout,
swig_stderr)
logging.error(
"command line:\n%s", ' '.join(command))
sys.exit(return_code)
logging.info("swig generation succeeded")
if swig_stdout is not None and len(swig_stdout) > 0:
logging.info("swig output: %s", swig_stdout)
# Move the depedency file we just generated to the proper location.
if options.generate_dependency_file:
if os.path.exists(temp_dep_file_path):
shutil.move(temp_dep_file_path, dependency_file)
else:
logging.error(
"failed to generate Python binding depedency file '%s'",
temp_dep_file_path)
if os.path.exists(dependency_file):
# Delete the old one.
os.remove(dependency_file)
sys.exit(-10)
def run_python_script(script_and_args):
"""Runs a python script, logging appropriately.
If the command returns anything non-zero, it is registered as
an error and exits the program.
@param script_and_args the python script to execute, along with
the command line arguments to pass to it.
"""
command = [sys.executable] + script_and_args
process = subprocess.Popen(command)
script_stdout, script_stderr = process.communicate()
return_code = process.returncode
if return_code != 0:
logging.error("failed to run %r: %r", command, script_stderr)
sys.exit(return_code)
else:
logging.info("ran script %r'", command)
if script_stdout is not None:
logging.info("output: %s", script_stdout)
def do_modify_python_lldb(options, config_build_dir):
"""Executes the modify-python-lldb.py script.
@param options the parsed command line arguments
@param config_build_dir the directory where the Python output was created.
"""
script_path = os.path.normcase(
os.path.join(
options.src_root,
"scripts",
"Python",
"modify-python-lldb.py"))
if not os.path.exists(script_path):
logging.error("failed to find python script: '%s'", script_path)
sys.exit(-11)
run_python_script([script_path, config_build_dir])
def get_python_module_path(options):
"""Returns the location where the lldb Python module should be placed.
@param options dictionary of options parsed from the command line.
@return the directory where the lldb module should be placed.
"""
if options.framework:
# Caller wants to use the OS X framework packaging.
# We are packaging in an OS X-style framework bundle. The
# module dir will be within the
# LLDB.framework/Resources/Python subdirectory.
return os.path.join(
options.target_dir,
"LLDB.framework",
"Resources",
"Python",
"lldb")
else:
from distutils.sysconfig import get_python_lib
if options.prefix is not None:
module_path = get_python_lib(True, False, options.prefix)
else:
module_path = get_python_lib(True, False)
return os.path.normcase(
os.path.join(module_path, "lldb"))
def main(options):
"""Pepares the Python language binding to LLDB.
@param options the parsed command line argument dictionary
"""
# Setup generated dependency file options.
if options.generate_dependency_file:
dependency_file = os.path.normcase(os.path.join(
options.target_dir, "LLDBWrapPython.cpp.d"))
else:
dependency_file = None
# Keep track of all the swig-related settings.
settings = SwigSettings()
# Determine the final binding file path.
settings.output_file = os.path.normcase(
os.path.join(options.target_dir, "LLDBWrapPython.cpp"))
# Touch the output file (but don't really generate it) if python
# is disabled.
disable_python = os.getenv("LLDB_DISABLE_PYTHON", None)
if disable_python is not None and disable_python == "1":
remove_ignore_enoent(settings.output_file)
# Touch the file.
open(settings.output_file, 'w').close()
logging.info(
"Created empty python binding file due to LLDB_DISABLE_PYTHON "
"being set")
return
# We also check the GCC_PREPROCESSOR_DEFINITIONS to see if it
# contains LLDB_DISABLE_PYTHON. If so, we skip generating
# the binding.
gcc_preprocessor_defs = os.getenv("GCC_PREPROCESSOR_DEFINITIONS", None)
if gcc_preprocessor_defs is not None:
if re.search(r"LLDB_DISABLE_PYTHON", gcc_preprocessor_defs):
remove_ignore_enoent(settings.output_file)
# Touch the file
open(settings.output_file, 'w').close()
logging.info(
"Created empty python binding file due to "
"finding LLDB_DISABLE_PYTHON in GCC_PREPROCESSOR_DEFINITIONS")
return
# Setup paths used during swig invocation.
settings.input_file = os.path.normcase(
os.path.join(options.src_root, "scripts", "lldb.swig"))
scripts_python_dir = os.path.dirname(os.path.realpath(__file__))
settings.extensions_file = os.path.normcase(
os.path.join(scripts_python_dir, "python-extensions.swig"))
settings.wrapper_file = os.path.normcase(
os.path.join(scripts_python_dir, "python-wrapper.swig"))
settings.typemaps_file = os.path.normcase(
os.path.join(scripts_python_dir, "python-typemaps.swig"))
settings.safecast_file = os.path.normcase(
os.path.join(scripts_python_dir, "python-swigsafecast.swig"))
settings.header_files = get_header_files(options)
settings.interface_files = get_interface_files(options)
generate_output = settings.output_out_of_date()
# Determine where to put the module.
python_module_path = get_python_module_path(options)
logging.info("python module path: %s", python_module_path)
# Handle the configuration build dir.
if options.config_build_dir is not None:
config_build_dir = options.config_build_dir
else:
config_build_dir = python_module_path
# Allow missing/non-link _lldb.so to force regeneration.
if not generate_output:
# Ensure the _lldb.so file exists.
so_path = os.path.join(python_module_path, "_lldb.so")
if not os.path.exists(so_path) or not os.path.islink(so_path):
logging.info("_lldb.so doesn't exist or isn't a symlink")
generate_output = True
# Allow missing __init__.py to force regeneration.
if not generate_output:
# Ensure the __init__.py for the lldb module can be found.
init_path = os.path.join(python_module_path, "__init__.py")
if not os.path.exists(init_path):
logging.info("__init__.py doesn't exist")
generate_output = True
if not generate_output:
logging.info(
"Skipping Python binding generation: everything is up to date")
return
# Generate the Python binding with swig.
logging.info("Python binding is out of date, regenerating")
do_swig_rebuild(options, dependency_file, config_build_dir, settings)
if options.generate_dependency_file:
return
# Post process the swig-generated file.
do_modify_python_lldb(options, config_build_dir)
# This script can be called by another Python script by calling the main()
# function directly
if __name__ == "__main__":
print("Script cannot be called directly.")
sys.exit(-1)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
// leaving this undefined ensures we will get a linker error if we try to use SBTypeToSWIGWrapper()
// for a type for which we did not specialze this function
template <typename SBClass>
PyObject*
SBTypeToSWIGWrapper (SBClass* sb_object);
template <typename SBClass>
PyObject*
SBTypeToSWIGWrapper (SBClass& sb_object)
{
return SBTypeToSWIGWrapper(&sb_object);
}
template <typename SBClass>
PyObject*
SBTypeToSWIGWrapper (const SBClass& sb_object)
{
return SBTypeToSWIGWrapper(&sb_object);
}
template <>
PyObject*
SBTypeToSWIGWrapper (PyObject* py_object)
{
return py_object;
}
template <>
PyObject*
SBTypeToSWIGWrapper (const char* c_str)
{
if (c_str)
return PyString_FromString(c_str);
return NULL;
}
template <>
PyObject*
SBTypeToSWIGWrapper (unsigned int* c_int)
{
if (!c_int)
return NULL;
return PyInt_FromLong(*c_int);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBEvent* event_sb)
{
return SWIG_NewPointerObj((void *) event_sb, SWIGTYPE_p_lldb__SBEvent, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBProcess* process_sb)
{
return SWIG_NewPointerObj((void *) process_sb, SWIGTYPE_p_lldb__SBProcess, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBThread* thread_sb)
{
return SWIG_NewPointerObj((void *) thread_sb, SWIGTYPE_p_lldb__SBThread, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBThreadPlan* thread_plan_sb)
{
return SWIG_NewPointerObj((void *) thread_plan_sb, SWIGTYPE_p_lldb__SBThreadPlan, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBTarget* target_sb)
{
return SWIG_NewPointerObj((void *) target_sb, SWIGTYPE_p_lldb__SBTarget, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBFrame* frame_sb)
{
return SWIG_NewPointerObj((void *) frame_sb, SWIGTYPE_p_lldb__SBFrame, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBDebugger* debugger_sb)
{
return SWIG_NewPointerObj((void *) debugger_sb, SWIGTYPE_p_lldb__SBDebugger, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBBreakpoint* breakpoint_sb)
{
return SWIG_NewPointerObj((void *) breakpoint_sb, SWIGTYPE_p_lldb__SBBreakpoint, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBWatchpoint* watchpoint_sb)
{
return SWIG_NewPointerObj((void *) watchpoint_sb, SWIGTYPE_p_lldb__SBWatchpoint, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBBreakpointLocation* breakpoint_location_sb)
{
return SWIG_NewPointerObj((void *) breakpoint_location_sb, SWIGTYPE_p_lldb__SBBreakpointLocation, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBBreakpointName* breakpoint_name_sb)
{
return SWIG_NewPointerObj((void *) breakpoint_name_sb, SWIGTYPE_p_lldb__SBBreakpointName, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBValue* value_sb)
{
return SWIG_NewPointerObj((void *) value_sb, SWIGTYPE_p_lldb__SBValue, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBCommandReturnObject* cmd_ret_obj_sb)
{
return SWIG_NewPointerObj((void *) cmd_ret_obj_sb, SWIGTYPE_p_lldb__SBCommandReturnObject, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBExecutionContext* ctx_sb)
{
return SWIG_NewPointerObj((void *) ctx_sb, SWIGTYPE_p_lldb__SBExecutionContext, 0);
}
template <>
PyObject*
SBTypeToSWIGWrapper (lldb::SBTypeSummaryOptions* summary_options_sb)
{
return SWIG_NewPointerObj((void *) summary_options_sb, SWIGTYPE_p_lldb__SBTypeSummaryOptions, 0);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,312 @@
#!/usr/bin/python
from __future__ import print_function
import argparse
import getpass
import os
import os.path
import re
import select
import sys
import subprocess
_COMMON_SYNC_OPTS = "-avzh --delete"
_COMMON_EXCLUDE_OPTS = "--exclude=DerivedData --exclude=.svn --exclude=.git --exclude=llvm-build/Release+Asserts"
def normalize_configuration(config_text):
if not config_text:
return "debug"
config_lower = config_text.lower()
if config_lower in ["debug", "release"]:
return config_lower
else:
raise Exception("unknown configuration specified: %s" % config_text)
def parse_args():
DEFAULT_REMOTE_ROOT_DIR = "/mnt/ssd/work/macosx.sync"
DEFAULT_REMOTE_HOSTNAME = "tfiala2.mtv.corp.google.com"
OPTIONS_FILENAME = ".remote-build.conf"
DEFAULT_SSH_PORT = "22"
parser = argparse.ArgumentParser(fromfile_prefix_chars='@')
parser.add_argument(
"--configuration",
"-c",
help="specify configuration (Debug, Release)",
default=normalize_configuration(
os.environ.get(
'CONFIGURATION',
'Debug')))
parser.add_argument(
"--debug", "-d",
action="store_true",
help="help debug the remote-build script by adding extra logging")
parser.add_argument(
"--local-lldb-dir", "-l", metavar="DIR",
help="specify local lldb directory (Xcode layout assumed for llvm/clang)",
default=os.getcwd())
parser.add_argument(
"--port", "-p",
help="specify the port ssh should use to connect to the remote side",
default=DEFAULT_SSH_PORT)
parser.add_argument(
"--remote-address", "-r", metavar="REMOTE-ADDR",
help="specify the dns name or ip address of the remote linux system",
default=DEFAULT_REMOTE_HOSTNAME)
parser.add_argument(
"--remote-dir", metavar="DIR",
help="specify the root of the linux source/build dir",
default=DEFAULT_REMOTE_ROOT_DIR)
parser.add_argument(
"--user", "-u", help="specify the user name for the remote system",
default=getpass.getuser())
parser.add_argument(
"--xcode-action",
"-x",
help="$(ACTION) from Xcode",
nargs='?',
default=None)
command_line_args = sys.argv[1:]
if os.path.exists(OPTIONS_FILENAME):
# Prepend the file so that command line args override the file
# contents.
command_line_args.insert(0, "@%s" % OPTIONS_FILENAME)
return parser.parse_args(command_line_args)
def maybe_create_remote_root_dir(args):
commandline = [
"ssh",
"-p", args.port,
"%s@%s" % (args.user, args.remote_address),
"mkdir",
"-p",
args.remote_dir]
print("create remote root dir command:\n{}".format(commandline))
return subprocess.call(commandline)
def init_with_args(args):
# Expand any user directory specs in local-side source dir (on MacOSX).
args.local_lldb_dir = os.path.expanduser(args.local_lldb_dir)
# Append the configuration type to the remote build dir.
args.configuration = normalize_configuration(args.configuration)
args.remote_build_dir = os.path.join(
args.remote_dir,
"build-%s" % args.configuration)
# We assume the local lldb directory is really named 'lldb'.
# This is because on the remote end, the local lldb root dir
# is copied over underneath llvm/tools and will be named there
# whatever it is named locally. The remote build will assume
# is is called lldb.
if os.path.basename(args.local_lldb_dir) != 'lldb':
raise Exception(
"local lldb root needs to be called 'lldb' but was {} instead"
.format(os.path.basename(args.local_lldb_dir)))
args.lldb_dir_relative_regex = re.compile(
"%s/llvm/tools/lldb/" % args.remote_dir)
args.llvm_dir_relative_regex = re.compile("%s/" % args.remote_dir)
print("Xcode action:", args.xcode_action)
# Ensure the remote directory exists.
result = maybe_create_remote_root_dir(args)
if result == 0:
print("using remote root dir: %s" % args.remote_dir)
else:
print("remote root dir doesn't exist and could not be created, "
+ "error code:", result)
return False
return True
def sync_llvm(args):
commandline = ["rsync"]
commandline.extend(_COMMON_SYNC_OPTS.split())
commandline.extend(_COMMON_EXCLUDE_OPTS.split())
commandline.append("--exclude=/llvm/tools/lldb")
commandline.extend(["-e", "ssh -p {}".format(args.port)])
commandline.extend([
"%s/llvm" % args.local_lldb_dir,
"%s@%s:%s" % (args.user, args.remote_address, args.remote_dir)])
if args.debug:
print("going to execute llvm sync: {}".format(commandline))
return subprocess.call(commandline)
def sync_lldb(args):
commandline = ["rsync"]
commandline.extend(_COMMON_SYNC_OPTS.split())
commandline.extend(_COMMON_EXCLUDE_OPTS.split())
commandline.append("--exclude=/lldb/llvm")
commandline.extend(["-e", "ssh -p {}".format(args.port)])
commandline.extend([args.local_lldb_dir, "%s@%s:%s/llvm/tools" %
(args.user, args.remote_address, args.remote_dir)])
if args.debug:
print("going to execute lldb sync: {}".format(commandline))
return subprocess.call(commandline)
def build_cmake_command(args):
# args.remote_build_dir
# args.configuration in ('release', 'debug')
if args.configuration == 'debug-optimized':
build_type_name = "RelWithDebInfo"
elif args.configuration == 'release':
build_type_name = "Release"
else:
build_type_name = "Debug"
ld_flags = "\"-lstdc++ -lm\""
install_dir = os.path.join(
args.remote_build_dir, "..", "install-{}".format(args.configuration))
command_line = [
"cmake",
"-GNinja",
"-DCMAKE_CXX_COMPILER=clang",
"-DCMAKE_C_COMPILER=clang",
# "-DCMAKE_CXX_FLAGS=%s" % cxx_flags,
"-DCMAKE_SHARED_LINKER_FLAGS=%s" % ld_flags,
"-DCMAKE_EXE_LINKER_FLAGS=%s" % ld_flags,
"-DCMAKE_INSTALL_PREFIX:PATH=%s" % install_dir,
"-DCMAKE_BUILD_TYPE=%s" % build_type_name,
"-Wno-dev",
os.path.join("..", "llvm")
]
return command_line
def maybe_configure(args):
commandline = [
"ssh",
"-p", args.port,
"%s@%s" % (args.user, args.remote_address),
"cd", args.remote_dir, "&&",
"mkdir", "-p", args.remote_build_dir, "&&",
"cd", args.remote_build_dir, "&&"
]
commandline.extend(build_cmake_command(args))
if args.debug:
print("configure command: {}".format(commandline))
return subprocess.call(commandline)
def filter_build_line(args, line):
lldb_relative_line = args.lldb_dir_relative_regex.sub('', line)
if len(lldb_relative_line) != len(line):
# We substituted - return the modified line
return lldb_relative_line
# No match on lldb path (longer on linux than llvm path). Try
# the llvm path match.
return args.llvm_dir_relative_regex.sub('', line)
def run_remote_build_command(args, build_command_list):
commandline = [
"ssh",
"-p", args.port,
"%s@%s" % (args.user, args.remote_address),
"cd", args.remote_build_dir, "&&"]
commandline.extend(build_command_list)
if args.debug:
print("running remote build command: {}".format(commandline))
proc = subprocess.Popen(
commandline,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# Filter stdout/stderr output for file path mapping.
# We do this to enable Xcode to see filenames relative to the
# MacOSX-side directory structure.
while True:
reads = [proc.stdout.fileno(), proc.stderr.fileno()]
select_result = select.select(reads, [], [])
for fd in select_result[0]:
if fd == proc.stdout.fileno():
line = proc.stdout.readline()
display_line = filter_build_line(args, line.rstrip())
if display_line and len(display_line) > 0:
print(display_line)
elif fd == proc.stderr.fileno():
line = proc.stderr.readline()
display_line = filter_build_line(args, line.rstrip())
if display_line and len(display_line) > 0:
print(display_line, file=sys.stderr)
proc_retval = proc.poll()
if proc_retval is not None:
# Process stopped. Drain output before finishing up.
# Drain stdout.
while True:
line = proc.stdout.readline()
if line:
display_line = filter_build_line(args, line.rstrip())
if display_line and len(display_line) > 0:
print(display_line)
else:
break
# Drain stderr.
while True:
line = proc.stderr.readline()
if line:
display_line = filter_build_line(args, line.rstrip())
if display_line and len(display_line) > 0:
print(display_line, file=sys.stderr)
else:
break
return proc_retval
def build(args):
return run_remote_build_command(args, ["time", "ninja"])
def clean(args):
return run_remote_build_command(args, ["ninja", "clean"])
if __name__ == "__main__":
# Handle arg parsing.
args = parse_args()
# Initialize the system.
if not init_with_args(args):
exit(1)
# Sync over llvm and clang source.
sync_llvm(args)
# Sync over lldb source.
sync_lldb(args)
# Configure the remote build if it's not already.
maybe_configure(args)
if args.xcode_action == 'clean':
exit(clean(args))
else:
exit(build(args))

View File

@ -0,0 +1,26 @@
import inspect
import os
import sys
def find_lldb_root():
lldb_root = os.path.dirname(inspect.getfile(inspect.currentframe()))
while True:
lldb_root = os.path.dirname(lldb_root)
if lldb_root is None:
return None
test_path = os.path.join(lldb_root, "use_lldb_suite_root.py")
if os.path.isfile(test_path):
return lldb_root
return None
lldb_root = find_lldb_root()
if lldb_root is not None:
import imp
fp, pathname, desc = imp.find_module("use_lldb_suite_root", [lldb_root])
try:
imp.load_module("use_lldb_suite_root", fp, pathname, desc)
finally:
if fp:
fp.close()