Index: .gitignore =================================================================== --- .gitignore +++ .gitignore @@ -63,3 +63,5 @@ /clang/utils/analyzer/projects/*/PatchedSource /clang/utils/analyzer/projects/*/ScanBuildResults /clang/utils/analyzer/projects/*/RefScanBuildResults +# automodapi generates temporary files here. +/lldb/docs/python_api/api/ Index: lldb/docs/CMakeLists.txt =================================================================== --- lldb/docs/CMakeLists.txt +++ lldb/docs/CMakeLists.txt @@ -15,60 +15,43 @@ ) endif() -if (LLDB_ENABLE_PYTHON) - find_program(EPYDOC_EXECUTABLE NAMES epydoc epydoc.py) - if(EPYDOC_EXECUTABLE) - message(STATUS "Found epydoc - ${EPYDOC_EXECUTABLE}") - - find_program(DOT_EXECUTABLE dot) - if(DOT_EXECUTABLE) - set(EPYDOC_OPTIONS ${EPYDOC_OPTIONS} --graph all --dotpath ${DOT_EXECUTABLE}) - message(STATUS "Found dot - ${DOT_EXECUTABLE}") - endif() - - # Pretend to make a python package so that we can generate the reference. - # Because we don't build liblldb, epydoc will complain that the import of - # _lldb.so failed, but that doesn't prevent it from generating the docs. - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lldb) - get_target_property(lldb_bindings_dir swig_wrapper_python BINARY_DIR) - add_custom_target(lldb-python-doc-package - COMMAND "${CMAKE_COMMAND}" -E copy "${lldb_bindings_dir}/lldb.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/__init__.py" - COMMENT "Copying lldb.py to pretend package.") - add_dependencies(lldb-python-doc-package swig_wrapper_python) +if (LLVM_ENABLE_SPHINX) + include(AddSphinxTarget) +endif() - set(DOC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/doc") - file(MAKE_DIRECTORY "${DOC_DIR}") - add_custom_target(lldb-python-doc - ${EPYDOC_EXECUTABLE} - --html - lldb - -o ${CMAKE_CURRENT_BINARY_DIR}/python_reference - --name "LLDB python API" - --url "http://lldb.llvm.org" - ${EPYDOC_OPTIONS} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Generating LLDB Python API reference with epydoc" VERBATIM - ) - add_dependencies(lldb-python-doc swig_wrapper_python lldb-python-doc-package) - else() - message(STATUS "Could NOT find epydoc") - endif() +if (LLDB_ENABLE_PYTHON AND SPHINX_FOUND) + # Pretend that the SWIG generated API is a Python package. + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lldb) + get_target_property(lldb_bindings_dir swig_wrapper_python BINARY_DIR) + add_custom_target(lldb-python-doc-package + COMMAND "${CMAKE_COMMAND}" -E copy "${lldb_bindings_dir}/lldb.py" "${CMAKE_CURRENT_BINARY_DIR}/lldb/__init__.py" + COMMENT "Copying lldb.py to pretend its a Python package.") + add_dependencies(lldb-python-doc-package swig_wrapper_python) + + # Let sphinx generate the Python API reference. + # The sphinx config needs to know where the generated LLDB module is. + # There doesn't seem a way to pass pass parameters to the conf.py script, + # so pass the path to the module via the LLDB_SWIG_MODULE environment variable. + add_custom_target(lldb-python-doc + ${CMAKE_COMMAND} -E env "LLDB_SWIG_MODULE=${CMAKE_CURRENT_BINARY_DIR}" + ${SPHINX_EXECUTABLE} -M html "${CMAKE_CURRENT_SOURCE_DIR}/python_api" "${CMAKE_CURRENT_BINARY_DIR}/python_reference/" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Generating LLDB Python API reference" VERBATIM + ) + add_dependencies(lldb-python-doc swig_wrapper_python lldb-python-doc-package) endif () -if (LLVM_ENABLE_SPHINX) - include(AddSphinxTarget) - if (SPHINX_FOUND) - if (${SPHINX_OUTPUT_HTML}) - add_sphinx_target(html lldb) - # Sphinx does not reliably update the custom CSS files, so force - # a clean rebuild of the documentation every time. - add_custom_target(clean-lldb-html COMMAND "${CMAKE_COMMAND}" -E - remove_directory ${CMAKE_CURRENT_BINARY_DIR}/html) - add_dependencies(docs-lldb-html clean-lldb-html) - endif() +if (SPHINX_FOUND) + if (${SPHINX_OUTPUT_HTML}) + add_sphinx_target(html lldb) + # Sphinx does not reliably update the custom CSS files, so force + # a clean rebuild of the documentation every time. + add_custom_target(clean-lldb-html COMMAND "${CMAKE_COMMAND}" -E + remove_directory ${CMAKE_CURRENT_BINARY_DIR}/html) + add_dependencies(docs-lldb-html clean-lldb-html) + endif() - if (${SPHINX_OUTPUT_MAN}) - add_sphinx_target(man lldb) - endif() + if (${SPHINX_OUTPUT_MAN}) + add_sphinx_target(man lldb) endif() endif() Index: lldb/docs/_lldb/__init__.py =================================================================== --- /dev/null +++ lldb/docs/_lldb/__init__.py @@ -0,0 +1,9 @@ +from unittest.mock import Mock +import sys +import types + +# This package acts as a mock implementation of the native _lldb module so +# that generating the LLDB documentation doesn't actually require building all +# of LLDB. +module_name = '_lldb' +sys.modules[module_name] = Mock() Index: lldb/docs/python_api/conf.py =================================================================== --- /dev/null +++ lldb/docs/python_api/conf.py @@ -0,0 +1,19 @@ +# Minimal sphinx configuration for generating LLDB's Python API reference. + +import os +import sys +# Add the parent directory that contains the mock _lldb native module which +# is imported by the `lldb` module. +sys.path.insert(0, os.path.abspath("..")) +# Add the build directory that contains the `lldb` module. LLDB_SWIG_MODULE is +# set by CMake. +sys.path.insert(0, os.getenv("LLDB_SWIG_MODULE")) + +project = 'LLDB Python API' +copyright = '2021, The LLDB Team' +author = 'The LLDB Team' + +extensions = ['sphinx_automodapi.automodapi'] + +exclude_patterns = [] +html_theme = 'sphinxdoc' Index: lldb/docs/python_api/index.rst =================================================================== --- /dev/null +++ lldb/docs/python_api/index.rst @@ -0,0 +1,102 @@ +LLDB Python API +================================ + +.. + The long list of "skip" filters out several global functions that are + generated by SWIG (but which are not useful as they are only the + backend for their respective static functions in the classes). + Without this list +.. automodapi:: lldb + :no-inheritance-diagram: + :skip: SBBreakpoint_EventIsBreakpointEvent + :skip: SBBreakpoint_GetBreakpointEventTypeFromEvent + :skip: SBBreakpoint_GetBreakpointFromEvent + :skip: SBBreakpoint_GetBreakpointLocationAtIndexFromEvent + :skip: SBBreakpoint_GetNumBreakpointLocationsFromEvent + :skip: SBCommandInterpreter_EventIsCommandInterpreterEvent + :skip: SBCommandInterpreter_GetArgumentDescriptionAsCString + :skip: SBCommandInterpreter_GetArgumentTypeAsCString + :skip: SBCommandInterpreter_GetBroadcasterClass + :skip: SBCommunication_GetBroadcasterClass + :skip: SBData_CreateDataFromCString + :skip: SBData_CreateDataFromDoubleArray + :skip: SBData_CreateDataFromSInt + :skip: SBData_CreateDataFromSInt + :skip: SBData_CreateDataFromUInt + :skip: SBData_CreateDataFromUInt + :skip: SBData_CreateDataFromSInt32Array + :skip: SBData_CreateDataFromSInt64Array + :skip: SBData_CreateDataFromUInt32Array + :skip: SBData_CreateDataFromUInt64Array + :skip: SBDebugger_Create + :skip: SBDebugger_Create + :skip: SBDebugger_Destroy + :skip: SBDebugger_FindDebuggerWithID + :skip: SBDebugger_GetBuildConfiguration + :skip: SBDebugger_GetDefaultArchitecture + :skip: SBDebugger_GetInternalVariableValue + :skip: SBDebugger_GetVersionString + :skip: SBDebugger_Initialize + :skip: SBDebugger_InitializeWithErrorHandling + :skip: SBDebugger_MemoryPressureDetected + :skip: SBDebugger_SetDefaultArchitecture + :skip: SBDebugger_SetInternalVariable + :skip: SBDebugger_StateAsCString + :skip: SBDebugger_StateIsRunningState + :skip: SBDebugger_StateIsStoppedState + :skip: SBDebugger_Terminate + :skip: SBEvent_GetCStringFromEvent + :skip: SBFileSpec_ResolvePath + :skip: SBFile_MakeBorrowed + :skip: SBFile_MakeBorrowedForcingIOMethods + :skip: SBFile_MakeForcingIOMethods + :skip: SBHostOS_GetLLDBPath + :skip: SBHostOS_GetLLDBPythonPath + :skip: SBHostOS_GetProgramFileSpec + :skip: SBHostOS_GetUserHomeDirectory + :skip: SBHostOS_ThreadCancel + :skip: SBHostOS_ThreadCreate + :skip: SBHostOS_ThreadCreated + :skip: SBHostOS_ThreadDetach + :skip: SBHostOS_ThreadJoin + :skip: SBLanguageRuntime_GetLanguageTypeFromString + :skip: SBLanguageRuntime_GetNameForLanguageType + :skip: SBModuleSpecList_GetModuleSpecifications + :skip: SBModule_GarbageCollectAllocatedModules + :skip: SBModule_GetNumberAllocatedModules + :skip: SBPlatform_GetHostPlatform + :skip: SBProcess_EventIsProcessEvent + :skip: SBProcess_EventIsStructuredDataEvent + :skip: SBProcess_GetBroadcasterClassName + :skip: SBProcess_GetInterruptedFromEvent + :skip: SBProcess_GetNumRestartedReasonsFromEvent + :skip: SBProcess_GetProcessFromEvent + :skip: SBProcess_GetRestartedFromEvent + :skip: SBProcess_GetRestartedReasonAtIndexFromEvent + :skip: SBProcess_GetStateFromEvent + :skip: SBProcess_GetStructuredDataFromEvent + :skip: SBReproducer_Capture + :skip: SBReproducer_PassiveReplay + :skip: SBReproducer_SetAutoGenerate + :skip: SBReproducer_SetWorkingDirectory + :skip: SBTarget_EventIsTargetEvent + :skip: SBTarget_GetBroadcasterClassName + :skip: SBTarget_GetModuleAtIndexFromEvent + :skip: SBTarget_GetNumModulesFromEvent + :skip: SBTarget_GetTargetFromEvent + :skip: SBThread_EventIsThreadEvent + :skip: SBThread_GetBroadcasterClassName + :skip: SBThread_GetStackFrameFromEvent + :skip: SBThread_GetThreadFromEvent + :skip: SBTypeSummary_CreateWithFunctionName + :skip: SBTypeSummary_CreateWithScriptCode + :skip: SBTypeSummary_CreateWithSummaryString + :skip: SBTypeSynthetic_CreateWithClassName + :skip: SBTypeSynthetic_CreateWithScriptCode + :skip: SBWatchpoint_EventIsWatchpointEvent + :skip: SBWatchpoint_GetWatchpointEventTypeFromEvent + :skip: SBWatchpoint_GetWatchpointFromEvent + :skip: command + :skip: in_range + :skip: is_numeric_type + :skip: lldb_iter