summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2021-01-06 17:22:48 +0100
committerMilian Wolff <milian.wolff@kdab.com>2021-01-11 17:24:42 +0000
commit59416050f2faf5f53009c135d7afbe605af3c5f8 (patch)
tree0b22addf5ba3bfa38838e00c94081f5f37ccfd6a
parent730dd687d5da090cbc34ba448ca581a235b239c3 (diff)
Use QLibrary to find librustc_demangle at runtime
Don't link to librustc_demangle at compile time, just try to find it at runtime via QLibrary and then use it. This makes it much easier to enable/disable support for rust demangling for packagers. Fixes: https://github.com/KDAB/hotspot/issues/269 Change-Id: Ib33e2699780ed6d827bddeea75f82137daeacc9d Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--CMakeLists.txt10
-rw-r--r--app/CMakeLists.txt6
-rw-r--r--app/perfdwarfdiecache.cpp32
-rw-r--r--cmake/FindLibRustcDemangle.cmake22
4 files changed, 55 insertions, 15 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b892b27..d379096 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,10 +8,12 @@ endif()
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(Zstd)
-set(RUSTC_DEMANGLE_INCLUDE_DIR "" CACHE STRING "Path to the folder containing rustc_demangle.h from https://github.com/alexcrichton/rustc-demangle")
-set(RUSTC_DEMANGLE_LIBRARY "" CACHE STRING "Path to the librustc_demangle.so library from https://github.com/alexcrichton/rustc-demangle")
-option(WITH_RUSTC_DEMANGLE "Build rust demangle support" OFF)
-add_feature_info("Rust demangler for perfparser" WITH_RUSTC_DEMANGLE "Requires RUSTC_DEMANGLE_INCLUDE_DIR and RUSTC_DEMANGLE_LIBRARY to be specified")
+find_package(LibRustcDemangle)
+set_package_properties(LibRustcDemangle PROPERTIES
+ DESCRIPTION "Demangling for Rust symbols, written in Rust."
+ PURPOSE "Demangling of Rust symbols"
+ URL "https://github.com/alexcrichton/rustc-demangle"
+ TYPE RUNTIME)
add_subdirectory(app)
add_subdirectory(tests)
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 746583e..b324907 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -30,12 +30,6 @@ if (Zstd_FOUND)
target_compile_definitions(perfparser_lib PRIVATE HAVE_ZSTD=1)
endif()
-if (WITH_RUSTC_DEMANGLE)
- target_include_directories(perfparser_lib PRIVATE ${RUSTC_DEMANGLE_INCLUDE_DIR})
- target_link_libraries(perfparser_lib PRIVATE ${RUSTC_DEMANGLE_LIBRARY})
- target_compile_definitions(perfparser_lib PRIVATE HAVE_RUSTC_DEMANGLE=1)
-endif()
-
add_qtc_executable(perfparser
DEPENDS
perfparser_lib
diff --git a/app/perfdwarfdiecache.cpp b/app/perfdwarfdiecache.cpp
index 4823646..4b70c0b 100644
--- a/app/perfdwarfdiecache.cpp
+++ b/app/perfdwarfdiecache.cpp
@@ -22,11 +22,35 @@
#include <dwarf.h>
-#ifdef HAVE_RUSTC_DEMANGLE
-#include <rustc_demangle.h>
-#endif
+#include <QLibrary>
+#include <QDebug>
namespace {
+bool rustc_demangle(const char *symbol, char *buffer, size_t bufferSize)
+{
+ using demangler_t = int (*) (const char*, char *, size_t);
+ static const auto demangler = []() -> demangler_t {
+ QLibrary lib(QStringLiteral("rustc_demangle"));
+ if (!lib.load()) {
+ qDebug() << "failed to load rustc_demangle library, rust demangling is support not available."
+ << lib.errorString();
+ return nullptr;
+ }
+ const auto rawSymbol = lib.resolve("rustc_demangle");
+ if (!rawSymbol) {
+ qDebug() << "failed to resolve rustc_demangle function in library"
+ << lib.fileName() << lib.errorString();
+ return nullptr;
+ }
+ return reinterpret_cast<demangler_t>(rawSymbol);
+ }();
+
+ if (demangler)
+ return demangler(symbol, buffer, bufferSize);
+ else
+ return false;
+}
+
enum class WalkResult
{
Recurse,
@@ -227,10 +251,8 @@ QByteArray demangle(const QByteArray &mangledName)
static size_t demangleBufferLength = 1024;
static char *demangleBuffer = reinterpret_cast<char *>(eu_compat_malloc(demangleBufferLength));
-#ifdef HAVE_RUSTC_DEMANGLE
if (rustc_demangle(mangledName.constData(), demangleBuffer, demangleBufferLength))
return demangleBuffer;
-#endif
// Require GNU v3 ABI by the "_Z" prefix.
if (mangledName[0] == '_' && mangledName[1] == 'Z') {
diff --git a/cmake/FindLibRustcDemangle.cmake b/cmake/FindLibRustcDemangle.cmake
new file mode 100644
index 0000000..c247e16
--- /dev/null
+++ b/cmake/FindLibRustcDemangle.cmake
@@ -0,0 +1,22 @@
+if (LIBRUSTC_DEMANGLE_LIBRARIES)
+ set (LibRustcDemangle_FIND_QUIETLY TRUE)
+endif()
+
+find_library(LIBRUSTC_DEMANGLE_LIBRARIES
+ NAMES
+ rustc_demangle
+ PATHS
+ /usr/lib
+ /usr/local/lib
+ /opt/local/lib
+ /sw/lib
+ ENV LIBRARY_PATH
+ ENV LD_LIBRARY_PATH)
+
+include (FindPackageHandleStandardArgs)
+
+# handle the QUIETLY and REQUIRED arguments and set LIBRUSTC_DEMANGLE_FOUND to TRUE if all listed variables are TRUE
+find_package_handle_standard_args(LibRustcDemangle DEFAULT_MSG
+ LIBRUSTC_DEMANGLE_LIBRARIES)
+
+mark_as_advanced(LIBRUSTC_DEMANGLE_LIBRARIES)