mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 09:52:27 -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
|
#end lib_target
|
||||||
|
|
||||||
|
|
||||||
#begin 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 BUILD_TARGET $[HAVE_PYTHON]
|
||||||
#define USE_PACKAGES tinyxml python
|
#define USE_PACKAGES tinyxml python
|
||||||
#define TARGET p3dpython
|
#define TARGET libp3dpython
|
||||||
|
#define LIB_PREFIX
|
||||||
|
|
||||||
#define OTHER_LIBS \
|
#define OTHER_LIBS \
|
||||||
dtoolutil:c dtoolbase:c dtool:m \
|
dtoolutil:c dtoolbase:c dtool:m \
|
||||||
@ -122,12 +130,35 @@
|
|||||||
|
|
||||||
#begin bin_target
|
#begin bin_target
|
||||||
#define BUILD_TARGET $[HAVE_PYTHON]
|
#define BUILD_TARGET $[HAVE_PYTHON]
|
||||||
|
#define USE_PACKAGES tinyxml python
|
||||||
#define TARGET p3dpython
|
#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 \
|
#define SOURCES \
|
||||||
|
binaryXml.cxx binaryXml.h \
|
||||||
fhandle.h \
|
fhandle.h \
|
||||||
p3dPythonMain.cxx \
|
handleStream.cxx handleStream.h handleStream.I \
|
||||||
run_p3dpython.h
|
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
|
#end bin_target
|
||||||
|
|
||||||
#begin static_lib_target
|
#begin static_lib_target
|
||||||
|
@ -19,29 +19,16 @@
|
|||||||
#include <string.h> // strrchr
|
#include <string.h> // strrchr
|
||||||
using namespace std;
|
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
|
// Function: main
|
||||||
// Description: This is a trivial main() function that loads and runs
|
// Description: This is a trivial main() function that invokes
|
||||||
// libp3dpython.dll. It's used to build p3dpython.exe,
|
// P3DPythonRun. It's used to build p3dpython.exe,
|
||||||
// which is the preferred way to run Python in a child
|
// which is the preferred way to run Python in a child
|
||||||
// process, as a separate executable.
|
// process, as a separate executable.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[]) {
|
main(int argc, char *argv[]) {
|
||||||
const char *program_name = argv[0];
|
const char *program_name = argv[0];
|
||||||
const char *dll_file = NULL;
|
|
||||||
const char *archive_file = NULL;
|
const char *archive_file = NULL;
|
||||||
const char *input_handle_str = NULL;
|
const char *input_handle_str = NULL;
|
||||||
const char *output_handle_str = NULL;
|
const char *output_handle_str = NULL;
|
||||||
@ -49,27 +36,19 @@ main(int argc, char *argv[]) {
|
|||||||
const char *interactive_console_str = NULL;
|
const char *interactive_console_str = NULL;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
dll_file = argv[1];
|
archive_file = argv[1];
|
||||||
}
|
}
|
||||||
if (argc > 2) {
|
if (argc > 2) {
|
||||||
archive_file = argv[2];
|
input_handle_str = argv[2];
|
||||||
}
|
}
|
||||||
if (argc > 3) {
|
if (argc > 3) {
|
||||||
input_handle_str = argv[3];
|
output_handle_str = argv[3];
|
||||||
}
|
}
|
||||||
if (argc > 4) {
|
if (argc > 4) {
|
||||||
output_handle_str = argv[4];
|
error_handle_str = argv[4];
|
||||||
}
|
}
|
||||||
if (argc > 5) {
|
if (argc > 5) {
|
||||||
error_handle_str = argv[5];
|
interactive_console_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (archive_file == NULL || *archive_file == '\0') {
|
if (archive_file == NULL || *archive_file == '\0') {
|
||||||
@ -118,121 +97,6 @@ main(int argc, char *argv[]) {
|
|||||||
<< ", " << error_handle << "\n";
|
<< ", " << error_handle << "\n";
|
||||||
cerr << "interactive_console = " << interactive_console << "\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,
|
if (!run_p3dpython(program_name, archive_file, input_handle, output_handle,
|
||||||
error_handle, interactive_console)) {
|
error_handle, interactive_console)) {
|
||||||
cerr << "Failure on startup.\n";
|
cerr << "Failure on startup.\n";
|
||||||
|
@ -747,51 +747,16 @@ start_p3dpython(P3DInstance *inst) {
|
|||||||
<< "PRC_PATH set to: " << prc_path << "\n";
|
<< "PRC_PATH set to: " << prc_path << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the name of the executable and dynamic library to run.
|
// Get the name of the executable to run. Ideally, we'll run the
|
||||||
// Ideally, we'll run the executable successfully, in a sub-process;
|
// executable successfully, in a sub-process; this will in turn load
|
||||||
// this will in turn load and run the dynamic library. If that
|
// and run the dynamic library. If that fails for some reason, we
|
||||||
// fails for some reason, we can fall back to loading and running
|
// can fall back to loading and running the library directly.
|
||||||
// the library directly.
|
_p3dpython_exe = P3D_PLUGIN_P3DPYTHON;
|
||||||
_p3dpython_exe = _python_root_dir + "/p3dpython";
|
if (_p3dpython_exe.empty()) {
|
||||||
|
_p3dpython_exe = _python_root_dir + "/p3dpython";
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
_p3dpython_exe += ".exe";
|
_p3dpython_exe += ".exe";
|
||||||
#endif
|
#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.
|
// Populate the new process' environment.
|
||||||
@ -998,8 +963,7 @@ start_p3dpython(P3DInstance *inst) {
|
|||||||
// to p3dpython.
|
// to p3dpython.
|
||||||
_mf_filename = inst->_panda3d->get_archive_file_pathname();
|
_mf_filename = inst->_panda3d->get_archive_file_pathname();
|
||||||
|
|
||||||
nout << "Attempting to start python from " << _p3dpython_exe
|
nout << "Attempting to start python from " << _p3dpython_exe << "\n";
|
||||||
<< " and " << _p3dpython_dll << "\n";
|
|
||||||
|
|
||||||
bool started_p3dpython;
|
bool started_p3dpython;
|
||||||
if (one_process) {
|
if (one_process) {
|
||||||
@ -1225,10 +1189,10 @@ win_create_process() {
|
|||||||
// Construct the command-line string, containing the quoted
|
// Construct the command-line string, containing the quoted
|
||||||
// command-line arguments.
|
// command-line arguments.
|
||||||
ostringstream stream;
|
ostringstream stream;
|
||||||
stream << "\"" << _p3dpython_exe << "\" \"" << _p3dpython_dll
|
stream << "\"" << _p3dpython_exe << "\" \"" << _mf_filename
|
||||||
<< "\" \"" << _mf_filename << "\" \"" << _input_handle
|
<< "\" \"" << _input_handle << "\" \"" << _output_handle
|
||||||
<< "\" \"" << _output_handle << "\" \"" << _error_handle
|
<< "\" \"" << _error_handle << "\" \"" << _interactive_console
|
||||||
<< "\" \"" << _interactive_console << "\"";
|
<< "\"";
|
||||||
|
|
||||||
// I'm not sure why CreateProcess wants a non-const char pointer for
|
// 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
|
// 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;
|
error_handle_stream << _error_handle;
|
||||||
string error_handle_str = error_handle_stream.str();
|
string error_handle_str = error_handle_stream.str();
|
||||||
|
|
||||||
execle(_p3dpython_exe.c_str(),
|
execle(_p3dpython_exe.c_str(), _p3dpython_exe.c_str(),
|
||||||
_p3dpython_exe.c_str(), _p3dpython_dll.c_str(),
|
|
||||||
_mf_filename.c_str(), input_handle_str.c_str(),
|
_mf_filename.c_str(), input_handle_str.c_str(),
|
||||||
output_handle_str.c_str(), error_handle_str.c_str(),
|
output_handle_str.c_str(), error_handle_str.c_str(),
|
||||||
_interactive_console ? "1" : "0", (char *)0, &ptrs[0]);
|
_interactive_console ? "1" : "0", (char *)0, &ptrs[0]);
|
||||||
@ -1386,12 +1349,14 @@ p3dpython_thread_run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now load the library.
|
// Now load the library.
|
||||||
|
string libp3dpython = _python_root_dir + "/libp3dpython";
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
libp3dpython += ".dll";
|
||||||
SetErrorMode(0);
|
SetErrorMode(0);
|
||||||
HMODULE module = LoadLibrary(_p3dpython_dll.c_str());
|
HMODULE module = LoadLibrary(libp3dpython.c_str());
|
||||||
if (module == NULL) {
|
if (module == NULL) {
|
||||||
// Couldn't load the DLL.
|
// Couldn't load the DLL.
|
||||||
nout << "Couldn't load " << _p3dpython_dll << "\n";
|
nout << "Couldn't load " << libp3dpython << "\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1399,10 +1364,15 @@ p3dpython_thread_run() {
|
|||||||
|
|
||||||
#else // _WIN32
|
#else // _WIN32
|
||||||
// Posix case.
|
// 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) {
|
if (module == NULL) {
|
||||||
// Couldn't load the .so.
|
// Couldn't load the .so.
|
||||||
nout << "Couldn't load " << _p3dpython_dll << "\n";
|
nout << "Couldn't load " << libp3dpython << "\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1416,7 +1386,7 @@ p3dpython_thread_run() {
|
|||||||
return;
|
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,
|
_input_handle, _output_handle, _error_handle,
|
||||||
_interactive_console)) {
|
_interactive_console)) {
|
||||||
nout << "Failure on startup.\n";
|
nout << "Failure on startup.\n";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user