Merged revisions 342-393,401-404,413,424,426-427,429-433,435-437,439-442,445,448 via svnmerge from

https://svn.pyinstaller.python-hosting.com/branches/python2.5

........
  r342 | naufraghi | 2007-12-03 20:02:47 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r238@rosen:  naufraghi | 2007-12-03 19:59:24 +0100
    r200@rosen:  naufraghi | 2007-11-23 15:54:13 +0100
    Cleanup, remove some warning
   
........
  r343 | naufraghi | 2007-12-03 20:02:56 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r239@rosen:  naufraghi | 2007-12-03 19:59:24 +0100
    r201@rosen:  naufraghi | 2007-11-23 17:23:15 +0100
    Allow starting runtests from any path
   
........
  r344 | naufraghi | 2007-12-03 20:03:04 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r240@rosen:  naufraghi | 2007-12-03 20:00:51 +0100
    r202@rosen:  naufraghi | 2007-11-23 17:24:17 +0100
    Add natural sort for tests
   
........
  r345 | naufraghi | 2007-12-03 20:03:12 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r241@rosen:  naufraghi | 2007-12-03 20:00:51 +0100
    r203@rosen:  naufraghi | 2007-11-23 17:32:46 +0100
    Fix some fragile import?
   
........
  r346 | naufraghi | 2007-12-03 20:03:21 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r242@rosen:  naufraghi | 2007-12-03 20:01:01 +0100
    r204@rosen:  naufraghi | 2007-11-23 17:46:41 +0100
    Adds a basic way to choose tests to run
   
........
  r347 | naufraghi | 2007-12-03 20:03:29 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r243@rosen:  naufraghi | 2007-12-03 20:01:04 +0100
    r205@rosen:  naufraghi | 2007-11-23 17:57:31 +0100
    Adds and xml.dom test
   
........
  r348 | naufraghi | 2007-12-03 20:03:38 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r244@rosen:  naufraghi | 2007-12-03 20:01:04 +0100
    r206@rosen:  naufraghi | 2007-11-23 18:05:04 +0100
    Remove cmd line quoting
   
........
  r349 | naufraghi | 2007-12-03 20:03:46 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r245@rosen:  naufraghi | 2007-12-03 20:01:06 +0100
    r207@rosen:  naufraghi | 2007-11-23 19:47:13 +0100
    Adds 'import os' in one specfile
   
........
  r350 | naufraghi | 2007-12-03 20:03:54 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r246@rosen:  naufraghi | 2007-12-03 20:01:08 +0100
    r208@rosen:  naufraghi | 2007-11-23 19:49:21 +0100
    Add an 'encoding' hiddeimport test
   
........
  r351 | naufraghi | 2007-12-03 20:04:05 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r248@rosen:  naufraghi | 2007-12-03 20:01:08 +0100
    r211@rosen:  naufraghi | 2007-11-27 16:13:30 +0100
    Rewrite exec in execfile
   
........
  r352 | naufraghi | 2007-12-03 20:04:15 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r250@rosen:  naufraghi | 2007-12-03 20:01:09 +0100
    r214@rosen:  naufraghi | 2007-11-30 11:49:23 +0100
    Adds support for extended __path__
   
........
  r353 | naufraghi | 2007-12-03 20:04:23 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r251@rosen:  naufraghi | 2007-12-03 20:01:13 +0100
    r215@rosen:  naufraghi | 2007-11-30 11:52:18 +0100
    Simplify execfile
   
........
  r354 | naufraghi | 2007-12-03 20:04:30 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r252@rosen:  naufraghi | 2007-12-03 20:01:15 +0100
    r216@rosen:  naufraghi | 2007-11-30 11:52:56 +0100
    Fix output path
   
........
  r355 | naufraghi | 2007-12-03 20:04:38 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r253@rosen:  naufraghi | 2007-12-03 20:01:16 +0100
    r217@rosen:  naufraghi | 2007-11-30 12:13:17 +0100
    Add optional logging of self.moduleds
   
........
  r356 | naufraghi | 2007-12-03 20:04:46 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r254@rosen:  naufraghi | 2007-12-03 20:01:16 +0100
    r218@rosen:  naufraghi | 2007-11-30 12:19:13 +0100
    Add __str__ at Module class (and adds a default __file__ too)
   
........
  r357 | naufraghi | 2007-12-03 20:04:54 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r255@rosen:  naufraghi | 2007-12-03 20:01:18 +0100
    r219@rosen:  naufraghi | 2007-11-30 12:30:19 +0100
    Add version info to log filename
   
........
  r358 | naufraghi | 2007-12-03 20:05:01 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r256@rosen:  naufraghi | 2007-12-03 20:01:19 +0100
    r220@rosen:  naufraghi | 2007-11-30 16:11:07 +0100
    Asset-ize a comment + cosmetics (align variable name to other scopes)
   
........
  r359 | naufraghi | 2007-12-03 20:05:09 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r257@rosen:  naufraghi | 2007-12-03 20:01:21 +0100
    r221@rosen:  naufraghi | 2007-11-30 16:46:17 +0100
    Add comments and a None-iti assert
   
........
  r360 | naufraghi | 2007-12-03 20:05:16 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r258@rosen:  naufraghi | 2007-12-03 20:01:24 +0100
    r222@rosen:  naufraghi | 2007-12-03 16:23:17 +0100
    Remove user interaction
   
........
  r361 | naufraghi | 2007-12-03 20:05:25 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r259@rosen:  naufraghi | 2007-12-03 20:01:25 +0100
    r223@rosen:  naufraghi | 2007-12-03 16:39:48 +0100
    Activate the option to run selected tests: runtests.py --run 12 13
   
........
  r362 | naufraghi | 2007-12-03 20:05:32 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r260@rosen:  naufraghi | 2007-12-03 20:01:28 +0100
    r224@rosen:  naufraghi | 2007-12-03 16:51:02 +0100
    Adds a test that fails
   
........
  r363 | naufraghi | 2007-12-03 20:05:41 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r261@rosen:  naufraghi | 2007-12-03 20:01:28 +0100
    r225@rosen:  naufraghi | 2007-12-03 17:11:07 +0100
    Expand imports
   
........
  r364 | naufraghi | 2007-12-03 20:05:48 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r262@rosen:  naufraghi | 2007-12-03 20:01:29 +0100
    r226@rosen:  naufraghi | 2007-12-03 17:12:21 +0100
    Reorder imports
   
........
  r365 | naufraghi | 2007-12-03 20:05:55 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r263@rosen:  naufraghi | 2007-12-03 20:01:30 +0100
    r227@rosen:  naufraghi | 2007-12-03 17:16:11 +0100
    Turns 1-0 to True-False
   
........
  r366 | naufraghi | 2007-12-03 20:06:03 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r264@rosen:  naufraghi | 2007-12-03 20:01:30 +0100
    r228@rosen:  naufraghi | 2007-12-03 17:32:17 +0100
    Path cleanup
   
........
  r367 | naufraghi | 2007-12-03 20:06:10 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r265@rosen:  naufraghi | 2007-12-03 20:01:32 +0100
    r229@rosen:  naufraghi | 2007-12-03 17:35:21 +0100
    Followup: Path cleanup
   
........
  r368 | naufraghi | 2007-12-03 20:06:17 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r266@rosen:  naufraghi | 2007-12-03 20:01:33 +0100
    r230@rosen:  naufraghi | 2007-12-03 18:42:00 +0100
    Add some docs to assemble()
   
........
  r369 | naufraghi | 2007-12-03 20:06:23 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r267@rosen:  naufraghi | 2007-12-03 20:01:35 +0100
    r231@rosen:  naufraghi | 2007-12-03 18:55:32 +0100
    Remove criptic outN.toc numbering, use class names + reformat docs
   
........
  r370 | naufraghi | 2007-12-03 20:06:30 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r268@rosen:  naufraghi | 2007-12-03 20:01:36 +0100
    r232@rosen:  naufraghi | 2007-12-03 18:56:26 +0100
    Restore common prefix 'out'
   
........
  r371 | naufraghi | 2007-12-03 20:06:38 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r269@rosen:  naufraghi | 2007-12-03 20:01:37 +0100
    r236@rosen:  naufraghi | 2007-12-03 19:16:19 +0100
    Cosmetic
   
........
  r372 | naufraghi | 2007-12-03 20:06:45 +0100 (Lun, 03 Dic 2007) | 5 lines
  
   r270@rosen:  naufraghi | 2007-12-03 20:01:37 +0100
    r237@rosen:  naufraghi | 2007-12-03 19:17:17 +0100
    Factorize py[c|o] extension choice
   
........
  r373 | naufraghi | 2007-12-04 12:01:51 +0100 (Mar, 04 Dic 2007) | 3 lines
  
   r302@rosen:  naufraghi | 2007-12-04 12:00:38 +0100
   Restore invcnum
........
  r374 | naufraghi | 2007-12-04 12:01:58 +0100 (Mar, 04 Dic 2007) | 3 lines
  
   r303@rosen:  naufraghi | 2007-12-04 12:01:41 +0100
   Add warning for mod == None
........
  r375 | naufraghi | 2007-12-04 12:08:04 +0100 (Mar, 04 Dic 2007) | 2 lines
  
  Add final final "done" message
........
  r376 | naufraghi | 2007-12-04 12:09:30 +0100 (Mar, 04 Dic 2007) | 3 lines
  
  Ops, is "config.dat"
........
  r377 | naufraghi | 2007-12-04 12:26:20 +0100 (Mar, 04 Dic 2007) | 2 lines
  
  Restored removed "break"
........
  r378 | naufraghi | 2007-12-04 16:01:18 +0100 (Mar, 04 Dic 2007) | 2 lines
  
  Remove already logged warning
........
  r379 | naufraghi | 2007-12-04 17:46:50 +0100 (Mar, 04 Dic 2007) | 1 line
  
  Minimize test case
........
  r380 | naufraghi | 2007-12-04 17:51:07 +0100 (Mar, 04 Dic 2007) | 1 line
  
  Update PathImportDirector if __path__ changes (for example if modified by _xmlplus hook)
........
  r381 | naufraghi | 2007-12-04 18:06:10 +0100 (Mar, 04 Dic 2007) | 1 line
  
  Localize hiddenimport and add hook
........
  r382 | naufraghi | 2007-12-04 19:37:45 +0100 (Mar, 04 Dic 2007) | 1 line
  
  Add another elementree test
........
  r383 | naufraghi | 2007-12-17 12:58:57 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Fix importHook debug print, add other (commented) print debugs
........
  r384 | naufraghi | 2007-12-17 13:00:32 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Support more then one log per spec
........
  r385 | naufraghi | 2007-12-17 13:01:10 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Add hidden xml.etree.ElementTree import
........
  r386 | naufraghi | 2007-12-17 13:02:35 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Restore PATH before assert + comments
........
  r387 | naufraghi | 2007-12-17 14:42:32 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Print warnings for generic excepts in the code
........
  r388 | naufraghi | 2007-12-17 14:56:12 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Use a specific exception for Owners
........
  r389 | naufraghi | 2007-12-17 16:44:59 +0100 (Lun, 17 Dic 2007) | 1 line
  
  Remove final comma
........
  r390 | naufraghi | 2007-12-18 14:51:06 +0100 (Mar, 18 Dic 2007) | 1 line
  
  Expand debug print
........
  r391 | naufraghi | 2007-12-19 18:21:05 +0100 (Mer, 19 Dic 2007) | 1 line
  
  Avoid 'import os' that causes problems in py25
........
  r392 | naufraghi | 2007-12-19 18:34:46 +0100 (Mer, 19 Dic 2007) | 1 line
  
  Represent with %r the exception
........
  r393 | naufraghi | 2007-12-19 18:37:52 +0100 (Mer, 19 Dic 2007) | 1 line
  
  Add comments and commented prints
........
  r401 | naufraghi | 2008-01-11 16:47:02 +0100 (Ven, 11 Gen 2008) | 1 line
  
  Use sys.executable saved at build time (unknown when frozen)
........
  r402 | naufraghi | 2008-01-11 17:17:37 +0100 (Ven, 11 Gen 2008) | 1 line
  
  Restore linux compatibility
........
  r403 | naufraghi | 2008-01-11 18:37:22 +0100 (Ven, 11 Gen 2008) | 1 line
  
  Add test for sys.getfilesystemencoding()
........
  r404 | naufraghi | 2008-01-11 19:42:42 +0100 (Ven, 11 Gen 2008) | 1 line
  
  Accept different error under windows (FIXME: do a real isfile check)
........
  r413 | naufraghi | 2008-01-25 19:47:50 +0100 (Ven, 25 Gen 2008) | 1 line
  
  Restore compatibility with python 2.4
........
  r424 | naufraghi | 2008-02-18 11:53:12 +0100 (Lun, 18 Feb 2008) | 3 lines
  
   r343@trinity:  naufraghi | 2008-02-18 11:53:00 +0100
   Merge dal trunk
........
  r426 | naufraghi | 2008-02-18 14:49:15 +0100 (Lun, 18 Feb 2008) | 1 line
  
  Catch SyntaxError too
........
  r427 | naufraghi | 2008-02-18 15:02:45 +0100 (Lun, 18 Feb 2008) | 1 line
  
  Revert: DummyZlib is a zero commpression zlib
........
  r429 | naufraghi | 2008-02-23 17:05:35 +0100 (Sab, 23 Feb 2008) | 1 line
  
  Add a (failing) test on module imp
........
  r430 | naufraghi | 2008-02-23 18:12:59 +0100 (Sab, 23 Feb 2008) | 1 line
  
  Modified runtest, now all tests are executed (default) but the interactive one(s), thet are executed if -i option is provided
........
  r431 | naufraghi | 2008-02-23 18:18:02 +0100 (Sab, 23 Feb 2008) | 1 line
  
  Merge dal branch dl
........
  r432 | danielevarrazzo | 2008-02-24 14:38:15 +0100 (Dom, 24 Feb 2008) | 2 lines
  
  Added missing file from the 'dl' branch.
........
  r433 | naufraghi | 2008-02-25 13:07:44 +0100 (Lun, 25 Feb 2008) | 1 line
  
  Continue on test failure and report (...) at the end
........
  r435 | naufraghi | 2008-02-25 13:28:08 +0100 (Lun, 25 Feb 2008) | 1 line
  
  Stub of a launcher rebuilder
........
  r436 | danielevarrazzo | 2008-02-25 13:30:56 +0100 (Lun, 25 Feb 2008) | 2 lines
  
  The Python library is found both in onedir and onefile mode.
........
  r437 | naufraghi | 2008-02-25 18:42:16 +0100 (Lun, 25 Feb 2008) | 1 line
  
  Add comments and (commented) debug prints
........
  r439 | naufraghi | 2008-02-28 00:16:38 +0100 (Gio, 28 Feb 2008) | 1 line
  
  Cosmetics
........
  r440 | danielevarrazzo | 2008-02-28 20:21:15 +0100 (Gio, 28 Feb 2008) | 4 lines
  
  The Python library is added to the package even if bindepend couldn't find it.
  
  This may happen when Python is statically linked, e.g. on debian-based systems.
........
  r441 | naufraghi | 2008-03-01 00:46:00 +0100 (Sab, 01 Mar 2008) | 1 line
  
  Remove too restrictive assert
........
  r442 | naufraghi | 2008-03-01 00:47:07 +0100 (Sab, 01 Mar 2008) | 1 line
  
  Run Configure.py after make
........
  r445 | naufraghi | 2008-04-28 19:42:13 +0200 (Lun, 28 Apr 2008) | 1 line
  
  Merge follow up
........
  r448 | naufraghi | 2008-04-30 15:41:51 +0200 (Mer, 30 Apr 2008) | 2 lines
  
  ops, svnmerge was not complete...
........


git-svn-id: http://svn.pyinstaller.org/trunk@449 8dd32b29-ccff-0310-8a9a-9233e24343b1
This commit is contained in:
naufraghi
2008-04-30 14:30:09 +00:00
parent 063e5070e4
commit 82ab43bb1e
30 changed files with 794 additions and 258 deletions
+72 -30
View File
@@ -86,7 +86,7 @@ def build(spec):
BUILDPATH = os.path.join(SPECPATH, bpath)
if not os.path.exists(BUILDPATH):
os.mkdir(BUILDPATH)
exec open(spec, 'r').read()+'\n'
execfile(spec)
def mtime(fnm):
try:
@@ -94,12 +94,16 @@ def mtime(fnm):
except:
return 0
def absnormpath(apath):
return os.path.abspath(os.path.normpath(apath))
class Target:
invcnum = 0
def __init__(self):
self.invcnum = Target.invcnum
Target.invcnum = Target.invcnum + 1
self.out = os.path.join(BUILDPATH, 'out%d.toc' % self.invcnum)
Target.invcnum += 1
self.out = os.path.join(BUILDPATH, 'out%s%d.toc' % (self.__class__.__name__,
self.invcnum))
self.dependencies = TOC()
def __postinit__(self):
print "checking %s" % (self.__class__.__name__,)
@@ -116,7 +120,7 @@ class Analysis(Target):
self.pathex = []
if pathex:
for path in pathex:
self.pathex.append(os.path.abspath(os.path.normpath(path)))
self.pathex.append(absnormpath(path))
self.hookspath = hookspath
self.excludes = excludes
self.scripts = TOC()
@@ -127,54 +131,57 @@ class Analysis(Target):
outnm = os.path.basename(self.out)
if last_build == 0:
print "building %s because %s non existent" % (self.__class__.__name__, outnm)
return 1
return True
for fnm in self.inputs:
if mtime(fnm) > last_build:
print "building because %s changed" % fnm
return 1
return True
try:
inputs, pathex, hookspath, excludes, scripts, pure, binaries = eval(open(self.out, 'r').read())
except:
print "building because %s disappeared" % outnm
return 1
return True
if inputs != self.inputs:
print "building %s because inputs changed" % outnm
return 1
return True
if pathex != self.pathex:
print "building %s because pathex changed" % outnm
return 1
return True
if hookspath != self.hookspath:
print "building %s because hookspath changed" % outnm
return 1
return True
if excludes != self.excludes:
print "building %s because excludes changed" % outnm
return 1
return True
for (nm, fnm, typ) in scripts:
if mtime(fnm) > last_build:
print "building because %s changed" % fnm
return 1
return True
for (nm, fnm, typ) in pure:
if mtime(fnm) > last_build:
print "building because %s changed" % fnm
return 1
return True
elif mtime(fnm[:-1]) > last_build:
print "building because %s changed" % fnm[:-1]
return 1
return True
for (nm, fnm, typ) in binaries:
if mtime(fnm) > last_build:
print "building because %s changed" % fnm
return 1
return True
self.scripts = TOC(scripts)
self.pure = TOC(pure)
self.binaries = TOC(binaries)
return 0
return False
def assemble(self):
print "running Analysis", os.path.basename(self.out)
paths = self.pathex
for i in range(len(paths)):
paths[i] = os.path.abspath(os.path.normpath(paths[i]))
dirs = {}
pynms = []
# FIXME: isn't self.pathex already norm-abs-pathed?
paths[i] = absnormpath(paths[i])
###################################################
# Scan inputs and prepare:
dirs = {} # input directories
pynms = [] # python filenames with no extension
for script in self.inputs:
if not os.path.exists(script):
print "Analysis: script %s not found!" % script
@@ -182,22 +189,27 @@ class Analysis(Target):
d, base = os.path.split(script)
if not d:
d = os.getcwd()
d = os.path.abspath(os.path.normpath(d))
d = absnormpath(d)
pynm, ext = os.path.splitext(base)
dirs[d] = 1
pynms.append(pynm)
###################################################
# Initialize analyzer and analyze scripts
analyzer = mf.ImportTracker(dirs.keys()+paths, self.hookspath, self.excludes)
#print analyzer.path
scripts = []
scripts = [] # will contain scripts to bundle
for i in range(len(self.inputs)):
script = self.inputs[i]
print "Analyzing:", script
analyzer.analyze_script(script)
scripts.append((pynms[i], script, 'PYSOURCE'))
pure = []
binaries = []
rthooks = []
###################################################
# Fills pure, binaries and rthookcs lists to TOC
pure = [] # pure python modules
binaries = [] # binaries to bundle
rthooks = [] # rthooks if needed
for modnm, mod in analyzer.modules.items():
# FIXME: why can we have a mod == None here?
if mod is not None:
hooks = findRTHook(modnm) #XXX
if hooks:
@@ -213,11 +225,12 @@ class Analysis(Target):
else:
pure.append((modnm, fnm, 'PYMODULE'))
binaries.extend(bindepend.Dependencies(binaries))
self.fixMissingPythonLib(binaries)
scripts[1:1] = rthooks
self.scripts = TOC(scripts)
self.pure = TOC(pure)
self.binaries = TOC(binaries)
try:
try: # read .toc
oldstuff = eval(open(self.out, 'r').read())
except:
oldstuff = None
@@ -236,6 +249,28 @@ class Analysis(Target):
print self.out, "no change!"
return 0
def fixMissingPythonLib(self, binaries):
"""Add the Python library if missing from the binaries.
Some linux distributions (e.g. debian-based) statically build the
Python executable to the libpython, so bindepend doesn't include
it in its output.
"""
if sys.platform != 'linux2': return
name = 'libpython%d.%d.so' % sys.version_info[:2]
for (nm, fnm, typ) in binaries:
if typ == 'BINARY' and name in fnm:
# lib found
return
lib = bindepend.findLibrary(name)
if lib is None:
raise IOError("Python library not found!")
binaries.append((os.path.split(lib)[1], lib, 'BINARY'))
def findRTHook(modnm):
hooklist = rthooks.get(modnm)
if hooklist:
@@ -311,8 +346,10 @@ def cacheDigest(fnm):
digest = md5.new(data).digest()
return digest
def checkCache(fnm, strip, upx):
if not strip and not upx:
def checkCache(fnm, strip, upx, fix_paths=1):
# On darwin a cache is required anyway to keep the libaries
# with relative install names
if not strip and not upx and sys.platform != 'darwin':
return fnm
if strip:
strip = 1
@@ -337,6 +374,7 @@ def checkCache(fnm, strip, upx):
basenm = os.path.normcase(os.path.basename(fnm))
digest = cacheDigest(fnm)
cachedfile = os.path.join(cachedir, basenm)
cmd = None
if cache_index.has_key(basenm):
if digest != cache_index[basenm]:
os.remove(cachedfile)
@@ -344,13 +382,17 @@ def checkCache(fnm, strip, upx):
return cachedfile
if upx:
if strip:
fnm = checkCache(fnm, 1, 0)
fnm = checkCache(fnm, 1, 0, fix_paths=0)
cmd = "upx --best -q \"%s\"" % cachedfile
else:
cmd = "strip \"%s\"" % cachedfile
if strip:
cmd = "strip \"%s\"" % cachedfile
shutil.copy2(fnm, cachedfile)
os.chmod(cachedfile, 0755)
os.system(cmd)
if cmd: os.system(cmd)
if sys.platform == 'darwin' and fix_paths:
bindepend.fixOsxPaths(cachedfile)
# update cache index
cache_index[basenm] = digest
+7 -9
View File
@@ -25,8 +25,11 @@ cygwin = sys.platform == 'cygwin'
configfile = os.path.join(HOME, 'config.dat')
try:
config = eval(open(configfile, 'r').read())
except IOError:
except IOError, SyntaxError:
# IOerror: file not present
# SyntaxError: invalid file (platform change?)
config = {'useELFEXE':1} # if not set by Make.py we can assume Windows
# Save Python version, to detect and avoid conflicts
config["pythonVersion"] = sys.version
@@ -38,13 +41,8 @@ print "I: computing EXE_dependencies"
python = sys.executable
if not iswin:
while os.path.islink(python):
python = os.readlink(python)
if not os.path.isabs(python):
for dir in string.split(os.environ['PATH'], os.pathsep):
test = os.path.join(dir, python)
if os.path.exists(test):
python = test
break
python = os.path.join(os.path.split(python)[0], os.readlink(python))
toc = bindepend.Dependencies([('', python, '')])
if iswin and sys.version[:3] == '1.5':
import exceptions
@@ -241,4 +239,4 @@ outf = open(configfile, 'w')
import pprint
pprint.pprint(config, outf)
outf.close()
print "I: config.dat generation done!"
+9 -3
View File
@@ -275,9 +275,11 @@ class Archive:
class DummyZlib:
def decompress(self, data):
raise RuntimeError, "zlib required but cannot be imported"
#raise RuntimeError, "zlib required but cannot be imported"
return data
def compress(self, data, lvl):
raise RuntimeError, "zlib required but cannot be imported"
#raise RuntimeError, "zlib required but cannot be imported"
return data
import iu
##############################################################
@@ -313,6 +315,7 @@ class ZlibArchive(Archive):
except ImportError:
zlib = DummyZlib()
else:
print "WARNING: compression level=0!!!"
zlib = DummyZlib()
@@ -367,7 +370,10 @@ class ZlibArchive(Archive):
class PYZOwner(iu.Owner):
def __init__(self, path):
self.pyz = ZlibArchive(path)
try:
self.pyz = ZlibArchive(path)
except IOError, e:
raise iu.OwnerError(e)
iu.Owner.__init__(self, path)
def getmod(self, nm, newmod=imp.new_module):
rslt = self.pyz.extract(nm)
+91 -10
View File
@@ -34,6 +34,7 @@ import time
import string
import sys
import re
from glob import glob
seen = {}
_bpath = None
@@ -73,6 +74,7 @@ excludes = {'KERNEL32.DLL':1,
'PSAPI.DLL':1,
'MSVCP80.DLL':1,
'MSVCR80.DLL':1,
# regex excludes
'^/usr/lib':1,
'^/lib':1,
'^/lib/tls':1,
@@ -265,25 +267,48 @@ def Dependencies(lTOC):
continue
#print "I: analyzing", pth
seen[string.upper(nm)] = 1
for lib, npth in selectImports(pth):
if seen.get(string.upper(lib),0):
continue
lTOC.append((lib, npth, 'BINARY'))
return lTOC
def selectImports(pth):
"""Return the dependencies of a binary that should be included.
Return a list of pairs (name, fullpath)
"""
rv = []
dlls = getImports(pth)
for lib in dlls:
#print "I: found", lib
if not iswin and not cygwin:
# plain win case
npth = lib
dir, lib = os.path.split(lib)
if excludes.get(dir,0):
continue
else:
# all other platforms
npth = getfullnameof(lib, os.path.dirname(pth))
# now npth is a candidate lib
# check again for excludes but with regex FIXME: split the list
if excludesRe.search(npth):
continue
if seen.get(string.upper(lib),0):
continue
if 'libpython' not in npth and 'Python.framework' not in npth:
# skip libs not containing (libpython or Python.framework)
#print "I: skipping %20s <- %s" % (npth, pth)
continue
else:
#print "I: inserting %20s <- %s" % (npth, pth)
pass
if npth:
lTOC.append((lib, npth, 'BINARY'))
rv.append((lib, npth))
else:
print "E: lib not found:", lib, "dependency of", pth
return lTOC
return rv
def _getImports_ldd(pth):
"""Find the binary dependencies of PTH.
@@ -353,8 +378,64 @@ def getWindowsPath():
_bpath.extend(string.split(os.environ.get('PATH', ''), os.pathsep))
return _bpath
def fixOsxPaths(moduleName):
for name, lib in selectImports(moduleName):
dest = os.path.join("@executable_path", name)
cmd = "install_name_tool -change %s %s %s" % (lib, dest, moduleName)
os.system(cmd)
def findLibrary(name):
"""Look for a library in the system.
Emulate the algorithm used by dlopen.
`name`must include the prefix, e.g. ``libpython2.4.so``
"""
assert sys.platform == 'linux2', "Current implementation for Linux only"
lib = None
# Look in the LD_LIBRARY_PATH
lp = os.environ.get('LD_LIBRARY_PATH')
if lp:
for path in string.split(lp, os.pathsep):
libs = glob(os.path.join(path, name + '*'))
if libs:
lib = libs[0]
break
# Look in /etc/ld.so.cache
if lib is None:
expr = r'/[^\(\)\s]*%s\.[^\(\)\s]*' % re.escape(name)
m = re.search(expr, os.popen('/sbin/ldconfig -p 2>/dev/null').read())
if m:
lib = m.group(0)
# Look in the known safe paths
if lib is None:
for path in ['/lib', '/usr/lib']:
libs = glob(os.path.join(path, name + '*'))
if libs:
lib = libs[0]
break
# give up :(
if lib is None:
return None
# Resolve the file name into the soname
dir, file = os.path.split(lib)
return os.path.join(dir, getSoname(lib))
def getSoname(filename):
"""Return the soname of a library."""
cmd = "objdump -p -j .dynamic 2>/dev/null " + filename
m = re.search(r'\s+SONAME\s+([^\s]+)', os.popen(cmd).read())
if m: return m.group(1)
if __name__ == "__main__":
if len(sys.argv) < 2:
print "Usage: python %s BINARYFILE" % sys.argv[0]
sys.exit(0)
print getImports(sys.argv[1])
if len(sys.argv) < 2:
print "Usage: python %s BINARYFILE" % sys.argv[0]
sys.exit(0)
print getImports(sys.argv[1])
+29 -13
View File
@@ -23,6 +23,7 @@
import os, sys, glob, string
import shutil
try:
here=os.path.dirname(__file__)
except NameError:
@@ -53,20 +54,23 @@ def clean():
except OSError, e:
print e
def runtests(sources=None):
def runtests(alltests, filters=None):
info = "Executing PyInstaller tests in: %s" % os.getcwd()
print "*"*len(info)
print info
print "*"*len(info)
alltests = glob.glob('test*[0-9].py')
if not sources:
build_python = open("python_exe.build", "w")
build_python.write(sys.executable)
build_python.close()
if not filters:
tests = alltests
else:
tests = []
for part in sources:
for part in filters:
tests += [t for t in alltests if part in t and t not in tests]
tests.sort(key=lambda x: (len(x), x)) # test1 < test10
path = os.environ["PATH"]
counter = dict(passed=[],failed=[])
for src in tests:
print
print "################## BUILDING TEST %s #################################" % src
@@ -80,14 +84,26 @@ def runtests(sources=None):
print
res = os.system('dist%s%s%s.exe' % (test, os.sep, test))
os.environ["PATH"] = path
assert res == 0, "%s Test error!" % src
print "################## FINISHING TEST %s ################################" % src
if res == 0:
counter["passed"].append(src)
print "################## FINISHING TEST %s ################################" % src
else:
counter["failed"].append(src)
print "#################### TEST %s FAILED #################################" % src
print counter
if __name__ == '__main__':
if len(sys.argv) == 1:
clean()
runtests()
if '--clean' in sys.argv:
clean()
if '--run' in sys.argv:
runtests(sys.argv[2:])
normal_tests = glob.glob('test*[0-9].py')
interactive_tests = glob.glob('test*[0-9]i.py')
args = sys.argv[1:]
if "-i" in args:
print "Running interactive tests"
tests = interactive_tests
else:
print "Running normal tests (-i for interactive tests)"
tests = normal_tests
clean()
runtests(tests)
+4 -1
View File
@@ -1,4 +1,7 @@
# Verify packagin of PIL.Image. Specifically, the hidden import of FixTk
# importing tkinter is causing some problems.
from Image import fromstring
try:
from Image import fromstring
except ImportError:
fromstring = "PIL missing!! Install PIL before running this test!"
print fromstring
+4 -1
View File
@@ -1,4 +1,7 @@
# Verify packagin of PIL.Image. Specifically, the hidden import of FixTk
# importing tkinter is causing some problems.
from PIL.Image import fromstring
try:
from PIL.Image import fromstring
except ImportError:
fromstring = "PIL missing!! Install PIL before running this test!"
print fromstring
+19
View File
@@ -0,0 +1,19 @@
# Copyright (C) 2005, Giovanni Bajo
# Based on previous work under copyright (c) 2001, 2002 McMillan Enterprises, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
print "test12 - xml.com"
from xml.dom import pulldom
print "test12 - done"
+14
View File
@@ -0,0 +1,14 @@
import os
a = Analysis(['../support/_mountzlib.py', 'test12.py'],
pathex=[])
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
exclude_binaries=1,
name='test12.exe',
debug=0,
console=1)
coll = COLLECT( exe,
a.binaries,
name='disttest12')
+26
View File
@@ -0,0 +1,26 @@
# Copyright (C) 2007, Matteo Bertini
# Based on previous work under copyright (c) 2001, 2002 McMillan Enterprises, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
print "test13 - Used to fail if _xmlplus is installed"
import sys
if sys.version_info[:2] >= (2, 5):
import _elementtree
print "test13 DONE"
else:
print "Python 2.5 test13 skipped"
+18
View File
@@ -0,0 +1,18 @@
a = Analysis(['../support/_mountzlib.py',
'../support/useUnicode.py',
'test13.py'],
pathex=[])
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
exclude_binaries=1,
name='test13.exe',
debug=False,
strip=False,
upx=False,
console=1 )
coll = COLLECT( exe,
a.binaries,
strip=False,
upx=False,
name='disttest13')
+38
View File
@@ -0,0 +1,38 @@
# Copyright (C) 2007, Matteo Bertini
# Based on previous work under copyright (c) 2001, 2002 McMillan Enterprises, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
print "test14 - Used to fail if _xmlplus is installed"
import sys
if sys.version_info[:2] >= (2, 5):
import subprocess
import xml.etree.ElementTree as ET
print "#"*50
print "xml.etree.ElementTree", dir(ET)
print "#"*50
import xml.etree.cElementTree as cET
pyexe = open("python_exe.build").read()
out = subprocess.Popen(pyexe + ' -c "import xml.etree.cElementTree as cET; print dir(cET)"',
stdout=subprocess.PIPE, shell=True).stdout.read().strip()
assert str(dir(cET)) == out, (str(dir(cET)), out)
print "test14 DONE"
else:
print "Python 2.5 test14 skipped"
+18
View File
@@ -0,0 +1,18 @@
a = Analysis(['../support/_mountzlib.py',
'../support/useUnicode.py',
'test14.py'],
pathex=[])
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
exclude_binaries=1,
name='test14.exe',
debug=False,
strip=False,
upx=False,
console=1 )
coll = COLLECT( exe,
a.binaries,
strip=False,
upx=False,
name='disttest14')
+35
View File
@@ -0,0 +1,35 @@
# Copyright (C) 2007, Matteo Bertini
# Based on previous work under copyright (c) 2001, 2002 McMillan Enterprises, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
print "test15 sys.getfilesystemencoding()"
import sys
if sys.version_info[:2] >= (2, 5):
import subprocess
import email
assert type(email.Header) == email.LazyImporter
pyexe = open("python_exe.build").read()
out = subprocess.Popen(pyexe + ' -c "import sys; print sys.getfilesystemencoding()"',
stdout=subprocess.PIPE, shell=True).stdout.read().strip()
assert str(sys.getfilesystemencoding()) == out, (str(sys.getfilesystemencoding()), out)
print "test15 DONE"
else:
print "Python 2.5 test14 skipped"
+18
View File
@@ -0,0 +1,18 @@
a = Analysis(['../support/_mountzlib.py',
'../support/useUnicode.py',
'test15.py'],
pathex=[])
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
exclude_binaries=1,
name='test15.exe',
debug=False,
strip=False,
upx=False,
console=1 )
coll = COLLECT( exe,
a.binaries,
strip=False,
upx=False,
name='disttest15')
+35
View File
@@ -0,0 +1,35 @@
# Copyright (C) 2007, Matteo Bertini
# Based on previous work under copyright (c) 2001, 2002 McMillan Enterprises, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
print "test16 imp.find_module"
import sys
import imp
modname = "test15"
for p in sys.path:
try:
i = imp.find_module(modname, [p])
except ImportError:
continue
else:
raise ImportError("Couldn't find the real '%s' module" % modname)
# as in setuptools/site.py
print "test16 DONE"
+18
View File
@@ -0,0 +1,18 @@
a = Analysis(['../support/_mountzlib.py',
'../support/useUnicode.py',
'test16.py'],
pathex=[])
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
exclude_binaries=1,
name='test16.exe',
debug=False,
strip=False,
upx=False,
console=1 )
coll = COLLECT( exe,
a.binaries,
strip=False,
upx=False,
name='disttest16')
+1 -1
View File
@@ -27,4 +27,4 @@ while 1:
sys.stdout.write(data)
if 'Q' in data:
break
print "test4 - done"
print "test4i - done"
@@ -1,13 +1,13 @@
a = Analysis(['../support/_mountzlib.py', 'test4.py'],
a = Analysis(['../support/_mountzlib.py', 'test4i.py'],
pathex=[])
pyz = PYZ(a.pure)
exe = EXE(pyz,
a.scripts,
[('u', '', 'OPTION')],
exclude_binaries=1,
name='buildtest4/test4.exe',
name='buildtest4i/test4i.exe',
debug=0,
console=1)
coll = COLLECT( exe,
a.binaries,
name='disttest4')
name='disttest4i')
+18
View File
@@ -0,0 +1,18 @@
# Copyright (C) 2005, Giovanni Bajo
# Based on previous work under copyright (c) 2001, 2002 McMillan Enterprises, Inc.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
hiddenimports = ['pyexpat', 'xml.etree.ElementTree']
+24 -10
View File
@@ -44,6 +44,12 @@ except AttributeError:
STRINGTYPE = type('')
class OwnerError(IOError):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return "<OwnerError %s>" % self.msg
class Owner:
def __init__(self, path):
self.path = path
@@ -56,7 +62,7 @@ class DirOwner(Owner):
if path == '':
path = _os_getcwd()
if not pathisdir(path):
raise ValueError, "%s is not a directory" % path
raise OwnerError("%s is not a directory" % path)
Owner.__init__(self, path)
def getmod(self, nm, getsuffixes=imp.get_suffixes, loadco=marshal.loads, newmod=imp.new_module):
pth = _os_path_join(self.path, nm)
@@ -69,8 +75,8 @@ class DirOwner(Owner):
attempt = pth+ext
try:
st = _os_stat(attempt)
except:
pass
except OSError, e:
assert e.errno == 2 #[Errno 2] No such file or directory
else:
if typ == imp.C_EXTENSION:
fp = open(attempt, 'rb')
@@ -164,8 +170,8 @@ class RegistryImportDirector(ImportDirector):
try:
#hkey = win32api.RegOpenKeyEx(root, subkey, 0, KEY_ALL_ACCESS)
hkey = win32api.RegOpenKeyEx(root, subkey, 0, KEY_READ)
except:
pass
except Exception, e:
print "FIXME: RegOpenKeyEx Exception", e
else:
numsubkeys, numvalues, lastmodified = win32api.RegQueryInfoKey(hkey)
for i in range(numsubkeys):
@@ -228,7 +234,7 @@ class PathImportDirector(ImportDirector):
# this may cause an import, which may cause recursion
# hence the protection
owner = klass(path)
except:
except OwnerError, e:
pass
else:
break
@@ -247,6 +253,12 @@ def getDescr(fnm):
UNTRIED = -1
class ImportManagerException(Exception):
def __init__(self, args):
self.args = args
def __repr__(self):
return "<%s: %s>" % (self.__name__, self.args)
class ImportManager:
# really the equivalent of builtin import
def __init__(self):
@@ -273,7 +285,7 @@ class ImportManager:
__builtin__.reload = self.reloadHook
def importHook(self, name, globals=None, locals=None, fromlist=None, level=-1):
# first see if we could be importing a relative name
#print "importHook(%s, %s, locals, %s)" % (name, globals['__name__'], fromlist)
#print "importHook(%s, %s, locals, %s)" % (name, getattr(globals, '__name__', None), fromlist)
_sys_modules_get = sys.modules.get
contexts = [None]
if globals and level == -1:
@@ -312,7 +324,9 @@ class ImportManager:
if mod is UNTRIED:
try:
mod = _self_doimport(nm, ctx, fqname)
except:
except Exception, e:
print "FIXME: _self_doimport %r" % e,
print " nm='%s' ctx='%s' fqname='%s'" % (nm, ctx, fqname)
if threaded:
self._release()
raise
@@ -356,8 +370,8 @@ class ImportManager:
self._acquire()
try:
mod = self.doimport(nm, ctx, ctx+'.'+nm)
except:
pass
except Exception, e:
print "FIXME: self.doimport Exception", e
if threaded:
self._release()
#print "importHook done with %s %s %s (case 3)" % (name, globals['__name__'], fromlist)
Executable
+5
View File
@@ -0,0 +1,5 @@
#!/bin/bash
echo "USAGE $0 some-python-version"
cd source/linux && $1 Make.py && make clean && make && cd -
$1 Configure.py
+61 -16
View File
@@ -37,6 +37,14 @@ else:
def caseOk(filename):
return True
def pyco():
"""
Returns correct extension ending: 'c' or 'o'
"""
if __debug__:
return 'c'
else:
return 'o'
class Owner:
def __init__(self, path):
@@ -64,13 +72,15 @@ class DirOwner(Owner):
attempt = pth+ext
try:
st = os.stat(attempt)
except:
except Exception, e:
#print "DirOwner", e
pass
else:
# Check case
if not caseOk(attempt):
continue
if typ == imp.C_EXTENSION:
#print "DirOwner.getmod -> ExtensionModule(%s, %s)" % (nm, attempt)
return ExtensionModule(nm, attempt)
elif typ == imp.PY_SOURCE:
py = (attempt, st)
@@ -79,16 +89,15 @@ class DirOwner(Owner):
if py or pyc:
break
if py is None and pyc is None:
#print "DirOwner.getmod -> (py == pyc == None)"
return None
while 1:
# If we have no pyc or py is newer
if pyc is None or py and pyc[1][8] < py[1][8]:
try:
stuff = open(py[0], 'r').read()+'\n'
co = compile(string.replace(stuff, "\r\n", "\n"), py[0], 'exec')
if __debug__:
pth = py[0] + 'c'
else:
pth = py[0] + 'o'
pth = py[0] + pyco()
break
except SyntaxError, e:
print "Syntax error in", py[0]
@@ -101,9 +110,10 @@ class DirOwner(Owner):
pth = pyc[0]
break
except (ValueError, EOFError):
print "W: bad .pyc found (%s)" % pyc[0]
print "W: bad .pyc found (%s), will use .py" % pyc[0]
pyc = None
else:
#print "DirOwner.getmod while 1 -> None"
return None
if not os.path.isabs(pth):
pth = os.path.abspath(pth)
@@ -111,6 +121,7 @@ class DirOwner(Owner):
mod = PkgModule(nm, pth, co)
else:
mod = PyModule(nm, pth, co)
#print "DirOwner.getmod -> %s" % mod
return mod
class PYZOwner(Owner):
@@ -172,7 +183,8 @@ class RegistryImportDirector(ImportDirector):
try:
#hkey = win32api.RegOpenKeyEx(root, subkey, 0, win32con.KEY_ALL_ACCESS)
hkey = win32api.RegOpenKeyEx(root, subkey, 0, win32con.KEY_READ)
except:
except Exception, e:
#print "RegistryImportDirector", e
pass
else:
numsubkeys, numvalues, lastmodified = win32api.RegQueryInfoKey(hkey)
@@ -246,7 +258,8 @@ class PathImportDirector(ImportDirector):
# this may cause an import, which may cause recursion
# hence the protection
owner = klass(path)
except:
except Exception, e:
#print "PathImportDirector", e
pass
else:
break
@@ -269,6 +282,25 @@ UNTRIED = -1
imptyps = ['top-level', 'conditional', 'delayed', 'delayed, conditional']
import hooks
if __debug__:
import sys
import UserDict
class LogDict(UserDict.UserDict):
count = 0
def __init__(self, *args):
UserDict.UserDict.__init__(self, *args)
LogDict.count += 1
self.logfile = open("logdict%s-%d.log" % (".".join(map(str, sys.version_info)),
LogDict.count), "w")
def __setitem__(self, key, value):
self.logfile.write("%s: %s -> %s\n" % (key, self.data.get(key), value))
UserDict.UserDict.__setitem__(self, key, value)
def __delitem__(self, key):
self.logfile.write(" DEL %s\n" % key)
UserDict.UserDict.__delitem__(self, key)
else:
LogDict = dict
class ImportTracker:
# really the equivalent of builtin import
def __init__(self, xpath=None, hookspath=None, excludes=None):
@@ -277,7 +309,7 @@ class ImportTracker:
if xpath:
self.path = xpath
self.path.extend(sys.path)
self.modules = {}
self.modules = LogDict()
self.metapath = [
BuiltinImportDirector(),
FrozenImportDirector(),
@@ -400,24 +432,33 @@ class ImportTracker:
def ispackage(self, nm):
return self.modules[nm].ispackage()
def doimport(self, nm, parentnm, fqname):
def doimport(self, nm, ctx, fqname):
# Not that nm is NEVER a dotted name at this point
assert ("." not in nm), nm
if fqname in self.excludes:
return None
if parentnm:
parent = self.modules[parentnm]
if ctx:
parent = self.modules[ctx]
if parent.ispackage():
mod = parent.doimport(nm)
if mod:
# insert the new module in the parent package
# FIXME why?
setattr(parent, nm, mod)
else:
# if parent is not a package, there is nothing more to do
return None
else:
# now we're dealing with an absolute import
# try to import nm using available directors
for director in self.metapath:
mod = director.getmod(nm)
if mod:
break
# here we have `mod` from:
# mod = parent.doimport(nm)
# or
# mod = director.getmod(nm)
if mod:
mod.__name__ = fqname
self.modules[fqname] = mod
@@ -445,7 +486,11 @@ class ImportTracker:
print "W: %s is changing it's name to %s" % (fqname, mod.__name__)
self.modules[mod.__name__] = mod
else:
assert (mod == None), mod
self.modules[fqname] = None
# should be equivalent using only one
# self.modules[fqname] = mod
# here
return mod
def getwarnings(self):
warnings = self.warnings.keys()
@@ -474,6 +519,7 @@ class Module:
typ = 'UNKNOWN'
def __init__(self, nm):
self.__name__ = nm
self.__file__ = None
self._all = []
self.imports = []
self.warnings = []
@@ -484,6 +530,8 @@ class Module:
pass
def xref(self, nm):
self._xref[nm] = 1
def __str__(self):
return "<Module %s %s %s>" % (self.__name__, self.__file__, self.imports)
class BuiltinModule(Module):
typ = 'BUILTIN'
@@ -503,10 +551,7 @@ class PyModule(Module):
self.co = co
self.__file__ = pth
if os.path.splitext(self.__file__)[1] == '.py':
if __debug__:
self.__file__ = self.__file__ + 'c'
else:
self.__file__ = self.__file__ + 'o'
self.__file__ = self.__file__ + pyco()
self.scancode()
def scancode(self):
self.imports, self.warnings, allnms = scan_code(self.co)
+82 -94
View File
@@ -34,6 +34,7 @@
#else
#include <unistd.h>
#include <fcntl.h>
#include <dlfcn.h>
#include <dirent.h>
#endif
#include <sys/types.h>
@@ -42,7 +43,7 @@
#ifndef NOZLIB
#include "zlib.h"
#endif
#ifdef WIN32
/*
* Python Entry point declarations (see macros in launch.h).
*/
@@ -51,10 +52,8 @@ DECLVAR(Py_OptimizeFlag);
DECLVAR(Py_VerboseFlag);
DECLPROC(Py_Initialize);
DECLPROC(Py_Finalize);
DECLPROC(Py_CompileString);
DECLPROC(PyImport_ExecCodeModule);
DECLPROC(PyRun_SimpleString);
DECLPROC(PySys_SetArgv);
DECLPROC(Py_SetProgramName);
DECLPROC(PyImport_ImportModule);
DECLPROC(PyImport_AddModule);
@@ -62,7 +61,6 @@ DECLPROC(PyObject_SetAttrString);
DECLPROC(PyList_New);
DECLPROC(PyList_Append);
DECLPROC(Py_BuildValue);
DECLPROC(PyFile_FromString);
DECLPROC(PyString_FromStringAndSize);
DECLPROC(PyObject_CallFunction);
DECLPROC(PyModule_GetDict);
@@ -70,24 +68,15 @@ DECLPROC(PyDict_GetItemString);
DECLPROC(PyErr_Clear);
DECLPROC(PyErr_Occurred);
DECLPROC(PyErr_Print);
DECLPROC(PyObject_CallObject);
DECLPROC(PyObject_CallMethod);
DECLPROC(PySys_AddWarnOption);
DECLPROC(PyEval_InitThreads);
DECLPROC(PyEval_AcquireThread);
DECLPROC(PyEval_ReleaseThread);
DECLPROC(PyEval_AcquireLock);
DECLPROC(PyEval_ReleaseLock);
DECLPROC(PyThreadState_Swap);
DECLPROC(PyThreadState_New);
DECLPROC(PyThreadState_Clear);
DECLPROC(PyThreadState_Delete);
DECLPROC(PyInterpreterState_New);
DECLPROC(Py_NewInterpreter);
DECLPROC(Py_EndInterpreter);
DECLPROC(PyInt_AsLong);
DECLPROC(PySys_SetObject);
#endif
#ifdef WIN32
#define PATHSEP ";"
@@ -319,7 +308,11 @@ int openArchive()
}
return 0;
}
#ifdef WIN32
#ifndef WIN32
#define HMODULE void *
#define HINSTANCE void *
#endif
int mapNames(HMODULE dll)
{
/* Get all of the entry points that we are interested in */
@@ -328,10 +321,8 @@ int mapNames(HMODULE dll)
GETVAR(dll, Py_VerboseFlag);
GETPROC(dll, Py_Initialize);
GETPROC(dll, Py_Finalize);
GETPROC(dll, Py_CompileString);
GETPROC(dll, PyImport_ExecCodeModule);
GETPROC(dll, PyRun_SimpleString);
GETPROC(dll, PySys_SetArgv);
GETPROC(dll, Py_SetProgramName);
GETPROC(dll, PyImport_ImportModule);
GETPROC(dll, PyImport_AddModule);
@@ -339,7 +330,6 @@ int mapNames(HMODULE dll)
GETPROC(dll, PyList_New);
GETPROC(dll, PyList_Append);
GETPROC(dll, Py_BuildValue);
GETPROC(dll, PyFile_FromString);
GETPROC(dll, PyString_FromStringAndSize);
GETPROC(dll, PyObject_CallFunction);
GETPROC(dll, PyModule_GetDict);
@@ -347,39 +337,30 @@ int mapNames(HMODULE dll)
GETPROC(dll, PyErr_Clear);
GETPROC(dll, PyErr_Occurred);
GETPROC(dll, PyErr_Print);
GETPROC(dll, PyObject_CallObject);
GETPROC(dll, PyObject_CallMethod);
if (ntohl(f_cookie.pyvers) >= 21) {
GETPROC(dll, PySys_AddWarnOption);
}
GETPROC(dll, PyEval_InitThreads);
GETPROC(dll, PyEval_AcquireThread);
GETPROC(dll, PyEval_ReleaseThread);
GETPROC(dll, PyEval_AcquireLock);
GETPROC(dll, PyEval_ReleaseLock);
GETPROC(dll, PyThreadState_Swap);
GETPROC(dll, PyThreadState_New);
GETPROC(dll, PyThreadState_Clear);
GETPROC(dll, PyThreadState_Delete);
GETPROC(dll, PyInterpreterState_New);
GETPROC(dll, Py_NewInterpreter);
GETPROC(dll, Py_EndInterpreter);
GETPROC(dll, PyErr_Print);
GETPROC(dll, PyInt_AsLong);
GETPROC(dll, PySys_SetObject);
return 0;
}
#endif
/*
* Load the Python DLL, and get all of the necessary entry points
* Windows only (dynamic load)
*/
int loadPython()
{
#ifdef WIN32
HINSTANCE dll;
char dllpath[_MAX_PATH + 1];
#ifdef WIN32
/* Determine the path */
sprintf(dllpath, "%spython%02d.dll", f_homepathraw, ntohl(f_cookie.pyvers));
@@ -402,11 +383,36 @@ int loadPython()
}
mapNames(dll);
#else
/* Determine the path */
#ifdef __APPLE__
sprintf(dllpath, "%sPython",
f_workpath ? f_workpath : f_homepath);
#else
sprintf(dllpath, "%slibpython%01d.%01d.so.1.0",
f_workpath ? f_workpath : f_homepath,
ntohl(f_cookie.pyvers) / 10, ntohl(f_cookie.pyvers) % 10);
#endif
/* Load the DLL */
dll = dlopen(dllpath, RTLD_NOW|RTLD_GLOBAL);
if (dll) {
VS("%s\n", dllpath);
}
if (dll == 0) {
FATALERROR("Error loading Python lib '%s': %s\n",
dllpath, dlerror());
return -1;
}
mapNames(dll);
#endif
return 0;
}
#ifdef WIN32
/*
* use this from a dll instead of loadPython()
* it will attach to an existing pythonXX.dll,
@@ -414,6 +420,7 @@ int loadPython()
*/
int attachPython(int *loadedNew)
{
#ifdef WIN32
HMODULE dll;
char nm[_MAX_PATH + 1];
@@ -428,9 +435,9 @@ int attachPython(int *loadedNew)
}
mapNames(dll);
*loadedNew = 0;
#endif
return 0;
}
#endif
/*
* Return pointer to next toc entry.
@@ -472,11 +479,7 @@ int setRuntimeOptions(void)
VS("%s\n", ptoc->name);
switch (ptoc->name[0]) {
case 'v':
#if defined WIN32
*Py_VerboseFlag = 1;
#else
Py_VerboseFlag = 1;
#endif
*PI_Py_VerboseFlag = 1;
break;
case 'u':
unbuffered = 1;
@@ -484,23 +487,15 @@ int setRuntimeOptions(void)
#ifdef HAVE_WARNINGS
case 'W':
if (ntohl(f_cookie.pyvers) >= 21) {
PySys_AddWarnOption(&ptoc->name[2]);
PI_PySys_AddWarnOption(&ptoc->name[2]);
}
break;
#endif
case 's':
#if defined WIN32
*Py_NoSiteFlag = 0;
#else
Py_NoSiteFlag = 0;
#endif
*PI_Py_NoSiteFlag = 0;
break;
case 'O':
#if defined WIN32
*Py_OptimizeFlag = 1;
#else
Py_OptimizeFlag = 1;
#endif
*PI_Py_OptimizeFlag = 1;
break;
}
}
@@ -572,46 +567,40 @@ int startPython(int argc, char *argv[])
/* Start python. */
/* VS("Loading python\n"); */
#if defined WIN32
*Py_NoSiteFlag = 1; /* maybe changed to 0 by setRuntimeOptions() */
#else
Py_NoSiteFlag = 1;
#endif
*PI_Py_NoSiteFlag = 1; /* maybe changed to 0 by setRuntimeOptions() */
setRuntimeOptions();
#ifdef WIN32
Py_SetProgramName(f_archivename); /*XXX*/
#endif
Py_Initialize();
PI_Py_SetProgramName(f_archivename); /*XXX*/
PI_Py_Initialize();
/* Set sys.path */
/* VS("Manipulating Python's sys.path\n"); */
strcpy(tmp, f_homepath);
tmp[strlen(tmp)-1] = '\0';
PyRun_SimpleString("import sys\n");
PyRun_SimpleString("while sys.path:\n del sys.path[0]\n");
PI_PyRun_SimpleString("import sys\n");
PI_PyRun_SimpleString("while sys.path:\n del sys.path[0]\n");
sprintf(cmd, "sys.path.append('%s')", tmp);
PyRun_SimpleString (cmd);
PI_PyRun_SimpleString (cmd);
if (pathlen == 2) {
strcpy(tmp, f_workpath);
tmp[strlen(tmp)-1] = '\0';
sprintf(cmd, "sys.path.insert(0, '%s')", tmp);
PyRun_SimpleString(cmd);
PI_PyRun_SimpleString(cmd);
}
/* Set argv[0] to be the archiveName */
py_argv = PyList_New(0);
val = Py_BuildValue("s", f_archivename);
PyList_Append(py_argv, val);
py_argv = PI_PyList_New(0);
val = PI_Py_BuildValue("s", f_archivename);
PI_PyList_Append(py_argv, val);
for (i = 1; i < argc; ++i) {
val = Py_BuildValue ("s", argv[i]);
PyList_Append (py_argv, val);
val = PI_Py_BuildValue ("s", argv[i]);
PI_PyList_Append (py_argv, val);
}
sys = PyImport_ImportModule("sys");
sys = PI_PyImport_ImportModule("sys");
/* VS("Setting sys.argv\n"); */
PyObject_SetAttrString(sys, "argv", py_argv);
PI_PyObject_SetAttrString(sys, "argv", py_argv);
/* Check for a python error */
if (PyErr_Occurred())
if (PI_PyErr_Occurred())
{
FATALERROR("Error detected starting Python VM.");
return -1;
@@ -628,12 +617,9 @@ int importModules()
PyObject *marshal;
PyObject *marshaldict;
PyObject *loadfunc;
PyObject *pyfile;
TOC *ptoc;
PyObject *co;
PyObject *mod;
PyObject *res;
char buf[32];
VS("importing modules from CArchive\n");
@@ -641,9 +627,9 @@ int importModules()
* Here we collect some reference to PyObject that we don't dereference
* Doesn't matter because the objects won't be going away anyway.
*/
marshal = PyImport_ImportModule("marshal");
marshaldict = PyModule_GetDict(marshal);
loadfunc = PyDict_GetItemString(marshaldict, "loads");
marshal = PI_PyImport_ImportModule("marshal");
marshaldict = PI_PyModule_GetDict(marshal);
loadfunc = PI_PyDict_GetItemString(marshaldict, "loads");
/* Iterate through toc looking for module entries (type 'm')
* this is normally just bootstrap stuff (archive and iu)
@@ -657,22 +643,22 @@ int importModules()
/* .pyc/.pyo files have 8 bytes header. Skip it and get a Python
* string directly pointing at the marshalled code.
*/
PyObject *mods = PyString_FromStringAndSize(modbuf + 8,
PyObject *mods = PI_PyString_FromStringAndSize(modbuf + 8,
ntohl(ptoc->ulen) - 8);
VS("%s\n", ptoc->name);
co = PyObject_CallFunction(loadfunc, "O", mods);
mod = PyImport_ExecCodeModule(ptoc->name, co);
co = PI_PyObject_CallFunction(loadfunc, "O", mods);
mod = PI_PyImport_ExecCodeModule(ptoc->name, co);
/* Check for errors in loading */
if (mod == NULL) {
FATALERROR("mod is NULL - %s", ptoc->name);
}
if (PyErr_Occurred())
if (PI_PyErr_Occurred())
{
PyErr_Print();
PyErr_Clear();
PI_PyErr_Print();
PI_PyErr_Clear();
}
Py_DECREF(mods);
@@ -696,7 +682,7 @@ int installZlib(TOC *ptoc)
char *cmd = (char *) malloc(strlen(tmpl) + strlen(f_archivename) + 32);
sprintf(cmd, tmpl, f_archivename, zlibpos);
/*VS(cmd);*/
rc = PyRun_SimpleString(cmd);
rc = PI_PyRun_SimpleString(cmd);
if (rc != 0)
{
FATALERROR("Error in command: %s\n", cmd);
@@ -902,7 +888,7 @@ int runScripts()
/* Get data out of the archive. */
data = extract(ptoc);
/* Run it */
rc = PyRun_SimpleString(data);
rc = PI_PyRun_SimpleString(data);
/* log errors and abort */
if (rc != 0) {
VS("RC: %d from %s\n", rc, ptoc->name);
@@ -930,27 +916,27 @@ int callSimpleEntryPoint(char *name, int *presult)
/* Objects with refs to kill. */
PyObject *func = NULL, *pyresult = NULL;
mod = PyImport_AddModule("__main__"); /* NO ref added */
mod = PI_PyImport_AddModule("__main__"); /* NO ref added */
if (!mod) {
VS("No __main__\n");
goto done;
}
dict = PyModule_GetDict(mod); /* NO ref added */
dict = PI_PyModule_GetDict(mod); /* NO ref added */
if (!mod) {
VS("No __dict__\n");
goto done;
}
func = PyDict_GetItemString(dict, name);
func = PI_PyDict_GetItemString(dict, name);
if (func == NULL) { /* should explicitly check KeyError */
VS("CallSimpleEntryPoint can't find the function name\n");
rc = -2;
goto done;
}
pyresult = PyObject_CallFunction(func, "");
pyresult = PI_PyObject_CallFunction(func, "");
if (pyresult==NULL) goto done;
PyErr_Clear();
*presult = PyInt_AsLong(pyresult);
rc = PyErr_Occurred() ? -1 : 0;
PI_PyErr_Clear();
*presult = PI_PyInt_AsLong(pyresult);
rc = PI_PyErr_Occurred() ? -1 : 0;
VS( rc ? "Finished with failure\n" : "Finished OK\n");
/* all done! */
done:
@@ -960,8 +946,8 @@ done:
cause failures in later async code */
if (rc)
/* But we will print them 'cos they may be useful */
PyErr_Print();
PyErr_Clear();
PI_PyErr_Print();
PI_PyErr_Clear();
return rc;
}
@@ -995,7 +981,7 @@ int launchembedded(char const * archivePath, char const * archiveName)
VS("Started Python\n");
/* a signal to scripts */
PyRun_SimpleString("import sys;sys.frozen='dll'\n");
PI_PyRun_SimpleString("import sys;sys.frozen='dll'\n");
VS("set sys.frozen\n");
/* Import modules from archive - this is to bootstrap */
if (importModules())
@@ -1009,7 +995,7 @@ int launchembedded(char const * archivePath, char const * archiveName)
if (runScripts())
return -1;
VS("All scripts run\n");
if (PyErr_Occurred()) {
if (PI_PyErr_Occurred()) {
/*PyErr_Clear();*/
VS("Some error occurred\n");
}
@@ -1024,7 +1010,9 @@ int launchembedded(char const * archivePath, char const * archiveName)
*/
int init(char const * archivePath, char const * archiveName, char const * workpath)
{
#ifdef WIN32
char *p;
#endif
if (workpath) {
f_workpath = (char *)workpath;
@@ -1173,6 +1161,6 @@ int getPyVersion(void)
}
void finalizePython(void)
{
Py_Finalize();
PI_Py_Finalize();
}
+54 -33
View File
@@ -42,29 +42,42 @@
#include <netinet/in.h>
#endif
/* On Windows, we use dynamic loading so one binary
/* We use dynamic loading so one binary
can be used with (nearly) any Python version.
This is the cruft necessary to do Windows dynamic loading
This is the cruft necessary to do dynamic loading
*/
#ifdef WIN32
/*
* These macros used to define variables to hold dynamically accessed entry
* points. These are declared 'extern' in this header, and defined fully later.
*/
#ifdef WIN32
#define EXTDECLPROC(result, name, args)\
typedef result (__cdecl *__PROC__##name) args;\
extern __PROC__##name name;
extern __PROC__##name PI_##name;
#define EXTDECLVAR(vartyp, name)\
typedef vartyp __VAR__##name;\
extern __VAR__##name *name;
extern __VAR__##name *PI_##name;
/*
#else
#define EXTDECLPROC(result, name, args)\
typedef result (*__PROC__##name) args;\
extern __PROC__##name PI_##name;
#define EXTDECLVAR(vartyp, name)\
typedef vartyp __VAR__##name;\
extern __VAR__##name *PI_##name;
#endif /* WIN32 */
/*
* These types and macros are included from the Python header file object.h
* They are needed to do very basic Python functionality.
*/
typedef _typeobject;
/*typedef _typeobject;*/
typedef struct _object {
int ob_refcnt;
struct _typeobject *ob_type;
@@ -125,10 +138,8 @@ EXTDECLVAR(int, Py_OptimizeFlag);
EXTDECLVAR(int, Py_VerboseFlag);
EXTDECLPROC(int, Py_Initialize, (void));
EXTDECLPROC(int, Py_Finalize, (void));
EXTDECLPROC(PyObject *, Py_CompileString, (char *, char *, int));
EXTDECLPROC(PyObject *, PyImport_ExecCodeModule, (char *, PyObject *));
EXTDECLPROC(int, PyRun_SimpleString, (char *));
EXTDECLPROC(int, PySys_SetArgv, (int, char **));
EXTDECLPROC(void, Py_SetProgramName, (char *));
EXTDECLPROC(PyObject *, PyImport_ImportModule, (char *));
EXTDECLPROC(PyObject *, PyImport_AddModule, (char *));
@@ -136,55 +147,65 @@ EXTDECLPROC(int, PyObject_SetAttrString, (PyObject *, char *, PyObject *));
EXTDECLPROC(PyObject *, PyList_New, (int));
EXTDECLPROC(int, PyList_Append, (PyObject *, PyObject *));
EXTDECLPROC(PyObject *, Py_BuildValue, (char *, ...));
EXTDECLPROC(PyObject *, PyFile_FromString, (char *, char *));
EXTDECLPROC(PyObject *, PyString_FromStringAndSize, (const char *, int));
EXTDECLPROC(PyObject *, PyObject_CallFunction, (PyObject *, char *, ...));
EXTDECLPROC(PyObject *, PyModule_GetDict, (PyObject *));
EXTDECLPROC(PyObject *, PyDict_GetItemString, (PyObject *, char *));
EXTDECLPROC(void, PyErr_Clear, () );
EXTDECLPROC(PyObject *, PyErr_Occurred, () );
EXTDECLPROC(void, PyErr_Print, () );
EXTDECLPROC(PyObject *, PyObject_CallObject, (PyObject *, PyObject*) );
EXTDECLPROC(PyObject *, PyObject_CallMethod, (PyObject *, char *, char *, ...) );
EXTDECLPROC(void, PySys_AddWarnOption, (char *));
EXTDECLPROC(void, PyEval_InitThreads, () );
EXTDECLPROC(void, PyErr_Clear, (void) );
EXTDECLPROC(PyObject *, PyErr_Occurred, (void) );
EXTDECLPROC(void, PyErr_Print, (void) );
EXTDECLPROC(void, PySys_AddWarnOption, (char *));
EXTDECLPROC(void, PyEval_InitThreads, (void) );
EXTDECLPROC(void, PyEval_AcquireThread, (PyThreadState *) );
EXTDECLPROC(void, PyEval_ReleaseThread, (PyThreadState *) );
EXTDECLPROC(void, PyEval_AcquireLock, (void) );
EXTDECLPROC(void, PyEval_ReleaseLock, (void) );
EXTDECLPROC(PyThreadState *, PyThreadState_Swap, (PyThreadState *) );
EXTDECLPROC(PyThreadState *, PyThreadState_New, (PyInterpreterState *) );
EXTDECLPROC(void, PyThreadState_Clear, (PyThreadState *) );
EXTDECLPROC(void, PyThreadState_Delete, (PyThreadState *) );
EXTDECLPROC(PyInterpreterState *, PyInterpreterState_New, () );
EXTDECLPROC(PyThreadState *, Py_NewInterpreter, () );
EXTDECLPROC(PyThreadState *, Py_NewInterpreter, (void) );
EXTDECLPROC(void, Py_EndInterpreter, (PyThreadState *) );
EXTDECLPROC(void, PyErr_Print, () );
EXTDECLPROC(long, PyInt_AsLong, (PyObject *) );
EXTDECLPROC(int, PySys_SetObject, (char *, PyObject *));
/* Macros to declare and get Python entry points in the C file.
* Typedefs '__PROC__...' have been done above
*/
#ifdef WIN32
#define DECLPROC(name)\
__PROC__##name name = NULL;
__PROC__##name PI_##name = NULL;
#define GETPROC(dll, name)\
name = (__PROC__##name)GetProcAddress (dll, #name);\
if (!name) {\
PI_##name = (__PROC__##name)GetProcAddress (dll, #name);\
if (!PI_##name) {\
FATALERROR ("Cannot GetProcAddress for " #name);\
return -1;\
}
#define DECLVAR(name)\
__VAR__##name *name = NULL;
__VAR__##name *PI_##name = NULL;
#define GETVAR(dll, name)\
name = (__VAR__##name *)GetProcAddress (dll, #name);\
if (!name) {\
PI_##name = (__VAR__##name *)GetProcAddress (dll, #name);\
if (!PI_##name) {\
FATALERROR ("Cannot GetProcAddress for " #name);\
return -1;\
}
#else
#include <Python.h>
#endif /* WIN32 dynamic load cruft */
#define DECLPROC(name)\
__PROC__##name PI_##name = NULL;
#define GETPROC(dll, name)\
PI_##name = (__PROC__##name)dlsym (dll, #name);\
if (!PI_##name) {\
FATALERROR ("Cannot dlsym for " #name);\
return -1;\
}
#define DECLVAR(name)\
__VAR__##name *PI_##name = NULL;
#define GETVAR(dll, name)\
PI_##name = (__VAR__##name *)dlsym(dll, #name);\
if (!PI_##name) {\
FATALERROR ("Cannot dlsym for " #name);\
return -1;\
}
#endif /* WIN32 */
/*
* #defines
+1 -5
View File
@@ -164,10 +164,6 @@ def main():
if non_elf:
cflags.append('-DNONELF')
libs = [os.path.join(sysconfig.get_config_vars('LIBPL')[0], sysconfig.get_config_vars('LIBRARY')[0])]
if not os.path.isfile(libs[0]):
print "WARNING: could not find Python static library at:", libs[0]
somevars = {}
if os.path.exists(makefile_in):
makevars = sysconfig.parse_makefile(makefile_in)
@@ -178,7 +174,7 @@ def main():
somevars['CFLAGS'] = string.join(cflags) # override
files = ['$(OPT)', '$(LDFLAGS)', '$(LINKFORSHARED)', 'getpath.c'] + \
files + libs + \
files + \
['$(MODLIBS)', '$(LIBS)', '$(SYSLIBS)', '-lz'] # XXX zlib not always -lz
outfp = bkfile.open('Makefile', 'w')
+25 -7
View File
@@ -36,12 +36,13 @@ PERFORMANCE OF THIS SOFTWARE.
/* Return the initial module search path. */
#include "Python.h"
#include "getpath.h"
#include "osdefs.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h> /* getenv */
#if HAVE_UNISTD_H
#include <unistd.h>
@@ -149,12 +150,14 @@ joinpath(char *buffer, char *stuff)
static void
calculate_path(void)
{
char *prog = Py_GetProgramName(); /* use Py_SetProgramName(argv[0]) before Py_Initialize() */
char *prog = PI_GetProgramName(); /* use Py_SetProgramName(argv[0]) before Py_Initialize() */
char argv0_path[MAXPATHLEN+1];
char *epath;
char *path = NULL;
char *ppath = NULL;
int numchars;
#if HAVE_READLINK
int numchars;
#endif
if (strchr(prog, SEP))
strcpy(progpath, prog);
@@ -236,8 +239,23 @@ calculate_path(void)
}
/* External interface */
static char *progname = "python";
void
PI_SetProgramName(char *pn)
{
if (pn && *pn)
progname = pn;
}
char *
Py_GetPath(void)
PI_GetProgramName(void)
{
return progname;
}
char *
PI_GetPath(void)
{
if (!module_search_path)
calculate_path();
@@ -245,7 +263,7 @@ Py_GetPath(void)
}
char *
Py_GetPrefix(void)
PI_GetPrefix(void)
{
if (!module_search_path)
calculate_path();
@@ -253,7 +271,7 @@ Py_GetPrefix(void)
}
char *
Py_GetExecPrefix(void)
PI_GetExecPrefix(void)
{
if (!module_search_path)
calculate_path();
@@ -261,7 +279,7 @@ Py_GetExecPrefix(void)
}
char *
Py_GetProgramFullPath(void)
PI_GetProgramFullPath(void)
{
if (!module_search_path)
calculate_path();
+42
View File
@@ -0,0 +1,42 @@
/*
* A special version for minimal installs, where
* the bootstrap path is the directory in which
* the executable lives.
*
* Copyright (C) 2007, Daniele Varrazzo
* Based on previous work under copyright (c) 2002 McMillan Enterprises, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* In addition to the permissions in the GNU General Public License, the
* authors give you unlimited permission to link or embed the compiled
* version of this file into combinations with other programs, and to
* distribute those combinations without any restriction coming from the
* use of this file. (The General Public License restrictions do apply in
* other respects; for example, they cover modification of the file, and
* distribution when not linked into a combine executable.)
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef PI_GETPATH_H
#define PI_GETPATH_H
void PI_SetProgramName(char *pn);
char *PI_GetProgramName(void);
char *PI_GetPath(void);
char *PI_GetPrefix(void);
char *PI_GetExecPrefix(void);
char *PI_GetProgramFullPath(void);
#endif /* PI_GETPATH_H */
+5 -4
View File
@@ -26,6 +26,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "launch.h"
#include "getpath.h"
#ifdef FREEZE_EXCEPTIONS
extern unsigned char M_exceptions[];
@@ -54,19 +55,19 @@ int main(int argc, char* argv[])
if (strncasecmp(&argv[0][strlen(argv[0])-4], ".exe", 4)) {
strcpy(thisfile, argv[0]);
strcat(thisfile, ".exe");
Py_SetProgramName(thisfile);
PI_SetProgramName(thisfile);
}
else
#endif
Py_SetProgramName(argv[0]);
strcpy(thisfile, Py_GetProgramFullPath());
PI_SetProgramName(argv[0]);
strcpy(thisfile, PI_GetProgramFullPath());
VS("thisfile is %s\n", thisfile);
workpath = getenv( "_MEIPASS2" );
VS("_MEIPASS2 (workpath) is %s\n", (workpath ? workpath : "NULL"));
/* fill in here (directory of thisfile) */
strcpy(homepath, Py_GetPrefix());
strcpy(homepath, PI_GetPrefix());
strcat(homepath, "/");
VS("homepath is %s\n", homepath);
+18 -18
View File
@@ -70,36 +70,36 @@ int launch(char const * archivePath, char const * archiveName)
if (loadedNew) {
/* Start Python with silly command line */
PyEval_InitThreads();
PI_PyEval_InitThreads();
if (startPython(1, (char**)&pathnm))
return -1;
VS("Started new Python");
thisthread = PyThreadState_Swap(NULL);
PyThreadState_Swap(thisthread);
thisthread = PI_PyThreadState_Swap(NULL);
PI_PyThreadState_Swap(thisthread);
}
else {
VS("Attached to existing Python");
/* start a mew interp */
thisthread = PyThreadState_Swap(NULL);
PyThreadState_Swap(thisthread);
thisthread = PI_PyThreadState_Swap(NULL);
PI_PyThreadState_Swap(thisthread);
if (thisthread == NULL) {
thisthread = Py_NewInterpreter();
thisthread = PI_Py_NewInterpreter();
VS("created thisthread");
}
else
VS("grabbed thisthread");
PyRun_SimpleString("import sys;sys.argv=[]");
PI_PyRun_SimpleString("import sys;sys.argv=[]");
}
/* a signal to scripts */
PyRun_SimpleString("import sys;sys.frozen='dll'\n");
PI_PyRun_SimpleString("import sys;sys.frozen='dll'\n");
VS("set sys.frozen");
/* Create a 'frozendllhandle' as a counterpart to
sys.dllhandle (which is the Pythonxx.dll handle)
*/
obHandle = Py_BuildValue("i", gInstance);
PySys_SetObject("frozendllhandle", obHandle);
obHandle = PI_Py_BuildValue("i", gInstance);
PI_PySys_SetObject("frozendllhandle", obHandle);
Py_XDECREF(obHandle);
/* Import modules from archive - this is to bootstrap */
if (importModules())
@@ -113,14 +113,14 @@ int launch(char const * archivePath, char const * archiveName)
if (runScripts())
return -1;
VS("All scripts run");
if (PyErr_Occurred()) {
// PyErr_Print();
//PyErr_Clear();
if (PI_PyErr_Occurred()) {
// PI_PyErr_Print();
//PI_PyErr_Clear();
VS("Some error occurred");
}
VS("PGL released");
// Abandon our thread state.
PyEval_ReleaseThread(thisthread);
PI_PyEval_ReleaseThread(thisthread);
VS("OK.");
return 0;
}
@@ -262,9 +262,9 @@ STDAPI DllRegisterServer()
int rc, pyrc;
if (gPythoncom == 0)
startUp();
PyEval_AcquireThread(thisthread);
PI_PyEval_AcquireThread(thisthread);
rc = callSimpleEntryPoint("DllRegisterServer", &pyrc);
PyEval_ReleaseThread(thisthread);
PI_PyEval_ReleaseThread(thisthread);
return rc==0 ? pyrc : SELFREG_E_CLASS;
}
@@ -273,8 +273,8 @@ STDAPI DllUnregisterServer()
int rc, pyrc;
if (gPythoncom == 0)
startUp();
PyEval_AcquireThread(thisthread);
PI_PyEval_AcquireThread(thisthread);
rc = callSimpleEntryPoint("DllUnregisterServer", &pyrc);
PyEval_ReleaseThread(thisthread);
PI_PyEval_ReleaseThread(thisthread);
return rc==0 ? pyrc : SELFREG_E_CLASS;
}