Full rewrite of ppython. Instead of invoking the python interpreter by launching it's process, it interfaces to the Python API to import the script as module.

Basically, it's a hybrid between what it used to be and what the scripts would be, frozen.
The advantage of the first is that ppython is now a very small wrapper instead of the hacky problematic mess it used to be.
The advantage of the second is that the scripts are not as big as if they would be frozen. And they can be modified.
This commit is contained in:
rdb 2009-09-18 16:08:30 +00:00
parent 141fa88c7c
commit f97959e94b
2 changed files with 29 additions and 229 deletions

View File

@ -1,243 +1,41 @@
///////////////////////////////////////////////////////////////////////
//
// This is a little wrapper to make it easy to run a python
// program from the command line.
// program from the command line. Basically, it just interfaces
// to the Python API and imports the module that was specified
// by the IMPORT_MODULE preprocessor definition when it was compiled.
//
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
//
// Windows Version
//
///////////////////////////////////////////////////////////////////////
#include <Python.h>
#ifdef WIN32
#ifdef BUILDING_GENPYCODE
#define LINK_SOURCE "\\bin\\genpycode.exe"
#define LINK_TARGET "\\python\\python.exe"
#ifndef IMPORT_MODULE
#error IMPORT_MODULE must be defined when compiling ppython.cxx !
#endif
#ifdef BUILDING_PACKPANDA
#define LINK_SOURCE "\\bin\\packpanda.exe"
#define LINK_TARGET "\\python\\python.exe"
#endif
#define _STRINGIFY(s) #s
#define STRINGIFY(s) _STRINGIFY(s)
#define IMPORT_MODULE_STR STRINGIFY(IMPORT_MODULE)
#ifdef BUILDING_EGGCACHER
#define LINK_SOURCE "\\bin\\eggcacher.exe"
#define LINK_TARGET "\\python\\python.exe"
#endif
int main(int argc, char **argv) {
int sts = 0;
#ifdef BUILDING_PFREEZE
#define LINK_SOURCE "\\bin\\pfreeze.exe"
#define LINK_TARGET "\\python\\python.exe"
#endif
Py_SetProgramName(argv[0]);
Py_Initialize();
#include <windows.h>
#include <winuser.h>
#include <stdlib.h>
#include <process.h>
#include <malloc.h>
#include <stdio.h>
#include <signal.h>
#define PATH_MAX 1024
void pathfail(void)
{
fprintf(stderr, "Cannot locate the root of the panda tree\n");
exit(1);
}
int main(int argc, char **argv)
{
char fnbuf[PATH_MAX],ppbuf[PATH_MAX],pabuf[PATH_MAX],modcmd[PATH_MAX];
int fnlen;
// Ask windows for the file name of this executable.
fnlen = GetModuleFileName(NULL, fnbuf, 1023);
if ((fnlen <= 0)||(fnlen >= 1023)) pathfail();
fnbuf[fnlen] = 0;
// Make sure that the executable's name ends in LINK_SOURCE
int srclen = strlen(LINK_SOURCE);
if (fnlen < srclen + 4) pathfail();
if (stricmp(fnbuf + fnlen - srclen, LINK_SOURCE)) pathfail();
fnlen -= srclen; fnbuf[fnlen] = 0;
// See if we can find the panda root. If not, abort.
sprintf(ppbuf,"%s/include/dtool_config.h",fnbuf);
FILE *f = fopen(ppbuf,"r");
if (f==0) pathfail();
fclose(f);
// Set the PYTHONPATH
char *pp = getenv("PYTHONPATH");
if (pp) sprintf(ppbuf,"PYTHONPATH=%s;%s\\bin;%s",fnbuf,fnbuf,pp);
else sprintf(ppbuf,"PYTHONPATH=%s;%s\\bin",fnbuf,fnbuf);
putenv(ppbuf);
// Fetch the command line and trim the first word.
char *cmdline = GetCommandLine();
char *args = cmdline;
bool inquote = false;
while (*args && ((*args != ' ')||(inquote))) {
if (*args == '"') inquote = !inquote;
args++;
if (Py_VerboseFlag) {
fprintf(stderr, "Python %s\\n%s\\n", Py_GetVersion(), Py_GetCopyright());
}
while (*args==' ') args++;
// Append LINK_TARGET to the file name.
if (fnlen + strlen(LINK_TARGET) > 1023) pathfail();
strcat(fnbuf, LINK_TARGET);
// Calculate MODCMD
#ifdef BUILDING_GENPYCODE
sprintf(modcmd,"python -c \"import direct.ffi.jGenPyCode\" %s",args);
#endif
#ifdef BUILDING_PACKPANDA
sprintf(modcmd,"python -c \"import direct.directscripts.packpanda\" %s",args);
#endif
#ifdef BUILDING_EGGCACHER
sprintf(modcmd,"python -c \"import direct.directscripts.eggcacher\" %s",args);
#endif
#ifdef BUILDING_PFREEZE
sprintf(modcmd,"python -c \"import direct.showutil.pfreeze\" %s",args);
#endif
PySys_SetArgv(argc, argv);
// Run it.
signal(SIGINT, SIG_IGN);
PROCESS_INFORMATION pinfo;
STARTUPINFO sinfo;
GetStartupInfo(&sinfo);
BOOL ok = CreateProcess(fnbuf,modcmd,NULL,NULL,TRUE,NULL,NULL,NULL,&sinfo,&pinfo);
if (ok) WaitForSingleObject(pinfo.hProcess,INFINITE);
}
#endif /* WIN32 */
///////////////////////////////////////////////////////////////////////
//
// Linux and OSX and FreeBSD Version
//
// This would probably work on most unixes, with the possible
// exception of the /proc/self/exe bit.
//
///////////////////////////////////////////////////////////////////////
#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__)
#ifdef BUILDING_GENPYCODE
#define LINK_SOURCE "/bin/genpycode"
#endif
#ifdef BUILDING_PACKPANDA
#define LINK_SOURCE "/bin/packpanda"
#endif
#ifdef BUILDING_EGGCACHER
#define LINK_SOURCE "/bin/eggcacher"
#endif
#ifdef BUILDING_PFREEZE
#define LINK_SOURCE "/bin/pfreeze"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <sys/param.h>
#if defined( __APPLE__)
#include <sys/malloc.h>
#elif !defined(__FreeBSD__)
#include <malloc.h>
#endif
void errorexit(const char *s)
{
fprintf(stderr,"%s\n", s);
exit(1);
}
void pathfail(void)
{
fprintf(stderr, "Cannot locate the root of the panda tree\n");
exit(1);
}
int main(int argc, char **argv)
{
char fnbuf[PATH_MAX],ppbuf[PATH_MAX];
char *modargv[1024];
int fnlen,modargc;
// Ask the OS for the file name of this executable.
#ifdef __FreeBSD__
int ok = readlink("/proc/curproc/file", fnbuf, PATH_MAX-1);
#else
int ok = readlink("/proc/self/exe", fnbuf, PATH_MAX-1);
#endif
if (ok<0) {
if (argc>0) strcpy(fnbuf, argv[0]);
else errorexit("Cannot read /proc/sys/exe");
PyObject* m = PyImport_ImportModule(IMPORT_MODULE_STR);
if (m <= 0) {
PyErr_Print();
sts = 1;
}
fnbuf[PATH_MAX-1] = 0;
fnlen = strlen(fnbuf);
// Make sure that the executable's name ends in LINK_SOURCE
int srclen = strlen(LINK_SOURCE);
if (fnlen < srclen + 4) pathfail();
if (strcmp(fnbuf + fnlen - srclen, LINK_SOURCE)) pathfail();
fnlen -= srclen; fnbuf[fnlen] = 0;
// See if we can find the 'direct' tree locally.
// If not, continue anyway. It may be possible to succeed.
sprintf(ppbuf,"%s/include/dtool_config.h",fnbuf);
FILE *f = fopen(ppbuf,"r");
if (f) {
char *pp = getenv("PYTHONPATH");
if (pp) sprintf(ppbuf,"PYTHONPATH=%s:%s/lib:%s",fnbuf,fnbuf,pp);
else sprintf(ppbuf,"PYTHONPATH=%s:%s/lib",fnbuf,fnbuf);
putenv(ppbuf);
}
// Calculate MODARGV
modargc=0;
modargv[modargc++] = (char*)"python";
#ifdef BUILDING_GENPYCODE
modargv[modargc++] = (char*)"-c";
modargv[modargc++] = (char*)"import direct.ffi.jGenPyCode";
#endif
#ifdef BUILDING_PACKPANDA
modargv[modargc++] = (char*)"-c";
modargv[modargc++] = (char*)"import direct.directscripts.packpanda";
#endif
#ifdef BUILDING_EGGCACHER
modargv[modargc++] = (char*)"-c";
modargv[modargc++] = (char*)"import direct.directscripts.eggcacher";
#endif
#ifdef BUILDING_PFREEZE
modargv[modargc++] = (char*)"-c";
modargv[modargc++] = (char*)"import direct.showutil.pfreeze";
#endif
for (int i=1; i<argc; i++) modargv[modargc++] = argv[i];
modargv[modargc] = 0;
// Run it.
execv("/usr/bin/python", modargv);
Py_Finalize();
return sts;
}
#endif /* LINUX */

View File

@ -2995,16 +2995,18 @@ TargetAdd('libtinydisplay.dll', input=COMMON_PANDA_LIBS)
#
if (PkgSkip("PYTHON")==0):
OPTS=['DIR:direct/src/directbase']
OPTS=['DIR:direct/src/directbase', 'PYTHON']
TargetAdd('directbase_directbase.obj', opts=OPTS+['BUILDING:DIRECT'], input='directbase.cxx')
DefSymbol("BUILDING:PACKPANDA", "IMPORT_MODULE", "direct.directscripts.packpanda")
TargetAdd('packpanda.obj', opts=OPTS+['BUILDING:PACKPANDA'], input='ppython.cxx')
TargetAdd('packpanda.exe', input='packpanda.obj')
TargetAdd('packpanda.exe', opts=['WINUSER'])
TargetAdd('packpanda.exe', opts=['PYTHON'])
TargetAdd('eggcacher.obj', opts=OPTS+['BUILDING:EGGCACHER'], input='ppython.cxx')
TargetAdd('eggcacher.exe', input='eggcacher.obj')
TargetAdd('eggcacher.exe', opts=['WINUSER'])
DefSymbol("BUILDING:EGGCACHER", "IMPORT_MODULE", "direct.directscripts.eggcacher")
TargetAdd('eggcacher.obj', opts=OPTS+['BUILDING:EGGCACHER'], input='ppython.cxx')
TargetAdd('eggcacher.exe', input='eggcacher.obj')
TargetAdd('eggcacher.exe', opts=['PYTHON'])
#
# DIRECTORY: direct/src/dcparser/