diff --git a/deps/obs-scripting/obs-scripting-python-import.c b/deps/obs-scripting/obs-scripting-python-import.c index 942a691dd..db926fc39 100644 --- a/deps/obs-scripting/obs-scripting-python-import.c +++ b/deps/obs-scripting/obs-scripting-python-import.c @@ -27,22 +27,26 @@ #endif #ifdef _WIN32 -#define SO_EXT ".dll" +#include +#include +#define F_OK 0 +#define access _access +#define VERSION_PATTERN "%d%d" +#define FILE_PATTERN "python%s.dll" +#define PATH_MAX MAX_PATH #elif __APPLE__ -#define SO_EXT ".dylib" +#define VERSION_PATTERN "%d.%d" +#define FILE_PATTERN "Python.framework/Versions/Current/lib/libpython%s.dylib" #endif -#ifdef __APPLE__ -#define PYTHON_LIB_SUBDIR "lib/" -#else -#define PYTHON_LIB_SUBDIR "" -#endif +#define PY_MAJOR_VERSION_MAX 3 +#define PY_MINOR_VERSION_MAX 10 bool import_python(const char *python_path) { struct dstr lib_path; bool success = false; - void *lib; + void *lib = NULL; if (!python_path) python_path = ""; @@ -50,11 +54,42 @@ bool import_python(const char *python_path) dstr_init_copy(&lib_path, python_path); dstr_replace(&lib_path, "\\", "/"); if (!dstr_is_empty(&lib_path)) { - dstr_cat(&lib_path, "/" PYTHON_LIB_SUBDIR); + dstr_cat(&lib_path, "/"); } - dstr_cat(&lib_path, PYTHON_LIB SO_EXT); - lib = os_dlopen(lib_path.array); + struct dstr lib_candidate_path; + dstr_init_copy(&lib_candidate_path, lib_path.array); + + char cur_version[5]; + char next_version[5]; + + char temp[PATH_MAX]; + + sprintf(cur_version, VERSION_PATTERN, PY_MAJOR_VERSION_MAX, + PY_MINOR_VERSION_MAX); + sprintf(temp, FILE_PATTERN, cur_version); + + dstr_cat(&lib_candidate_path, temp); + + int minor_version = PY_MINOR_VERSION_MAX; + do { + if (access(lib_candidate_path.array, F_OK) == 0) { + lib = os_dlopen(lib_candidate_path.array); + } + + if (lib) { + break; + } + + sprintf(cur_version, VERSION_PATTERN, PY_MAJOR_VERSION_MAX, + minor_version); + sprintf(next_version, VERSION_PATTERN, PY_MAJOR_VERSION_MAX, + --minor_version); + dstr_replace(&lib_candidate_path, cur_version, next_version); + } while (minor_version > 5); + + dstr_free(&lib_candidate_path); + if (!lib) { blog(LOG_WARNING, "[Python] Could not load library: %s", lib_path.array); @@ -155,7 +190,6 @@ bool import_python(const char *python_path) #endif #undef IMPORT_FUNC - success = true; fail: diff --git a/deps/obs-scripting/obs-scripting-python-import.h b/deps/obs-scripting/obs-scripting-python-import.h index 82f9472be..2fe99b55a 100644 --- a/deps/obs-scripting/obs-scripting-python-import.h +++ b/deps/obs-scripting/obs-scripting-python-import.h @@ -44,7 +44,6 @@ #endif #if RUNTIME_LINK - #ifdef NO_REDEFS #define PY_EXTERN #else @@ -262,7 +261,7 @@ static inline void Import__Py_XDECREF(PyObject *op) #undef Py_XDECREF #define Py_XDECREF(op) Import__Py_XDECREF(_PyObject_CAST(op)) -#endif +#endif // PY_VERSION_HEX >= 0x030800f0 #if PY_VERSION_HEX >= 0x030900b0 static inline int Import_PyType_HasFeature(PyTypeObject *type, @@ -271,8 +270,7 @@ static inline int Import_PyType_HasFeature(PyTypeObject *type, return ((PyType_GetFlags(type) & feature) != 0); } #define PyType_HasFeature(t, f) Import_PyType_HasFeature(t, f) -#endif +#endif // PY_VERSION_HEX >= 0x030900b0 -#endif - -#endif +#endif // NO_REDEFS +#endif // RUNTIME_LINK diff --git a/deps/obs-scripting/obs-scripting-python.c b/deps/obs-scripting/obs-scripting-python.c index 2603fd704..947e34838 100644 --- a/deps/obs-scripting/obs-scripting-python.c +++ b/deps/obs-scripting/obs-scripting-python.c @@ -1624,8 +1624,17 @@ bool obs_scripting_load_python(const char *python_path) return false; if (python_path && *python_path) { +#ifdef __APPLE__ + char temp[PATH_MAX]; + sprintf(temp, "%s/Python.framework/Versions/Current", + python_path); + os_utf8_to_wcs(temp, 0, home_path, PATH_MAX); + Py_SetPythonHome(home_path); +#else + os_utf8_to_wcs(python_path, 0, home_path, 1024); Py_SetPythonHome(home_path); +#endif #if 0 dstr_copy(&old_path, getenv("PATH")); _putenv("PYTHONPATH=");