[Lldb-commits] [lldb] bc9f96a - [lldb] Dump build configuration with `version -v` (#170772)

via lldb-commits lldb-commits at lists.llvm.org
Mon Dec 8 10:11:43 PST 2025


Author: Jonas Devlieghere
Date: 2025-12-08T10:11:39-08:00
New Revision: bc9f96a5e62d0b89588092343d137995811a9b80

URL: https://github.com/llvm/llvm-project/commit/bc9f96a5e62d0b89588092343d137995811a9b80
DIFF: https://github.com/llvm/llvm-project/commit/bc9f96a5e62d0b89588092343d137995811a9b80.diff

LOG: [lldb] Dump build configuration with `version -v` (#170772)

Add a verbose option to the version command and include the "build
configuration" in the command output. This allows users to quickly
identify if their version of LLDB was built with support for
xml/curl/python/lua etc. This data is already available through the SB
API using SBDebugger::GetBuildConfiguration, but this makes it more
discoverable.

```
(lldb) version -v
lldb version 22.0.0git (git at github.com:llvm/llvm-project.git revision 21a2aac5e5456f9181384406f3b3fcad621a7076)
  clang revision 21a2aac5e5456f9181384406f3b3fcad621a7076
  llvm revision 21a2aac5e5456f9181384406f3b3fcad621a7076
  editline_wchar: yes
  lzma: yes
  curses: yes
  editline: yes
  fbsdvmcore: yes
  xml: yes
  lua: yes
  python: yes
  targets: [AArch64, AMDGPU, ARM, AVR, BPF, Hexagon, Lanai, LoongArch, Mips, MSP430, NVPTX, PowerPC, RISCV, Sparc, SPIRV, SystemZ, VE, WebAssembly, X86, XCore]
  curl: yes
```

Resolves #170727

Added: 
    lldb/test/Shell/Commands/command-version.test

Modified: 
    lldb/include/lldb/Core/Debugger.h
    lldb/source/API/SBDebugger.cpp
    lldb/source/Commands/CommandObjectVersion.cpp
    lldb/source/Commands/CommandObjectVersion.h
    lldb/source/Commands/Options.td
    lldb/source/Core/Debugger.cpp

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Core/Debugger.h b/lldb/include/lldb/Core/Debugger.h
index ead2ed35fadd4..a39413c06340c 100644
--- a/lldb/include/lldb/Core/Debugger.h
+++ b/lldb/include/lldb/Core/Debugger.h
@@ -107,6 +107,9 @@ class Debugger : public std::enable_shared_from_this<Debugger>,
 
   static void Destroy(lldb::DebuggerSP &debugger_sp);
 
+  /// Get the build configuration as structured data.
+  static StructuredData::DictionarySP GetBuildConfiguration();
+
   static lldb::DebuggerSP FindDebuggerWithID(lldb::user_id_t id);
 
   static lldb::DebuggerSP

diff  --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
index f939955ba57c8..3f34e7acb0673 100644
--- a/lldb/source/API/SBDebugger.cpp
+++ b/lldb/source/API/SBDebugger.cpp
@@ -709,61 +709,11 @@ const char *SBDebugger::StateAsCString(StateType state) {
   return lldb_private::StateAsCString(state);
 }
 
-static void AddBoolConfigEntry(StructuredData::Dictionary &dict,
-                               llvm::StringRef name, bool value,
-                               llvm::StringRef description) {
-  auto entry_up = std::make_unique<StructuredData::Dictionary>();
-  entry_up->AddBooleanItem("value", value);
-  entry_up->AddStringItem("description", description);
-  dict.AddItem(name, std::move(entry_up));
-}
-
-static void AddLLVMTargets(StructuredData::Dictionary &dict) {
-  auto array_up = std::make_unique<StructuredData::Array>();
-#define LLVM_TARGET(target)                                                    \
-  array_up->AddItem(std::make_unique<StructuredData::String>(#target));
-#include "llvm/Config/Targets.def"
-  auto entry_up = std::make_unique<StructuredData::Dictionary>();
-  entry_up->AddItem("value", std::move(array_up));
-  entry_up->AddStringItem("description", "A list of configured LLVM targets.");
-  dict.AddItem("targets", std::move(entry_up));
-}
-
 SBStructuredData SBDebugger::GetBuildConfiguration() {
   LLDB_INSTRUMENT();
 
-  auto config_up = std::make_unique<StructuredData::Dictionary>();
-  AddBoolConfigEntry(
-      *config_up, "xml", XMLDocument::XMLEnabled(),
-      "A boolean value that indicates if XML support is enabled in LLDB");
-  AddBoolConfigEntry(
-      *config_up, "curl", LLVM_ENABLE_CURL,
-      "A boolean value that indicates if CURL support is enabled in LLDB");
-  AddBoolConfigEntry(
-      *config_up, "curses", LLDB_ENABLE_CURSES,
-      "A boolean value that indicates if curses support is enabled in LLDB");
-  AddBoolConfigEntry(
-      *config_up, "editline", LLDB_ENABLE_LIBEDIT,
-      "A boolean value that indicates if editline support is enabled in LLDB");
-  AddBoolConfigEntry(*config_up, "editline_wchar", LLDB_EDITLINE_USE_WCHAR,
-                     "A boolean value that indicates if editline wide "
-                     "characters support is enabled in LLDB");
-  AddBoolConfigEntry(
-      *config_up, "lzma", LLDB_ENABLE_LZMA,
-      "A boolean value that indicates if lzma support is enabled in LLDB");
-  AddBoolConfigEntry(
-      *config_up, "python", LLDB_ENABLE_PYTHON,
-      "A boolean value that indicates if python support is enabled in LLDB");
-  AddBoolConfigEntry(
-      *config_up, "lua", LLDB_ENABLE_LUA,
-      "A boolean value that indicates if lua support is enabled in LLDB");
-  AddBoolConfigEntry(*config_up, "fbsdvmcore", LLDB_ENABLE_FBSDVMCORE,
-                     "A boolean value that indicates if fbsdvmcore support is "
-                     "enabled in LLDB");
-  AddLLVMTargets(*config_up);
-
   SBStructuredData data;
-  data.m_impl_up->SetObjectSP(std::move(config_up));
+  data.m_impl_up->SetObjectSP(Debugger::GetBuildConfiguration());
   return data;
 }
 

diff  --git a/lldb/source/Commands/CommandObjectVersion.cpp b/lldb/source/Commands/CommandObjectVersion.cpp
index f13ec18e240c0..fb7e399eb7260 100644
--- a/lldb/source/Commands/CommandObjectVersion.cpp
+++ b/lldb/source/Commands/CommandObjectVersion.cpp
@@ -8,13 +8,21 @@
 
 #include "CommandObjectVersion.h"
 
+#include "lldb/Core/Debugger.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Version/Version.h"
+#include "llvm/ADT/StringExtras.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
-// CommandObjectVersion
+#define LLDB_OPTIONS_version
+#include "CommandOptions.inc"
+
+llvm::ArrayRef<OptionDefinition>
+CommandObjectVersion::CommandOptions::GetDefinitions() {
+  return llvm::ArrayRef(g_version_options);
+}
 
 CommandObjectVersion::CommandObjectVersion(CommandInterpreter &interpreter)
     : CommandObjectParsed(interpreter, "version",
@@ -22,7 +30,45 @@ CommandObjectVersion::CommandObjectVersion(CommandInterpreter &interpreter)
 
 CommandObjectVersion::~CommandObjectVersion() = default;
 
+// Dump the array values on a single line.
+static void dump(const StructuredData::Array &array, Stream &s) {
+  std::vector<std::string> values;
+  array.ForEach([&](StructuredData::Object *object) -> bool {
+    values.emplace_back(object->GetStringValue().str());
+    return true;
+  });
+
+  s << '[' << llvm::join(values, ", ") << ']';
+}
+
+// The default dump output is too verbose.
+static void dump(const StructuredData::Dictionary &config, Stream &s) {
+  config.ForEach(
+      [&](llvm::StringRef key, StructuredData::Object *object) -> bool {
+        assert(object);
+
+        StructuredData::Dictionary *value_dict = object->GetAsDictionary();
+        assert(value_dict);
+
+        StructuredData::ObjectSP value_sp = value_dict->GetValueForKey("value");
+        assert(value_sp);
+
+        s << "  " << key << ": ";
+        if (StructuredData::Boolean *boolean = value_sp->GetAsBoolean())
+          s << (boolean ? "yes" : "no");
+        else if (StructuredData::Array *array = value_sp->GetAsArray())
+          dump(*array, s);
+        s << '\n';
+
+        return true;
+      });
+}
+
 void CommandObjectVersion::DoExecute(Args &args, CommandReturnObject &result) {
   result.AppendMessageWithFormat("%s\n", lldb_private::GetVersion());
+
+  if (m_options.verbose)
+    dump(*Debugger::GetBuildConfiguration(), result.GetOutputStream());
+
   result.SetStatus(eReturnStatusSuccessFinishResult);
 }

diff  --git a/lldb/source/Commands/CommandObjectVersion.h b/lldb/source/Commands/CommandObjectVersion.h
index 4ba081bf8706d..ea2741c8c79c4 100644
--- a/lldb/source/Commands/CommandObjectVersion.h
+++ b/lldb/source/Commands/CommandObjectVersion.h
@@ -9,20 +9,56 @@
 #ifndef LLDB_SOURCE_COMMANDS_COMMANDOBJECTVERSION_H
 #define LLDB_SOURCE_COMMANDS_COMMANDOBJECTVERSION_H
 
+#include "lldb/Host/OptionParser.h"
 #include "lldb/Interpreter/CommandObject.h"
+#include "lldb/Interpreter/Options.h"
 
 namespace lldb_private {
 
-// CommandObjectVersion
-
 class CommandObjectVersion : public CommandObjectParsed {
 public:
   CommandObjectVersion(CommandInterpreter &interpreter);
 
   ~CommandObjectVersion() override;
 
+  class CommandOptions : public Options {
+  public:
+    CommandOptions() = default;
+
+    ~CommandOptions() override = default;
+
+    Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
+                          ExecutionContext *execution_context) override {
+      Status error;
+      const int short_option = m_getopt_table[option_idx].val;
+
+      switch (short_option) {
+      case 'v':
+        verbose = true;
+        break;
+      default:
+        llvm_unreachable("Unimplemented option");
+      }
+
+      return error;
+    }
+
+    void OptionParsingStarting(ExecutionContext *execution_context) override {
+      verbose = false;
+    }
+
+    llvm::ArrayRef<OptionDefinition> GetDefinitions() override;
+
+    bool verbose;
+  };
+
+  Options *GetOptions() override { return &m_options; }
+
 protected:
   void DoExecute(Args &args, CommandReturnObject &result) override;
+
+private:
+  CommandOptions m_options;
 };
 
 } // namespace lldb_private

diff  --git a/lldb/source/Commands/Options.td b/lldb/source/Commands/Options.td
index b5c48ffaa6101..d96354a39b8b8 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -2558,3 +2558,8 @@ let Command = "statistics dump" in {
              "enabled state. Defaults to true for both summary and default "
              "mode.">;
 }
+
+let Command = "version" in {
+  def version_verbose : Option<"verbose", "v">,
+                        Desc<"Include build configuration in version output.">;
+}

diff  --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index 02f38e9094ec5..99f4a728e3f17 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -21,12 +21,14 @@
 #include "lldb/Core/Telemetry.h"
 #include "lldb/DataFormatters/DataVisualization.h"
 #include "lldb/Expression/REPL.h"
+#include "lldb/Host/Config.h"
 #include "lldb/Host/File.h"
 #include "lldb/Host/FileSystem.h"
 #include "lldb/Host/HostInfo.h"
 #include "lldb/Host/StreamFile.h"
 #include "lldb/Host/Terminal.h"
 #include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/XML.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Interpreter/OptionValue.h"
@@ -2442,3 +2444,56 @@ llvm::ThreadPoolInterface &Debugger::GetThreadPool() {
          "Debugger::GetThreadPool called before Debugger::Initialize");
   return *g_thread_pool;
 }
+
+static void AddBoolConfigEntry(StructuredData::Dictionary &dict,
+                               llvm::StringRef name, bool value,
+                               llvm::StringRef description) {
+  auto entry_up = std::make_unique<StructuredData::Dictionary>();
+  entry_up->AddBooleanItem("value", value);
+  entry_up->AddStringItem("description", description);
+  dict.AddItem(name, std::move(entry_up));
+}
+
+static void AddLLVMTargets(StructuredData::Dictionary &dict) {
+  auto array_up = std::make_unique<StructuredData::Array>();
+#define LLVM_TARGET(target)                                                    \
+  array_up->AddItem(std::make_unique<StructuredData::String>(#target));
+#include "llvm/Config/Targets.def"
+  auto entry_up = std::make_unique<StructuredData::Dictionary>();
+  entry_up->AddItem("value", std::move(array_up));
+  entry_up->AddStringItem("description", "A list of configured LLVM targets.");
+  dict.AddItem("targets", std::move(entry_up));
+}
+
+StructuredData::DictionarySP Debugger::GetBuildConfiguration() {
+  auto config_up = std::make_unique<StructuredData::Dictionary>();
+  AddBoolConfigEntry(
+      *config_up, "xml", XMLDocument::XMLEnabled(),
+      "A boolean value that indicates if XML support is enabled in LLDB");
+  AddBoolConfigEntry(
+      *config_up, "curl", LLVM_ENABLE_CURL,
+      "A boolean value that indicates if CURL support is enabled in LLDB");
+  AddBoolConfigEntry(
+      *config_up, "curses", LLDB_ENABLE_CURSES,
+      "A boolean value that indicates if curses support is enabled in LLDB");
+  AddBoolConfigEntry(
+      *config_up, "editline", LLDB_ENABLE_LIBEDIT,
+      "A boolean value that indicates if editline support is enabled in LLDB");
+  AddBoolConfigEntry(*config_up, "editline_wchar", LLDB_EDITLINE_USE_WCHAR,
+                     "A boolean value that indicates if editline wide "
+                     "characters support is enabled in LLDB");
+  AddBoolConfigEntry(
+      *config_up, "lzma", LLDB_ENABLE_LZMA,
+      "A boolean value that indicates if lzma support is enabled in LLDB");
+  AddBoolConfigEntry(
+      *config_up, "python", LLDB_ENABLE_PYTHON,
+      "A boolean value that indicates if python support is enabled in LLDB");
+  AddBoolConfigEntry(
+      *config_up, "lua", LLDB_ENABLE_LUA,
+      "A boolean value that indicates if lua support is enabled in LLDB");
+  AddBoolConfigEntry(*config_up, "fbsdvmcore", LLDB_ENABLE_FBSDVMCORE,
+                     "A boolean value that indicates if fbsdvmcore support is "
+                     "enabled in LLDB");
+  AddLLVMTargets(*config_up);
+  return config_up;
+}

diff  --git a/lldb/test/Shell/Commands/command-version.test b/lldb/test/Shell/Commands/command-version.test
new file mode 100644
index 0000000000000..b13ab96719e30
--- /dev/null
+++ b/lldb/test/Shell/Commands/command-version.test
@@ -0,0 +1,6 @@
+RUN: %lldb -b -o 'version -v' | FileCheck %s
+
+CHECK: lldb version
+CHECK: xml: {{yes|no}}
+CHECK: python: {{yes|no}}
+CHECK: targets: [{{.*}}]


        


More information about the lldb-commits mailing list