main.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file main.c
  10. * @author rdb
  11. * @date 2024-11-03
  12. */
  13. /**
  14. * This script embeds the Python interpreter and runs the unit testing suite.
  15. * It is designed for use with a statically built Panda3D, where the Panda3D
  16. * modules are linked directly into the interpreter.
  17. */
  18. #include <Python.h>
  19. #ifdef __EMSCRIPTEN__
  20. #include <emscripten/emscripten.h>
  21. #include <emscripten/em_asm.h>
  22. #endif
  23. #include "pandabase.h"
  24. #ifdef LINK_ALL_STATIC
  25. extern PyObject *PyInit_core();
  26. #ifdef HAVE_DIRECT
  27. extern PyObject *PyInit_direct();
  28. #endif
  29. #ifdef HAVE_PHYSICS
  30. extern PyObject *PyInit_physics();
  31. #endif
  32. #ifdef HAVE_EGG
  33. extern PyObject *PyInit_egg();
  34. extern EXPCL_PANDAEGG void init_libpandaegg();
  35. #endif
  36. #ifdef HAVE_BULLET
  37. extern PyObject *PyInit_bullet();
  38. #endif
  39. extern EXPCL_PANDA_PNMIMAGETYPES void init_libpnmimagetypes();
  40. #endif // LINK_ALL_STATIC
  41. int main(int argc, char **argv) {
  42. PyStatus status;
  43. PyConfig config;
  44. PyConfig_InitPythonConfig(&config);
  45. #ifdef __EMSCRIPTEN__
  46. // getenv does not work with emscripten, instead read the PYTHONPATH and
  47. // PYTHONHOME from the process.env variable if we're running in node.js.
  48. char path[4096], home[4096];
  49. path[0] = 0;
  50. home[0] = 0;
  51. EM_ASM({
  52. if (process && process.env) {
  53. var path = process.env.PYTHONPATH;
  54. var home = process.env.PYTHONHOME;
  55. if (path) {
  56. if (process.platform === 'win32') {
  57. path = path.replace(/;/g, ':');
  58. }
  59. stringToUTF8(path, $0, $1);
  60. }
  61. if (home) {
  62. stringToUTF8(home, $2, $3);
  63. }
  64. }
  65. }, path, sizeof(path), home, sizeof(home));
  66. if (path[0] != 0) {
  67. status = PyConfig_SetBytesString(&config, &config.pythonpath_env, path);
  68. if (PyStatus_Exception(status)) {
  69. goto exception;
  70. }
  71. }
  72. if (home[0] != 0) {
  73. status = PyConfig_SetBytesString(&config, &config.home, home);
  74. if (PyStatus_Exception(status)) {
  75. goto exception;
  76. }
  77. }
  78. #endif
  79. PyConfig_SetBytesString(&config, &config.run_module, "pytest");
  80. config.parse_argv = 0;
  81. status = PyConfig_SetBytesArgv(&config, argc, argv);
  82. if (PyStatus_Exception(status)) {
  83. goto exception;
  84. }
  85. status = Py_InitializeFromConfig(&config);
  86. if (PyStatus_Exception(status)) {
  87. goto exception;
  88. }
  89. PyConfig_Clear(&config);
  90. #ifdef LINK_ALL_STATIC
  91. #ifdef HAVE_EGG
  92. init_libpandaegg();
  93. #endif
  94. init_libpnmimagetypes();
  95. {
  96. PyObject *panda3d_module = PyImport_ImportModule("panda3d");
  97. PyObject *panda3d_dict = PyModule_GetDict(panda3d_module);
  98. PyObject *sys_modules = PySys_GetObject("modules");
  99. PyObject *core_module = PyInit_core();
  100. PyDict_SetItemString(panda3d_dict, "core", core_module);
  101. PyDict_SetItemString(sys_modules, "panda3d.core", core_module);
  102. #ifdef HAVE_DIRECT
  103. PyObject *direct_module = PyInit_direct();
  104. PyDict_SetItemString(panda3d_dict, "direct", direct_module);
  105. PyDict_SetItemString(sys_modules, "panda3d.direct", direct_module);
  106. #endif
  107. #ifdef HAVE_PHYSICS
  108. PyObject *physics_module = PyInit_physics();
  109. PyDict_SetItemString(panda3d_dict, "physics", physics_module);
  110. PyDict_SetItemString(sys_modules, "panda3d.physics", physics_module);
  111. #endif
  112. #ifdef HAVE_EGG
  113. PyObject *egg_module = PyInit_egg();
  114. PyDict_SetItemString(panda3d_dict, "egg", egg_module);
  115. PyDict_SetItemString(sys_modules, "panda3d.egg", egg_module);
  116. #endif
  117. #ifdef HAVE_BULLET
  118. PyObject *bullet_module = PyInit_bullet();
  119. PyDict_SetItemString(panda3d_dict, "bullet", bullet_module);
  120. PyDict_SetItemString(sys_modules, "panda3d.bullet", bullet_module);
  121. #endif
  122. }
  123. #endif // LINK_ALL_STATIC
  124. #ifdef __EMSCRIPTEN__
  125. // Default fd capturing doesn't work on emscripten
  126. PyRun_SimpleString("import sys; sys.argv.insert(1, '--capture=sys')");
  127. #endif
  128. return Py_RunMain();
  129. exception:
  130. PyConfig_Clear(&config);
  131. if (PyStatus_IsExit(status)) {
  132. return status.exitcode;
  133. }
  134. Py_ExitStatusException(status);
  135. }