From f97959e94b261f625f053a4bd8d8735713b481f3 Mon Sep 17 00:00:00 2001 From: rdb Date: Fri, 18 Sep 2009 16:08:30 +0000 Subject: [PATCH] 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. --- direct/src/directbase/ppython.cxx | 246 +++--------------------------- makepanda/makepanda.py | 12 +- 2 files changed, 29 insertions(+), 229 deletions(-) diff --git a/direct/src/directbase/ppython.cxx b/direct/src/directbase/ppython.cxx index af396692b2..01a01cde05 100755 --- a/direct/src/directbase/ppython.cxx +++ b/direct/src/directbase/ppython.cxx @@ -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 -#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 -#include -#include -#include -#include -#include -#include -#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 -#include -#include -#include -#include -#include -#if defined( __APPLE__) - #include -#elif !defined(__FreeBSD__) - #include -#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