diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt --- a/lldb/CMakeLists.txt +++ b/lldb/CMakeLists.txt @@ -37,6 +37,19 @@ endif() if (NOT LLDB_DISABLE_PYTHON) + execute_process( + COMMAND ${PYTHON_EXECUTABLE} + -c "import distutils.sysconfig, sys; print(distutils.sysconfig.get_python_lib(True, False, sys.argv[1]))" + ${CMAKE_INSTALL_PREFIX} + OUTPUT_VARIABLE LLDB_PYTHON_DEFAULT_ABSOLUTE_INSTALL_PATH + OUTPUT_STRIP_TRAILING_WHITESPACE) + + file(RELATIVE_PATH LLDB_PYTHON_DEFAULT_RELATIVE_PATH + ${CMAKE_INSTALL_PREFIX} ${LLDB_PYTHON_DEFAULT_ABSOLUTE_INSTALL_PATH}) + + set(LLDB_PYTHON_RELATIVE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH} + CACHE STRING "Path where Python modules are installed, relative to install prefix") + add_subdirectory(scripts) endif () @@ -195,6 +208,12 @@ get_target_property(lldb_scripts_dir swig_wrapper BINARY_DIR) get_target_property(liblldb_build_dir liblldb LIBRARY_OUTPUT_DIRECTORY) + if(LLDB_BUILD_FRAMEWORK) + set(lldb_python_build_path "${liblldb_build_dir}/LLDB.framework/Resources/Python/lldb") + else() + set(lldb_python_build_path "${CMAKE_BINARY_DIR}/${LLDB_PYTHON_RELATIVE_PATH}/lldb") + endif() + # Add a Post-Build Event to copy over Python files and create the symlink # to liblldb.so for the Python API(hardlink on Windows). add_custom_target(finish_swig ALL @@ -206,6 +225,7 @@ --prefix=${CMAKE_BINARY_DIR} --cmakeBuildConfiguration=${CMAKE_CFG_INTDIR} --lldbLibDir=lib${LLVM_LIBDIR_SUFFIX} + --lldbPythonPath=${lldb_python_build_path} ${use_python_wrapper_from_src_dir} ${use_six_py_from_system} VERBATIM @@ -219,6 +239,12 @@ # Ensure we do the python post-build step when building lldb. add_dependencies(lldb finish_swig) + if(NOT LLDB_BUILD_FRAMEWORK) + # Install the LLDB python module + install(DIRECTORY ${CMAKE_BINARY_DIR}/${LLDB_PYTHON_RELATIVE_PATH}/ + DESTINATION ${LLDB_PYTHON_RELATIVE_PATH}) + endif() + # Add a Post-Build Event to copy the custom Python DLL to the lldb binaries dir so that Windows can find it when launching # lldb.exe or any other executables that were linked with liblldb. if (WIN32 AND NOT "${PYTHON_DLL}" STREQUAL "") diff --git a/lldb/scripts/CMakeLists.txt b/lldb/scripts/CMakeLists.txt --- a/lldb/scripts/CMakeLists.txt +++ b/lldb/scripts/CMakeLists.txt @@ -53,21 +53,4 @@ add_custom_target(swig_wrapper ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapPython.cpp ${CMAKE_CURRENT_BINARY_DIR}/lldb.py -) - -if(NOT LLDB_BUILD_FRAMEWORK) - execute_process( - COMMAND ${PYTHON_EXECUTABLE} - -c "import distutils.sysconfig, sys; print(distutils.sysconfig.get_python_lib(True, False, sys.argv[1]))" - ${CMAKE_BINARY_DIR} - OUTPUT_VARIABLE SWIG_PYTHON_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process( - COMMAND ${PYTHON_EXECUTABLE} - -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(True, False, ''))" - OUTPUT_VARIABLE SWIG_INSTALL_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) - - # Install the LLDB python module - install(DIRECTORY ${SWIG_PYTHON_DIR}/ DESTINATION ${SWIG_INSTALL_DIR}) -endif() +) \ No newline at end of file diff --git a/lldb/scripts/Python/finishSwigPythonLLDB.py b/lldb/scripts/Python/finishSwigPythonLLDB.py --- a/lldb/scripts/Python/finishSwigPythonLLDB.py +++ b/lldb/scripts/Python/finishSwigPythonLLDB.py @@ -597,86 +597,6 @@ return (bOk, strConfigBldDir, strErrMsg) -#++--------------------------------------------------------------------------- -# Details: Determine where to put the files. Retrieve the directory path for -# Python's dist_packages/ site_package folder on a Windows platform. -# Args: vDictArgs - (R) Program input parameters. -# Returns: Bool - True = function success, False = failure. -# Str - Python Framework directory path. -# strErrMsg - Error description on task failure. -# Throws: None. -#-- - - -def get_framework_python_dir_windows(vDictArgs): - dbg = utilsDebug.CDebugFnVerbose( - "Python script get_framework_python_dir_windows()") - bOk = True - strWkDir = "" - strErrMsg = "" - - # We are being built by LLVM, so use the PYTHON_INSTALL_DIR argument, - # and append the python version directory to the end of it. Depending - # on the system other stuff may need to be put here as well. - from distutils.sysconfig import get_python_lib - strPythonInstallDir = "" - bHaveArgPrefix = "--prefix" in vDictArgs - if bHaveArgPrefix: - strPythonInstallDir = os.path.normpath(vDictArgs["--prefix"]) - - bHaveArgCmakeBuildConfiguration = "--cmakeBuildConfiguration" in vDictArgs - if bHaveArgCmakeBuildConfiguration: - strPythonInstallDir = os.path.join( - strPythonInstallDir, - vDictArgs["--cmakeBuildConfiguration"]) - - if strPythonInstallDir.__len__() != 0: - strWkDir = get_python_lib(True, False, strPythonInstallDir) - else: - strWkDir = get_python_lib(True, False) - strWkDir = os.path.normcase(os.path.join(strWkDir, "lldb")) - - return (bOk, strWkDir, strErrMsg) - -#++--------------------------------------------------------------------------- -# Details: Retrieve the directory path for Python's dist_packages/ -# site_package folder on a UNIX style platform. -# Args: vDictArgs - (R) Program input parameters. -# Returns: Bool - True = function success, False = failure. -# Str - Python Framework directory path. -# strErrMsg - Error description on task failure. -# Throws: None. -#-- - - -def get_framework_python_dir_other_platforms(vDictArgs): - dbg = utilsDebug.CDebugFnVerbose( - "Python script get_framework_python_dir_other_platform()") - bOk = True - strWkDir = "" - strErrMsg = "" - bDbg = "-d" in vDictArgs - - bMakeFileCalled = "-m" in vDictArgs - if bMakeFileCalled: - dbg.dump_text("Built by LLVM") - return get_framework_python_dir_windows(vDictArgs) - else: - dbg.dump_text("Built by XCode") - # We are being built by XCode, so all the lldb Python files can go - # into the LLDB.framework/Resources/Python subdirectory. - strWkDir = vDictArgs["--targetDir"] - strWkDir = os.path.join(strWkDir, "LLDB.framework") - if os.path.exists(strWkDir): - if bDbg: - print((strMsgFoundLldbFrameWkDir % strWkDir)) - strWkDir = os.path.join(strWkDir, "Resources", "Python", "lldb") - strWkDir = os.path.normcase(strWkDir) - else: - bOk = False - strErrMsg = strErrMsgFrameWkPyDirNotExist % strWkDir - - return (bOk, strWkDir, strErrMsg) #++--------------------------------------------------------------------------- # Details: Retrieve the directory path for Python's dist_packages/ @@ -697,15 +617,12 @@ 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) + bHavePythonPath = "--lldbPythonPath" in vDictArgs + if bHavePythonPath: + strWkDir = os.path.normpath(vDictArgs["--lldbPythonPath"]) else: - bOk, strWkDir, strErrMsg = get_framework_python_dir_other_platforms( - vDictArgs) + bOk = False + strErrMsg = "--lldbPythonPath is not set." return (bOk, strWkDir, strErrMsg) diff --git a/lldb/scripts/finishSwigWrapperClasses.py b/lldb/scripts/finishSwigWrapperClasses.py --- a/lldb/scripts/finishSwigWrapperClasses.py +++ b/lldb/scripts/finishSwigWrapperClasses.py @@ -179,6 +179,7 @@ "prefix=", "cmakeBuildConfiguration=", "lldbLibDir=", + "lldbPythonPath=", "argsFile", "useSystemSix"] dictArgReq = {"-h": "o", # o = optional, m = mandatory @@ -191,7 +192,8 @@ "--cmakeBuildConfiguration": "o", "--lldbLibDir": "o", "--argsFile": "o", - "--useSystemSix": "o"} + "--useSystemSix": "o", + "--lldbPythonPath": "m"} # Check for mandatory parameters nResult, dictArgs, strMsg = utilsArgsParse.parse(vArgv, strListArgs, @@ -293,11 +295,9 @@ # Iterate script directory find any script language directories for scriptLang in listDirs: - # __pycache__ is a magic directory in Python 3 that holds .pyc files - if scriptLang != "__pycache__" and scriptLang != "swig_bot_lib": - dbg.dump_text("Executing language script for \'%s\'" % scriptLang) - nResult, strStatusMsg = run_post_process( - scriptLang, strFinishFileName, vDictArgs) + dbg.dump_text("Executing language script for \'%s\'" % scriptLang) + nResult, strStatusMsg = run_post_process( + scriptLang, strFinishFileName, vDictArgs) if nResult < 0: break @@ -337,13 +337,6 @@ 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 = "-m" in dictArgs - nResult, strMsg = run_post_process_for_each_script_supported(dictArgs) program_exit(nResult, strMsg) diff --git a/lldb/scripts/get_relative_lib_dir.py b/lldb/scripts/get_relative_lib_dir.py deleted file mode 100644 --- a/lldb/scripts/get_relative_lib_dir.py +++ /dev/null @@ -1,44 +0,0 @@ -import distutils.sysconfig -import os -import platform -import re -import sys - - -def get_python_relative_libdir(): - """Returns the appropropriate python libdir relative to the build directory. - - @param exe_path the path to the lldb executable - - @return the python path that needs to be added to sys.path (PYTHONPATH) - in order to find the lldb python module. - """ - if platform.system() != 'Linux': - return None - - # We currently have a bug in lldb -P that does not account for - # architecture variants in python paths for - # architecture-specific modules. Handle the lookup here. - # When that bug is fixed, we should just ask lldb for the - # right answer always. - arch_specific_libdir = distutils.sysconfig.get_python_lib(True, False) - split_libdir = arch_specific_libdir.split(os.sep) - lib_re = re.compile(r"^lib.*$") - - for i in range(len(split_libdir)): - match = lib_re.match(split_libdir[i]) - if match is not None: - # We'll call this the relative root of the lib dir. - # Things like RHEL will have an arch-specific python - # lib dir, which isn't 'lib' on x86_64. - return os.sep.join(split_libdir[i:]) - # Didn't resolve it. - return None - -if __name__ == '__main__': - lib_dir = get_python_relative_libdir() - if lib_dir is not None: - sys.stdout.write(lib_dir) - sys.exit(0) - else: - sys.exit(1) diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt --- a/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt +++ b/lldb/source/Plugins/ScriptInterpreter/Python/CMakeLists.txt @@ -1,15 +1,7 @@ -if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows") - # Call a python script to gather the arch-specific libdir for - # modules like the lldb module. - execute_process( - COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/../../../../scripts/get_relative_lib_dir.py - RESULT_VARIABLE get_libdir_status - OUTPUT_VARIABLE relative_libdir - ) - if (get_libdir_status EQUAL 0) - add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${relative_libdir}") - endif() +if(NOT LLDB_PYTHON_RELATIVE_PATH) + message(FATAL_ERROR "LLDB_PYTHON_RELATIVE_PATH is not set yet.") endif() +add_definitions(-DLLDB_PYTHON_RELATIVE_LIBDIR="${LLDB_PYTHON_RELATIVE_PATH}") add_lldb_library(lldbPluginScriptInterpreterPython PLUGIN PythonDataObjects.cpp diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.h @@ -48,8 +48,7 @@ protected: static void ComputePythonDirForApple(llvm::SmallVectorImpl &path); - static void ComputePythonDirForPosix(llvm::SmallVectorImpl &path); - static void ComputePythonDirForWindows(llvm::SmallVectorImpl &path); + static void ComputePythonDir(llvm::SmallVectorImpl &path); }; } // namespace lldb_private diff --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp --- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp +++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp @@ -305,39 +305,20 @@ auto rend = llvm::sys::path::rend(path_ref); auto framework = std::find(rbegin, rend, "LLDB.framework"); if (framework == rend) { - ComputePythonDirForPosix(path); + ComputePythonDir(path); return; } path.resize(framework - rend); llvm::sys::path::append(path, style, "LLDB.framework", "Resources", "Python"); } -void ScriptInterpreterPython::ComputePythonDirForPosix( +void ScriptInterpreterPython::ComputePythonDir( llvm::SmallVectorImpl &path) { - auto style = llvm::sys::path::Style::posix; -#if defined(LLDB_PYTHON_RELATIVE_LIBDIR) // Build the path by backing out of the lib dir, then building with whatever // the real python interpreter uses. (e.g. lib for most, lib64 on RHEL - // x86_64). - llvm::sys::path::remove_filename(path, style); - llvm::sys::path::append(path, style, LLDB_PYTHON_RELATIVE_LIBDIR); -#else - llvm::sys::path::append(path, style, - "python" + llvm::Twine(PY_MAJOR_VERSION) + "." + - llvm::Twine(PY_MINOR_VERSION), - "site-packages"); -#endif -} - -void ScriptInterpreterPython::ComputePythonDirForWindows( - llvm::SmallVectorImpl &path) { - auto style = llvm::sys::path::Style::windows; - llvm::sys::path::remove_filename(path, style); - llvm::sys::path::append(path, style, "lib", "site-packages"); - - // This will be injected directly through FileSpec.GetDirectory().SetString(), - // so we need to normalize manually. - std::replace(path.begin(), path.end(), '\\', '/'); + // x86_64, or bin on Windows). + llvm::sys::path::remove_filename(path); + llvm::sys::path::append(path, LLDB_PYTHON_RELATIVE_LIBDIR); } FileSpec ScriptInterpreterPython::GetPythonDir() { @@ -350,11 +331,10 @@ #if defined(__APPLE__) ComputePythonDirForApple(path); -#elif defined(_WIN32) - ComputePythonDirForWindows(path); #else - ComputePythonDirForPosix(path); + ComputePythonDir(path); #endif + llvm::sys::path::native(path); spec.GetDirectory().SetString(path); return spec; }();