mirror of
https://github.com/thp/pyotherside.git
synced 2025-02-05 08:08:23 +08:00
Load libpython globally on Linux distributions
This commit is contained in:
parent
5dbde1fc30
commit
5289b79e7d
74
src/global_libpython_loader.cpp
Normal file
74
src/global_libpython_loader.cpp
Normal file
@ -0,0 +1,74 @@
|
||||
|
||||
/**
|
||||
* PyOtherSide: Asynchronous Python 3 Bindings for Qt 5
|
||||
* Copyright (c) 2013, Thomas Perl <m@thp.io>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
**/
|
||||
|
||||
#include "global_libpython_loader.h"
|
||||
|
||||
namespace GlobalLibPythonLoader {
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <link.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static int load_python_globally_callback(struct dl_phdr_info *info, size_t size, void *data)
|
||||
{
|
||||
int major, minor;
|
||||
char *basename = strrchr(info->dlpi_name, '/');
|
||||
int *success = (int *)data;
|
||||
|
||||
if (basename != NULL) {
|
||||
if (sscanf(basename, "/libpython%d.%d.so", &major, &minor) != 2) {
|
||||
if (sscanf(basename, "/libpython%d.%dm.so", &major, &minor) != 2) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void *pylib = dlopen(info->dlpi_name, RTLD_GLOBAL | RTLD_NOW);
|
||||
if (pylib != NULL) {
|
||||
*success = 1;
|
||||
} else {
|
||||
fprintf(stderr, "Could not load python library '%s': %s\n",
|
||||
info->dlpi_name, dlerror());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool loadPythonGlobally()
|
||||
{
|
||||
int success = 0;
|
||||
dl_iterate_phdr(load_python_globally_callback, &success);
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
#else /* __linux__ */
|
||||
|
||||
bool loadPythonGlobally()
|
||||
{
|
||||
/* On non-Linux systems, no need to load globally */
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif /* __linux__ */
|
||||
|
||||
}; /* namespace GlobalLibPythonLoader */
|
26
src/global_libpython_loader.h
Normal file
26
src/global_libpython_loader.h
Normal file
@ -0,0 +1,26 @@
|
||||
|
||||
/**
|
||||
* PyOtherSide: Asynchronous Python 3 Bindings for Qt 5
|
||||
* Copyright (c) 2013, Thomas Perl <m@thp.io>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
* PERFORMANCE OF THIS SOFTWARE.
|
||||
**/
|
||||
|
||||
#ifndef PYOTHERSIDE_GLOBAL_LIBPYTHON_LOADER_H
|
||||
#define PYOTHERSIDE_GLOBAL_LIBPYTHON_LOADER_H
|
||||
|
||||
namespace GlobalLibPythonLoader {
|
||||
bool loadPythonGlobally();
|
||||
};
|
||||
|
||||
#endif /* PYOTHERSIDE_GLOBAL_LIBPYTHON_LOADER_H */
|
@ -19,6 +19,7 @@
|
||||
#include "qpython_priv.h"
|
||||
#include "qpython.h"
|
||||
#include "qpython_imageprovider.h"
|
||||
#include "global_libpython_loader.h"
|
||||
|
||||
#include "pyotherside_plugin.h"
|
||||
|
||||
@ -42,6 +43,13 @@ void
|
||||
PyOtherSideExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri)
|
||||
{
|
||||
Q_ASSERT(QString(PYOTHERSIDE_PLUGIN_ID) == uri);
|
||||
|
||||
// In some Linux distributions, the plugin (and subsequently libpython)
|
||||
// isn't loaded with the RTLD_GLOBAL flag, so symbols in libpython that
|
||||
// are needed by shared Python modules won't be resolved unless we also
|
||||
// load libpython again RTLD_GLOBAL again. We do this here.
|
||||
GlobalLibPythonLoader::loadPythonGlobally();
|
||||
|
||||
engine->addImageProvider(PYOTHERSIDE_IMAGEPROVIDER_ID, new QPythonImageProvider);
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,10 @@ HEADERS += qpython_worker.h
|
||||
SOURCES += qpython_priv.cpp
|
||||
HEADERS += qpython_priv.h
|
||||
|
||||
# Globally Load Python hack
|
||||
SOURCES += global_libpython_loader.cpp
|
||||
HEADERS += global_libpython_loader.h
|
||||
|
||||
# Type System Conversion Logic
|
||||
HEADERS += converter.h
|
||||
HEADERS += qvariant_converter.h
|
||||
|
Loading…
x
Reference in New Issue
Block a user