Commits

Anonymous committed a02c967

Cleaned up the Cocoa-Python project template.

Comments (0)

Files changed (6)

+2002-11-08  Bill Bumgarner  <bbum@codefab.com>
+	* Cleaned up the Cocoa-Python project template.
+
 2002-11-05  Bill Bumgarner  <bbum@codefab.com>
 	* added an NSNumber test
 

pyobjc/Examples/TableModel2/TableModel2.pbproj/project.pbxproj

 //F52
 //F53
 //F54
-		F5318F930371DBBD01A801DC = {
-			fileRef = F57653070371679F01A801DC;
-			isa = PBXBuildFile;
-			settings = {
-			};
-		};
 		F5318F940371DBCB01A801DC = {
 			fileRef = F57653070371679F01A801DC;
 			isa = PBXBuildFile;
 				F61BA2B7035799D301C36587,
 				F61BA2B9035799DD01C36587,
 				F61BA2BA035799E001C36587,
-				F5318F930371DBBD01A801DC,
 			);
 			isa = PBXCopyFilesBuildPhase;
 			runOnlyForDeploymentPostprocessing = 1;

pyobjc/Project Templates/Cocoa-Python Application/CocoaApp.pbproj/project.pbxproj

 		};
 		080E96DDFE201D6D7F000001 = {
 			children = (
-				F60DD8BC0358A22201C8ED3C,
 				F60DD8BD0358A22201C8ED3C,
 			);
 			isa = PBXGroup;
 		};
 		29B97315FDCFA39411CA2CEA = {
 			children = (
+				F60DD8BC0358A22201C8ED3C,
 				29B97316FDCFA39411CA2CEA,
 			);
 			isa = PBXGroup;
 //F64
 		F60DD8BC0358A22201C8ED3C = {
 			isa = PBXExecutableFileReference;
-			path = Main.py;
+			path = __main__.py;
 			refType = 2;
 		};
 		F60DD8BD0358A22201C8ED3C = {

pyobjc/Project Templates/Cocoa-Python Application/Main.py

-#
-#  Main.py
-#  �PROJECTNAME�
-#
-#  Created by �FULLUSERNAME� on �DATE�.
-#  Copyright (c) �YEAR� �ORGANIZATIONNAME�. All rights reserved.
-#
-
-# 
-# Upon an installation build, the project copies the PyObjC modules
-# into the 'pyobjc' directory within the Resources directory of
-# the app wrapper.  The following adjusts sys.path to include that
-# directory.
-#
-import sys
-import os.path
-sys.path.insert(0, os.path.join(sys.path[0], "pyobjc"))
-
-#
-# Import the components of the Python<->ObjC bridge.
-#
-import objc
-import Foundation
-import AppKit
-
-#
-# Automatically load any frameworks identified by the bootstrap
-# process (the code in bin-python-main.m).
-#
-# If any of the frameworks have an Init.py, it will be executed
-# and, as such, can be used to load/initialize any of the
-# frameworks in the Python interpreter context.
-#
-pyFrameworkPathsIndex = sys.argv.index("-PyFrameworkPaths")
-if not (pyFrameworkPathsIndex == -1):
-  import string
-  from Foundation import NSBundle
-  paths = string.split(sys.argv[pyFrameworkPathsIndex + 1], ":")
-  count = 0
-  for path in paths:
-    bundle = NSBundle.bundleWithPath_(path)
-    bundle.principalClass()
-    sys.path.insert(count, bundle.resourcePath())
-    count = count + 1
-    
-    initPath = bundle.pathForResource_ofType_( "Init", "py")
-    if initPath:
-      execfile(initPath, globals(), locals())
-
-#
-# Import application specific componentry.  At the least, all
-# classes necessary to load the main NIB file must be loaded here.
-#
-import MyAppDelegate
-
-#
-# Pass control to the Appkit.
-#
-# From this point on, application intiailization, execution and
-# termination works exactly like any other Cocoa application.
-#
-sys.exit( AppKit.NSApplicationMain(sys.argv) )

pyobjc/Project Templates/Cocoa-Python Application/__main__.py

+#
+#  Main.py
+#  �PROJECTNAME�
+#
+#  Created by �FULLUSERNAME� on �DATE�.
+#  Copyright (c) �YEAR� �ORGANIZATIONNAME�. All rights reserved.
+#
+
+# 
+# Upon an installation build, the project copies the PyObjC modules
+# into the 'pyobjc' directory within the Resources directory of
+# the app wrapper.  The following adjusts sys.path to include that
+# directory.
+#
+import sys
+import os.path
+sys.path.insert(0, os.path.join(sys.path[0], "pyobjc"))
+
+#
+# Import the components of the Python<->ObjC bridge.
+#
+import objc
+import Foundation
+import AppKit
+
+#
+# Automatically load any frameworks identified by the bootstrap
+# process (the code in bin-python-main.m).
+#
+# If any of the frameworks have an Init.py, it will be executed
+# and, as such, can be used to load/initialize any of the
+# frameworks in the Python interpreter context.
+#
+pyFrameworkPathsIndex = sys.argv.index("-PyFrameworkPaths")
+if not (pyFrameworkPathsIndex == -1):
+  import string
+  from Foundation import NSBundle
+  paths = string.split(sys.argv[pyFrameworkPathsIndex + 1], ":")
+  count = 0
+  for path in paths:
+    bundle = NSBundle.bundleWithPath_(path)
+    bundle.principalClass()
+    sys.path.insert(count, bundle.resourcePath())
+    count = count + 1
+    
+    initPath = bundle.pathForResource_ofType_( "Init", "py")
+    if initPath:
+      execfile(initPath, globals(), locals())
+
+#
+# Import application specific componentry.  At the least, all
+# classes necessary to load the main NIB file must be loaded here.
+#
+import MyAppDelegate
+
+#
+# Pass control to the Appkit.
+#
+# From this point on, application intiailization, execution and
+# termination works exactly like any other Cocoa application.
+#
+sys.exit( AppKit.NSApplicationMain(sys.argv) )

pyobjc/Project Templates/Cocoa-Python Application/bin-python-main.m

 #import <sys/param.h>
 #import <unistd.h>
 
-int pyobjc_main(int argc, char * const *argv, char *envp[])
+int pyobjc_main(int argc, char * const *argv, char * const *envp)
 {
   // The autorelease pool is not released on purpose.   The call to execve() destroys the
   // calling process entirely and, as such, memory management in the traditional sense
   [[NSAutoreleasePool alloc] init];
 
   const char **childArgv = alloca(sizeof(char *) * (argc + 5));
-  const char *pythonBinPathPtr;
-  const char *mainPyPathPtr;
+  char **childEnvp = (char **)envp;
   NSEnumerator *bundleEnumerator = [[NSBundle allFrameworks] reverseObjectEnumerator];
   NSBundle *aBundle;
-  NSMutableArray *bundlePaths = [[NSMutableArray array] retain];
+  NSBundle *mainBundle = [NSBundle mainBundle];
+  NSMutableArray *bundlePaths = [NSMutableArray array];
   int i;
 
+  // if this is set, it is most likely because of PBX or because the developer is doing something....
+  if ( !getenv("DYLD_FRAMEWORK_PATH") ) {
+    // if not, put the DYLD environment into a state where we can actually load frameworks from within the app
+    // wrapper where the frameworks may have inter-dependencies.
+    NSArray *paths = [NSArray arrayWithObjects: [mainBundle sharedFrameworksPath], [mainBundle privateFrameworksPath], nil];
+    NSString *joinedPaths = [paths componentsJoinedByString: @":"];
+    const char *dyldFrameworkPath = [[NSString stringWithFormat: @"DYLD_FRAMEWORK_PATH=%@", joinedPaths] UTF8String];
+    const char *dyldLibraryPath = [[NSString stringWithFormat: @"DYLD_LIBRARY_PATH=%@", joinedPaths] UTF8String];
+
+    for(i=0; envp[i]; i++);
+    childEnvp = malloc( sizeof(char *) * (i+4) );
+
+    bcopy( envp, childEnvp, ( i * sizeof(char *) ) );
+
+    childEnvp[i++] = (char *)dyldFrameworkPath;
+    childEnvp[i++] = (char *)dyldLibraryPath;
+
+    // useful for debugging-- set this as a default.
+    if ([[NSUserDefaults standardUserDefaults] boolForKey: @"DYLD_PRINT_LIBRARIES"])
+      childEnvp[i++] = (char *)"DYLD_PRINT_LIBRARIES=1";
+    childEnvp[i++] = NULL;
+  }
+
+  // grab a list of all frameworks that were linked into this executable
   while ( aBundle = [bundleEnumerator nextObject] ) {
     if ( [[[aBundle bundlePath] pathExtension] isEqualToString: @"framework"] )
       [bundlePaths addObject: [aBundle bundlePath]];
   }
 
+  // figure out which python interpreter to use
   NSString *pythonBinPath = [[NSUserDefaults standardUserDefaults] stringForKey: @"PythonBinPath"];
   pythonBinPath = pythonBinPath ? pythonBinPath : @"/usr/bin/python";
-  [pythonBinPath retain];
-  pythonBinPathPtr = [pythonBinPath UTF8String];
 
-  NSString *mainPyFile = [[[NSBundle mainBundle] infoDictionary] objectForKey: @"PrincipalPythonFile"];
-  NSString *mainPyPath = nil;
+  const char *pythonBinPathPtr = [pythonBinPath UTF8String];
 
-  if (mainPyFile)
-    mainPyPath = [[NSBundle mainBundle] pathForResource: mainPyFile ofType: nil];
-
-  if ( !mainPyPath )
-    mainPyPath = [[NSBundle mainBundle] pathForResource: @"Main.py" ofType: nil];
-
+  // find main python file.  __main__.py seems to be a standard.
+  NSString *mainPyPath = [mainBundle pathForResource: @"__main__.py" ofType: nil];
   if ( !mainPyPath )
     [NSException raise: NSInternalInconsistencyException
-                format: @"%s:%d pyobjc_main() Failed to find main python entry point for application.  Exiting.", __FILE__, __LINE__];
-  [mainPyPath retain];
-  mainPyPathPtr = [mainPyPath UTF8String];
+                format: @"%s:%d pyobjc_main() Failed to find file __main__.py in app wrapper.  Exiting.", __FILE__, __LINE__];
+  const char *mainPyPathPtr = [mainPyPath UTF8String];
 
+  // construct argv for the child
+
+  // the path to the executable in the app wrapper -- must be in the app wrapper or CFBundle does not initialize correctly
   childArgv[0] = argv[0];
+
+  // path to the python file that acts as the main entry point
   childArgv[1] = mainPyPathPtr;
+
+  // Pass original arguments (such as -NSOpen) verbatum
+  //
+  // Move each argument right one slot
   for (i = 1; i<argc; i++)
     childArgv[i+1] = argv[i];
-  childArgv[i+1] = "-PyFrameworkPaths";
-  childArgv[i+2] = [[bundlePaths componentsJoinedByString: @":"] UTF8String];
-  childArgv[i+3] = NULL;
+  i++; // compensate for i+1 in for() loop
 
-  return execve(pythonBinPathPtr, (char **)childArgv, envp);
+  // add an argument that lists all frameworks
+  childArgv[i++] = "-PyFrameworkPaths";
+  childArgv[i++] = [[bundlePaths componentsJoinedByString: @":"] UTF8String];
+
+  // terminate the arg list
+  childArgv[i++] = NULL;
+
+  // print a nice debugging helper message, if desired
+  if ([[[NSProcessInfo processInfo] environment] objectForKey: @"SHOWPID"])
+    NSLog(@"Process ID is: %d (\n\tgdb %s %d\n to debug)", getpid(), pythonBinPathPtr, getpid());
+
+  // pass control to the python interpreter
+  return execve(pythonBinPathPtr, (char **)childArgv, childEnvp);
 }
 
-int main(int argc, char * const *argv, char *envp[])
+int main(int argc, char * const *argv, char * const *envp)
 {
   return pyobjc_main(argc, argv, envp);
 }