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

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Thu Dec 4 15:38:31 PST 2025


https://github.com/JDevlieghere updated https://github.com/llvm/llvm-project/pull/170772

>From 38d27e4313ba38b5a54ffaab2ee68f53b21a3f2e Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 4 Dec 2025 12:00:11 -0800
Subject: [PATCH 1/3] Move GetBuildConfiguration from SBDebugger -> Debugger

---
 lldb/include/lldb/Core/Debugger.h |  3 ++
 lldb/source/API/SBDebugger.cpp    | 52 +----------------------------
 lldb/source/Core/Debugger.cpp     | 55 +++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 51 deletions(-)

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/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;
+}

>From 21a2aac5e5456f9181384406f3b3fcad621a7076 Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 4 Dec 2025 15:27:27 -0800
Subject: [PATCH 2/3] [lldb] Dump build configuration with `version -v`

Add a verbose option to the `help` 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 is more
discoverable.

Fixes #170727
---
 lldb/source/Commands/CommandObjectVersion.cpp | 52 ++++++++++++++++++-
 lldb/source/Commands/CommandObjectVersion.h   | 40 +++++++++++++-
 lldb/source/Commands/Options.td               |  5 ++
 3 files changed, 94 insertions(+), 3 deletions(-)

diff --git a/lldb/source/Commands/CommandObjectVersion.cpp b/lldb/source/Commands/CommandObjectVersion.cpp
index f13ec18e240c0..e4e37e3b06d9a 100644
--- a/lldb/source/Commands/CommandObjectVersion.cpp
+++ b/lldb/source/Commands/CommandObjectVersion.cpp
@@ -8,13 +8,20 @@
 
 #include "CommandObjectVersion.h"
 
+#include "lldb/Core/Debugger.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
 #include "lldb/Version/Version.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 +29,50 @@ CommandObjectVersion::CommandObjectVersion(CommandInterpreter &interpreter)
 
 CommandObjectVersion::~CommandObjectVersion() = default;
 
+// Dump the array values on a single line.
+static void dump(const StructuredData::Array &array, Stream &s) {
+  s << '[';
+
+  bool add_separator = false;
+  array.ForEach([&](StructuredData::Object *object) -> bool {
+    if (add_separator)
+      s << ", ";
+    s << object->GetStringValue();
+    add_separator = true;
+    return true;
+  });
+
+  s << ']';
+}
+
+// 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 ed061312e2bb4..4abdbf3e596fd 100644
--- a/lldb/source/Commands/Options.td
+++ b/lldb/source/Commands/Options.td
@@ -2432,3 +2432,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.">;
+}

>From 8b90d98257abbbe30d50f9556cf060c8d9e6ab9c Mon Sep 17 00:00:00 2001
From: Jonas Devlieghere <jonas at devlieghere.com>
Date: Thu, 4 Dec 2025 15:38:18 -0800
Subject: [PATCH 3/3] Add test

---
 lldb/test/Shell/Commands/command-version.test | 6 ++++++
 1 file changed, 6 insertions(+)
 create mode 100644 lldb/test/Shell/Commands/command-version.test

diff --git a/lldb/test/Shell/Commands/command-version.test b/lldb/test/Shell/Commands/command-version.test
new file mode 100644
index 0000000000000..ccd7bc7e8fd76
--- /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:
+CHECK: python:
+CHECK: targets: [{{.*}}]



More information about the lldb-commits mailing list