Browse Source

support a windows debug plugin

David Rose 16 years ago
parent
commit
14efb1cbaf

+ 9 - 4
direct/src/extensions_native/extension_native_helpers.py

@@ -16,10 +16,15 @@ if sys.platform == "win32":
     # On Windows, dynamic libraries end in ".dll".
     dll_ext = '.dll'
 
-    # If we launched from python_d.exe, we need to load
-    # libpanda_d.dll, etc.
-    if sys.executable.endswith('_d.exe'):
-        dll_suffix = '_d'
+    # We allow the caller to preload dll_suffix into the sys module.
+    dll_suffix = getattr(sys, 'dll_suffix', None)
+
+    if dll_suffix is None:
+        # Otherwise, we try to determine it from the executable name:
+        # python_d.exe implies _d across the board.
+        if sys.executable.endswith('_d.exe'):
+            dll_suffix = '_d'
+            
 elif sys.platform == "darwin":
     # On OSX, the dynamic libraries usually end in .dylib, but
     # sometimes we need .so.

+ 4 - 3
direct/src/plugin/make_package.py

@@ -23,9 +23,9 @@ Options:
      the local machine that will be filled with the contents of the
      package directory for the web server.
 
-  -p name_version[_platform]
+  -p name[_platform]_version
 
-     Specify the package name, version, and optional platfom, of the
+     Specify the package name, (optional) platform, and version of the
      package to build.
 
 """
@@ -210,8 +210,9 @@ def makePackage(args):
             if len(tokens) >= 1:
                 pm.packageName = tokens[0]
             if len(tokens) >= 2:
-                pm.packagePlatform = tokens[1]
+                pm.packageVersion = tokens[1]
             if len(tokens) >= 3:
+                pm.packagePlatform = pm.packageVersion
                 pm.packageVersion = tokens[2]
             if len(tokens) >= 4:
                 raise ArgumentError, 'Too many tokens in string: %s' % (value)

+ 8 - 0
direct/src/plugin/p3dPythonRun.cxx

@@ -98,6 +98,14 @@ P3DPythonRun::
 ////////////////////////////////////////////////////////////////////
 bool P3DPythonRun::
 run_python() {
+#if defined(_WIN32) && defined(USE_DEBUG_PYTHON)
+  // On Windows, in a debug build, we have to preload sys.dll_suffix =
+  // "_d", so that the Panda DLL preloader can import the correct
+  // filenames.
+  PyRun_SimpleString("import sys; sys.dll_suffix = '_d'");
+  
+#endif
+
   // First, load runp3d_frozen.pyd.  Since this is a magic frozen pyd,
   // importing it automatically makes all of its frozen contents
   // available to import as well.

+ 15 - 11
direct/src/plugin/p3dWinSplashWindow.cxx

@@ -205,9 +205,11 @@ unregister_window_class() {
 void P3DWinSplashWindow::
 start_thread() {
   _thread_continue = true;
+  _thread_running = true;
   _thread = CreateThread(NULL, 0, &win_thread_run, this, 0, &_thread_id);
-  if (_thread != NULL) {
-    _thread_running = true;
+  if (_thread == NULL) {
+    // Thread never got started.
+    _thread_running = false;
   }
 }
 
@@ -226,16 +228,17 @@ stop_thread() {
   }
 
   if (_thread != NULL){ 
-    // We can't actually wait for the thread to finish, since there
-    // might be a deadlock there: the thread can't finish deleting its
-    // window unless we're pumping the message loop for the parent,
-    // which won't happen if we're sitting here waiting.  No worries;
-    // we don't *really* need to wait for the thread.
-    
-    //  WaitForSingleObject(_thread, INFINITE);
+    WaitForSingleObject(_thread, INFINITE);
 
     CloseHandle(_thread);
     _thread = NULL;
+
+    // Now that the thread has exited, we can safely close its window.
+    // (We couldn't close the window in the thread, because that would
+    // cause a deadlock situation--the thread can't acknowledge the
+    // window closing until we spin the event loop in the parent
+    // thread.)
+    close_window();
   }
 }
 
@@ -295,7 +298,7 @@ thread_run() {
     retval = GetMessage(&msg, NULL, 0, 0);
   }
 
-  close_window();
+  // Tell our parent thread that we're done.
   _thread_running = false;
 }
 
@@ -566,7 +569,8 @@ update_image_filename(const string &image_filename, bool image_filename_temp) {
 ////////////////////////////////////////////////////////////////////
 //     Function: P3DWinSplashWindow::close_window
 //       Access: Private
-//  Description: Closes the window created above.
+//  Description: Closes the window created above.  This call is
+//               actually made in the main thread.
 ////////////////////////////////////////////////////////////////////
 void P3DWinSplashWindow::
 close_window() {

+ 30 - 6
direct/src/showutil/FreezeTool.py

@@ -12,6 +12,14 @@ from distutils.sysconfig import PREFIX, get_python_inc, get_python_version
 import direct
 from pandac.PandaModules import *
 
+# Check to see if we are running python_d, which implies we have a
+# debug build, and we have to build the module with debug options.
+# This is only relevant on Windows.
+
+# I wonder if there's a better way to determine this?
+python = os.path.splitext(os.path.split(sys.executable)[1])[0]
+isDebugBuild = (python.lower().endswith('_d'))
+
 # These are modules that Python always tries to import up-front.  They
 # must be frozen in any main.exe.
 startupModules = [
@@ -44,6 +52,14 @@ MSVC = None
 # Directory to Windows Platform SDK (if relevant)
 PSDK = None
 
+# The setting to control release vs. debug builds.  Only relevant on
+# Windows.
+MD = None
+
+# The _d extension to add to dll filenames on Windows in debug builds.
+dllext = ''
+
+
 if sys.platform == 'win32':
     Python = PREFIX
     
@@ -66,18 +82,24 @@ if sys.platform == 'win32':
     else:
         print 'Could not locate the Microsoft Windows Platform SDK! Try running from the Visual Studio Command Prompt.'
         sys.exit(1)
+
+    # We need to use the correct compiler setting for debug vs. release builds.
+    MD = '/MD'
+    if isDebugBuild:
+        MD = '/MDd'
+        dllext = '_d'
     
     # If it is run by makepanda, it handles the MSVC and PlatformSDK paths itself.
     if ('MAKEPANDA' in os.environ):
-        compileObj = 'cl /wd4996 /Fo%(basename)s.obj /nologo /c /MD /Zi /O2 /Ob2 /EHsc /Zm300 /W3 /I"%(pythonIPath)s" %(filename)s'
+        compileObj = 'cl /wd4996 /Fo%(basename)s.obj /nologo /c %(MD)s /Zi /O2 /Ob2 /EHsc /Zm300 /W3 /I"%(pythonIPath)s" %(filename)s'
         linkExe = 'link /nologo /MAP:NUL /FIXED:NO /OPT:REF /STACK:4194304 /INCREMENTAL:NO /LIBPATH:"%(python)s\libs"  /out:%(basename)s.exe %(basename)s.obj'
-        linkDll = 'link /nologo /DLL /MAP:NUL /FIXED:NO /OPT:REF /INCREMENTAL:NO /LIBPATH:"%(python)s\libs"  /out:%(basename)s.pyd %(basename)s.obj'
+        linkDll = 'link /nologo /DLL /MAP:NUL /FIXED:NO /OPT:REF /INCREMENTAL:NO /LIBPATH:"%(python)s\libs"  /out:%(basename)s%(dllext)s.pyd %(basename)s.obj'
     else:
         os.environ['PATH'] += ';' + MSVC + '\\bin;' + MSVC + '\\Common7\\IDE;' + PSDK + '\\bin'
         
-        compileObj = 'cl /wd4996 /Fo%(basename)s.obj /nologo /c /MD /Zi /O2 /Ob2 /EHsc /Zm300 /W3 /I"%(pythonIPath)s" /I"%(PSDK)s\include" /I"%(MSVC)s\include" %(filename)s'
+        compileObj = 'cl /wd4996 /Fo%(basename)s.obj /nologo /c %(MD)s /Zi /O2 /Ob2 /EHsc /Zm300 /W3 /I"%(pythonIPath)s" /I"%(PSDK)s\include" /I"%(MSVC)s\include" %(filename)s'
         linkExe = 'link /nologo /MAP:NUL /FIXED:NO /OPT:REF /STACK:4194304 /INCREMENTAL:NO /LIBPATH:"%(PSDK)s\lib" /LIBPATH:"%(MSVC)s\lib" /LIBPATH:"%(python)s\libs"  /out:%(basename)s.exe %(basename)s.obj'
-        linkDll = 'link /nologo /DLL /MAP:NUL /FIXED:NO /OPT:REF /INCREMENTAL:NO /LIBPATH:"%(PSDK)s\lib" /LIBPATH:"%(MSVC)s\lib" /LIBPATH:"%(python)s\libs"  /out:%(basename)s.pyd %(basename)s.obj'
+        linkDll = 'link /nologo /DLL /MAP:NUL /FIXED:NO /OPT:REF /INCREMENTAL:NO /LIBPATH:"%(PSDK)s\lib" /LIBPATH:"%(MSVC)s\lib" /LIBPATH:"%(python)s\libs"  /out:%(basename)s%(dllext)s.pyd %(basename)s.obj'
 
 elif sys.platform == 'darwin':
     # OSX
@@ -457,7 +479,6 @@ class Freezer:
         """
 
         moduleName = moduleName.replace("/", ".").replace("direct.src", "direct")
-
         if implicit:
             token = self.MTAuto
         else:
@@ -768,7 +789,7 @@ class Freezer:
             dllexport = ''
             if self.platform == 'win32':
                 dllexport = '__declspec(dllexport) '
-                target = basename + '.pyd'
+                target = basename + dllext + '.pyd'
             else:
                 target = basename + '.so'
             
@@ -804,6 +825,7 @@ class Freezer:
             'python' : Python,
             'MSVC' : MSVC,
             'PSDK' : PSDK,
+            'MD' : MD,
             'pythonIPath' : PythonIPath,
             'pythonVersion' : PythonVersion,
             'filename' : filename,
@@ -831,6 +853,7 @@ class Freezer:
             'python' : Python,
             'MSVC' : MSVC,
             'PSDK' : PSDK,
+            'MD' : MD,
             'pythonIPath' : PythonIPath,
             'pythonVersion' : PythonVersion,
             'filename' : filename,
@@ -848,6 +871,7 @@ class Freezer:
             'pythonVersion' : PythonVersion,
             'filename' : filename,
             'basename' : basename,
+            'dllext' : dllext,
             }
         print >> sys.stderr, link
         if os.system(link) != 0: