mangohud support: getLibraryString should return absolute path when possible

Some distros ship MangoHub vulkan layer json with bare shared object name
instead of an absolute path. This breaks environment config as
`MinecraftInstance::createLaunchEnvironment()` seems to require absolute
path of `libMangoHud.so`.

Since we already have `MangoHud::findLibrary()` lying around, use that to
figure out where `libMangoHud.so` really is. In case of a platform that
doesn't support `dlopen()`, fallback to old behavior and return the path
verbatim as it is recorded in vk layer json.

Signed-off-by: Tianhao Chai <cth451@gmail.com>
This commit is contained in:
Tianhao Chai 2024-08-09 14:11:44 -04:00
parent b41e730707
commit c2192cfa98
No known key found for this signature in database
GPG Key ID: 6BC17BFCD0F07862
2 changed files with 23 additions and 9 deletions

View File

@ -40,8 +40,8 @@ namespace MangoHud {
QString getLibraryString() QString getLibraryString()
{ {
/* /**
* Check for vulkan layers in this order: * Guess MangoHud install location by searching for vulkan layers in this order:
* *
* $VK_LAYER_PATH * $VK_LAYER_PATH
* $XDG_DATA_DIRS (/usr/local/share/:/usr/share/) * $XDG_DATA_DIRS (/usr/local/share/:/usr/share/)
@ -49,8 +49,9 @@ QString getLibraryString()
* /etc * /etc
* $XDG_CONFIG_DIRS (/etc/xdg) * $XDG_CONFIG_DIRS (/etc/xdg)
* $XDG_CONFIG_HOME (~/.config) * $XDG_CONFIG_HOME (~/.config)
*
* @returns Absolute path of libMangoHud.so if found and empty QString otherwise.
*/ */
QStringList vkLayerList; QStringList vkLayerList;
{ {
QString home = QDir::homePath(); QString home = QDir::homePath();
@ -85,7 +86,7 @@ QString getLibraryString()
vkLayerList << FS::PathCombine(xdgConfigHome, "vulkan", "implicit_layer.d"); vkLayerList << FS::PathCombine(xdgConfigHome, "vulkan", "implicit_layer.d");
} }
for (QString vkLayer : vkLayerList) { for (const QString& vkLayer : vkLayerList) {
// prefer to use architecture specific vulkan layers // prefer to use architecture specific vulkan layers
QString currentArch = QSysInfo::currentCpuArchitecture(); QString currentArch = QSysInfo::currentCpuArchitecture();
@ -95,8 +96,8 @@ QString getLibraryString()
QStringList manifestNames = { QString("MangoHud.%1.json").arg(currentArch), "MangoHud.json" }; QStringList manifestNames = { QString("MangoHud.%1.json").arg(currentArch), "MangoHud.json" };
QString filePath = ""; QString filePath{};
for (QString manifestName : manifestNames) { for (const QString& manifestName : manifestNames) {
QString tryPath = FS::PathCombine(vkLayer, manifestName); QString tryPath = FS::PathCombine(vkLayer, manifestName);
if (QFile::exists(tryPath)) { if (QFile::exists(tryPath)) {
filePath = tryPath; filePath = tryPath;
@ -111,10 +112,23 @@ QString getLibraryString()
auto conf = Json::requireDocument(filePath, vkLayer); auto conf = Json::requireDocument(filePath, vkLayer);
auto confObject = Json::requireObject(conf, vkLayer); auto confObject = Json::requireObject(conf, vkLayer);
auto layer = Json::ensureObject(confObject, "layer"); auto layer = Json::ensureObject(confObject, "layer");
return Json::ensureString(layer, "library_path"); QString libraryName = Json::ensureString(layer, "library_path");
#ifdef __GLIBC__
// Check whether mangohud is usable on a glibc based system
if (!libraryName.isEmpty()) {
QString libraryPath = findLibrary(libraryName);
if (!libraryPath.isEmpty()) {
return libraryPath;
}
}
#else
// Without glibc return recorded shared library as-is.
return libraryName;
#endif
} }
return QString(); return {};
} }
QString findLibrary(QString libName) QString findLibrary(QString libName)

View File

@ -608,7 +608,7 @@ QProcessEnvironment MinecraftInstance::createLaunchEnvironment()
// dlsym variant is only needed for OpenGL and not included in the vulkan layer // dlsym variant is only needed for OpenGL and not included in the vulkan layer
appendLib("libMangoHud_dlsym.so"); appendLib("libMangoHud_dlsym.so");
appendLib("libMangoHud_opengl.so"); appendLib("libMangoHud_opengl.so");
appendLib(mangoHudLib.fileName()); preloadList << mangoHudLibString;
} }
env.insert("LD_PRELOAD", preloadList.join(QLatin1String(":"))); env.insert("LD_PRELOAD", preloadList.join(QLatin1String(":")));