コード例 #1
0
ファイル: start.c プロジェクト: kivy/python-for-android
/* 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;
}
コード例 #2
0
ファイル: start.c プロジェクト: KeyWeeUsr/python-for-android
/* 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;
}
コード例 #3
0
ファイル: start.c プロジェクト: latin1593/python-for-android
/* 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;
}