Exemple #1
0
int main()
{
    LPWSTR *szArglist;
    int nArgs;
    wchar_t wszPath[10240];
    wchar_t wszCmd[10240];
    wchar_t *p;
    char* szCmd;

    GetModuleFileNameW(NULL, wszPath, sizeof(wszPath));
    p = wcsrchr(wszPath, L'\\');
    if (p == NULL) {
            printf("Get module file name error!\n");
            return -1;
    }
    *p = 0;

    szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);

    swprintf(wszCmd, L"PATH=%s\\DLLs;%%PATH%%", wszPath);
    _wputenv(wszCmd);

    Py_NoSiteFlag = 1;
    Py_SetPythonHome(wszPath);
    swprintf(wszCmd, L"%s\\Lib", wszPath);
    Py_SetPath(wszCmd);
    Py_Initialize();
    PySys_SetArgv(nArgs-1, szArglist+1);

    swprintf(wszCmd,
            L"import sys\n"
            L"cur = r'%s'\n"
            L"join = lambda *args: '\\\\'.join(args)\n"
            L"sys.path = [join(cur, f) for f in ['', 'Lib', 'Lib/libstdpy.zip', 'site-packages', 'DLLs']]\n"
            L"import os; join = os.path.join\n"
            L"sys.path += [join(cur, 'Lib', f) for f in os.listdir(join(cur, 'Lib')) if f.endswith('.zip') and f != 'libstdpy.zip']\n"
            L"sys.path.insert(1, join(cur, 'src.zip'))\n"
            L"m = r'%s'\n"
            L"sys.path.insert(0, os.path.split(m)[0])\n"
            L"import imp; imp.load_source('__main__', m)\n",
            wszPath, *(szArglist+1));
    /* wprintf(wszCmd); */
    szCmd = to_utf8(wszCmd);
    PyRun_SimpleString(szCmd);
    free(szCmd);
    LocalFree(szArglist);
    return 0;
}
Exemple #2
0
VOID AppendPackage()
{
    PLDR_MODULE Self;
    UNICODE_STRING SelfPath;

    static WCHAR PythonZip[] = L"python.zip";

    ml::MlInitialize();

    //Py_IgnoreEnvironmentFlag = TRUE;
    //Py_NoSiteFlag = TRUE;
    Py_DontWriteBytecodeFlag = TRUE;
    //Py_NoUserSiteDirectory = TRUE;

    Self = FindLdrModuleByHandle(nullptr);

    SelfPath = Self->FullDllName;
    SelfPath.Length -= Self->BaseDllName.Length;

    Py_SetPath(ml::String::Format(
        L"%wZ;%wZ%s;%wZ%s\\site-packages;%wZlib;%wZDLLs;%wZUserSite",
        &SelfPath,                      // exe path
        &SelfPath, PythonZip,           // ./python.zip
        &SelfPath, PythonZip,           // ./python.zip/site-packages
        &SelfPath,                      // ./lib
        &SelfPath,                      // ./DLLs
        &SelfPath                       // ./UserSite
    ));

    ml::String      PathEnv, UserSite;
    PWSTR           EnvBuffer;
    ULONG           Length;
    UNICODE_STRING  Path;

    RtlInitEmptyString(&Path);
    RtlExpandEnvironmentStrings_U(nullptr, &USTR(L"%Path%"), &Path, &Length);

    EnvBuffer = (PWSTR)AllocStack(Length);
    RtlInitEmptyString(&Path, EnvBuffer, Length);

    RtlExpandEnvironmentStrings_U(nullptr, &USTR(L"%Path%"), &Path, nullptr);

    UserSite = SelfPath;
    UserSite += L"UserSite";

    PathEnv = SelfPath;
    PathEnv += L"DLLs;";

    EnumDirectoryFiles(
        nullptr, L"*.*", 0, UserSite, nullptr,
        [] (PVOID Buffer, PWIN32_FIND_DATAW FindData, ULONG_PTR Context) -> LONG
        {
            ml::String *PathEnv = (ml::String *)Context;

            if (FLAG_OFF(FindData->dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY))
                return 0;

            (*PathEnv) += FindData->cFileName;
            (*PathEnv) += ';';

            return 0;
        },
        (ULONG_PTR)&PathEnv,
        EDF_PROCDIR | EDF_BEFORE
    );


    PathEnv += Path;
    PathEnv += ';';
    RtlSetEnvironmentVariable(nullptr, &USTR(L"Path"), PathEnv);
}
Exemple #3
0
/* int main(int argc, char **argv) { */
int main(int argc, char *argv[]) {

  char *env_argument = NULL;
  char *env_entrypoint = NULL;
  char *env_logname = NULL;
  char entrypoint[ENTRYPOINT_MAXLEN];
  int ret = 0;
  FILE *fd;

  setenv("P4A_BOOTSTRAP", "SDL2", 1);  // env var to identify p4a to applications

  LOGP("Initializing Python for Android");
  env_argument = getenv("ANDROID_ARGUMENT");
  setenv("ANDROID_APP_PATH", env_argument, 1);
  env_entrypoint = getenv("ANDROID_ENTRYPOINT");
  env_logname = getenv("PYTHON_NAME");

  if (!getenv("ANDROID_UNPACK")) {
    /* ANDROID_UNPACK currently isn't set in services */
    setenv("ANDROID_UNPACK", env_argument, 1);
  }
  
  if (env_logname == NULL) {
    env_logname = "python";
    setenv("PYTHON_NAME", "python", 1);
  }

  LOGP("Changing directory to the one provided by ANDROID_ARGUMENT");
  LOGP(env_argument);
  chdir(env_argument);

  Py_SetProgramName(L"android_python");

#if PY_MAJOR_VERSION >= 3
  /* our logging module for android
   */
  PyImport_AppendInittab("androidembed", initandroidembed);
#endif

  LOGP("Preparing to initialize python");

  // Set up the python path
  char paths[256];

  char crystax_python_dir[256];
  snprintf(crystax_python_dir, 256,
           "%s/crystax_python", getenv("ANDROID_UNPACK"));
  char python_bundle_dir[256];
  snprintf(python_bundle_dir, 256,
           "%s/_python_bundle", getenv("ANDROID_UNPACK"));
  if (dir_exists(crystax_python_dir) || dir_exists(python_bundle_dir)) {
    if (dir_exists(crystax_python_dir)) {
        LOGP("crystax_python exists");
        snprintf(paths, 256,
                "%s/stdlib.zip:%s/modules",
                crystax_python_dir, crystax_python_dir);
    }

    if (dir_exists(python_bundle_dir)) {
        LOGP("_python_bundle dir exists");
        snprintf(paths, 256,
                "%s/stdlib.zip:%s/modules",
                python_bundle_dir, python_bundle_dir);
    }

    LOGP("calculated paths to be...");
    LOGP(paths);


    #if PY_MAJOR_VERSION >= 3
        wchar_t *wchar_paths = Py_DecodeLocale(paths, NULL);
        Py_SetPath(wchar_paths);
    #else
        char *wchar_paths = paths;
        LOGP("Can't Py_SetPath in python2, so crystax python2 doesn't work yet");
        exit(1);
    #endif

        LOGP("set wchar paths...");
  } else {
      // We do not expect to see crystax_python any more, so no point
      // reminding the user about it. If it does exist, we'll have
      // logged it earlier.
      LOGP("_python_bundle does not exist");
  }

  Py_Initialize();

#if PY_MAJOR_VERSION < 3
  PySys_SetArgv(argc, argv);
#endif

  LOGP("Initialized python");

  /* ensure threads will work.
   */
  LOGP("AND: Init threads");
  PyEval_InitThreads();

#if PY_MAJOR_VERSION < 3
  initandroidembed();
#endif

  PyRun_SimpleString("import androidembed\nandroidembed.log('testing python "
                     "print redirection')");

  /* inject our bootstrap code to redirect python stdin/stdout
   * replace sys.path with our path
   */
  PyRun_SimpleString("import sys, posix\n");
  if (dir_exists("lib")) {
    /* If we built our own python, set up the paths correctly */
    LOGP("Setting up python from ANDROID_PRIVATE");
    PyRun_SimpleString("private = posix.environ['ANDROID_APP_PATH']\n"
                       "argument = posix.environ['ANDROID_ARGUMENT']\n"
                       "sys.path[:] = [ \n"
                       "    private + '/lib/python27.zip', \n"
                       "    private + '/lib/python2.7/', \n"
                       "    private + '/lib/python2.7/lib-dynload/', \n"
                       "    private + '/lib/python2.7/site-packages/', \n"
                       "    argument ]\n");
  }

  char add_site_packages_dir[256];
  if (dir_exists(crystax_python_dir)) {
    snprintf(add_site_packages_dir, 256,
             "sys.path.append('%s/site-packages')",
             crystax_python_dir);

    PyRun_SimpleString("import sys\n"
                       "sys.argv = ['notaninterpreterreally']\n"
                       "from os.path import realpath, join, dirname");
    PyRun_SimpleString(add_site_packages_dir);
    /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */
    PyRun_SimpleString("sys.path = ['.'] + sys.path");
  }

  if (dir_exists(python_bundle_dir)) {
    snprintf(add_site_packages_dir, 256,
             "sys.path.append('%s/site-packages')",
             python_bundle_dir);

    PyRun_SimpleString("import sys\n"
                       "sys.argv = ['notaninterpreterreally']\n"
                       "from os.path import realpath, join, dirname");
    PyRun_SimpleString(add_site_packages_dir);
    /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */
    PyRun_SimpleString("sys.path = ['.'] + sys.path");
  }

  PyRun_SimpleString(
      "class LogFile(object):\n"
      "    def __init__(self):\n"
      "        self.buffer = ''\n"
      "    def write(self, s):\n"
      "        s = self.buffer + s\n"
      "        lines = s.split(\"\\n\")\n"
      "        for l in lines[:-1]:\n"
      "            androidembed.log(l)\n"
      "        self.buffer = lines[-1]\n"
      "    def flush(self):\n"
      "        return\n"
      "sys.stdout = sys.stderr = LogFile()\n"
      "print('Android path', sys.path)\n"
      "import os\n"
      "print('os.environ is', os.environ)\n"
      "print('Android kivy bootstrap done. __name__ is', __name__)");

#if PY_MAJOR_VERSION < 3
  PyRun_SimpleString("import site; print site.getsitepackages()\n");
#endif

  LOGP("AND: Ran string");

  /* run it !
   */
  LOGP("Run user program, change dir and execute entrypoint");

  /* Get the entrypoint, search the .pyo then .py
   */
  char *dot = strrchr(env_entrypoint, '.');
  if (dot <= 0) {
    LOGP("Invalid entrypoint, abort.");
    return -1;
  }
  if (strlen(env_entrypoint) > ENTRYPOINT_MAXLEN - 2) {
      LOGP("Entrypoint path is too long, try increasing ENTRYPOINT_MAXLEN.");
      return -1;
  }
  if (!strcmp(dot, ".pyo")) {
    if (!file_exists(env_entrypoint)) {
      /* fallback on .py */
      strcpy(entrypoint, env_entrypoint);
      entrypoint[strlen(env_entrypoint) - 1] = '\0';
      LOGP(entrypoint);
      if (!file_exists(entrypoint)) {
        LOGP("Entrypoint not found (.pyo, fallback on .py), abort");
        return -1;
      }
    } else {
      strcpy(entrypoint, env_entrypoint);
    }
  } else if (!strcmp(dot, ".py")) {
    /* if .py is passed, check the pyo version first */
    strcpy(entrypoint, env_entrypoint);
    entrypoint[strlen(env_entrypoint) + 1] = '\0';
    entrypoint[strlen(env_entrypoint)] = 'o';
    if (!file_exists(entrypoint)) {
      /* fallback on pure python version */
      if (!file_exists(env_entrypoint)) {
        LOGP("Entrypoint not found (.py), abort.");
        return -1;
      }
      strcpy(entrypoint, env_entrypoint);
    }
  } else {
    LOGP("Entrypoint have an invalid extension (must be .py or .pyo), abort.");
    return -1;
  }
  // LOGP("Entrypoint is:");
  // LOGP(entrypoint);
  fd = fopen(entrypoint, "r");
  if (fd == NULL) {
    LOGP("Open the entrypoint failed");
    LOGP(entrypoint);
    return -1;
  }

  /* run python !
   */
  ret = PyRun_SimpleFile(fd, entrypoint);

  if (PyErr_Occurred() != NULL) {
    ret = 1;
    PyErr_Print(); /* This exits with the right code if SystemExit. */
    PyObject *f = PySys_GetObject("stdout");
    if (PyFile_WriteString(
            "\n", f)) /* python2 used Py_FlushLine, but this no longer exists */
      PyErr_Clear();
  }

  /* close everything
   */
  Py_Finalize();
  fclose(fd);

  LOGP("Python for android ended.");
  return ret;
}
Exemple #4
0
//-------------------------------------------------------------------------------------
bool Script::install(const wchar_t* pythonHomeDir, std::wstring pyPaths, 
	const char* moduleName, COMPONENT_TYPE componentType)
{
	std::wstring pySysPaths = SCRIPT_PATH;
	wchar_t* pwpySysResPath = strutil::char2wchar(const_cast<char*>(Resmgr::getSingleton().getPySysResPath().c_str()));
	strutil::kbe_replace(pySysPaths, L"../../res/", pwpySysResPath);
	pyPaths += pySysPaths;
	free(pwpySysResPath);

#if KBE_PLATFORM == PLATFORM_WIN32
	Py_SetPythonHome(const_cast<wchar_t*>(pythonHomeDir));								// 先设置python的环境变量
#else
	std::wstring fs = L";";
	std::wstring rs = L":";
	size_t pos = 0; 

	while(true)
	{ 
		pos = pyPaths.find(fs, pos);
		if (pos == std::wstring::npos) break;
		pyPaths.replace(pos, fs.length(), rs);
	}  

	Py_SetPath(pyPaths.c_str()); 
	char* tmpchar = strutil::wchar2char(const_cast<wchar_t*>(pyPaths.c_str()));
	DEBUG_MSG(boost::format("Script::install: paths=%1%.\n") % tmpchar);
	free(tmpchar);
	
#endif
	// Initialise python
	// Py_VerboseFlag = 2;
	Py_FrozenFlag = 1;

	// Warn if tab and spaces are mixed in indentation.
	// Py_TabcheckFlag = 1;
	Py_NoSiteFlag = 1;
	Py_IgnoreEnvironmentFlag = 1;
	Py_Initialize();                      											// python解释器的初始化  
    if (!Py_IsInitialized())
    {
    	ERROR_MSG("Script::install::Py_Initialize is failed!\n");
        return false;
    } 

#if KBE_PLATFORM == PLATFORM_WIN32
	PySys_SetPath(pyPaths.c_str());
#endif

	PyObject *m = PyImport_AddModule("__main__");

	module_ = PyImport_AddModule(moduleName);										// 添加一个脚本基础模块
	if (module_ == NULL)
		return false;
	
	const char* componentName = COMPONENT_NAME_EX(componentType);
	if (PyModule_AddStringConstant(module_, "component", componentName))
	{
		ERROR_MSG(boost::format("Script::init: Unable to set KBEngine.component to %1%\n") %
			componentName );
		return false;
	}
	
	// 注册产生uuid方法到py
	APPEND_SCRIPT_MODULE_METHOD(module_,		genUUID64,			__py_genUUID64,					METH_VARARGS,			0);

	if(!install_py_dlls())
	{
		ERROR_MSG("Script::init: install_py_dlls() is failed!\n");
		return false;
	}

#ifndef KBE_SINGLE_THREADED
	s_pOurInitTimeModules = PyDict_Copy( PySys_GetObject( "modules" ) );
	s_pMainThreadState = PyThreadState_Get();
	s_defaultContext = s_pMainThreadState;
	PyEval_InitThreads();

	KBEConcurrency::setMainThreadIdleFunctions(
		&Script::releaseLock, &Script::acquireLock );
#endif

	ScriptStdOutErr::installScript(NULL);											// 安装py重定向模块
	ScriptStdOutErrHook::installScript(NULL);

	static struct PyModuleDef moduleDesc =   
	{  
			 PyModuleDef_HEAD_INIT,  
			 moduleName,  
			 "This module is created by KBEngine!",  
			 -1,  
			 NULL  
	};  

	PyModule_Create(&moduleDesc);													// 初始化基础模块
	PyObject_SetAttrString(m, moduleName, module_);									// 将模块对象加入main

	pyStdouterr_ = new ScriptStdOutErr();											// 重定向python输出
	pyStdouterrHook_ = new ScriptStdOutErrHook();
	
	if(!pyStdouterr_->install()){													// 安装py重定向脚本模块
		ERROR_MSG("Script::install::pyStdouterr_->install() is failed!\n");
		SCRIPT_ERROR_CHECK();
		return false;
	}
	
	Pickler::initialize();
	PyProfile::initialize(this);
	PyStruct::initialize();
	Copy::initialize();
	SCRIPT_ERROR_CHECK();

	math::installModule("Math");
	INFO_MSG("Script::install is successfully!\n");
	return installExtraModule("KBExtra");
}
Exemple #5
0
int AppMain()
{
	std::wstring exe_dir;

	// Get exe's directory
	{
		wchar_t exe_path_buf[MAX_PATH + 1];
		GetModuleFileName(NULL, exe_path_buf, MAX_PATH);

		exe_dir = exe_path_buf;

		size_t last_backslash_pos = exe_dir.find_last_of(L"\\/");
		if (last_backslash_pos >= 0)
		{
			exe_dir = exe_dir.substr(0, last_backslash_pos);
		}
		else
		{
			exe_dir = L"";
		}
	}

	// Setup environment variable "PATH"
	{
		std::wstring env_path;

		wchar_t tmp_buf[1];
		DWORD ret = GetEnvironmentVariable(L"PATH", tmp_buf, 0);
		if (ret > 0)
		{
			DWORD len = ret;
			wchar_t * buf = (wchar_t*)malloc((len + 1) * sizeof(wchar_t));

			GetEnvironmentVariable(L"PATH", buf, (len + 1) * sizeof(wchar_t));

			env_path = buf;

			free(buf);
		}

		env_path = exe_dir + L"/lib;" + env_path;

		SetEnvironmentVariable(L"PATH", env_path.c_str());
	}

	// Python home
	{
#if defined(_DEBUG)
		Py_SetPythonHome(PYTHON_INSTALL_PATH);
#else
		Py_SetPythonHome(const_cast<wchar_t*>(exe_dir.c_str()));
#endif //_DEBUG
	}

	// Python module search path
	{
		std::wstring python_path;

		python_path += exe_dir + L"/extension;";
		
		#if defined(_DEBUG)
		python_path += exe_dir + L";";
		python_path += exe_dir + L"/..;";
		python_path += std::wstring(PYTHON_INSTALL_PATH) + L"\\Lib;";
		python_path += std::wstring(PYTHON_INSTALL_PATH) + L"\\Lib\\site-packages;";
		python_path += std::wstring(PYTHON_INSTALL_PATH) + L"\\DLLs;";
		#else
		python_path += exe_dir + L"/library.zip;";
		python_path += exe_dir + L"/lib;";
		#endif
		
		Py_SetPath(python_path.c_str());
	}

	// Initialization
	Py_Initialize();

	// Setup sys.argv
	{
		wchar_t * cmdline = GetCommandLine();

		int argc;
		wchar_t ** argv = CommandLineToArgvW(cmdline, &argc);

		PySys_SetArgv(argc, argv);

		LocalFree(argv);
	}

	// Execute python side main script
	{
		PyObject * module = PyImport_ImportModule("cfiler_main");
		if (module == NULL)
		{
			PyErr_Print();
		}

		Py_XDECREF(module);
		module = NULL;
	}

	// Termination
	Py_Finalize();

	return 0;
}
Exemple #6
0
void setupPythonEnv(const char* argv0Param)
{
    //Disable user sites as they could conflict with Natron bundled packages.
    //If this is set, Python won’t add the user site-packages directory to sys.path.
    //See https://www.python.org/dev/peps/pep-0370/
    ProcInfo::putenv_wrapper("PYTHONNOUSERSITE", "1");
    ++Py_NoUserSiteDirectory;

    //
    // set up paths, clear those that don't exist or are not valid
    //
    std::string binPath = ProcInfo::applicationDirPath(argv0Param);
    binPath = StrUtils::toNativeSeparators(binPath);
#ifdef __NATRON_WIN32__
    static std::string pythonHome = binPath + "\\.."; // must use static storage
    std::string pyPathZip = pythonHome + "\\lib\\python" NATRON_PY_VERSION_STRING_NO_DOT ".zip";
    std::string pyPath = pythonHome +  "\\lib\\python" NATRON_PY_VERSION_STRING;
    std::string pluginPath = binPath + "\\..\\Plugins";
#else
#  if defined(__NATRON_LINUX__)
    static std::string pythonHome = binPath + "/.."; // must use static storage
#  elif defined(__NATRON_OSX__)
    static std::string pythonHome = binPath+ "/../Frameworks/Python.framework/Versions/" NATRON_PY_VERSION_STRING; // must use static storage
#  else
#    error "unsupported platform"
#  endif
    std::string pyPathZip = pythonHome + "/lib/python" NATRON_PY_VERSION_STRING_NO_DOT ".zip";
    std::string pyPath = pythonHome + "/lib/python" NATRON_PY_VERSION_STRING;
    std::string pluginPath = binPath + "/../Plugins";
#endif
    if ( !fileExists( StrUtils::fromNativeSeparators(pyPathZip) ) ) {
#     if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG)
        printf( "\"%s\" does not exist, not added to PYTHONPATH\n", pyPathZip.c_str() );
#     endif
        pyPathZip.clear();
    }
    if ( !dirExists( StrUtils::fromNativeSeparators(pyPath) ) ) {
#     if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG)
        printf( "\"%s\" does not exist, not added to PYTHONPATH\n", pyPath.c_str() );
#     endif
        pyPath.clear();
    }
    if ( !dirExists( StrUtils::fromNativeSeparators(pluginPath) ) ) {
#     if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG)
        printf( "\"%s\" does not exist, not added to PYTHONPATH\n", pluginPath.c_str() );
#     endif
        pluginPath.clear();
    }
    // PYTHONHOME is really useful if there's a python inside it
    if ( pyPathZip.empty() && pyPath.empty() ) {
#     if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG)
        printf( "dir \"%s\" does not exist or does not contain lib/python*, not setting PYTHONHOME\n", pythonHome.c_str() );
#     endif
        pythonHome.clear();
    }

    /////////////////////////////////////////
    // Py_SetPythonHome
    /////////////////////////////////////////
    //
    // Must be done before Py_Initialize (see doc of Py_Initialize)
    //
    // The argument should point to a zero-terminated character string in static storage whose contents will not change for the duration of the program’s execution

    if ( !pythonHome.empty() ) {
#     if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG)
        printf( "Py_SetPythonHome(\"%s\")\n", pythonHome.c_str() );
#     endif
#     if PY_MAJOR_VERSION >= 3
        // Python 3
        static const std::wstring pythonHomeW = StrUtils::utf8_to_utf16(pythonHome); // must use static storage
        Py_SetPythonHome( const_cast<wchar_t*>( pythonHomeW.c_str() ) );
#     else
        // Python 2
        Py_SetPythonHome( const_cast<char*>( pythonHome.c_str() ) );
#     endif
    }


    /////////////////////////////////////////
    // PYTHONPATH and Py_SetPath
    /////////////////////////////////////////
    //
    // note: to check the python path of a python install, execute:
    // python -c 'import sys,pprint; pprint.pprint( sys.path )'
    //
    // to build the python27.zip, cd to lib/python2.7, and generate the pyo and the zip file using:
    //
    //  python -O -m compileall .
    //  zip -r ../python27.zip *.py* bsddb compiler ctypes curses distutils email encodings hotshot idlelib importlib json logging multiprocessing pydoc_data sqlite3 unittest wsgiref xml
    //
    std::string pythonPath = ProcInfo::getenv_wrapper("PYTHONPATH");
    //Add the Python distribution of Natron to the Python path

    std::vector<std::string> toPrepend;
    if ( !pyPathZip.empty() ) {
        toPrepend.push_back(pyPathZip);
    }
    if ( !pyPath.empty() ) {
        toPrepend.push_back(pyPath);
    }
    if ( !pluginPath.empty() ) {
        toPrepend.push_back(pluginPath);
    }

#if defined(__NATRON_OSX__) && defined DEBUG
    // in debug mode, also prepend the local PySide directory
    // homebrew's pyside directory
    toPrepend.push_back("/usr/local/Cellar/pyside/1.2.2_1/lib/python" NATRON_PY_VERSION_STRING "/site-packages");
    // macport's pyside directory
    toPrepend.push_back("/opt/local/Library/Frameworks/Python.framework/Versions/" NATRON_PY_VERSION_STRING "/lib/python" NATRON_PY_VERSION_STRING "/site-packages");
#endif

    if ( toPrepend.empty() ) {
#     if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG)
        printf("PYTHONPATH not modified\n");
#     endif
    } else {
#     ifdef __NATRON_WIN32__
        const char pathSep = ';';
#     else
        const char pathSep = ':';
#     endif
        std::string toPrependStr = StrUtils::join(toPrepend, pathSep);
        if (pythonPath.empty()) {
            pythonPath = toPrependStr;
        } else {
            pythonPath = toPrependStr + pathSep + pythonPath;
        }
        // qputenv on minw will just call putenv, but we want to keep the utf16 info, so we need to call _wputenv
#     if 0//def __NATRON_WIN32__
        _wputenv_s(L"PYTHONPATH", StrUtils::utf8_to_utf16(pythonPath).c_str());
#     else
        ProcInfo::putenv_wrapper( "PYTHONPATH", pythonPath.c_str() );
        //Py_SetPath( pythonPathString.c_str() ); // does not exist in Python 2
#     endif
#     if PY_MAJOR_VERSION >= 3
        std::wstring pythonPathString = StrUtils::utf8_to_utf16(pythonPath);
        Py_SetPath( pythonPathString.c_str() ); // argument is copied internally, no need to use static storage
#     endif
#     if defined(NATRON_CONFIG_SNAPSHOT) || defined(DEBUG)
        printf( "PYTHONPATH set to %s\n", pythonPath.c_str() );
#     endif
    }

} // setupPythonEnv
Exemple #7
0
/* int main(int argc, char **argv) { */
int main(int argc, char *argv[]) {

  char *env_argument = NULL;
  char *env_entrypoint = NULL;
  char *env_logname = NULL;
  char entrypoint[ENTRYPOINT_MAXLEN];
  int ret = 0;
  FILE *fd;

  LOGP("Initializing Python for Android");

  // Set a couple of built-in environment vars:
  setenv("P4A_BOOTSTRAP", bootstrap_name, 1);  // env var to identify p4a to applications
  env_argument = getenv("ANDROID_ARGUMENT");
  setenv("ANDROID_APP_PATH", env_argument, 1);
  env_entrypoint = getenv("ANDROID_ENTRYPOINT");
  env_logname = getenv("PYTHON_NAME");
  if (!getenv("ANDROID_UNPACK")) {
    /* ANDROID_UNPACK currently isn't set in services */
    setenv("ANDROID_UNPACK", env_argument, 1);
  }
  if (env_logname == NULL) {
    env_logname = "python";
    setenv("PYTHON_NAME", "python", 1);
  }

  // Set additional file-provided environment vars:
  LOGP("Setting additional env vars from p4a_env_vars.txt");
  char env_file_path[256];
  snprintf(env_file_path, sizeof(env_file_path),
           "%s/p4a_env_vars.txt", getenv("ANDROID_UNPACK"));
  FILE *env_file_fd = fopen(env_file_path, "r");
  if (env_file_fd) {
    char* line = NULL;
    size_t len = 0;
    while (getline(&line, &len, env_file_fd) != -1) {
      if (strlen(line) > 0) {
        char *eqsubstr = strstr(line, "=");
        if (eqsubstr) {
          size_t eq_pos = eqsubstr - line;

          // Extract name:
          char env_name[256];
          strncpy(env_name, line, sizeof(env_name));
          env_name[eq_pos] = '\0';

          // Extract value (with line break removed:
          char env_value[256];
          strncpy(env_value, (char*)(line + eq_pos + 1), sizeof(env_value));
          if (strlen(env_value) > 0 &&
              env_value[strlen(env_value)-1] == '\n') {
            env_value[strlen(env_value)-1] = '\0';
            if (strlen(env_value) > 0 &&
                env_value[strlen(env_value)-1] == '\r') {
              // Also remove windows line breaks (\r\n)
              env_value[strlen(env_value)-1] = '\0';
            } 
          }

          // Set value:
          setenv(env_name, env_value, 1);
        }
      }
    }
    fclose(env_file_fd);
  } else {
    LOGP("Warning: no p4a_env_vars.txt found / failed to open!");
  }

  LOGP("Changing directory to the one provided by ANDROID_ARGUMENT");
  LOGP(env_argument);
  chdir(env_argument);

#if PY_MAJOR_VERSION < 3
  Py_NoSiteFlag=1;
#endif

#if PY_MAJOR_VERSION < 3
  Py_SetProgramName("android_python");
#else
  Py_SetProgramName(L"android_python");
#endif

#if PY_MAJOR_VERSION >= 3
  /* our logging module for android
   */
  PyImport_AppendInittab("androidembed", initandroidembed);
#endif

  LOGP("Preparing to initialize python");

  // Set up the python path
  char paths[256];

  char crystax_python_dir[256];
  snprintf(crystax_python_dir, 256,
           "%s/crystax_python", getenv("ANDROID_UNPACK"));
  char python_bundle_dir[256];
  snprintf(python_bundle_dir, 256,
           "%s/_python_bundle", getenv("ANDROID_UNPACK"));
  if (dir_exists(crystax_python_dir) || dir_exists(python_bundle_dir)) {
    if (dir_exists(crystax_python_dir)) {
        LOGP("crystax_python exists");
        snprintf(paths, 256,
                "%s/stdlib.zip:%s/modules",
                crystax_python_dir, crystax_python_dir);
    }

    if (dir_exists(python_bundle_dir)) {
        LOGP("_python_bundle dir exists");
        snprintf(paths, 256,
                "%s/stdlib.zip:%s/modules",
                python_bundle_dir, python_bundle_dir);
    }

    LOGP("calculated paths to be...");
    LOGP(paths);

    #if PY_MAJOR_VERSION >= 3
        wchar_t *wchar_paths = Py_DecodeLocale(paths, NULL);
        Py_SetPath(wchar_paths);
    #endif

        LOGP("set wchar paths...");
  } else {
      // We do not expect to see crystax_python any more, so no point
      // reminding the user about it. If it does exist, we'll have
      // logged it earlier.
      LOGP("_python_bundle does not exist");
  }

  Py_Initialize();

#if PY_MAJOR_VERSION < 3
  // Can't Py_SetPath in python2 but we can set PySys_SetPath, which must
  // be applied after Py_Initialize rather than before like Py_SetPath
  #if PY_MICRO_VERSION >= 15
    // Only for python native-build
    PySys_SetPath(paths);
  #endif
  PySys_SetArgv(argc, argv);
#endif

  LOGP("Initialized python");

  /* ensure threads will work.
   */
  LOGP("AND: Init threads");
  PyEval_InitThreads();

#if PY_MAJOR_VERSION < 3
  initandroidembed();
#endif

  PyRun_SimpleString("import androidembed\nandroidembed.log('testing python "
                     "print redirection')");

  /* inject our bootstrap code to redirect python stdin/stdout
   * replace sys.path with our path
   */
  PyRun_SimpleString("import sys, posix\n");
  if (dir_exists("lib")) {
    /* If we built our own python, set up the paths correctly.
     * This is only the case if we are using the python2legacy recipe
     */
    LOGP("Setting up python from ANDROID_APP_PATH");
    PyRun_SimpleString("private = posix.environ['ANDROID_APP_PATH']\n"
                       "argument = posix.environ['ANDROID_ARGUMENT']\n"
                       "sys.path[:] = [ \n"
                       "    private + '/lib/python27.zip', \n"
                       "    private + '/lib/python2.7/', \n"
                       "    private + '/lib/python2.7/lib-dynload/', \n"
                       "    private + '/lib/python2.7/site-packages/', \n"
                       "    argument ]\n");
  }

  char add_site_packages_dir[256];
  if (dir_exists(crystax_python_dir)) {
    snprintf(add_site_packages_dir, 256,
             "sys.path.append('%s/site-packages')",
             crystax_python_dir);

    PyRun_SimpleString("import sys\n"
                       "sys.argv = ['notaninterpreterreally']\n"
                       "from os.path import realpath, join, dirname");
    PyRun_SimpleString(add_site_packages_dir);
    /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */
    PyRun_SimpleString("sys.path = ['.'] + sys.path");
  }

  if (dir_exists(python_bundle_dir)) {
    snprintf(add_site_packages_dir, 256,
             "sys.path.append('%s/site-packages')",
             python_bundle_dir);

    PyRun_SimpleString("import sys\n"
                       "sys.argv = ['notaninterpreterreally']\n"
                       "from os.path import realpath, join, dirname");
    PyRun_SimpleString(add_site_packages_dir);
    /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */
    PyRun_SimpleString("sys.path = ['.'] + sys.path");
  }

  PyRun_SimpleString(
      "class LogFile(object):\n"
      "    def __init__(self):\n"
      "        self.buffer = ''\n"
      "    def write(self, s):\n"
      "        s = self.buffer + s\n"
      "        lines = s.split(\"\\n\")\n"
      "        for l in lines[:-1]:\n"
      "            androidembed.log(l)\n"
      "        self.buffer = lines[-1]\n"
      "    def flush(self):\n"
      "        return\n"
      "sys.stdout = sys.stderr = LogFile()\n"
      "print('Android path', sys.path)\n"
      "import os\n"
      "print('os.environ is', os.environ)\n"
      "print('Android kivy bootstrap done. __name__ is', __name__)");

#if PY_MAJOR_VERSION < 3
  PyRun_SimpleString("import site; print site.getsitepackages()\n");
#endif

  LOGP("AND: Ran string");

  /* run it !
   */
  LOGP("Run user program, change dir and execute entrypoint");

  /* Get the entrypoint, search the .pyo then .py
   */
  char *dot = strrchr(env_entrypoint, '.');
#if PY_MAJOR_VERSION > 2
  char *ext = ".pyc";
#else
  char *ext = ".pyo";
#endif
  if (dot <= 0) {
    LOGP("Invalid entrypoint, abort.");
    return -1;
  }
  if (strlen(env_entrypoint) > ENTRYPOINT_MAXLEN - 2) {
      LOGP("Entrypoint path is too long, try increasing ENTRYPOINT_MAXLEN.");
      return -1;
  }
  if (!strcmp(dot, ext)) {
    if (!file_exists(env_entrypoint)) {
      /* fallback on .py */
      strcpy(entrypoint, env_entrypoint);
      entrypoint[strlen(env_entrypoint) - 1] = '\0';
      LOGP(entrypoint);
      if (!file_exists(entrypoint)) {
        LOGP("Entrypoint not found (.pyc/.pyo, fallback on .py), abort");
        return -1;
      }
    } else {
      strcpy(entrypoint, env_entrypoint);
    }
  } else if (!strcmp(dot, ".py")) {
    /* if .py is passed, check the pyo version first */
    strcpy(entrypoint, env_entrypoint);
    entrypoint[strlen(env_entrypoint) + 1] = '\0';
#if PY_MAJOR_VERSION > 2
    entrypoint[strlen(env_entrypoint)] = 'c';
#else
    entrypoint[strlen(env_entrypoint)] = 'o';
#endif
    if (!file_exists(entrypoint)) {
      /* fallback on pure python version */
      if (!file_exists(env_entrypoint)) {
        LOGP("Entrypoint not found (.py), abort.");
        return -1;
      }
      strcpy(entrypoint, env_entrypoint);
    }
  } else {
    LOGP("Entrypoint have an invalid extension (must be .py or .pyc/.pyo), abort.");
    return -1;
  }
  // LOGP("Entrypoint is:");
  // LOGP(entrypoint);
  fd = fopen(entrypoint, "r");
  if (fd == NULL) {
    LOGP("Open the entrypoint failed");
    LOGP(entrypoint);
    return -1;
  }

  /* run python !
   */
  ret = PyRun_SimpleFile(fd, entrypoint);
  fclose(fd);

  if (PyErr_Occurred() != NULL) {
    ret = 1;
    PyErr_Print(); /* This exits with the right code if SystemExit. */
    PyObject *f = PySys_GetObject("stdout");
    if (PyFile_WriteString(
            "\n", f)) /* python2 used Py_FlushLine, but this no longer exists */
      PyErr_Clear();
  }

  LOGP("Python for android ended.");

  /* Shut down: since regular shutdown causes issues sometimes
     (seems to be an incomplete shutdown breaking next launch)
     we'll use sys.exit(ret) to shutdown, since that one works.

     Reference discussion:

     https://github.com/kivy/kivy/pull/6107#issue-246120816
   */
  char terminatecmd[256];
  snprintf(
    terminatecmd, sizeof(terminatecmd),
    "import sys; sys.exit(%d)\n", ret
  );
  PyRun_SimpleString(terminatecmd);

  /* This should never actually be reached, but we'll leave the clean-up
   * here just to be safe.
   */
#if PY_MAJOR_VERSION < 3
  Py_Finalize();
  LOGP("Unexpectedly reached Py_FinalizeEx(), but was successful.");
#else
  if (Py_FinalizeEx() != 0)  // properly check success on Python 3
    LOGP("Unexpectedly reached Py_FinalizeEx(), and got error!");
  else
    LOGP("Unexpectedly reached Py_FinalizeEx(), but was successful.");
#endif

  return ret;
}
Exemple #8
0
/* int main(int argc, char **argv) { */
int main(int argc, char *argv[]) {

    char *env_argument = NULL;
    int ret = 0;
    FILE *fd;

 /* AND: Several filepaths are hardcoded here, these must be made
    configurable */
 /* AND: P4A uses env vars...not sure what's best */
    LOG("Initialize Python for Android");
    /* env_argument = "/data/data/org.kivy.android/files"; */
    env_argument = getenv("ANDROID_ARGUMENT");
    /* setenv("ANDROID_APP_PATH", env_argument, 1); */
    
    /* setenv("ANDROID_ARGUMENT", env_argument, 1); */
    /* setenv("ANDROID_PRIVATE", env_argument, 1); */
    /* setenv("ANDROID_APP_PATH", env_argument, 1); */
    /* setenv("PYTHONHOME", env_argument, 1); */
    /* setenv("PYTHONPATH", "/data/data/org.kivy.android/files:/data/data/org.kivy.android/files/lib", 1); */

    /* LOG("AND: Set env vars"); */
    /* LOG(argv[0]); */
    /* LOG("AND: That was argv 0"); */
	//setenv("PYTHONVERBOSE", "2", 1);
    
    LOG("Changing directory to the one provided by ANDROID_ARGUMENT");
    LOG(env_argument);
    chdir(env_argument);

    Py_SetProgramName(L"android_python");

#if PY_MAJOR_VERSION >= 3
    /* our logging module for android
     */
    PyImport_AppendInittab("androidembed", initandroidembed);
#endif
    
    LOG("Preparing to initialize python");
    
    if (dir_exists("crystax_python/")) {
      LOG("crystax_python exists");
        char paths[256];
        snprintf(paths, 256, "%s/crystax_python/stdlib.zip:%s/crystax_python/modules", env_argument, env_argument);
        /* snprintf(paths, 256, "%s/stdlib.zip:%s/modules", env_argument, env_argument); */
        LOG("calculated paths to be...");
        LOG(paths);
        
#if PY_MAJOR_VERSION >= 3
        wchar_t* wchar_paths = Py_DecodeLocale(paths, NULL);
        Py_SetPath(wchar_paths);
#else
        char* wchar_paths = paths;
        LOG("Can't Py_SetPath in python2, so crystax python2 doesn't work yet");
        exit(1);
#endif
     
        LOG("set wchar paths...");
    } else { LOG("crystax_python does not exist");}

    Py_Initialize();
    
#if PY_MAJOR_VERSION < 3
    PySys_SetArgv(argc, argv);
#endif
    
    LOG("Initialized python");

    /* ensure threads will work.
     */
    LOG("AND: Init threads");
    PyEval_InitThreads();
    

#if PY_MAJOR_VERSION < 3
    initandroidembed();
#endif

    PyRun_SimpleString("import androidembed\nandroidembed.log('testing python print redirection')");
    
    /* inject our bootstrap code to redirect python stdin/stdout
     * replace sys.path with our path
     */
    PyRun_SimpleString("import sys, posix\n");
    if (dir_exists("lib")) {
        /* If we built our own python, set up the paths correctly */
      LOG("Setting up python from ANDROID_PRIVATE");
        PyRun_SimpleString(
            "private = posix.environ['ANDROID_PRIVATE']\n" \
            "argument = posix.environ['ANDROID_ARGUMENT']\n" \
            "sys.path[:] = [ \n" \
            "    private + '/lib/python27.zip', \n" \
            "    private + '/lib/python2.7/', \n" \
            "    private + '/lib/python2.7/lib-dynload/', \n" \
            "    private + '/lib/python2.7/site-packages/', \n" \
            "    argument ]\n");
    } 

    if (dir_exists("crystax_python")) {
      char add_site_packages_dir[256];
      snprintf(add_site_packages_dir, 256, "sys.path.append('%s/crystax_python/site-packages')", 
               env_argument);
      
      PyRun_SimpleString(
          "import sys\n"             \
          "sys.argv = ['notaninterpreterreally']\n"  \
          "from os.path import realpath, join, dirname");
      PyRun_SimpleString(add_site_packages_dir);
      /* "sys.path.append(join(dirname(realpath(__file__)), 'site-packages'))") */
      PyRun_SimpleString("sys.path = ['.'] + sys.path");
    }
    
    PyRun_SimpleString(
        "class LogFile(object):\n" \
        "    def __init__(self):\n" \
        "        self.buffer = ''\n" \
        "    def write(self, s):\n" \
        "        s = self.buffer + s\n" \
        "        lines = s.split(\"\\n\")\n" \
        "        for l in lines[:-1]:\n" \
        "            androidembed.log(l)\n" \
        "        self.buffer = lines[-1]\n" \
        "    def flush(self):\n" \
        "        return\n" \
        "sys.stdout = sys.stderr = LogFile()\n" \
		"print('Android path', sys.path)\n" \
        "import os\n" \
        "print('os.environ is', os.environ)\n" \
        "print('Android kivy bootstrap done. __name__ is', __name__)");

    /* PyRun_SimpleString( */
    /*     "import sys, posix\n" \ */
    /*     "private = posix.environ['ANDROID_PRIVATE']\n" \ */
    /*     "argument = posix.environ['ANDROID_ARGUMENT']\n" \ */
    /*     "sys.path[:] = [ \n" \ */
	/* 	"    private + '/lib/python27.zip', \n" \ */
	/* 	"    private + '/lib/python2.7/', \n" \ */
	/* 	"    private + '/lib/python2.7/lib-dynload/', \n" \ */
	/* 	"    private + '/lib/python2.7/site-packages/', \n" \ */
	/* 	"    argument ]\n" \ */
    /*     "import androidembed\n" \ */
    /*     "class LogFile(object):\n" \ */
    /*     "    def __init__(self):\n" \ */
    /*     "        self.buffer = ''\n" \ */
    /*     "    def write(self, s):\n" \ */
    /*     "        s = self.buffer + s\n" \ */
    /*     "        lines = s.split(\"\\n\")\n" \ */
    /*     "        for l in lines[:-1]:\n" \ */
    /*     "            androidembed.log(l)\n" \ */
    /*     "        self.buffer = lines[-1]\n" \ */
    /*     "    def flush(self):\n" \ */
    /*     "        return\n" \ */
    /*     "sys.stdout = sys.stderr = LogFile()\n" \ */
	/* 	"import site; print site.getsitepackages()\n"\ */
	/* 	"print 'Android path', sys.path\n" \ */
    /*     "print 'Android kivy bootstrap done. __name__ is', __name__"); */

    LOG("AND: Ran string");

    /* run it !
     */
    LOG("Run user program, change dir and execute main.py");

	/* search the initial main.py
	 */
	char *main_py = "main.pyo";
	if ( file_exists(main_py) == 0 ) {
		if ( file_exists("main.py") )
			main_py = "main.py";
		else
			main_py = NULL;
	}

	if ( main_py == NULL ) {
		LOG("No main.pyo / main.py found.");
		return -1;
	}

    fd = fopen(main_py, "r");
    if ( fd == NULL ) {
        LOG("Open the main.py(o) failed");
        return -1;
    }

    /* run python !
     */
    ret = PyRun_SimpleFile(fd, main_py);

    if (PyErr_Occurred() != NULL) {
        ret = 1;
        PyErr_Print(); /* This exits with the right code if SystemExit. */
        PyObject *f = PySys_GetObject("stdout");
        if (PyFile_WriteString("\n", f))  /* python2 used Py_FlushLine, but this no longer exists */
          PyErr_Clear();
    }

    /* close everything
     */
	Py_Finalize();
    fclose(fd);

    LOG("Python for android ended.");
    return ret;
}
Exemple #9
0
//---------------------------------------------------------------------------------
// Initializes python.
//---------------------------------------------------------------------------------
bool CPythonManager::Initialize( void )
{
	// Construct a path to the python engine directory.
	char szPythonHome[MAX_GAME_PATH];
	V_snprintf(szPythonHome, MAX_GAME_PATH, "%s/Python3", g_GamePaths.GetSPDir());
	V_FixSlashes(szPythonHome);
	DevMsg(1, "[SP] Python home path set to %s\n", szPythonHome);

	// Convert to wide char for python.
	wchar_t wszPythonHome[1024];
	V_strtowcs(szPythonHome, -1, wszPythonHome, 1024);

	// Set that as the python home directory.
 	Py_SetPythonHome(wszPythonHome);
 	Py_SetProgramName(wszPythonHome);
	Py_SetPath(wszPythonHome);

	// Initialize python and its namespaces.
	Py_Initialize();

	// Print some information
	DevMsg(1, "Python version %s initialized!\n", Py_GetVersion());

	// Make sure sys is imported.
	PyRun_SimpleString("import sys");

	// Add the Python API path.
	AddToSysPath("/packages/source-python");

	// Add operating system specific paths.
#if defined(WIN32)
	AddToSysPath("/Python3/plat-win");
#else
	AddToSysPath("/Python3/plat-linux");

	// We've got a bunch of linux shared objects here we need to load.
	AddToSysPath("/Python3/lib-dynload");
#endif

	// Site packages for any extra packages...
	AddToSysPath("/packages/site-packages");

	// Add the custom packages path.
	AddToSysPath("/packages/custom");

	// And of course, the plugins directory for script imports.
	AddToSysPath("/plugins");

	// Initialize all converters
	InitConverters();

	// Initialize all submodules
	modulsp_init();

	// Import the main module file.
	DevMsg(1, "[SP] Importing main module..\n");
	BEGIN_BOOST_PY()

		python::import("__init__");

	END_BOOST_PY_NORET(); // Noret because we have more stuff to do after this import.

	DevMsg(0, "[Source.Python] Loaded successfully.\n");

	return true;
}
Exemple #10
0
//-------------------------------------------------------------------------------------
bool Script::install(const wchar_t* pythonHomeDir, std::wstring pyPaths, 
	const char* moduleName, COMPONENT_TYPE componentType)
{
	std::wstring pySysPaths = SCRIPT_PATH;
	wchar_t* pwpySysResPath = strutil::char2wchar(const_cast<char*>(Resmgr::getSingleton().getPySysResPath().c_str()));
	strutil::kbe_replace(pySysPaths, L"../../res/", pwpySysResPath);
	pyPaths += pySysPaths;
	free(pwpySysResPath);

	// 先设置python的环境变量
	Py_SetPythonHome(const_cast<wchar_t*>(pythonHomeDir));								

#if KBE_PLATFORM != PLATFORM_WIN32
	std::wstring fs = L";";
	std::wstring rs = L":";
	size_t pos = 0; 

	while(true)
	{ 
		pos = pyPaths.find(fs, pos);
		if (pos == std::wstring::npos) break;
		pyPaths.replace(pos, fs.length(), rs);
	}  

	char* tmpchar = strutil::wchar2char(const_cast<wchar_t*>(pyPaths.c_str()));
	DEBUG_MSG(fmt::format("Script::install(): paths={}.\n", tmpchar));
	free(tmpchar);
	
#endif
	// Initialise python
	// Py_VerboseFlag = 2;
	Py_FrozenFlag = 1;

	// Warn if tab and spaces are mixed in indentation.
	// Py_TabcheckFlag = 1;
	Py_NoSiteFlag = 1;
	Py_IgnoreEnvironmentFlag = 1;

	Py_SetPath(pyPaths.c_str());

	// python解释器的初始化  
	Py_Initialize();
    if (!Py_IsInitialized())
    {
    	ERROR_MSG("Script::install(): Py_Initialize is failed!\n");
        return false;
    } 

	PyObject *m = PyImport_AddModule("__main__");

	// 添加一个脚本基础模块
	module_ = PyImport_AddModule(moduleName);
	if (module_ == NULL)
		return false;
	
	const char* componentName = COMPONENT_NAME_EX(componentType);
	if (PyModule_AddStringConstant(module_, "component", componentName))
	{
		ERROR_MSG(fmt::format("Script::install(): Unable to set KBEngine.component to {}\n",
			componentName));
		return false;
	}
	
	// 注册产生uuid方法到py
	APPEND_SCRIPT_MODULE_METHOD(module_,		genUUID64,			__py_genUUID64,					METH_VARARGS,			0);

	if(!install_py_dlls())
	{
		ERROR_MSG("Script::install(): install_py_dlls() is failed!\n");
		return false;
	}

	// 安装py重定向模块
	ScriptStdOut::installScript(NULL);
	ScriptStdErr::installScript(NULL);

	/*
	static struct PyModuleDef moduleDesc =
	{  
			 PyModuleDef_HEAD_INIT,  
			 moduleName,  
			 "This module is created by KBEngine!", 
			 -1,  
			 NULL  
	};  

	// 初始化基础模块
	PyModule_Create(&moduleDesc);
	*/

	// 将模块对象加入main
	PyObject_SetAttrString(m, moduleName, module_);	
	PyObject_SetAttrString(module_, "__doc__", PyUnicode_FromString("This module is created by KBEngine!"));

	// 重定向python输出
	pyStdouterr_ = new ScriptStdOutErr();
	
	// 安装py重定向脚本模块
	if(!pyStdouterr_->install()){
		ERROR_MSG("Script::install::pyStdouterr_->install() is failed!\n");
		delete pyStdouterr_;
		SCRIPT_ERROR_CHECK();
		return false;
	}
	
	PyGC::initialize();
	Pickler::initialize();
	PyProfile::initialize(this);
	PyStruct::initialize();
	Copy::initialize();
	SCRIPT_ERROR_CHECK();

	math::installModule("Math");
	INFO_MSG(fmt::format("Script::install(): is successfully, Python=({})!\n", Py_GetVersion()));
	return installExtraModule("KBExtra");
}
Exemple #11
0
int init_with_instance(HMODULE hmod_exe, char *frozen)
{

	int rc = 0;
	HMODULE hmod_pydll;

/*	Py_NoSiteFlag = 1; /* Suppress 'import site' */
/*	Py_InspectFlag = 1; /* Needed to determine whether to exit at SystemExit */

	calc_dirname(hmod_exe);
//	wprintf(L"modulename %s\n", modulename);
//	wprintf(L"dirname %s\n", dirname);

	if (!locate_script(hmod_exe)) {
		SystemError(-1, "FATAL ERROR: Could not locate script");
//		printf("FATAL ERROR locating script\n");
		return -1;
	}

	hmod_pydll = load_pythondll();
	if (hmod_pydll == NULL) {
		SystemError(-1, "FATAL ERROR: Could not load python library");
//		printf("FATAL Error: could not load python library\n");
		return -1;
	}
	if (PythonLoaded(hmod_pydll) < 0) {
		SystemError(-1, "FATAL ERROR: Failed to load some Python symbols");
//		printf("FATAL Error: failed to load some Python symbols\n");
		return -1;
	}

	set_vars(hmod_pydll);

	/*
	  _memimporter contains the magic which allows to load
	  dlls from memory, without unpacking them to the file-system.

	  It is compiled into all the exe-stubs.
	*/
	PyImport_AppendInittab("_memimporter", PyInit__memimporter);

	/*
	  Start the ball rolling.
	*/
	Py_SetProgramName(modulename);
	Py_SetPath(libfilename);
	Py_Initialize();


	/* Set sys.frozen so apps that care can tell.  If the caller did pass
	   NULL, sys.frozen will be set to 'True'.  If a string is passed this
	   is used as the frozen attribute.  run.c passes "console_exe",
	   run_w.c passes "windows_exe", run_dll.c passes "dll" This falls
	   apart when you consider that in some cases, a single process may
	   end up with two py2exe generated apps - but still, we reset frozen
	   to the correct 'current' value for the newly initializing app.
	*/
	if (frozen == NULL)
		PySys_SetObject("frozen", PyBool_FromLong(1));
	else {
		PyObject *o = PyUnicode_FromString(frozen);
		if (o) {
			PySys_SetObject("frozen", o);
			Py_DECREF(o);
		}
	}
	return rc;
}
Exemple #12
0
//---------------------------------------------------------------------------------
// Initializes python.
//---------------------------------------------------------------------------------
bool CPythonManager::Initialize( void )
{
	// Construct a path to the python engine directory.
	char szPythonHome[MAX_PATH_LENGTH];
	V_snprintf(szPythonHome, MAX_PATH_LENGTH, "%s/Python3", GetSourcePythonDir());
	V_FixSlashes(szPythonHome);
	DevMsg(1, MSG_PREFIX "Python home path set to %s\n", szPythonHome);

	// Convert to wide char for python.
	wchar_t wszPythonHome[MAX_PATH_LENGTH];
	V_strtowcs(szPythonHome, -1, wszPythonHome, MAX_PATH_LENGTH);

	// Set that as the python home directory.
 	Py_SetPythonHome(wszPythonHome);
 	Py_SetProgramName(wszPythonHome);
	Py_SetPath(wszPythonHome);

	// Initialize python and its namespaces.
	Py_Initialize();

	// Print some information
	DevMsg(1, MSG_PREFIX "Python version %s initialized!\n", Py_GetVersion());
	
	// Set sys.argv and update sys.path
	DevMsg(1, MSG_PREFIX "Setting sys.argv...\n");
	ICommandLine* pCommandLine = CommandLine();

	int iParamCount = pCommandLine->ParmCount();
	wchar_t** argv = new wchar_t*[iParamCount];
	for (int i=0; i < iParamCount; i++)
	{
		const char* szParam = pCommandLine->GetParm(i);
		int iParamLength = strlen(szParam);

		wchar_t* wszParam = new wchar_t[iParamLength+1];
		// Not sure what's wrong with V_strtowcs, but it seems like it
		// doesn't convert the string correctly on Linux
		mbstowcs(wszParam, szParam, iParamLength+1);

		argv[i] = wszParam;
	}
	PySys_SetArgv(iParamCount, argv);

	// Make sure sys is imported.
	PyRun_SimpleString("import sys");

	// Add the Python API path.
	AddToSysPath("/packages/source-python");

	// Add operating system specific paths.
#if defined(WIN32)
	AddToSysPath("/Python3/plat-win");
#else
	AddToSysPath("/Python3/plat-linux");

	// We've got a bunch of linux shared objects here we need to load.
	AddToSysPath("/Python3/lib-dynload");
#endif

	// Site packages for any extra packages...
	AddToSysPath("/packages/site-packages");

	// Add the custom packages path.
	AddToSysPath("/packages/custom");

	// And of course, the plugins directory for script imports.
	AddToSysPath("/plugins");

	// Initialize all converters
	InitConverters();

	// Initialize all submodules
	if (!modulsp_init())
	{
		Msg(MSG_PREFIX "Failed to initialize internal modules.\n");
		return false;
	}

	// Import the main module file.
	DevMsg(1, MSG_PREFIX "Loading main module...\n");

	try {
		python::import("__init__").attr("load")();
	}
	catch( ... ) {
		PyErr_Print();
		PyErr_Clear();
		Msg(MSG_PREFIX "Failed to load the main module.\n");
		return false;
	}

	return true;
}