Move MAIN_DIR initialization code from interrogate to panda3d

Using the new -init flag, see panda3d/interrogate#3
This commit is contained in:
rdb 2025-02-02 20:11:32 +01:00
parent ea1cbe47ac
commit 79d6727077
9 changed files with 111 additions and 7 deletions

View File

@ -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)

View File

@ -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

View File

@ -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
)

View File

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

View File

@ -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
}

View File

@ -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();

View File

@ -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')

View File

@ -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

View File

@ -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)