Skip to content

Commit

Permalink
Allow DlLoader to have multiple fallback names when searching for a l…
Browse files Browse the repository at this point in the history
…ibrary (#1635)
  • Loading branch information
Qining authored Feb 22, 2018
1 parent 15ce46c commit 0a1be56
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 15 deletions.
2 changes: 1 addition & 1 deletion core/cc/armlinux/get_vulkan_proc_address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,6 @@ GetVulkanInstanceProcAddressFunc* GetVulkanInstanceProcAddress = getVulkanInstan
GetVulkanDeviceProcAddressFunc* GetVulkanDeviceProcAddress = getVulkanDeviceProcAddress;
GetVulkanProcAddressFunc* GetVulkanProcAddress = getVulkanProcAddress;
bool HasVulkanLoader() {
return DlLoader::can_load("libvulkan.so");
return DlLoader::can_load("libvulkan.so") || DlLoader::can_load("libvulkan.so.1");
}
} // namespace core
38 changes: 30 additions & 8 deletions core/cc/dl_loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,15 @@
namespace {

// load defs
void* load(const char* name) {
void* load() {
return nullptr;
}

template<typename... ConstCharPtrs>
void* load(const char* name, ConstCharPtrs... fallback_names) {
void* ret = nullptr;
#if TARGET_OS == GAPID_OS_WINDOWS
return reinterpret_cast<void*>(LoadLibraryExA(name, NULL, 0));
ret = reinterpret_cast<void*>(LoadLibraryExA(name, NULL, 0));
#elif TARGET_OS == GAPID_OS_OSX
if (name == nullptr) {
return nullptr;
Expand All @@ -50,14 +56,19 @@ void* load(const char* name) {
remove(tmp);
}
}
return res;
ret = res;
#else
return dlopen(name, RTLD_NOW | RTLD_LOCAL);
ret = dlopen(name, RTLD_NOW | RTLD_LOCAL);
#endif // TARGET_OS
if (ret == nullptr) {
return load(fallback_names...);
}
return ret;
}

void* must_load(const char* name) {
void* res = load(name);
template<typename... ConstCharPtrs>
void* must_load(const char* name, ConstCharPtrs... fallback_names) {
void* res = load(name, fallback_names...);
if (res == nullptr) {
#if TARGET_OS == GAPID_OS_WINDOWS
GAPID_FATAL("Can't load library %s: %d", name, GetLastError());
Expand Down Expand Up @@ -100,8 +111,8 @@ void close(void* lib) {
} // anonymous namespace

namespace core {

DlLoader::DlLoader(const char* name) : mLibrary(must_load(name)) {}
template<typename... ConstCharPtrs>
DlLoader::DlLoader(const char* name, ConstCharPtrs... fallback_names) : mLibrary(must_load(name, fallback_names...)) {}

DlLoader::~DlLoader() {
close(mLibrary);
Expand All @@ -125,4 +136,15 @@ bool DlLoader::can_load(const char* lib_name) {
return false;
}

#define CC const char*
#define DL(...) \
template DlLoader::DlLoader(__VA_ARGS__)
DL(CC _1);
DL(CC _1, CC _2);
DL(CC _1, CC _2, CC _3);
DL(CC _1, CC _2, CC _3, CC _4);
DL(CC _1, CC _2, CC _3, CC _4, CC _5);
#undef DL
#undef CC

} // namespace core
10 changes: 6 additions & 4 deletions core/cc/dl_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ namespace core {
// Utility class for retrieving function pointers from dynamic libraries.
class DlLoader {
public:
// Loads the specified dynamic library.
// If the library cannot be loaded then this is a fatal error.
// For *nix systems, a nullptr can be used to search the application's functions.
DlLoader(const char* name);
// Loads the dynamic library specified by the given name and fallback names
// (if any). Names will be used to try to find the library in order. If the
// library cannot be loaded then this is a fatal error. For *nix systems,
// a nullptr can be used to search the application's functions.
template<typename... ConstCharPtrs>
DlLoader(const char* name, ConstCharPtrs... fallback_names);

// Unloads the library loaded in the constructor.
~DlLoader();
Expand Down
4 changes: 2 additions & 2 deletions core/cc/linux/get_vulkan_proc_address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ typedef size_t VkInstance;
void* getVulkanInstanceProcAddress(size_t instance, const char *name, bool bypassLocal) {
typedef PFN_vkVoidFunction (*VPAPROC)(VkInstance instance, const char *name);

static DlLoader dylib("libvulkan.so");
static DlLoader dylib("libvulkan.so", "libvulkan.so.1");

if (VPAPROC vpa = reinterpret_cast<VPAPROC>(dylib.lookup("vkGetInstanceProcAddr"))) {
if (void* proc = vpa(instance, name)) {
Expand Down Expand Up @@ -72,6 +72,6 @@ GetVulkanInstanceProcAddressFunc* GetVulkanInstanceProcAddress = getVulkanInstan
GetVulkanDeviceProcAddressFunc* GetVulkanDeviceProcAddress = getVulkanDeviceProcAddress;
GetVulkanProcAddressFunc* GetVulkanProcAddress = getVulkanProcAddress;
bool HasVulkanLoader() {
return DlLoader::can_load("libvulkan.so");
return DlLoader::can_load("libvulkan.so") || DlLoader::can_load("libvulkan.so.1");
}
} // namespace core

0 comments on commit 0a1be56

Please sign in to comment.