Skip to content

Commit 18033c2

Browse files
Split the list of paths from a single string.
1 parent 9faeca3 commit 18033c2

File tree

2 files changed

+55
-21
lines changed

2 files changed

+55
-21
lines changed

include/pybind11/detail/non_limited_api.h

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
#include "common.h"
66

77
#include <filesystem>
8+
#include <string_view>
9+
#include <vector>
10+
#include <utility>
811
#ifdef _WIN32
912
#define WIN32_LEAN_AND_MEAN
1013
#define NOMINMAX 1
@@ -89,9 +92,12 @@ using namespace detail;
8992
#define PYBIND11_NONLIMITEDAPI_API_IMPL
9093
#endif
9194

92-
// `app_suffix` can be null.
95+
// Searches for `pybind11nonlimitedapi[_`app_suffix`][_X.Y]` in `library_dir / library_dir_suffixes...` (in all suffixes in order).
96+
// Setting `use_version_specific_lib` to false removes the `_X.Y` part.
97+
// Setting `app_suffix` to nullptr removes the `_`+app_suffix part.
9398
// `library_dir` can be empty, then it's ignored.
94-
PYBIND11_NONLIMITEDAPI_API void EnsureSharedLibraryIsLoaded(bool use_version_specific_lib, const char *app_suffix, std::filesystem::path library_dir);
99+
// If `library_dir_suffixes` is empty, `{"."}` is assumed.
100+
PYBIND11_NONLIMITEDAPI_API void EnsureSharedLibraryIsLoaded(bool use_version_specific_lib, const char *app_suffix, std::filesystem::path library_dir, std::vector<std::filesystem::path> library_dir_suffixes);
95101

96102
#ifndef PYBIND11_NONLIMITEDAPI_FUNC
97103
#define PYBIND11_NONLIMITEDAPI_FUNC(ret_, func_, params_, param_uses_) \
@@ -184,10 +190,10 @@ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
184190
#define PYBIND11_NONLIMITEDAPI_LIB_SUFFIX_FOR_MODULE nullptr
185191
#endif
186192

187-
#ifdef PYBIND11_NONLIMITEDAPI_SHIM_PATH_RELATIVE_TO_LIBRARY_DIR
188-
#define PYBIND11_NONLIMITEDAPI_SHIM_PATH_RELATIVE_TO_LIBRARY_DIR_WITH_SLASH / PYBIND11_NONLIMITEDAPI_SHIM_PATH_RELATIVE_TO_LIBRARY_DIR
189-
#else
190-
#define PYBIND11_NONLIMITEDAPI_SHIM_PATH_RELATIVE_TO_LIBRARY_DIR_WITH_SLASH
193+
// This is a single `|`-separated string.
194+
// Would normally use a comma-separated list of strings, but nvcc chokes on it (considers `-DA=B,C` to mean `-DA=B -DC`).
195+
#ifndef PYBIND11_NONLIMITEDAPI_SHIM_PATHS_RELATIVE_TO_LIBRARY_DIR
196+
#define PYBIND11_NONLIMITEDAPI_SHIM_PATHS_RELATIVE_TO_LIBRARY_DIR ""
191197
#endif
192198

193199
#ifdef _WIN32
@@ -209,15 +215,15 @@ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
209215
else if (size == MAX_PATH) \
210216
throw std::runtime_error( "pybind11 non-limited-api: The self library path is too long." ); \
211217
\
212-
return std::filesystem::path(path).parent_path() PYBIND11_NONLIMITEDAPI_SHIM_PATH_RELATIVE_TO_LIBRARY_DIR_WITH_SLASH; \
218+
return std::filesystem::path(path).parent_path(); \
213219
}()
214220
#else
215221
#define PYBIND11_NONLIMITEDAPI_GET_SHARED_LIBRARY_DIR(module_) \
216222
[]{ \
217223
Dl_info info; \
218224
if (!dladdr((void*)PYBIND11_CONCAT(PyInit_, module_), &info)) \
219225
throw std::runtime_error( "pybind11 non-limited-api: Failed to get the self library path." ); \
220-
return std::filesystem::path(info.dli_fname).parent_path() PYBIND11_NONLIMITEDAPI_SHIM_PATH_RELATIVE_TO_LIBRARY_DIR_WITH_SLASH; \
226+
return std::filesystem::path(info.dli_fname).parent_path(); \
221227
}()
222228
#endif
223229

@@ -227,7 +233,22 @@ PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
227233
PYBIND11_MAYBE_UNUSED \
228234
static void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ &); \
229235
PYBIND11_PLUGIN_IMPL(name) { \
230-
pybind11::non_limited_api::EnsureSharedLibraryIsLoaded(true, PYBIND11_NONLIMITEDAPI_LIB_SUFFIX_FOR_MODULE, PYBIND11_NONLIMITEDAPI_GET_SHARED_LIBRARY_DIR(name)); \
236+
std::vector<std::filesystem::path> suffixes; \
237+
{ \
238+
std::string_view v = PYBIND11_NONLIMITEDAPI_SHIM_PATHS_RELATIVE_TO_LIBRARY_DIR; \
239+
if (!v.empty()) \
240+
{ \
241+
while (true) \
242+
{ \
243+
auto pos = v.find_first_of('|'); /* Using a weird separator because nvcc chokes on commas (considers `-DA=B,C` to mean `-DA=B -DC`) */\
244+
suffixes.emplace_back(v.substr(0, pos)); \
245+
if (pos == std::string_view::npos) \
246+
break; \
247+
v.remove_prefix(pos + 1); \
248+
} \
249+
} \
250+
} \
251+
pybind11::non_limited_api::EnsureSharedLibraryIsLoaded(true, PYBIND11_NONLIMITEDAPI_LIB_SUFFIX_FOR_MODULE, PYBIND11_NONLIMITEDAPI_GET_SHARED_LIBRARY_DIR(name), std::move(suffixes)); \
231252
PYBIND11_ENSURE_INTERNALS_READY \
232253
auto m = ::pybind11::module_::create_extension_module( \
233254
PYBIND11_TOSTRING(name), \

source/non_limited_api/non_limited_api_stubs.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ static void *&SharedLibraryHandle()
2222
return ret;
2323
}
2424

25-
void pybind11::non_limited_api::EnsureSharedLibraryIsLoaded(bool use_version_specific_lib, const char *app_suffix, std::filesystem::path library_dir)
25+
void pybind11::non_limited_api::EnsureSharedLibraryIsLoaded(bool use_version_specific_lib, const char *app_suffix, std::filesystem::path library_dir, std::vector<std::filesystem::path> library_dir_suffixes)
2626
{
2727
void *&handle = SharedLibraryHandle();
2828
if (handle)
@@ -51,19 +51,32 @@ void pybind11::non_limited_api::EnsureSharedLibraryIsLoaded(bool use_version_spe
5151
}
5252
}
5353

54-
// Get a path to this library.
55-
#ifdef _WIN32
56-
std::wstring dir;
57-
#else
58-
std::string dir;
59-
#endif
60-
if (!library_dir.empty())
54+
if (library_dir_suffixes.empty())
55+
library_dir_suffixes.push_back(".");
56+
57+
for (const auto &suffix : library_dir_suffixes)
6158
{
62-
dir = library_dir.native();
63-
dir += '/';
64-
}
59+
// Get a path to this library.
60+
#ifdef _WIN32
61+
std::wstring dir;
62+
#else
63+
std::string dir;
64+
#endif
65+
if (!library_dir.empty())
66+
{
67+
dir += library_dir.native();
68+
dir += '/';
69+
}
70+
if (suffix != ".")
71+
{
72+
dir += suffix.native();
73+
dir += '/';
74+
}
6575

66-
handle = PYBIND11_NONLIMITEDAPI_DLOPEN(dir, file);
76+
handle = PYBIND11_NONLIMITEDAPI_DLOPEN(dir, file);
77+
if (handle)
78+
break;
79+
}
6780
if (!handle)
6881
{
6982
std::fprintf(stderr, "pybind11 non-limited-api: Failed to load library `%s` with error `%s`.\n", file.c_str(), PYBIND11_NONLIMITEDAPI_DLOPEN_ERROR);

0 commit comments

Comments
 (0)