| 
									
										
										
										
											2004-12-26 23:02:05 +00:00
										 |  |  | """fixapplepython23 - Fix Apple-installed Python 2.3 (on Mac OS X 10.3)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Python 2.3 (and 2.3.X for X<5) have the problem that building an extension | 
					
						
							|  |  |  | for a framework installation may accidentally pick up the framework | 
					
						
							|  |  |  | of a newer Python, in stead of the one that was used to build the extension. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This script modifies the Makefile (in .../lib/python2.3/config) to use | 
					
						
							|  |  |  | the newer method of linking extensions with "-undefined dynamic_lookup" | 
					
						
							|  |  |  | which fixes this problem. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The script will first check all prerequisites, and return a zero exit | 
					
						
							|  |  |  | status also when nothing needs to be fixed. | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import os | 
					
						
							|  |  |  | import gestalt | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | MAKEFILE='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/Makefile' | 
					
						
							| 
									
										
										
										
											2005-01-01 22:33:36 +00:00
										 |  |  | CHANGES=(( | 
					
						
							|  |  |  |     'LDSHARED=\t$(CC) $(LDFLAGS) -bundle -framework $(PYTHONFRAMEWORK)\n', | 
					
						
							|  |  |  |     'LDSHARED=\t$(CC) $(LDFLAGS) -bundle -undefined dynamic_lookup\n' | 
					
						
							|  |  |  |     ),( | 
					
						
							|  |  |  |     'BLDSHARED=\t$(CC) $(LDFLAGS) -bundle -framework $(PYTHONFRAMEWORK)\n', | 
					
						
							|  |  |  |     'BLDSHARED=\t$(CC) $(LDFLAGS) -bundle -undefined dynamic_lookup\n' | 
					
						
							|  |  |  |     ),( | 
					
						
							|  |  |  |     'CC=\t\tgcc\n', | 
					
						
							|  |  |  |     'CC=\t\t/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-gcc\n' | 
					
						
							|  |  |  |     ),( | 
					
						
							|  |  |  |     'CXX=\t\tc++\n', | 
					
						
							|  |  |  |     'CXX=\t\t/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-g++\n' | 
					
						
							|  |  |  | )) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | GCC_SCRIPT='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-gcc' | 
					
						
							|  |  |  | GXX_SCRIPT='/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/config/PantherPythonFix/run-g++' | 
					
						
							|  |  |  | SCRIPT="""#!/bin/sh
 | 
					
						
							|  |  |  | export MACOSX_DEPLOYMENT_TARGET=10.3 | 
					
						
							|  |  |  | exec %s "${@}" | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2004-12-26 23:02:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def findline(lines, start): | 
					
						
							|  |  |  |     """return line starting with given string or -1""" | 
					
						
							|  |  |  |     for i in range(len(lines)): | 
					
						
							|  |  |  |         if lines[i][:len(start)] == start: | 
					
						
							|  |  |  |             return i | 
					
						
							|  |  |  |     return -1 | 
					
						
							| 
									
										
										
										
											2005-01-07 16:01:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-26 23:02:05 +00:00
										 |  |  | def fix(makefile, do_apply): | 
					
						
							|  |  |  |     """Fix the Makefile, if required.""" | 
					
						
							|  |  |  |     fixed = False | 
					
						
							|  |  |  |     lines = open(makefile).readlines() | 
					
						
							| 
									
										
										
										
											2005-01-07 16:01:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-01 22:33:36 +00:00
										 |  |  |     for old, new in CHANGES: | 
					
						
							|  |  |  |         i = findline(lines, new) | 
					
						
							|  |  |  |         if i >= 0: | 
					
						
							|  |  |  |             # Already fixed | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         i = findline(lines, old) | 
					
						
							|  |  |  |         if i < 0: | 
					
						
							|  |  |  |             print 'fixapplepython23: Python installation not fixed (appears broken)' | 
					
						
							|  |  |  |             print 'fixapplepython23: missing line:', old | 
					
						
							|  |  |  |             return 2 | 
					
						
							|  |  |  |         lines[i] = new | 
					
						
							| 
									
										
										
										
											2004-12-26 23:02:05 +00:00
										 |  |  |         fixed = True | 
					
						
							| 
									
										
										
										
											2005-01-07 16:01:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-26 23:02:05 +00:00
										 |  |  |     if fixed: | 
					
						
							|  |  |  |         if do_apply: | 
					
						
							|  |  |  |             print 'fixapplepython23: Fix to Apple-installed Python 2.3 applied' | 
					
						
							|  |  |  |             os.rename(makefile, makefile + '~') | 
					
						
							|  |  |  |             open(makefile, 'w').writelines(lines) | 
					
						
							|  |  |  |             return 0 | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             print 'fixapplepython23: Fix to Apple-installed Python 2.3 should be applied' | 
					
						
							|  |  |  |             return 1 | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         print 'fixapplepython23: No fix needed, appears to have been applied before' | 
					
						
							|  |  |  |         return 0 | 
					
						
							| 
									
										
										
										
											2005-01-07 16:01:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-01-01 22:33:36 +00:00
										 |  |  | def makescript(filename, compiler): | 
					
						
							|  |  |  |     """Create a wrapper script for a compiler""" | 
					
						
							|  |  |  |     dirname = os.path.split(filename)[0] | 
					
						
							|  |  |  |     if not os.access(dirname, os.X_OK): | 
					
						
							|  |  |  |         os.mkdir(dirname, 0755) | 
					
						
							|  |  |  |     fp = open(filename, 'w') | 
					
						
							|  |  |  |     fp.write(SCRIPT % compiler) | 
					
						
							|  |  |  |     fp.close() | 
					
						
							|  |  |  |     os.chmod(filename, 0755) | 
					
						
							|  |  |  |     print 'fixapplepython23: Created', filename | 
					
						
							| 
									
										
										
										
											2005-01-07 16:01:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-26 23:02:05 +00:00
										 |  |  | def main(): | 
					
						
							|  |  |  |     # Check for -n option | 
					
						
							|  |  |  |     if len(sys.argv) > 1 and sys.argv[1] == '-n': | 
					
						
							|  |  |  |         do_apply = False | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         do_apply = True | 
					
						
							|  |  |  |     # First check OS version | 
					
						
							|  |  |  |     if gestalt.gestalt('sysv') < 0x1030: | 
					
						
							|  |  |  |         print 'fixapplepython23: no fix needed on MacOSX < 10.3' | 
					
						
							|  |  |  |         sys.exit(0) | 
					
						
							|  |  |  |     # Test that a framework Python is indeed installed | 
					
						
							|  |  |  |     if not os.path.exists(MAKEFILE): | 
					
						
							|  |  |  |         print 'fixapplepython23: Python framework does not appear to be installed (?), nothing fixed' | 
					
						
							|  |  |  |         sys.exit(0) | 
					
						
							|  |  |  |     # Check that we can actually write the file | 
					
						
							|  |  |  |     if do_apply and not os.access(MAKEFILE, os.W_OK): | 
					
						
							|  |  |  |         print 'fixapplepython23: No write permission, please run with "sudo"' | 
					
						
							|  |  |  |         sys.exit(2) | 
					
						
							| 
									
										
										
										
											2005-01-01 22:33:36 +00:00
										 |  |  |     # Create the shell scripts | 
					
						
							|  |  |  |     if do_apply: | 
					
						
							|  |  |  |         if not os.access(GCC_SCRIPT, os.X_OK): | 
					
						
							|  |  |  |             makescript(GCC_SCRIPT, "gcc") | 
					
						
							|  |  |  |         if not os.access(GXX_SCRIPT, os.X_OK): | 
					
						
							|  |  |  |             makescript(GXX_SCRIPT, "g++") | 
					
						
							|  |  |  |     #  Finally fix the makefile | 
					
						
							| 
									
										
										
										
											2004-12-26 23:02:05 +00:00
										 |  |  |     rv = fix(MAKEFILE, do_apply) | 
					
						
							|  |  |  |     sys.exit(rv) | 
					
						
							| 
									
										
										
										
											2005-01-07 16:01:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-12-26 23:02:05 +00:00
										 |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     main() |