mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 16:58:40 -04:00
separate out p3dpython.exe and libp3dpython.dll
This commit is contained in:
parent
06fa43a83b
commit
1415193b5e
@ -93,10 +93,18 @@
|
||||
|
||||
#end lib_target
|
||||
|
||||
|
||||
#begin lib_target
|
||||
// *****
|
||||
// Note! This lib is used to run P3DPythonRun within the parent
|
||||
// (browser) process, instead of forking a child. This seems like
|
||||
// it's going to be a bad idea in the long term. This lib remains
|
||||
// for now as an experiment, but it will likely be removed very soon.
|
||||
// ****
|
||||
#define BUILD_TARGET $[HAVE_PYTHON]
|
||||
#define USE_PACKAGES tinyxml python
|
||||
#define TARGET p3dpython
|
||||
#define TARGET libp3dpython
|
||||
#define LIB_PREFIX
|
||||
|
||||
#define OTHER_LIBS \
|
||||
dtoolutil:c dtoolbase:c dtool:m \
|
||||
@ -122,12 +130,35 @@
|
||||
|
||||
#begin bin_target
|
||||
#define BUILD_TARGET $[HAVE_PYTHON]
|
||||
#define USE_PACKAGES tinyxml python
|
||||
#define TARGET p3dpython
|
||||
|
||||
#define OTHER_LIBS \
|
||||
dtoolutil:c dtoolbase:c dtool:m \
|
||||
interrogatedb:c dconfig:c dtoolconfig:m \
|
||||
express:c pandaexpress:m \
|
||||
prc:c pstatclient:c pandabase:c linmath:c putil:c \
|
||||
pipeline:c event:c nativenet:c net:c panda:m
|
||||
|
||||
#define SOURCES \
|
||||
binaryXml.cxx binaryXml.h \
|
||||
fhandle.h \
|
||||
p3dPythonMain.cxx \
|
||||
run_p3dpython.h
|
||||
handleStream.cxx handleStream.h handleStream.I \
|
||||
handleStreamBuf.cxx handleStreamBuf.h handleStreamBuf.I \
|
||||
p3d_lock.h p3d_plugin.h \
|
||||
p3d_plugin_config.h \
|
||||
p3dCInstance.cxx \
|
||||
p3dCInstance.h p3dCInstance.I \
|
||||
p3dPythonRun.cxx p3dPythonRun.h p3dPythonRun.I \
|
||||
run_p3dpython.h run_p3dpython.cxx
|
||||
|
||||
#define SOURCES $[SOURCES] \
|
||||
p3dPythonMain.cxx
|
||||
|
||||
// If you have to link with a static Python library, define it here.
|
||||
#define EXTRA_LIBS $[EXTRA_P3DPYTHON_LIBS]
|
||||
|
||||
#define WIN_SYS_LIBS user32.lib
|
||||
#end bin_target
|
||||
|
||||
#begin static_lib_target
|
||||
|
@ -19,29 +19,16 @@
|
||||
#include <string.h> // strrchr
|
||||
using namespace std;
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
static const string dll_ext = ".dll";
|
||||
#elif defined(__APPLE__)
|
||||
static const string dll_ext = ".dylib";
|
||||
#else
|
||||
static const string dll_ext = ".so";
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: main
|
||||
// Description: This is a trivial main() function that loads and runs
|
||||
// libp3dpython.dll. It's used to build p3dpython.exe,
|
||||
// Description: This is a trivial main() function that invokes
|
||||
// P3DPythonRun. It's used to build p3dpython.exe,
|
||||
// which is the preferred way to run Python in a child
|
||||
// process, as a separate executable.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
main(int argc, char *argv[]) {
|
||||
const char *program_name = argv[0];
|
||||
const char *dll_file = NULL;
|
||||
const char *archive_file = NULL;
|
||||
const char *input_handle_str = NULL;
|
||||
const char *output_handle_str = NULL;
|
||||
@ -49,27 +36,19 @@ main(int argc, char *argv[]) {
|
||||
const char *interactive_console_str = NULL;
|
||||
|
||||
if (argc > 1) {
|
||||
dll_file = argv[1];
|
||||
archive_file = argv[1];
|
||||
}
|
||||
if (argc > 2) {
|
||||
archive_file = argv[2];
|
||||
input_handle_str = argv[2];
|
||||
}
|
||||
if (argc > 3) {
|
||||
input_handle_str = argv[3];
|
||||
output_handle_str = argv[3];
|
||||
}
|
||||
if (argc > 4) {
|
||||
output_handle_str = argv[4];
|
||||
error_handle_str = argv[4];
|
||||
}
|
||||
if (argc > 5) {
|
||||
error_handle_str = argv[5];
|
||||
}
|
||||
if (argc > 6) {
|
||||
interactive_console_str = argv[6];
|
||||
}
|
||||
|
||||
if (dll_file == NULL || *dll_file == '\0') {
|
||||
cerr << "No libp3dpython filename specified on command line.\n";
|
||||
return 1;
|
||||
interactive_console_str = argv[5];
|
||||
}
|
||||
|
||||
if (archive_file == NULL || *archive_file == '\0') {
|
||||
@ -118,121 +97,6 @@ main(int argc, char *argv[]) {
|
||||
<< ", " << error_handle << "\n";
|
||||
cerr << "interactive_console = " << interactive_console << "\n";
|
||||
|
||||
// For some vague idea of security, we insist that this program can
|
||||
// only run libp3dpython.dll: you can't use it to load just any
|
||||
// arbitrary DLL on the system. Of course, if you're successfully
|
||||
// running this program in the first place, you probably don't need
|
||||
// any help to load an arbitrary DLL, but whatever.
|
||||
|
||||
// Find the basename of the dll_file.
|
||||
const char *slash = strrchr(dll_file, '/');
|
||||
#ifdef _WIN32
|
||||
const char *backslash = strrchr(dll_file, '\\');
|
||||
if (backslash != NULL && (slash == NULL || backslash > slash)) {
|
||||
slash = backslash;
|
||||
}
|
||||
#endif
|
||||
string basename;
|
||||
if (slash == NULL) {
|
||||
basename = dll_file;
|
||||
} else {
|
||||
//dirname = string(dll_file, slash - dll_file);
|
||||
basename = (slash + 1);
|
||||
}
|
||||
|
||||
string expected_basename = "libp3dpython" + dll_ext;
|
||||
if (basename != expected_basename) {
|
||||
cerr << dll_file << " does not name " << expected_basename << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Everything checks out. Load and run the library.
|
||||
|
||||
#ifdef _WIN32
|
||||
SetErrorMode(0);
|
||||
HMODULE module = LoadLibrary(dll_file);
|
||||
if (module == NULL) {
|
||||
// Couldn't load the DLL.
|
||||
cerr << "Couldn't load " << dll_file << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define get_func GetProcAddress
|
||||
|
||||
// Get the default values for the communication handles, if we
|
||||
// weren't given specific handles.
|
||||
if (input_handle == invalid_fhandle) {
|
||||
input_handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
|
||||
// Close the system input handle, so application code won't
|
||||
// accidentally read from our private input stream.
|
||||
if (!SetStdHandle(STD_INPUT_HANDLE, INVALID_HANDLE_VALUE)) {
|
||||
cerr << "unable to reset input handle\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (output_handle == invalid_fhandle) {
|
||||
output_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
|
||||
// Close the system output handle, so application code won't
|
||||
// accidentally write to our private output stream.
|
||||
if (!SetStdHandle(STD_OUTPUT_HANDLE, INVALID_HANDLE_VALUE)) {
|
||||
cerr << "unable to reset input handle\n";
|
||||
}
|
||||
}
|
||||
|
||||
// No matter what error handle we were given, make it
|
||||
// STD_ERROR_HANDLE.
|
||||
if (error_handle == invalid_fhandle) {
|
||||
error_handle = GetStdHandle(STD_ERROR_HANDLE);
|
||||
} else {
|
||||
SetStdHandle(STD_ERROR_HANDLE, error_handle);
|
||||
}
|
||||
|
||||
#else // _WIN32
|
||||
// Posix case.
|
||||
void *module = dlopen(dll_file, RTLD_LAZY | RTLD_LOCAL);
|
||||
if (module == NULL) {
|
||||
// Couldn't load the .so.
|
||||
cerr << "Couldn't load " << dll_file << "\n";
|
||||
char *message = dlerror();
|
||||
if (message != (char *)NULL) {
|
||||
cerr << message << "\n";
|
||||
} else {
|
||||
cerr << "No error.\n";
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define get_func dlsym
|
||||
|
||||
// Get the default values for the communication handles, if we
|
||||
// weren't given specific handles.
|
||||
if (input_handle == invalid_fhandle) {
|
||||
input_handle = STDIN_FILENO;
|
||||
}
|
||||
|
||||
if (output_handle == invalid_fhandle) {
|
||||
output_handle = STDOUT_FILENO;
|
||||
}
|
||||
|
||||
// No matter what error handle we were given, make it STDERR_FILENO.
|
||||
if (error_handle == invalid_fhandle) {
|
||||
error_handle = STDERR_FILENO;
|
||||
} else if (error_handle != STDERR_FILENO) {
|
||||
dup2(error_handle, STDERR_FILENO);
|
||||
close(error_handle);
|
||||
error_handle = STDERR_FILENO;
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
run_p3dpython_func *run_p3dpython = (run_p3dpython_func *)get_func(module, "run_p3dpython");
|
||||
if (run_p3dpython == NULL) {
|
||||
cerr << "Couldn't find run_p3dpython\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!run_p3dpython(program_name, archive_file, input_handle, output_handle,
|
||||
error_handle, interactive_console)) {
|
||||
cerr << "Failure on startup.\n";
|
||||
|
@ -747,51 +747,16 @@ start_p3dpython(P3DInstance *inst) {
|
||||
<< "PRC_PATH set to: " << prc_path << "\n";
|
||||
}
|
||||
|
||||
// Get the name of the executable and dynamic library to run.
|
||||
// Ideally, we'll run the executable successfully, in a sub-process;
|
||||
// this will in turn load and run the dynamic library. If that
|
||||
// fails for some reason, we can fall back to loading and running
|
||||
// the library directly.
|
||||
_p3dpython_exe = _python_root_dir + "/p3dpython";
|
||||
// Get the name of the executable to run. Ideally, we'll run the
|
||||
// executable successfully, in a sub-process; this will in turn load
|
||||
// and run the dynamic library. If that fails for some reason, we
|
||||
// can fall back to loading and running the library directly.
|
||||
_p3dpython_exe = P3D_PLUGIN_P3DPYTHON;
|
||||
if (_p3dpython_exe.empty()) {
|
||||
_p3dpython_exe = _python_root_dir + "/p3dpython";
|
||||
#ifdef _WIN32
|
||||
_p3dpython_exe += ".exe";
|
||||
_p3dpython_exe += ".exe";
|
||||
#endif
|
||||
|
||||
_p3dpython_dll = P3D_PLUGIN_P3DPYTHON;
|
||||
if (_p3dpython_dll.empty()) {
|
||||
_p3dpython_dll = _python_root_dir + "/libp3dpython";
|
||||
#ifdef _WIN32
|
||||
_p3dpython_dll += ".dll";
|
||||
#elif defined(__APPLE__)
|
||||
_p3dpython_dll += ".dylib";
|
||||
#else
|
||||
_p3dpython_dll += ".so";
|
||||
#endif
|
||||
} else {
|
||||
// We have a custom path to libp3dpython.dylib etc., for
|
||||
// development.
|
||||
|
||||
#ifdef __APPLE__
|
||||
// For some bizarre reason, Apple's dlopen() goes out of its way to
|
||||
// ignore whatever full path you specify, and always searches for
|
||||
// the file's basename along $DYLD_LIBRARY_PATH. Weird. To work
|
||||
// around this and load the full path we're actually asking for, we
|
||||
// have to ensure that our desired path appears first on
|
||||
// $DYLD_LIBRARY_PATH.
|
||||
|
||||
// This may also inadvertently put other (incorrect) files first
|
||||
// on the path, but presumably this won't cause too much trouble,
|
||||
// since the user is in development mode anyway and maybe won't
|
||||
// mind.
|
||||
size_t slash = _p3dpython_dll.rfind('/');
|
||||
if (slash != string::npos) {
|
||||
string dirname = _p3dpython_dll.substr(0, slash);
|
||||
cerr << "dirname is " << dirname << "\n";
|
||||
|
||||
dyld_path = dirname + ":" + dyld_path;
|
||||
cerr << "dyld_path is " << dyld_path << "\n";
|
||||
}
|
||||
#endif // __APPLE__
|
||||
}
|
||||
|
||||
// Populate the new process' environment.
|
||||
@ -998,8 +963,7 @@ start_p3dpython(P3DInstance *inst) {
|
||||
// to p3dpython.
|
||||
_mf_filename = inst->_panda3d->get_archive_file_pathname();
|
||||
|
||||
nout << "Attempting to start python from " << _p3dpython_exe
|
||||
<< " and " << _p3dpython_dll << "\n";
|
||||
nout << "Attempting to start python from " << _p3dpython_exe << "\n";
|
||||
|
||||
bool started_p3dpython;
|
||||
if (one_process) {
|
||||
@ -1225,10 +1189,10 @@ win_create_process() {
|
||||
// Construct the command-line string, containing the quoted
|
||||
// command-line arguments.
|
||||
ostringstream stream;
|
||||
stream << "\"" << _p3dpython_exe << "\" \"" << _p3dpython_dll
|
||||
<< "\" \"" << _mf_filename << "\" \"" << _input_handle
|
||||
<< "\" \"" << _output_handle << "\" \"" << _error_handle
|
||||
<< "\" \"" << _interactive_console << "\"";
|
||||
stream << "\"" << _p3dpython_exe << "\" \"" << _mf_filename
|
||||
<< "\" \"" << _input_handle << "\" \"" << _output_handle
|
||||
<< "\" \"" << _error_handle << "\" \"" << _interactive_console
|
||||
<< "\"";
|
||||
|
||||
// I'm not sure why CreateProcess wants a non-const char pointer for
|
||||
// its command-line string, but I'm not taking chances. It gets a
|
||||
@ -1330,8 +1294,7 @@ posix_create_process() {
|
||||
error_handle_stream << _error_handle;
|
||||
string error_handle_str = error_handle_stream.str();
|
||||
|
||||
execle(_p3dpython_exe.c_str(),
|
||||
_p3dpython_exe.c_str(), _p3dpython_dll.c_str(),
|
||||
execle(_p3dpython_exe.c_str(), _p3dpython_exe.c_str(),
|
||||
_mf_filename.c_str(), input_handle_str.c_str(),
|
||||
output_handle_str.c_str(), error_handle_str.c_str(),
|
||||
_interactive_console ? "1" : "0", (char *)0, &ptrs[0]);
|
||||
@ -1386,12 +1349,14 @@ p3dpython_thread_run() {
|
||||
}
|
||||
|
||||
// Now load the library.
|
||||
string libp3dpython = _python_root_dir + "/libp3dpython";
|
||||
#ifdef _WIN32
|
||||
libp3dpython += ".dll";
|
||||
SetErrorMode(0);
|
||||
HMODULE module = LoadLibrary(_p3dpython_dll.c_str());
|
||||
HMODULE module = LoadLibrary(libp3dpython.c_str());
|
||||
if (module == NULL) {
|
||||
// Couldn't load the DLL.
|
||||
nout << "Couldn't load " << _p3dpython_dll << "\n";
|
||||
nout << "Couldn't load " << libp3dpython << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1399,10 +1364,15 @@ p3dpython_thread_run() {
|
||||
|
||||
#else // _WIN32
|
||||
// Posix case.
|
||||
void *module = dlopen(_p3dpython_dll.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||
#ifdef __APPLE__
|
||||
libp3dpython += ".dylib";
|
||||
#else
|
||||
libp3dpython += ".so";
|
||||
#endif
|
||||
void *module = dlopen(libp3dpython.c_str(), RTLD_LAZY | RTLD_LOCAL);
|
||||
if (module == NULL) {
|
||||
// Couldn't load the .so.
|
||||
nout << "Couldn't load " << _p3dpython_dll << "\n";
|
||||
nout << "Couldn't load " << libp3dpython << "\n";
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1416,7 +1386,7 @@ p3dpython_thread_run() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!run_p3dpython(_p3dpython_dll.c_str(), _mf_filename.c_str(),
|
||||
if (!run_p3dpython(libp3dpython.c_str(), _mf_filename.c_str(),
|
||||
_input_handle, _output_handle, _error_handle,
|
||||
_interactive_console)) {
|
||||
nout << "Failure on startup.\n";
|
||||
|
Loading…
x
Reference in New Issue
Block a user