瀏覽代碼

Move MAIN_DIR initialization code from interrogate to panda3d

Using the new -init flag, see panda3d/interrogate#3
rdb 10 月之前
父節點
當前提交
79d6727077

+ 6 - 2
cmake/macros/Interrogate.cmake

@@ -283,7 +283,7 @@ endfunction(interrogate_sources)
 
 #
 # Function: add_python_module(module [lib1 [lib2 ...]] [LINK lib1 ...]
-#    [IMPORT mod1 ...])
+#    [IMPORT mod1 ...] [INIT func1 ...])
 # Uses interrogate to create a Python module. If the LINK keyword is specified,
 # the Python module is linked against the specified libraries instead of those
 # listed before. The IMPORT keyword makes the output module import another
@@ -305,7 +305,7 @@ function(add_python_module module)
 
   set(keyword)
   foreach(arg ${ARGN})
-    if(arg STREQUAL "LINK" OR arg STREQUAL "IMPORT" OR arg STREQUAL "COMPONENT")
+    if(arg STREQUAL "LINK" OR arg STREQUAL "IMPORT" OR arg STREQUAL "INIT" OR arg STREQUAL "COMPONENT")
       set(keyword "${arg}")
 
     elseif(keyword STREQUAL "LINK")
@@ -316,6 +316,10 @@ function(add_python_module module)
       list(APPEND import_flags "-import" "${arg}")
       set(keyword)
 
+    elseif(keyword STREQUAL "INIT")
+      list(APPEND import_flags "-init" "${arg}")
+      set(keyword)
+
     elseif(keyword STREQUAL "COMPONENT")
       set(component "${arg}")
       set(keyword)

+ 1 - 1
dtool/Config.cmake

@@ -265,7 +265,7 @@ if(BUILD_INTERROGATE)
     panda3d-interrogate
 
     GIT_REPOSITORY https://github.com/panda3d/interrogate.git
-    GIT_TAG 03418d6d7ddda7fb99abf27230aa42d1d8bd607e
+    GIT_TAG d2844d994fcc465a4e22b10001d3ac5c4012b814
 
     PREFIX ${_interrogate_dir}
     CMAKE_ARGS

+ 2 - 0
dtool/src/dtoolutil/CMakeLists.txt

@@ -69,6 +69,8 @@ set(P3DTOOLUTIL_IGATEEXT
   globPattern_ext.h
   iostream_ext.cxx
   iostream_ext.h
+  pyenv_init.cxx
+  pyenv_init.h
   textEncoder_ext.cxx
   textEncoder_ext.h
 )

+ 1 - 0
dtool/src/dtoolutil/p3dtoolutil_ext_composite.cxx

@@ -1,4 +1,5 @@
 #include "filename_ext.cxx"
 #include "globPattern_ext.cxx"
 #include "iostream_ext.cxx"
+#include "pyenv_init.cxx"
 #include "textEncoder_ext.cxx"

+ 80 - 0
dtool/src/dtoolutil/pyenv_init.cxx

@@ -0,0 +1,80 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file pyenv_init.cxx
+ * @author rdb
+ * @date 2025-02-02
+ */
+
+#include "pyenv_init.h"
+#include "py_panda.h"
+#include "executionEnvironment.h"
+
+/**
+ * Called when panda3d.core is initialized, does some initialization specific
+ * to the Python environment.
+ */
+void
+pyenv_init() {
+  // MAIN_DIR needs to be set very early; this seems like a convenient place
+  // to do that.  Perhaps we'll find a better place for this in the future.
+  static bool initialized_main_dir = false;
+  if (!initialized_main_dir) {
+    /*if (interrogatedb_cat.is_debug()) {
+      // Good opportunity to print this out once, at startup.
+      interrogatedb_cat.debug()
+        << "Python " << version << "\n";
+    }*/
+
+    if (!ExecutionEnvironment::has_environment_variable("MAIN_DIR")) {
+      // Grab the __main__ module and extract its __file__ attribute.
+      Filename main_dir;
+      PyObject *main_module = PyImport_ImportModule("__main__");
+      PyObject *file_attr = nullptr;
+      if (main_module != nullptr) {
+        file_attr = PyObject_GetAttrString(main_module, "__file__");
+      } else {
+        std::cerr << "Warning: unable to import __main__\n";
+      }
+      if (file_attr == nullptr) {
+        // Must be running in the interactive interpreter.  Use the CWD.
+        main_dir = ExecutionEnvironment::get_cwd();
+      } else {
+#if PY_MAJOR_VERSION >= 3
+        Py_ssize_t length;
+        wchar_t *buffer = PyUnicode_AsWideCharString(file_attr, &length);
+        if (buffer != nullptr) {
+          main_dir = Filename::from_os_specific_w(std::wstring(buffer, length));
+          main_dir.make_absolute();
+          main_dir = main_dir.get_dirname();
+          PyMem_Free(buffer);
+        }
+#else
+        char *buffer;
+        Py_ssize_t length;
+        if (PyString_AsStringAndSize(file_attr, &buffer, &length) != -1) {
+          main_dir = Filename::from_os_specific(std::string(buffer, length));
+          main_dir.make_absolute();
+          main_dir = main_dir.get_dirname();
+        }
+#endif
+        else {
+          std::cerr << "Invalid string for __main__.__file__\n";
+        }
+      }
+      ExecutionEnvironment::shadow_environment_variable("MAIN_DIR", main_dir.to_os_specific());
+      PyErr_Clear();
+    }
+    initialized_main_dir = true;
+  }
+
+  // Also, while we are at it, initialize the thread swap hook.
+#if defined(HAVE_THREADS) && defined(SIMPLE_THREADS)
+  global_thread_state_swap = PyThreadState_Swap;
+#endif
+}

+ 14 - 0
dtool/src/dtoolutil/pyenv_init.h

@@ -0,0 +1,14 @@
+/**
+ * PANDA 3D SOFTWARE
+ * Copyright (c) Carnegie Mellon University.  All rights reserved.
+ *
+ * All use of this software is subject to the terms of the revised BSD
+ * license.  You should have received a copy of this license along
+ * with this source code in a file named "LICENSE."
+ *
+ * @file pyenv_init.h
+ * @author rdb
+ * @date 2025-02-02
+ */
+
+extern "C" void pyenv_init();

+ 4 - 1
makepanda/makepanda.py

@@ -1651,6 +1651,9 @@ def CompileImod(wobj, wsrc, opts):
     importmod = GetValueOption(opts, "IMPORT:")
     if importmod:
         cmd += ' -import ' + importmod
+    initfunc = GetValueOption(opts, "INIT:")
+    if initfunc:
+        cmd += ' -init ' + initfunc
     for x in wsrc: cmd += ' ' + BracketNameWithQuotes(x)
     oscmd(cmd)
     CompileCxx(wobj,woutc,opts)
@@ -4168,7 +4171,7 @@ if GetTarget() != "emscripten":
 if PkgSkip("FREETYPE")==0:
     PyTargetAdd('core_module.obj', input='libp3pnmtext.in')
 
-PyTargetAdd('core_module.obj', opts=['IMOD:panda3d.core', 'ILIB:core'])
+PyTargetAdd('core_module.obj', opts=['IMOD:panda3d.core', 'ILIB:core', 'INIT:pyenv_init'])
 
 PyTargetAdd('core.pyd', input='libp3dtoolbase_igate.obj')
 PyTargetAdd('core.pyd', input='p3dtoolbase_typeHandle_ext.obj')

+ 2 - 2
makepanda/makepandacore.py

@@ -589,8 +589,8 @@ def GetInterrogateDir():
             return INTERROGATE_DIR
 
         dir = os.path.join(GetOutputDir(), "tmp", "interrogate")
-        if not os.path.isdir(os.path.join(dir, "panda3d_interrogate-0.4.0.dist-info")):
-            oscmd("\"%s\" -m pip install --force-reinstall --upgrade -t \"%s\" panda3d-interrogate==0.4.0" % (sys.executable, dir))
+        if not os.path.isdir(os.path.join(dir, "panda3d_interrogate-0.5.0.dist-info")):
+            oscmd("\"%s\" -m pip install --force-reinstall --upgrade -t \"%s\" panda3d-interrogate==0.5.0" % (sys.executable, dir))
 
         INTERROGATE_DIR = dir
 

+ 1 - 1
panda/CMakeLists.txt

@@ -107,7 +107,7 @@ if(HAVE_FREETYPE)
 endif()
 
 if(INTERROGATE_PYTHON_INTERFACE)
-  add_python_module(panda3d.core ${CORE_MODULE_COMPONENTS} LINK panda)
+  add_python_module(panda3d.core ${CORE_MODULE_COMPONENTS} LINK panda INIT pyenv_init)
 
   # Generate our __init__.py
   if(WIN32)