mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 00:32:57 -04:00
dtoolutil: Overhaul ExecutionEnvironment's dtool path hunting code
The main change here is it uses an array of expected filenames, which optionally itself feeds off of a compiler definition, rather than hardcoding the expected filenames straight into the search code. The other change is this code is omitted when building statically.
This commit is contained in:
parent
83c10d1a0b
commit
2f97b76b42
@ -85,6 +85,44 @@ extern char **GLOBAL_ARGV;
|
|||||||
extern int GLOBAL_ARGC;
|
extern int GLOBAL_ARGC;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// One of the responsibilities of ExecutionEnvironment is to determine the path
|
||||||
|
// to the binary file that contains itself (this is useful for making other
|
||||||
|
// components able to read files relative to Panda's installation directory).
|
||||||
|
// When built statically, this is easy - just use the main executable filename.
|
||||||
|
// When built shared, ExecutionEnvironment will introspect the memory map of
|
||||||
|
// the running process to look for dynamic library paths matching this list of
|
||||||
|
// predetermined filenames (ordered most likely to least likely).
|
||||||
|
|
||||||
|
#ifndef LINK_ALL_STATIC
|
||||||
|
static const char *const libp3dtool_filenames[] = {
|
||||||
|
#if defined(LIBP3DTOOL_FILENAMES)
|
||||||
|
|
||||||
|
// The build system is communicating the expected filename(s) for the
|
||||||
|
// libp3dtool dynamic library - no guesswork needed.
|
||||||
|
LIBP3DTOOL_FILENAMES
|
||||||
|
|
||||||
|
#elif defined(WIN32_VC)
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
"libp3dtool_d.dll",
|
||||||
|
#else
|
||||||
|
"libp3dtool.dll",
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
|
||||||
|
"libp3dtool." PANDA_ABI_VERSION_STR ".dylib",
|
||||||
|
"libp3dtool.dylib",
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
"libp3dtool.so." PANDA_ABI_VERSION_STR,
|
||||||
|
"libp3dtool.so",
|
||||||
|
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif /* !LINK_ALL_STATIC */
|
||||||
|
|
||||||
// Linux with GNU libc does have global argvargc variables, but we can't
|
// Linux with GNU libc does have global argvargc variables, but we can't
|
||||||
// safely access them at stat init time--at least, not in libc5. (It does seem
|
// safely access them at stat init time--at least, not in libc5. (It does seem
|
||||||
// to work with glibc2, however.)
|
// to work with glibc2, however.)
|
||||||
@ -546,13 +584,14 @@ read_args() {
|
|||||||
// First, we need to fill in _dtool_name. This contains the full path to
|
// First, we need to fill in _dtool_name. This contains the full path to
|
||||||
// the p3dtool library.
|
// the p3dtool library.
|
||||||
|
|
||||||
#ifdef WIN32_VC
|
#ifndef LINK_ALL_STATIC
|
||||||
#ifdef _DEBUG
|
#if defined(WIN32_VC)
|
||||||
HMODULE dllhandle = GetModuleHandle("libp3dtool_d.dll");
|
for (const char *filename : libp3dtool_filenames) {
|
||||||
#else
|
if (!_dtool_name.empty()) break;
|
||||||
HMODULE dllhandle = GetModuleHandle("libp3dtool.dll");
|
|
||||||
#endif
|
HMODULE dllhandle = GetModuleHandle(filename);
|
||||||
if (dllhandle != 0) {
|
if (!dllhandle) continue;
|
||||||
|
|
||||||
static const DWORD buffer_size = 1024;
|
static const DWORD buffer_size = 1024;
|
||||||
wchar_t buffer[buffer_size];
|
wchar_t buffer[buffer_size];
|
||||||
DWORD size = GetModuleFileNameW(dllhandle, buffer, buffer_size);
|
DWORD size = GetModuleFileNameW(dllhandle, buffer, buffer_size);
|
||||||
@ -562,46 +601,44 @@ read_args() {
|
|||||||
_dtool_name = tmp;
|
_dtool_name = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
// And on OSX we don't have procselfmaps, but some _dyld_* functions.
|
// And on OSX we don't have procselfmaps, but some _dyld_* functions.
|
||||||
|
|
||||||
if (_dtool_name.empty()) {
|
uint32_t ic = _dyld_image_count();
|
||||||
uint32_t ic = _dyld_image_count();
|
for (uint32_t i = 0; i < ic; ++i) {
|
||||||
for (uint32_t i = 0; i < ic; ++i) {
|
if (!_dtool_name.empty()) break;
|
||||||
const char *buffer = _dyld_get_image_name(i);
|
|
||||||
const char *tail = strrchr(buffer, '/');
|
const char *buffer = _dyld_get_image_name(i);
|
||||||
if (tail && (strcmp(tail, "/libp3dtool." PANDA_ABI_VERSION_STR ".dylib") == 0
|
if (!buffer) continue;
|
||||||
|| strcmp(tail, "/libp3dtool.dylib") == 0)) {
|
const char *tail = strrchr(buffer, '/');
|
||||||
|
if (!tail) continue;
|
||||||
|
|
||||||
|
for (const char *filename : libp3dtool_filenames) {
|
||||||
|
if (strcmp(&tail[1], filename) == 0) {
|
||||||
_dtool_name = buffer;
|
_dtool_name = buffer;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(RTLD_DI_ORIGIN)
|
#elif defined(RTLD_DI_ORIGIN)
|
||||||
// When building with glibc/uClibc, we typically have access to RTLD_DI_ORIGIN in Unix-like operating systems.
|
// When building with glibc/uClibc, we typically have access to RTLD_DI_ORIGIN in Unix-like operating systems.
|
||||||
|
|
||||||
char origin[PATH_MAX + 1];
|
char origin[PATH_MAX + 1];
|
||||||
|
|
||||||
if (_dtool_name.empty()) {
|
for (const char *filename : libp3dtool_filenames) {
|
||||||
void *dtool_handle = dlopen("libp3dtool.so." PANDA_ABI_VERSION_STR, RTLD_NOW | RTLD_NOLOAD);
|
if (!_dtool_name.empty()) break;
|
||||||
|
|
||||||
|
void *dtool_handle = dlopen(filename, RTLD_NOW | RTLD_NOLOAD);
|
||||||
if (dtool_handle != nullptr && dlinfo(dtool_handle, RTLD_DI_ORIGIN, origin) != -1) {
|
if (dtool_handle != nullptr && dlinfo(dtool_handle, RTLD_DI_ORIGIN, origin) != -1) {
|
||||||
_dtool_name = origin;
|
_dtool_name = origin;
|
||||||
_dtool_name += "/libp3dtool.so." PANDA_ABI_VERSION_STR;
|
_dtool_name += '/';
|
||||||
} else {
|
_dtool_name += filename;
|
||||||
// Try the version of libp3dtool.so without ABI suffix.
|
|
||||||
dtool_handle = dlopen("libp3dtool.so", RTLD_NOW | RTLD_NOLOAD);
|
|
||||||
if (dtool_handle != nullptr && dlinfo(dtool_handle, RTLD_DI_ORIGIN, origin) != -1) {
|
|
||||||
_dtool_name = origin;
|
|
||||||
_dtool_name += "/libp3dtool.so";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(RTLD_DI_ORIGIN) && defined(RTLD_DI_LINKMAP)
|
#elif defined(RTLD_DI_LINKMAP)
|
||||||
// On platforms without RTLD_DI_ORIGIN, we can use dlinfo with RTLD_DI_LINKMAP to get the origin of a loaded library.
|
// On platforms without RTLD_DI_ORIGIN, we can use dlinfo with RTLD_DI_LINKMAP to get the origin of a loaded library.
|
||||||
if (_dtool_name.empty()) {
|
if (_dtool_name.empty()) {
|
||||||
struct link_map *map;
|
struct link_map *map;
|
||||||
@ -612,12 +649,20 @@ read_args() {
|
|||||||
#endif
|
#endif
|
||||||
if (dlinfo(self, RTLD_DI_LINKMAP, &map)) {
|
if (dlinfo(self, RTLD_DI_LINKMAP, &map)) {
|
||||||
while (map != nullptr) {
|
while (map != nullptr) {
|
||||||
const char *tail = strrchr(map->l_name, '/');
|
if (!_dtool_name.empty()) break;
|
||||||
|
|
||||||
const char *head = strchr(map->l_name, '/');
|
const char *head = strchr(map->l_name, '/');
|
||||||
if (tail && head && (strcmp(tail, "/libp3dtool.so." PANDA_ABI_VERSION_STR) == 0
|
if (!head) continue;
|
||||||
|| strcmp(tail, "/libp3dtool.so") == 0)) {
|
const char *tail = strrchr(head, '/');
|
||||||
_dtool_name = head;
|
if (!tail) continue;
|
||||||
|
|
||||||
|
for (const char *filename : libp3dtool_filenames) {
|
||||||
|
if (strcmp(&tail[1], filename) == 0) {
|
||||||
|
_dtool_name = head;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map = map->l_next;
|
map = map->l_next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -634,19 +679,27 @@ read_args() {
|
|||||||
pifstream maps("/proc/self/maps");
|
pifstream maps("/proc/self/maps");
|
||||||
#endif
|
#endif
|
||||||
while (!maps.fail() && !maps.eof()) {
|
while (!maps.fail() && !maps.eof()) {
|
||||||
|
if (!_dtool_name.empty()) break;
|
||||||
|
|
||||||
char buffer[PATH_MAX];
|
char buffer[PATH_MAX];
|
||||||
buffer[0] = 0;
|
buffer[0] = 0;
|
||||||
maps.getline(buffer, PATH_MAX);
|
maps.getline(buffer, PATH_MAX);
|
||||||
const char *tail = strrchr(buffer, '/');
|
|
||||||
const char *head = strchr(buffer, '/');
|
const char *head = strchr(buffer, '/');
|
||||||
if (tail && head && (strcmp(tail, "/libp3dtool.so." PANDA_ABI_VERSION_STR) == 0
|
if (!head) continue;
|
||||||
|| strcmp(tail, "/libp3dtool.so") == 0)) {
|
const char *tail = strrchr(head, '/');
|
||||||
_dtool_name = head;
|
if (!tail) continue;
|
||||||
|
|
||||||
|
for (const char *filename : libp3dtool_filenames) {
|
||||||
|
if (strcmp(&tail[1], filename) == 0) {
|
||||||
|
_dtool_name = head;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
maps.close();
|
maps.close();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* !LINK_ALL_STATIC */
|
||||||
|
|
||||||
// Now, we need to fill in _binary_name. This contains the full path to the
|
// Now, we need to fill in _binary_name. This contains the full path to the
|
||||||
// currently running executable.
|
// currently running executable.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user