diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt --- a/lldb/CMakeLists.txt +++ b/lldb/CMakeLists.txt @@ -190,73 +190,108 @@ endif() if (NOT LLDB_DISABLE_PYTHON) - if(NOT LLDB_BUILD_FRAMEWORK) - set(use_python_wrapper_from_src_dir -m) - endif() - if(LLDB_USE_SYSTEM_SIX) - set(use_six_py_from_system --useSystemSix) + if(NOT LLDB_BUILD_FRAMEWORK) + set(use_python_wrapper_from_src_dir -m) + endif() + if(LLDB_USE_SYSTEM_SIX) + set(use_six_py_from_system --useSystemSix) + endif() + get_target_property(lldb_scripts_dir swig_wrapper BINARY_DIR) + get_target_property(liblldb_build_dir liblldb LIBRARY_OUTPUT_DIRECTORY) + + 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}/${CMAKE_CFG_INTDIR}/${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 + COMMAND + ${PYTHON_EXECUTABLE} ${LLDB_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py + --srcRoot=${LLDB_SOURCE_DIR} + --targetDir=${liblldb_build_dir} + --cfgBldDir=${lldb_scripts_dir} + --prefix=${CMAKE_BINARY_DIR} + --cmakeBuildConfiguration=${CMAKE_CFG_INTDIR} + --lldbLibDir=lib${LLVM_LIBDIR_SUFFIX} + --lldbPythonPath=${lldb_python_build_path} + ${use_python_wrapper_from_src_dir} + ${use_six_py_from_system} + VERBATIM + DEPENDS ${LLDB_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py + DEPENDS ${lldb_scripts_dir}/lldb.py + COMMENT "Python script sym-linking LLDB Python API") + + function(create_relative_symlink target dest_file output_dir output_name) + get_filename_component(dest_file ${dest_file} ABSOLUTE) + get_filename_component(output_dir ${output_dir} ABSOLUTE) + file(RELATIVE_PATH rel_dest_file ${output_dir} ${dest_file}) + if(CMAKE_HOST_UNIX) + set(LLVM_LINK_OR_COPY create_symlink) + else() + set(LLVM_LINK_OR_COPY copy) endif() - get_target_property(lldb_scripts_dir swig_wrapper BINARY_DIR) - get_target_property(liblldb_build_dir liblldb LIBRARY_OUTPUT_DIRECTORY) + add_custom_command(TARGET ${target} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${rel_dest_file}" "${output_dir}/${output_name}") + endfunction() - if(LLDB_BUILD_FRAMEWORK) - set(lldb_python_build_path "${liblldb_build_dir}/LLDB.framework/Resources/Python/lldb") + if(LLDB_BUILD_FRAMEWORK) + set(LIBLLDB_SYMLINK_DEST "${liblldb_build_dir}/LLDB.framework/LLDB") + else() + set(LIBLLDB_SYMLINK_DEST "${liblldb_build_dir}/liblldb${CMAKE_SHARED_LIBRARY_SUFFIX}") + endif() + if(WIN32) + if(CMAKE_BUILD_TYPE STREQUAL Debug) + set(LIBLLDB_SYMLINK_OUTPUT_FILE "_lldb_d.pyd") else() - set(lldb_python_build_path "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_PYTHON_RELATIVE_PATH}/lldb") + set(LIBLLDB_SYMLINK_OUTPUT_FILE "_lldb.pyd") endif() - get_filename_component(lldb_python_build_path ${lldb_python_build_path} ABSOLUTE) - - # 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 - COMMAND - ${PYTHON_EXECUTABLE} ${LLDB_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py - --srcRoot=${LLDB_SOURCE_DIR} - --targetDir=${liblldb_build_dir} - --cfgBldDir=${lldb_scripts_dir} - --prefix=${CMAKE_BINARY_DIR} - --cmakeBuildConfiguration=${CMAKE_CFG_INTDIR} - --lldbLibDir=lib${LLVM_LIBDIR_SUFFIX} - --lldbPythonPath=${lldb_python_build_path} - ${use_python_wrapper_from_src_dir} - ${use_six_py_from_system} - VERBATIM - DEPENDS ${LLDB_SOURCE_DIR}/scripts/finishSwigWrapperClasses.py - DEPENDS ${lldb_scripts_dir}/lldb.py - COMMENT "Python script sym-linking LLDB Python API") - - add_dependencies(finish_swig swig_wrapper liblldb lldb-argdumper) - set_target_properties(finish_swig swig_wrapper PROPERTIES FOLDER "lldb misc") - - # 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 - add_custom_target(lldb-python-scripts) - add_dependencies(lldb-python-scripts finish_swig) - install(DIRECTORY ${CMAKE_BINARY_DIR}/${LLDB_PYTHON_RELATIVE_PATH}/ - DESTINATION ${LLDB_PYTHON_RELATIVE_PATH} - COMPONENT lldb-python-scripts) - if (NOT LLVM_ENABLE_IDE) - add_llvm_install_targets(install-lldb-python-scripts - COMPONENT lldb-python-scripts - DEPENDS lldb-python-scripts) - endif() + else() + set(LIBLLDB_SYMLINK_OUTPUT_FILE "_lldb.so") + endif() + create_relative_symlink(finish_swig ${LIBLLDB_SYMLINK_DEST} + ${lldb_python_build_path} ${LIBLLDB_SYMLINK_OUTPUT_FILE}) + + if(NOT LLDB_BUILD_FRAMEWORK) + set(LLDB_ARGDUMPER_FILENAME "lldb-argdumper${CMAKE_EXECUTABLE_SUFFIX}") + create_relative_symlink(finish_swig "${LLVM_RUNTIME_OUTPUT_INTDIR}/${LLDB_ARGDUMPER_FILENAME}" + ${lldb_python_build_path} ${LLDB_ARGDUMPER_FILENAME}) + endif() + + add_dependencies(finish_swig swig_wrapper liblldb lldb-argdumper) + set_target_properties(finish_swig swig_wrapper PROPERTIES FOLDER "lldb misc") + + # 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 + add_custom_target(lldb-python-scripts) + add_dependencies(lldb-python-scripts finish_swig) + install(DIRECTORY ${CMAKE_BINARY_DIR}/${LLDB_PYTHON_RELATIVE_PATH}/ + DESTINATION ${LLDB_PYTHON_RELATIVE_PATH} + COMPONENT lldb-python-scripts) + if (NOT LLVM_ENABLE_IDE) + add_llvm_install_targets(install-lldb-python-scripts + COMPONENT lldb-python-scripts + DEPENDS lldb-python-scripts) endif() + 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 "") - # When using the Visual Studio CMake generator the lldb binaries end up in Release/bin, Debug/bin etc. - file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin" LLDB_BIN_DIR) - file(TO_NATIVE_PATH "${PYTHON_DLL}" PYTHON_DLL_NATIVE_PATH) - add_custom_command( - TARGET finish_swig - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${PYTHON_DLL_NATIVE_PATH} ${LLDB_BIN_DIR} VERBATIM - COMMENT "Copying Python DLL to LLDB binaries directory.") - 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 "") + # When using the Visual Studio CMake generator the lldb binaries end up in Release/bin, Debug/bin etc. + file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin" LLDB_BIN_DIR) + file(TO_NATIVE_PATH "${PYTHON_DLL}" PYTHON_DLL_NATIVE_PATH) + add_custom_command( + TARGET finish_swig + POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${PYTHON_DLL_NATIVE_PATH} ${LLDB_BIN_DIR} VERBATIM + COMMENT "Copying Python DLL to LLDB binaries directory.") + endif () endif () if(LLDB_BUILT_STANDALONE AND NOT LLVM_ENABLE_IDE) 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 @@ -245,284 +245,6 @@ return (bOk, strMsg) -#++--------------------------------------------------------------------------- -# Details: Make the symbolic link on a Windows platform. -# Args: vstrSrcFile - (R) Source file name. -# vstrTargetFile - (R) Destination file name. -# Returns: Bool - True = function success, False = failure. -# Str - Error description on task failure. -# Throws: None. -#-- - - -def make_symlink_windows(vstrSrcPath, vstrTargetPath): - print(("Making symlink from %s to %s" % (vstrSrcPath, vstrTargetPath))) - dbg = utilsDebug.CDebugFnVerbose("Python script make_symlink_windows()") - bOk = True - strErrMsg = "" - # If the src file doesn't exist, this is an error and we should throw. - src_stat = os.stat(vstrSrcPath) - - try: - target_stat = os.stat(vstrTargetPath) - # If the target file exists but refers to a different file, delete it so that we can - # re-create the link. This can happen if you run this script once (creating a link) - # and then delete the source file (so that a brand new file gets created the next time - # you compile and link), and then re-run this script, so that both the target hardlink - # and the source file exist, but the target refers to an old copy of - # the source. - if (target_stat.st_ino == src_stat.st_ino) and ( - target_stat.st_dev == src_stat.st_dev): - return (bOk, strErrMsg) - - os.remove(vstrTargetPath) - except: - # If the target file don't exist, ignore this exception, we will link - # it shortly. - pass - - try: - csl = ctypes.windll.kernel32.CreateHardLinkW - csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32) - csl.restype = ctypes.c_ubyte - if csl(vstrTargetPath, vstrSrcPath, 0) == 0: - raise ctypes.WinError() - except Exception as e: - if e.errno != 17: - bOk = False - strErrMsg = "WinError(%d): %s %s" % ( - e.errno, e.strerror, strErrMsgMakeSymlink) - strErrMsg += " Src:'%s' Target:'%s'" % ( - vstrSrcPath, vstrTargetPath) - - return (bOk, strErrMsg) - -#++--------------------------------------------------------------------------- -# Details: Make the symbolic link on a UNIX style platform. -# Args: vstrSrcFile - (R) Source file name. -# vstrTargetFile - (R) Destination file name. -# Returns: Bool - True = function success, False = failure. -# Str - Error description on task failure. -# Throws: None. -#-- - - -def make_symlink_other_platforms(vstrSrcPath, vstrTargetPath): - dbg = utilsDebug.CDebugFnVerbose( - "Python script make_symlink_other_platforms()") - bOk = True - strErrMsg = "" - - try: - os.symlink(vstrSrcPath, vstrTargetPath) - except OSError as e: - bOk = False - strErrMsg = "OSError(%d): %s %s" % ( - e.errno, e.strerror, strErrMsgMakeSymlink) - strErrMsg += " Src:'%s' Target:'%s'" % (vstrSrcPath, vstrTargetPath) - except: - bOk = False - strErrMsg = strErrMsgUnexpected % sys.exec_info()[0] - - return (bOk, strErrMsg) - - -def make_symlink_native(vDictArgs, strSrc, strTarget): - eOSType = utilsOsType.determine_os_type() - bDbg = "-d" in vDictArgs - bOk = True - strErrMsg = "" - - target_filename = os.path.basename(strTarget) - if eOSType == utilsOsType.EnumOsType.Unknown: - bOk = False - strErrMsg = strErrMsgOsTypeUnknown - elif eOSType == utilsOsType.EnumOsType.Windows: - if bDbg: - print((strMsgSymlinkMk % (target_filename, strSrc, strTarget))) - bOk, strErrMsg = make_symlink_windows(strSrc, - strTarget) - else: - if os.path.islink(strTarget): - if bDbg: - print((strMsgSymlinkExists % target_filename)) - return (bOk, strErrMsg) - if bDbg: - print((strMsgSymlinkMk % (target_filename, strSrc, strTarget))) - bOk, strErrMsg = make_symlink_other_platforms(strSrc, - strTarget) - - return (bOk, strErrMsg) - -#++--------------------------------------------------------------------------- -# Details: Make the symbolic link. -# Args: vDictArgs - (R) Program input parameters. -# vstrFrameworkPythonDir - (R) Python framework directory. -# vstrSrcFile - (R) Source file name. -# vstrTargetFile - (R) Destination file name. -# Returns: Bool - True = function success, False = failure. -# Str - Error description on task failure. -# Throws: None. -#-- - - -def make_symlink( - vDictArgs, - vstrFrameworkPythonDir, - vstrSrcFile, - vstrTargetFile): - dbg = utilsDebug.CDebugFnVerbose("Python script make_symlink()") - strTarget = os.path.join(vstrFrameworkPythonDir, vstrTargetFile) - strTarget = os.path.normcase(strTarget) - strSrc = "" - - os.chdir(vstrFrameworkPythonDir) - bMakeFileCalled = "-m" in vDictArgs - eOSType = utilsOsType.determine_os_type() - if not bMakeFileCalled: - strBuildDir = os.path.join("..", "..", "..") - else: - # Resolve vstrSrcFile path relatively the build directory - if eOSType == utilsOsType.EnumOsType.Windows: - # On a Windows platform the vstrFrameworkPythonDir looks like: - # llvm\\build\\Lib\\site-packages\\lldb - strBuildDir = os.path.join("..", "..", "..") - else: - # On a UNIX style platform the vstrFrameworkPythonDir looks like: - # llvm/build/lib/python2.7/site-packages/lldb - strBuildDir = os.path.join("..", "..", "..", "..") - strSrc = os.path.normcase(os.path.join(strBuildDir, vstrSrcFile)) - - return make_symlink_native(vDictArgs, strSrc, strTarget) - - -#++--------------------------------------------------------------------------- -# Details: Make the symbolic that the script bridge for Python will need in -# the Python framework directory. -# Args: vDictArgs - (R) Program input parameters. -# vstrFrameworkPythonDir - (R) Python framework directory. -# vstrLiblldbName - (R) File name for _lldb library. -# vstrLiblldbDir - (R) liblldb directory. -# Returns: Bool - True = function success, False = failure. -# Str - Error description on task failure. -# Throws: None. -#-- -def make_symlink_liblldb( - vDictArgs, - vstrFrameworkPythonDir, - vstrLiblldbFileName, - vstrLldbLibDir): - dbg = utilsDebug.CDebugFnVerbose("Python script make_symlink_liblldb()") - bOk = True - strErrMsg = "" - strTarget = vstrLiblldbFileName - strSrc = "" - - eOSType = utilsOsType.determine_os_type() - if eOSType == utilsOsType.EnumOsType.Windows: - # When importing an extension module using a debug version of python, you - # write, for example, "import foo", but the interpreter searches for - # "foo_d.pyd" - if is_debug_interpreter(): - strTarget += "_d" - strTarget += ".pyd" - else: - strTarget += ".so" - - bMakeFileCalled = "-m" in vDictArgs - if not bMakeFileCalled: - strSrc = "LLDB" - else: - strLibFileExtn = "" - if eOSType == utilsOsType.EnumOsType.Windows: - strSrc = os.path.join("bin", "liblldb.dll") - else: - if eOSType == utilsOsType.EnumOsType.Darwin: - strLibFileExtn = ".dylib" - else: - strLibFileExtn = ".so" - strSrc = os.path.join(vstrLldbLibDir, "liblldb" + strLibFileExtn) - - bOk, strErrMsg = make_symlink( - vDictArgs, vstrFrameworkPythonDir, strSrc, strTarget) - - return (bOk, strErrMsg) - -#++--------------------------------------------------------------------------- -# Details: Make the symbolic link to the lldb-argdumper. -# Args: vDictArgs - (R) Program input parameters. -# vstrFrameworkPythonDir - (R) Python framework directory. -# vstrArgdumperFileName - (R) File name for lldb-argdumper. -# Returns: Bool - True = function success, False = failure. -# Str - Error description on task failure. -# Throws: None. -#-- - - -def make_symlink_lldb_argdumper( - vDictArgs, - vstrFrameworkPythonDir, - vstrArgdumperFileName): - dbg = utilsDebug.CDebugFnVerbose( - "Python script make_symlink_lldb_argdumper()") - bOk = True - strErrMsg = "" - strTarget = vstrArgdumperFileName - strSrc = "" - - eOSType = utilsOsType.determine_os_type() - if eOSType == utilsOsType.EnumOsType.Windows: - strTarget += ".exe" - - bMakeFileCalled = "-m" in vDictArgs - if not bMakeFileCalled: - return (bOk, strErrMsg) - else: - strExeFileExtn = "" - if eOSType == utilsOsType.EnumOsType.Windows: - strExeFileExtn = ".exe" - strSrc = os.path.join("bin", "lldb-argdumper" + strExeFileExtn) - - bOk, strErrMsg = make_symlink( - vDictArgs, vstrFrameworkPythonDir, strSrc, strTarget) - - return (bOk, strErrMsg) - -#++--------------------------------------------------------------------------- -# Details: Make the symlink that the script bridge for Python will need in -# the Python framework directory. -# Args: vDictArgs - (R) Program input parameters. -# vstrFrameworkPythonDir - (R) Python framework directory. -# vstrLldbLibDir - (R) liblldb directory. -# Returns: Bool - True = function success, False = failure. -# strErrMsg - Error description on task failure. -# Throws: None. -#-- - - -def create_symlinks(vDictArgs, vstrFrameworkPythonDir, vstrLldbLibDir): - dbg = utilsDebug.CDebugFnVerbose("Python script create_symlinks()") - bOk = True - strErrMsg = "" - eOSType = utilsOsType.determine_os_type() - - # Make symlink for _lldb - strLibLldbFileName = "_lldb" - if bOk: - bOk, strErrMsg = make_symlink_liblldb(vDictArgs, - vstrFrameworkPythonDir, - strLibLldbFileName, - vstrLldbLibDir) - - # Make symlink for lldb-argdumper - strArgdumperFileName = "lldb-argdumper" - if bOk: - bOk, strErrMsg = make_symlink_lldb_argdumper(vDictArgs, - vstrFrameworkPythonDir, - strArgdumperFileName) - - return (bOk, strErrMsg) - def copy_six(vDictArgs, vstrFrameworkPythonDir): dbg = utilsDebug.CDebugFnVerbose("Python script copy_six()") @@ -723,10 +445,6 @@ bOk, strMsg = find_or_create_python_dir( vDictArgs, strFrameworkPythonDir) - if bOk: - bOk, strMsg = create_symlinks( - vDictArgs, strFrameworkPythonDir, strLldbLibDir) - bUseSystemSix = "--useSystemSix" in vDictArgs if not bUseSystemSix and bOk: