mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-09 04:50:14 +02:00
65 lines
2.9 KiB
C++
65 lines
2.9 KiB
C++
// yabridge: a Wine plugin bridge
|
|
// Copyright (C) 2020-2022 Robbert van der Helm
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
#include "linking.h"
|
|
|
|
#include <cassert>
|
|
|
|
#include <dlfcn.h>
|
|
|
|
namespace fs = ghc::filesystem;
|
|
|
|
fs::path get_this_file_location() {
|
|
// We'll try to find the library this function was defined in. When called
|
|
// from a copy of `libyabridge-*.so` this will return that library. Because
|
|
// the chainloader libraries load the plugin libraries from fixed locations,
|
|
// the plugin libraries cannot use this function directly when using the
|
|
// chainloaders.
|
|
|
|
// On success this returns a non-zero value, just to keep you on your toes
|
|
Dl_info info;
|
|
assert(dladdr(reinterpret_cast<void*>(get_this_file_location), &info) != 0);
|
|
assert(info.dli_fname);
|
|
|
|
std::string this_file(info.dli_fname);
|
|
|
|
// HACK: Not sure why, but `boost::dll::this_line_location()` used to return
|
|
// a path starting with a double slash on some systems. I've seen this
|
|
// happen on both Ubuntu 18.04 and 20.04, but not on Arch based
|
|
// distros. Under Linux a path starting with two slashes is treated
|
|
// the same as a path starting with only a single slash, but Wine will
|
|
// refuse to load any files when the path starts with two slashes. The
|
|
// easiest way to work around this if this happens is to just add
|
|
// another leading slash and then normalize the path, since three or
|
|
// more slashes will be coerced into a single slash. We no longer use
|
|
// Boost.Dll, but unless this was an obscure Boost.Filesystem bug it
|
|
// sounds more likely that it was caused by some `ld.so` setting.
|
|
// Unless we can really figure out what was causing this, it seems
|
|
// best to still account for it
|
|
if (this_file.starts_with("//")) {
|
|
const size_t path_start_pos = this_file.find_first_not_of('/');
|
|
if (path_start_pos != std::string::npos) {
|
|
// FIXME: This results in a spurious compiler warning if you inline
|
|
// `path_start`:
|
|
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105329
|
|
const std::string path_start = this_file.substr(path_start_pos);
|
|
this_file = "/" + path_start;
|
|
}
|
|
}
|
|
|
|
return this_file;
|
|
}
|