diff --git a/src/core/appdir.cpp b/src/core/appdir.cpp index d6b510d1..a04757da 100644 --- a/src/core/appdir.cpp +++ b/src/core/appdir.cpp @@ -385,10 +385,14 @@ namespace linuxdeploy { return stripPath; } - static std::string calculateRelativeRPath(const fs::path& originDir, const fs::path& dependencyLibrariesDir) { + static std::string calculateRelativeRPath(const fs::path& originDir, const fs::path& dependencyLibrariesDir, bool appendOrigin = true) { auto relPath = fs::relative(fs::absolute(dependencyLibrariesDir), fs::absolute(originDir)); - std::string rpath = "$ORIGIN/" + relPath.string() + ":$ORIGIN"; - return rpath; + if (relPath.empty() || relPath == ".") { + return "$ORIGIN"; + } else { + auto rpath = "$ORIGIN/" + relPath.string(); + return appendOrigin ? rpath + ":$ORIGIN" : rpath; + } } bool deployLibrary(const fs::path& path, bool forceDeploy = false, bool deployDependencies = true, const fs::path& destination = fs::path()) { @@ -803,13 +807,30 @@ namespace linuxdeploy { executables.push_back(file); } + for (const auto& file : listFilesInDirectory(path() / "usr/lib/libexec", true)) { + // make sure it's an ELF file + try { + elf_file::ElfFile elfFile(file); + } catch (const elf_file::ElfFileParseError&) { + // FIXME: remove this workaround once the MIME check below works as intended + continue; + } + + executables.push_back(file); + } + return executables; } std::vector AppDir::listSharedLibraries() const { + const auto libexecPath = (path() / "usr/lib/libexec/").string(); std::vector sharedLibraries; for (const auto& file : listFilesInDirectory(path() / "usr" / "lib", true)) { + // skip executables in libexec + if (util::stringStartsWith(file.string(), libexecPath)) + continue; + // exclude debug symbols if (d->isInDebugSymbolsLocation(file)) continue; @@ -836,7 +857,12 @@ namespace linuxdeploy { if (!d->deployElfDependencies(executable)) return false; - std::string rpath = "$ORIGIN/../" + PrivateData::getLibraryDirName(executable); + // set rpath correctly + const auto rpathDestination = path() / "usr" / PrivateData::getLibraryDirName(executable); + ldLog() << LD_DEBUG << "rpath destination:" << rpathDestination << std::endl; + + const auto rpath = PrivateData::calculateRelativeRPath(executable.parent_path(), rpathDestination, false); + ldLog() << LD_DEBUG << "Calculated rpath:" << rpath << std::endl; d->setElfRPathOperations[executable] = rpath; } @@ -848,13 +874,20 @@ namespace linuxdeploy { if (!d->deployElfDependencies(sharedLibrary)) return false; - const auto rpath = elf_file::ElfFile(sharedLibrary).getRPath(); - auto rpathList = util::split(rpath, ':'); - if (std::find(rpathList.begin(), rpathList.end(), "$ORIGIN") == rpathList.end()) { - rpathList.push_back("$ORIGIN"); + // add correct rpath + const auto rpathDestination = path() / "usr" / PrivateData::getLibraryDirName(sharedLibrary); + ldLog() << LD_DEBUG << "rpath destination:" << rpathDestination << std::endl; + + const auto rpath = PrivateData::calculateRelativeRPath(sharedLibrary.parent_path(), rpathDestination, false); + ldLog() << LD_DEBUG << "Calculated rpath:" << rpath << std::endl; + + const auto rpaths = elf_file::ElfFile(sharedLibrary).getRPath(); + auto rpathList = util::split(rpaths, ':'); + if (std::find(rpathList.begin(), rpathList.end(), rpath) == rpathList.end()) { + rpathList.push_back(rpath); d->setElfRPathOperations[sharedLibrary] = util::join(rpathList, ":"); } else { - d->setElfRPathOperations[sharedLibrary] = rpath; + d->setElfRPathOperations[sharedLibrary] = rpaths; } } diff --git a/src/plugin/plugin_process_handler.cpp b/src/plugin/plugin_process_handler.cpp index 07c41aae..6a4694eb 100644 --- a/src/plugin/plugin_process_handler.cpp +++ b/src/plugin/plugin_process_handler.cpp @@ -3,6 +3,7 @@ #include #include #include +#include // local headers #include diff --git a/src/subprocess/subprocess.cpp b/src/subprocess/subprocess.cpp index 92e0d803..e90b0f97 100644 --- a/src/subprocess/subprocess.cpp +++ b/src/subprocess/subprocess.cpp @@ -6,6 +6,7 @@ #include #include #include +#include // local headers #include "linuxdeploy/subprocess/subprocess.h"