kwk updated this revision to Diff 251086.
kwk added a comment.
Herald added a reviewer: jdoerfert.
- Added debuginfod2.py
- after running: autopep8 --in-place --aggressive --aggressive debuginfod2.py
- exponential backoff implemented
- Added http.py with doctests
- autopep8 --in-place --aggressive http.py
- change import
- Removed simulated startup time
- fixup
- Changed wording
- Using os.path.abspath on directory before using it
- Fixups
- Fixups
- Fixups
- hide port and hostname from ServeDirectoryWithHTTP
- lit test working for debuginfod and source list
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D75750/new/
https://reviews.llvm.org/D75750
Files:
lldb/cmake/modules/FindDebuginfod.cmake
lldb/cmake/modules/LLDBConfig.cmake
lldb/include/lldb/Host/Config.h.cmake
lldb/include/lldb/Host/DebugInfoD.h
lldb/packages/Python/lldbsuite/test/httpserver.py
lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/source/Core/SourceManager.cpp
lldb/source/Host/CMakeLists.txt
lldb/source/Host/common/DebugInfoD.cpp
lldb/test/Shell/SymbolFile/DWARF/source-list.cpp
lldb/test/Shell/lit.cfg.py
lldb/test/Shell/lit.site.cfg.py.in
Index: lldb/test/Shell/lit.site.cfg.py.in
===================================================================
--- lldb/test/Shell/lit.site.cfg.py.in
+++ lldb/test/Shell/lit.site.cfg.py.in
@@ -16,6 +16,7 @@
config.python_executable = "@PYTHON_EXECUTABLE@"
config.have_zlib = @LLVM_ENABLE_ZLIB@
config.lldb_enable_lzma = @LLDB_ENABLE_LZMA@
+config.lldb_enable_debuginfod = @LLDB_ENABLE_DEBUGINFOD@
config.host_triple = "@LLVM_HOST_TRIPLE@"
config.lldb_bitness = 64 if @LLDB_IS_64_BITS@ else 32
config.lldb_enable_python = @LLDB_ENABLE_PYTHON@
Index: lldb/test/Shell/lit.cfg.py
===================================================================
--- lldb/test/Shell/lit.cfg.py
+++ lldb/test/Shell/lit.cfg.py
@@ -117,6 +117,9 @@
if config.lldb_enable_lzma:
config.available_features.add('lzma')
+if config.lldb_enable_debuginfod:
+ config.available_features.add('debuginfod')
+
if find_executable('xz') != None:
config.available_features.add('xz')
Index: lldb/test/Shell/SymbolFile/DWARF/source-list.cpp
===================================================================
--- /dev/null
+++ lldb/test/Shell/SymbolFile/DWARF/source-list.cpp
@@ -0,0 +1,121 @@
+// clang-format off
+// REQUIRES: debuginfod
+// UNSUPPORTED: darwin, windows
+
+//------------------------------------------------------------------------------
+// Test Purpose:
+// =============
+// Test that we can display the source of functions using debuginfod when the
+// original source file is no longer present.
+//
+// The debuginfod client requires a buildid in the binary, so we compile one in.
+// We can create the directory structure on disc that the client expects on a
+// webserver that serves source files. Then we fire up a python based http
+// server in the root of that mock directory, set the DEBUGINFOD_URLS
+// environment variable and let LLDB do the rest.
+//
+// Go here to find more about debuginfod:
+// https://sourceware.org/elfutils/Debuginfod.html
+//------------------------------------------------------------------------------
+
+// We copy this file because we want to compile and later move it away
+// ===================================================================
+// RUN: mkdir -p %t.buildroot
+// RUN: cp %s %t.buildroot/test.cpp
+
+// We cd into the directory before compiling to get DW_AT_comp_dir pickup
+// %t.buildroot as well so it will be replaced by /my/new/path.
+// =======================================================================
+// RUN: cd %t.buildroot
+// RUN: %clang_host \
+// RUN: -g \
+// RUN: -Wl,--build-id="0xaaaaaaaaaabbbbbbbbbbccccccccccdddddddddd" \
+// RUN: -fdebug-prefix-map=%t.buildroot=/my/new/path \
+// RUN: -o %t \
+// RUN: test.cpp
+
+// We move the original source file to a directory that looks like a debuginfod
+// URL part.
+// ============================================================================
+// RUN: rm -rf %t.mock
+// RUN: mkdir -p %t.mock/buildid/aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd/source/my/new/path
+// RUN: mv test.cpp %t.mock/buildid/aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd/source/my/new/path
+
+// Adjust where debuginfod stores cache files:
+// ===========================================
+// RUN: rm -rfv %t.debuginfod_cache_path
+// RUN: mkdir -pv %t.debuginfod_cache_path
+// RUN: export DEBUGINFOD_CACHE_PATH=%t.debuginfod_cache_path
+
+// Start HTTP file server on port picked by OS and wait until it is ready
+// The server will be closed on exit of the test.
+// ======================================================================
+// RUN: rm -fv "%t.server.log"
+// RUN: timeout 5 python3 -u -m http.server 0 --directory %t.mock --bind "localhost" &> %t.server.log & export PID=$!
+// RUN: trap 'echo "SERVER LOG:"; cat %t.server.log; kill $PID;' EXIT INT
+
+// Extract HTTP address from the first line of the server log
+// (e.g. "Serving HTTP on 127.0.0.1 port 40587 (http://127.0.0.1:40587/) ..")
+// ==========================================================================
+// RUN: echo -n "Waiting for server to be ready"
+// RUN: SERVER_ADDRESS=""
+// RUN: while [ -z "$SERVER_ADDRESS" ]; do \
+// RUN: echo -n "."; \
+// RUN: sleep 0.01; \
+// RUN: SERVER_ADDRESS=$(head -n1 %t.server.log | grep "http://.\+/\+" -o); \
+// RUN: done
+// RUN: echo "DONE"
+
+//------------------------------------------------------------------------------
+// Invoke without debuginfod awareness
+// RUN: DEBUGINFOD_URLS="" \
+// RUN: %lldb -f %t -o 'source list -n main' | FileCheck --dump-input=fail %s --check-prefix=TEST-1
+
+// TEST-1: (lldb) source list -n main
+// TEST-1: File: /my/new/path/test.cpp
+// TEST-1-EMPTY:
+
+//------------------------------------------------------------------------------
+// Invoke with debuginfod awareness but point to a directory in which the source
+// files cannot be found by debuginfod.
+// RUN: DEBUGINFOD_URLS="http://example.com/debuginfod" \
+// RUN: %lldb -f %t -o 'source list -n main' | FileCheck --dump-input=fail %s --check-prefix=TEST-2
+
+// TEST-2: (lldb) source list -n main
+// TEST-2: File: /my/new/path/test.cpp
+// TEST-2-EMPTY:
+
+//------------------------------------------------------------------------------
+// Invoke with correct debuginfod awareness.
+// RUN: DEBUGINFOD_URLS="$SERVER_ADDRESS" \
+// RUN: %lldb -f %t -o 'source list -n main' | FileCheck --dump-input=fail %s --check-prefix=TEST-3
+
+// TEST-3: (lldb) source list -n main
+// TEST-3: File: /my/new/path/test.cpp
+// TEST-3: 109
+// TEST-3-NEXT: {{[0-9]+}} // Some context lines before
+// TEST-3-NEXT: {{[0-9]+}} // the function.
+// TEST-3-NEXT: {{[0-9]+}}
+// TEST-3-NEXT: {{[0-9]+}}
+// TEST-3-NEXT: {{[0-9]+}} int main(int argc, char **argv) {
+// TEST-3-NEXT: {{[0-9]+}} // Here are some comments.
+// TEST-3-NEXT: {{[0-9]+}} // That we should print when listing source.
+// TEST-3-NEXT: {{[0-9]+}} return 0;
+// TEST-3-NEXT: {{[0-9]+}} }
+// TEST-3-NEXT: {{[0-9]+}}
+// TEST-3-NEXT: {{[0-9]+}} // Some context lines after
+// TEST-3-NEXT: {{[0-9]+}} // the function.
+// TEST-3-EMPTY:
+
+// Some context lines before
+// the function.
+
+
+int main(int argc, char **argv) {
+ // Here are some comments.
+ // That we should print when listing source.
+ return 0;
+}
+
+// Some context lines after
+// the function.
\ No newline at end of file
Index: lldb/source/Host/common/DebugInfoD.cpp
===================================================================
--- /dev/null
+++ lldb/source/Host/common/DebugInfoD.cpp
@@ -0,0 +1,97 @@
+//===-- DebugInfoD.cpp ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/DebugInfoD.h"
+#include "lldb/Core/Module.h"
+#include "lldb/Host/Config.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Errno.h"
+
+#if LLDB_ENABLE_DEBUGINFOD
+#include "elfutils/debuginfod.h"
+#endif
+
+namespace lldb_private {
+
+namespace debuginfod {
+
+using namespace lldb;
+using namespace lldb_private;
+
+#if !LLDB_ENABLE_DEBUGINFOD
+bool isAvailable() { return false; }
+
+llvm::Error findSource(UUID buildID, const std::string &path,
+ std::string &cache_path) {
+ llvm_unreachable("debuginfod::findSource is unavailable");
+}
+
+#else // LLDB_ENABLE_DEBUGINFOD
+
+bool isAvailable() { return true; }
+
+llvm::Expected<std::string> findSource(UUID buildID, const std::string &path) {
+ if (!buildID.IsValid())
+ return llvm::createStringError(llvm::inconvertibleErrorCode(),
+ "invalid build ID: %s",
+ buildID.GetAsString("").c_str());
+
+ debuginfod_client *client = debuginfod_begin();
+
+ if (!client)
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "failed to create debuginfod connection handle: %s", strerror(errno));
+
+ // debuginfod_set_progressfn(client, [](debuginfod_client *client, long a,
+ // long b) -> int {
+ // fprintf(stderr, "KWK === a: %ld b : %ld \n", a, b);
+ // return 0; // continue
+ // });
+
+ char *cache_path = nullptr;
+ int rc = debuginfod_find_source(client, buildID.GetBytes().data(),
+ buildID.GetBytes().size(), path.c_str(),
+ &cache_path);
+
+ debuginfod_end(client);
+
+ std::string result_path;
+ if (cache_path) {
+ result_path = std::string(cache_path);
+ free(cache_path);
+ }
+
+ if (rc < 0) {
+ if (rc == -ENOSYS) // No DEBUGINFO_URLS were specified
+ return result_path;
+ else if (rc == -ENOENT) // No such file or directory, aka build-id not
+ // available on servers.
+ return result_path;
+ else
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "debuginfod_find_source query failed (CODE=%d): %s", -rc,
+ llvm::sys::StrError(-rc).c_str());
+ }
+
+ if (close(rc) < 0) {
+ return llvm::createStringError(
+ llvm::inconvertibleErrorCode(),
+ "failed to close result of call to debuginfo_find_source: %s",
+ llvm::sys::StrError(errno).c_str());
+ }
+
+ return result_path;
+}
+
+#endif // LLDB_ENABLE_DEBUGINFOD
+
+} // end of namespace debuginfod
+} // namespace lldb_private
Index: lldb/source/Host/CMakeLists.txt
===================================================================
--- lldb/source/Host/CMakeLists.txt
+++ lldb/source/Host/CMakeLists.txt
@@ -30,6 +30,7 @@
common/HostThread.cpp
common/LockFileBase.cpp
common/LZMA.cpp
+ common/DebugInfoD.cpp
common/MainLoop.cpp
common/MonitoringProcessLauncher.cpp
common/NativeProcessProtocol.cpp
@@ -161,6 +162,9 @@
if (LLDB_ENABLE_LZMA)
list(APPEND EXTRA_LIBS ${LIBLZMA_LIBRARIES})
endif()
+if (LLDB_ENABLE_DEBUGINFOD)
+ list(APPEND EXTRA_LIBS ${Debuginfod_LIBRARIES})
+endif()
if (WIN32)
list(APPEND LLDB_SYSTEM_LIBS psapi)
endif ()
Index: lldb/source/Core/SourceManager.cpp
===================================================================
--- lldb/source/Core/SourceManager.cpp
+++ lldb/source/Core/SourceManager.cpp
@@ -15,6 +15,7 @@
#include "lldb/Core/Highlighter.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
+#include "lldb/Host/DebugInfoD.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
@@ -402,7 +403,9 @@
if (target) {
m_source_map_mod_id = target->GetSourcePathMap().GetModificationID();
- if (!file_spec.GetDirectory() && file_spec.GetFilename()) {
+ SymbolContext sc;
+ if ((!file_spec.GetDirectory() && file_spec.GetFilename()) ||
+ !FileSystem::Instance().Exists(m_file_spec)) {
// If this is just a file name, lets see if we can find it in the
// target:
bool check_inlines = false;
@@ -416,7 +419,7 @@
bool got_multiple = false;
if (num_matches != 0) {
if (num_matches > 1) {
- SymbolContext sc;
+ // SymbolContext sc;
CompileUnit *test_cu = nullptr;
for (unsigned i = 0; i < num_matches; i++) {
@@ -432,11 +435,12 @@
}
}
if (!got_multiple) {
- SymbolContext sc;
+ // SymbolContext sc;
sc_list.GetContextAtIndex(0, sc);
if (sc.comp_unit)
m_file_spec = sc.comp_unit->GetPrimaryFile();
- m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec);
+ m_mod_time =
+ FileSystem::Instance().GetModificationTime(m_file_spec);
}
}
}
@@ -452,6 +456,24 @@
m_mod_time = FileSystem::Instance().GetModificationTime(m_file_spec);
}
}
+
+ // Try finding the file using elfutils' debuginfod
+ if (!FileSystem::Instance().Exists(m_file_spec) &&
+ debuginfod::isAvailable() && sc.module_sp) {
+ llvm::Expected<std::string> cache_path = debuginfod::findSource(
+ sc.module_sp->GetUUID(), file_spec.GetCString());
+ if (!cache_path) {
+ sc.module_sp->ReportWarning(
+ "An error occurred while finding the "
+ "source file %s using debuginfod for build ID %s: %s",
+ file_spec.GetCString(),
+ sc.module_sp->GetUUID().GetAsString("").c_str(),
+ llvm::toString(cache_path.takeError()).c_str());
+ } else if (!cache_path->empty()) {
+ m_file_spec = FileSpec(*cache_path);
+ m_mod_time = FileSystem::Instance().GetModificationTime(*cache_path);
+ }
+ }
}
}
Index: lldb/packages/Python/lldbsuite/test/lldbtest.py
===================================================================
--- lldb/packages/Python/lldbsuite/test/lldbtest.py
+++ lldb/packages/Python/lldbsuite/test/lldbtest.py
@@ -1,7 +1,7 @@
"""
LLDB module which provides the abstract base class of lldb test case.
-The concrete subclass can override lldbtest.TesBase in order to inherit the
+The concrete subclass can override lldbtest.TestBase in order to inherit the
common behavior for unitest.TestCase.setUp/tearDown implemented in this file.
The subclass should override the attribute mydir in order for the python runtime
Index: lldb/packages/Python/lldbsuite/test/httpserver.py
===================================================================
--- /dev/null
+++ lldb/packages/Python/lldbsuite/test/httpserver.py
@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*-
+"""
+The httpserver module contains an easy and ready-to-use HTTP file server.
+
+o ServeDirectoryWithHTTP: Spawns an HTTP file server in a separate thread.
+"""
+
+import http.server
+from threading import Thread, current_thread
+from sys import stderr
+from functools import partial
+from os.path import abspath
+
+
+def ServeDirectoryWithHTTP(directory="."):
+ """Spawns an http.server.HTTPServer in a separate thread on the given port.
+
+ The server serves files from the given *directory*. The port listening on
+ will automatically be picked by the operating system to avoid race
+ conditions when trying to bind to an open port that turns out not to be
+ free afterall. The hostname is always "localhost".
+
+ Parameters
+ ----------
+ directory : str, optional
+ The directory to server files from. Defaults to the current directory.
+
+ Returns
+ -------
+ http.server.HTTPServer
+ The HTTP server which is serving files from a separate thread.
+
+ It is not super necessary but you might want to call shutdown() on the
+ returned HTTP server object. This will stop the inifinite request loop
+ running in the thread which in turn will then exit. The reason why this
+ is only optional is that the thread in which the server runs is a daemon
+ thread which will be terminated when the main thread ends.
+
+ By calling shutdown() you'll get a cleaner shutdown because the socket
+ is properly closed.
+
+ str
+ The address of the server as a string, e.g. "http://localhost:1234".
+
+ Examples
+ --------
+ >>> from httpserver import ServeDirectoryWithHTTP
+ >>> from urllib.request import urlopen
+ >>> httpd, address = ServeDirectoryWithHTTP()
+ >>> print("Address:", address) # doctest:+ELLIPSIS
+ ...
+ Address: http://localhost...:...
+ >>> try:
+ ... url = address + "/httpserver.py"
+ ... print("Getting URL:", url) # doctest:+ELLIPSIS
+ ... with urlopen(url) as f:
+ ... print("Code:", f.getcode())
+ ... finally:
+ ... httpd.shutdown()
+ ...
+ Getting URL: http://localhost...:.../httpserver.py
+ Code: 200
+
+ In the example above, you can call f.read() to read the content of the file
+ you've asked for.
+
+ """
+
+ hostname = "localhost"
+ port = 0
+ directory = abspath(directory)
+ handler = partial(_SimpleRequestHandler, directory=directory)
+ httpd = http.server.HTTPServer((hostname, 0), handler, False)
+ # Block only for 0.5 seconds max
+ httpd.timeout = 0.5
+ # Allow for reusing the address
+ # HTTPServer sets this as well but I wanted to make this more obvious.
+ httpd.allow_reuse_address = True
+
+ _xprint("server about to bind to port %d on hostname '%s'" % (port, hostname))
+ httpd.server_bind()
+
+ address = "http://%s:%d" % (httpd.server_name, httpd.server_port)
+
+ _xprint("server about to listen on:", address)
+ httpd.server_activate()
+
+ def serve_forever(httpd):
+ with httpd: # to make sure httpd.server_close is called
+ _xprint("server about to serve files from directory (infinite request loop):", directory)
+ httpd.serve_forever()
+ _xprint("server left infinite request loop")
+
+ thread = Thread(target=serve_forever, args=(httpd, ))
+ thread.setDaemon(True)
+ thread.start()
+
+ return httpd, address
+
+
+def _xprint(*args, **kwargs):
+ """Wrapper function around print() that prepends the current thread name"""
+ print("[", current_thread().name, "]",
+ " ".join(map(str, args)), **kwargs, file=stderr)
+
+
+class _SimpleRequestHandler(http.server.SimpleHTTPRequestHandler):
+ """Same as SimpleHTTPRequestHandler with adjusted logging."""
+
+ def log_message(self, format, *args):
+ """Log an arbitrary message and prepend the given thread name."""
+ stderr.write("[ " + current_thread().name + " ] ")
+ http.server.SimpleHTTPRequestHandler.log_message(self, format, *args)
+
+
+if __name__ == "__main__":
+ from doctest import testmod
+ testmod(verbose=True)
Index: lldb/include/lldb/Host/DebugInfoD.h
===================================================================
--- /dev/null
+++ lldb/include/lldb/Host/DebugInfoD.h
@@ -0,0 +1,37 @@
+//===-- DebugInfoD.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_HOST_DEBUGINFOD_H
+#define LLDB_HOST_DEBUGINFOD_H
+
+#include "lldb/Utility/UUID.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/Error.h"
+
+namespace llvm {
+class Error;
+} // End of namespace llvm
+
+namespace lldb_private {
+
+namespace debuginfod {
+
+// Returns \c true if debuginfod support was compiled-in; otherwise \c false is
+// returned.
+bool isAvailable();
+
+// Asks all servers in environment variable \c DEBUGINFOD_URLS for the \a path
+// of an artifact with a given \a buildID and returns the path to a locally
+// cached version of the file. If there was an error, we return that instead.
+llvm::Expected<std::string> findSource(UUID buildID, const std::string &path);
+
+} // End of namespace debuginfod
+
+} // End of namespace lldb_private
+
+#endif // LLDB_HOST_DEBUGINFOD_H
Index: lldb/include/lldb/Host/Config.h.cmake
===================================================================
--- lldb/include/lldb/Host/Config.h.cmake
+++ lldb/include/lldb/Host/Config.h.cmake
@@ -36,6 +36,8 @@
#cmakedefine01 LLDB_ENABLE_LZMA
+#cmakedefine01 LLDB_ENABLE_DEBUGINFOD
+
#cmakedefine01 LLDB_ENABLE_CURSES
#cmakedefine01 LLDB_ENABLE_LIBEDIT
Index: lldb/cmake/modules/LLDBConfig.cmake
===================================================================
--- lldb/cmake/modules/LLDBConfig.cmake
+++ lldb/cmake/modules/LLDBConfig.cmake
@@ -58,6 +58,7 @@
add_optional_dependency(LLDB_ENABLE_LUA "Enable Lua scripting support in LLDB" LuaAndSwig LUAANDSWIG_FOUND)
add_optional_dependency(LLDB_ENABLE_PYTHON "Enable Python scripting support in LLDB" PythonInterpAndLibs PYTHONINTERPANDLIBS_FOUND)
add_optional_dependency(LLDB_ENABLE_LIBXML2 "Enable Libxml 2 support in LLDB" LibXml2 LIBXML2_FOUND VERSION 2.8)
+add_optional_dependency(LLDB_ENABLE_DEBUGINFOD "Enable Debuginfod support in LLDB" Debuginfod Debuginfod_FOUND)
option(LLDB_USE_SYSTEM_SIX "Use six.py shipped with system and do not install a copy of it" OFF)
option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON)
@@ -233,6 +234,10 @@
include_directories(${LIBLZMA_INCLUDE_DIRS})
endif()
+if (LLDB_ENABLE_DEBUGINFOD)
+ include_directories(${Debuginfod_INCLUDE_DIRS})
+endif()
+
if (LLDB_ENABLE_LIBXML2)
list(APPEND system_libs ${LIBXML2_LIBRARIES})
include_directories(${LIBXML2_INCLUDE_DIR})
Index: lldb/cmake/modules/FindDebuginfod.cmake
===================================================================
--- /dev/null
+++ lldb/cmake/modules/FindDebuginfod.cmake
@@ -0,0 +1,58 @@
+#.rst:
+# FindDebuginfod
+# -----------
+#
+# Find debuginfod library and headers
+#
+# The module defines the following variables:
+#
+# ::
+#
+# Debuginfod_FOUND - true if debuginfod was found
+# Debuginfod_INCLUDE_DIRS - include search path
+# Debuginfod_LIBRARIES - libraries to link
+# Debuginfod_VERSION_STRING - version number
+#
+# TODO(kwk): Debuginfod_VERSION_STRING is only set if pkg-config file is
+# available. Trying to see if we can get a MAJOR, MINOR, PATCH define in the
+# debuginfod.h file.
+
+if(Debuginfod_INCLUDE_DIRS AND Debuginfod_LIBRARIES)
+ set(Debuginfod_FOUND TRUE)
+else()
+ # Utilize package config (e.g. /usr/lib64/pkgconfig/libdebuginfod.pc) to fetch
+ # version information.
+ find_package(PkgConfig QUIET)
+ pkg_check_modules(PC_Debuginfod QUIET libdebuginfod)
+
+ find_path(Debuginfod_INCLUDE_DIRS
+ NAMES
+ elfutils/debuginfod.h
+ HINTS
+ /usr/include
+ ${PC_Debuginfod_INCLUDEDIR}
+ ${PC_Debuginfod_INCLUDE_DIRS}
+ ${CMAKE_INSTALL_FULL_INCLUDEDIR})
+ find_library(Debuginfod_LIBRARIES
+ NAMES
+ debuginfod
+ HINTS
+ ${PC_Debuginfod_LIBDIR}
+ ${PC_Debuginfod_LIBRARY_DIRS}
+ ${CMAKE_INSTALL_FULL_LIBDIR})
+
+ if(Debuginfod_INCLUDE_DIRS AND EXISTS "${Debuginfod_INCLUDE_DIRS}/debuginfod.h")
+ set(Debuginfod_VERSION_STRING "${PC_Debuginfod_VERSION}")
+ endif()
+
+ include(FindPackageHandleStandardArgs)
+ find_package_handle_standard_args(Debuginfod
+ FOUND_VAR
+ Debuginfod_FOUND
+ REQUIRED_VARS
+ Debuginfod_INCLUDE_DIRS
+ Debuginfod_LIBRARIES
+ VERSION_VAR
+ Debuginfod_VERSION_STRING)
+ mark_as_advanced(Debuginfod_INCLUDE_DIRS Debuginfod_LIBRARIES)
+endif()
\ No newline at end of file
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits