svn: r15890
This commit is contained in:
parent
94649604f6
commit
20ef0fb0f7
372
windows/builder/check_gtk_install.py
Normal file
372
windows/builder/check_gtk_install.py
Normal file
@ -0,0 +1,372 @@
|
||||
import sys
|
||||
import os
|
||||
import _winreg
|
||||
from ctypes.util import find_library
|
||||
import getopt
|
||||
import string
|
||||
|
||||
|
||||
#==== Set up logging system
|
||||
# need to also set up a logger for when run as a module.
|
||||
|
||||
# change to set up a console logger in module global space.
|
||||
# then add the file logger later once I know the path
|
||||
|
||||
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG,
|
||||
format='%(message)s',
|
||||
datefmt='%H:%M',
|
||||
filename= 'gtkcheck.log',
|
||||
filemode='w')
|
||||
#create a Handler for the console
|
||||
console = logging.StreamHandler()
|
||||
console.setLevel(logging.INFO)
|
||||
#Set a simple format for console
|
||||
formatter = logging.Formatter('%(levelname)-8s %(message)s')
|
||||
console.setFormatter(formatter)
|
||||
#add the console handler to the root handler
|
||||
log = logging.getLogger('CheckGtkApp')
|
||||
log.addHandler(console)
|
||||
|
||||
|
||||
NOT_FOUND_STR ='Not Found'
|
||||
#small selection of DLL's to test
|
||||
testdlls = ['libgdk-win32-2.0-0.dll', 'libglib-2.0-0.dll', 'libgobject-2.0-0.dll', 'libcairo-2.dll', ]
|
||||
|
||||
explain_exposed = ''' ***********************************************************
|
||||
* It seems that other installations are exposing GTK DLL's
|
||||
* to the operating system as they are in the environment
|
||||
* path variable BEFORE the runtime directory.
|
||||
* You should reorder the path variable to put your GTK
|
||||
* runtime path before these other installations on the path'''
|
||||
|
||||
explain_safe = ''' ***************************************************************
|
||||
* While there are other installations of GTK DLL's on the path,
|
||||
* it should be safe as they are on the path AFTER the runtime
|
||||
* directory. '''
|
||||
|
||||
def RunExeCommand( app, args ):
|
||||
cmd = app + ' ' + args
|
||||
#print "Running: ", cmd
|
||||
stdin, stdout, stderr = os.popen3( cmd )
|
||||
output = string.strip(stdout.read())
|
||||
#print output
|
||||
err = stderr.read()
|
||||
if err:
|
||||
print err
|
||||
return output
|
||||
|
||||
def CheckGtkInReg():
|
||||
global gtkPathInRegistry, gtkVersionInRegistry, dllPathInRegistry, dllPathShort
|
||||
log.info( '\n==== Checking Registry for GTK =====' )
|
||||
try:
|
||||
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\GTK\\2.0') as key:
|
||||
gtkVersionInRegistry = _winreg.QueryValueEx(key, 'Version')[0]
|
||||
gtkPathInRegistry = _winreg.QueryValueEx(key, 'Path')[0]
|
||||
dllPathInRegistry = _winreg.QueryValueEx(key, 'DllPath')[0]
|
||||
log.info( ' Version : %s'% gtkVersionInRegistry )
|
||||
log.info( ' Path : %s'% gtkPathInRegistry )
|
||||
log.info( ' DllPath : %s'% dllPathInRegistry )
|
||||
|
||||
except WindowsError, e:
|
||||
log.info( '\n GTK registry key not found in registry' )
|
||||
log.info( ''' ********************************************************************
|
||||
* This might not be an error, but means I don't know the directory to
|
||||
* your preferred GTK installation.
|
||||
* - try passing in your GTK installation path.\n''' )
|
||||
log.info( '-' * 60 )
|
||||
log.info( usage )
|
||||
sys.exit(0)
|
||||
|
||||
def WorkOutShortDosPath():
|
||||
global dllPathShort
|
||||
log.info( '\n==== Use win32Api to query short path name for GTK =====' )
|
||||
try:
|
||||
import win32api
|
||||
dllPathShort = win32api.GetShortPathName(dllPathInRegistry)
|
||||
log.info( ' DllPath8.3: %s' % dllPathShort )
|
||||
except ImportError:
|
||||
log.info( ' **Cant query short path name, Win32Api not installed' )
|
||||
log.info( ' install from http://python.net/crew/mhammond/win32/' )
|
||||
log.info( ' if you want this function to work' )
|
||||
|
||||
def FindLibsWithCtypes():
|
||||
# use ctypes to check where windows finds it's DLL's
|
||||
log.info( '\n==== Use ctypes to find dlls ====' )
|
||||
other_paths = []
|
||||
for dll in testdlls:
|
||||
dllpathvalid = False
|
||||
cpath = find_library(dll)
|
||||
if cpath:
|
||||
#print cpath
|
||||
if cpath == os.path.join(dllPathInRegistry, dll) \
|
||||
or cpath == os.path.join(dllPathShort, dll):
|
||||
dllpathvalid = True
|
||||
|
||||
if not dllpathvalid:
|
||||
pp = os.path.dirname(cpath)
|
||||
if pp not in other_paths:
|
||||
other_paths.append(pp)
|
||||
else:
|
||||
log.info( " ERROR:... ctypes failed to find %s" % dll)
|
||||
if other_paths:
|
||||
for pth in other_paths:
|
||||
log.info( " ERROR: ctypes loaded some gtk dll's from %s" % pth )
|
||||
else:
|
||||
log.info( " OK ... ctypes found dll's in %s" % os.path.dirname(cpath) )
|
||||
|
||||
def ScanDependencyFileForErrors(fname):
|
||||
fin = open(fname, 'r')
|
||||
lines = fin.readlines()
|
||||
fin.close()
|
||||
sysroot = os.environ["SystemRoot"]
|
||||
capture = False
|
||||
runtimedlls = {}
|
||||
for line in lines:
|
||||
if line.startswith(" Module"): # work out were paths end
|
||||
pthend_idx = line.find("File Time Stamp")
|
||||
acceptablePaths = [ dllPathShort.lower(),
|
||||
dllPathInRegistry.lower(),
|
||||
os.path.join(sysroot, 'system32').lower()
|
||||
]
|
||||
if line.startswith('----- ------------'):
|
||||
capture = True
|
||||
if capture and line.startswith('['):
|
||||
filename = line[5:pthend_idx].strip()
|
||||
dirname = os.path.dirname(filename).strip()
|
||||
parts = line[pthend_idx:].split()
|
||||
OK = False
|
||||
if dirname.startswith(os.path.join(sysroot, 'winsxs').lower()) \
|
||||
or dirname.startswith(os.path.join(sys.prefix, 'lib\site-packages\gtk-2.0').lower()):
|
||||
OK = True
|
||||
|
||||
for pth in acceptablePaths:
|
||||
if dirname == pth.lower():
|
||||
OK = True
|
||||
|
||||
if 'MSVCR90.DLL' in filename:
|
||||
if parts[0] == 'Error':
|
||||
runtimedlls[filename] = "Error dll not found"
|
||||
else:
|
||||
runtimedlls[filename] = parts[16]
|
||||
|
||||
if OK == False:
|
||||
if parts[0] == 'Error':
|
||||
log.info( " %s \tError dll not found" %( filename))
|
||||
else:
|
||||
log.info( " ERROR: %s \tVersion %s" %( filename, parts[16]))
|
||||
for rtdll in runtimedlls:
|
||||
if runtimedlls[rtdll].startswith("Error"):
|
||||
log.info( '\n ERROR: MS runtime %s not found'%rtdll )
|
||||
else:
|
||||
log.info( '\n MS runtime Version %s loaded from' % runtimedlls[rtdll] )
|
||||
log.info( " %s" %rtdll )
|
||||
log.info( '')
|
||||
|
||||
def CheckWithDependencyWalker():
|
||||
log.info( '\n==== Checking with Dependency Walker ====' )
|
||||
log.info( ' Please be patient takes some time' )
|
||||
exe = os.path.join(scriptpath, 'depends.exe')
|
||||
fout = os.path.join(scriptpath, 'depres.txt')
|
||||
f2check = [
|
||||
os.path.join(sys.prefix, 'Lib/site-packages/gtk-2.0/gtk/_gtk.pyd' ),
|
||||
os.path.join(sys.prefix, 'Lib/site-packages/gtk-2.0/gobject/_gobject.pyd' ),
|
||||
os.path.join(sys.prefix, 'Lib/site-packages/gtk-2.0/pangocairo.pyd' ),
|
||||
]
|
||||
if os.path.isfile( exe ):
|
||||
for ftest in f2check:
|
||||
if os.path.isfile( ftest ):
|
||||
#delete the output file before running command
|
||||
try:
|
||||
os.remove(fout)
|
||||
except WindowsError, e:
|
||||
pass
|
||||
log.info( ' Testing file %s' % ftest )
|
||||
out = RunExeCommand(exe, '/c /f1 /ot "%s" "%s"' % (fout, ftest) )
|
||||
if os.path.isfile(fout):
|
||||
ScanDependencyFileForErrors(fout)
|
||||
else:
|
||||
log.info( " ERROR: file %d does not exist", ftest )
|
||||
else:
|
||||
log.info( ' Cannot check with dependency walker, not installed in local directory' )
|
||||
log.info( ' get dependency walker from http://www.dependencywalker.com/' )
|
||||
log.info( ' and unzip into this directory for it to work.' )
|
||||
|
||||
def CheckPathForOtherGtkInstalls():
|
||||
log.info( '\n====Checking environment path for other gtk installations====' )
|
||||
ePath = os.environ['path']
|
||||
dirs = ePath.split(';')
|
||||
gtkpth_idx = 9999
|
||||
other_paths = []
|
||||
explain_level = 0
|
||||
for i, d in enumerate(dirs):
|
||||
#print '==%s==' %d
|
||||
if d == gtkPathInRegistry or d == dllPathInRegistry\
|
||||
or d == dllPathShort:
|
||||
gtkpth_idx = i
|
||||
continue
|
||||
for fname in testdlls:
|
||||
f = os.path.join(d, fname)
|
||||
if os.path.isfile( f ):
|
||||
#print ' Found Erronous gtk DLL %s' % f
|
||||
if d not in other_paths:
|
||||
other_paths.append(d)
|
||||
if i < gtkpth_idx: # path appears BEFORE runtime path
|
||||
log.info( ' ERROR: %s should not appear before runtime path' % d )
|
||||
explain_level = 2
|
||||
else:
|
||||
log.info( ' FOUND: %s, Probably OK as appears AFTER runtime path' % d )
|
||||
if explain_level <= 1:
|
||||
explain_level = 1
|
||||
if gtkpth_idx == 9999:
|
||||
log.info( '\n ERROR: Runtime directory not on enviroment path' )
|
||||
log.info( " ** Runtime needs to be on path to load DLL's from\n" )
|
||||
if explain_level == 2:
|
||||
log.info( explain_exposed )
|
||||
elif explain_level == 1:
|
||||
log.info( explain_safe )
|
||||
if len(other_paths) == 0:
|
||||
log.info( ' No other gtk installatons found\n' )
|
||||
|
||||
# ==== report what python thinks it's using =====
|
||||
MIN_PYTHON_VER = (2,5,1)
|
||||
UNTESTED_PYTHON_VER = (3,0,0)
|
||||
|
||||
MIN_GTK_VER = (2,10,11)
|
||||
UNTESTED_GTK_VER = (2,16,7)
|
||||
|
||||
MIN_PYGTK_VER = (2,10,6)
|
||||
UNTESTED_PYGTK_VER = (2,12,2)
|
||||
|
||||
MIN_GOBJECT_VER = (2,12,3)
|
||||
UNTESTED_GOBJECT_VER = (2,14,3)
|
||||
|
||||
MIN_CAIRO_VER = (1,2,6)
|
||||
UNTESTED_CAIRO_VER = (1,4,13)
|
||||
|
||||
def PrintFailedImport(appl, minVersion, result):
|
||||
log.info( '--%s version %d.%d.%d or above.....\t %s' % (appl, minVersion ,result) )
|
||||
|
||||
def PrintVersionResult(appl, minVersion, actualVersion, untestedVersion):
|
||||
minStr = '%d.%d.%d' % minVersion
|
||||
actStr = '%d.%d.%d' % actualVersion
|
||||
if minVersion <= actualVersion < untestedVersion:
|
||||
result = '...OK'
|
||||
elif actualVersion >= untestedVersion:
|
||||
result = '...UNTESTED VERSION'
|
||||
else:
|
||||
result = '...FAILED'
|
||||
log.info( '%s version %s or above.....\tfound %s %s' % (appl, minStr , actStr, result) )
|
||||
|
||||
def Import_pyGtkIntoPython():
|
||||
log.info( '\n==== Test import into python ====' )
|
||||
#py_str = 'found %d.%d.%d' % sys.version_info[:3]
|
||||
PrintVersionResult(' Python ', MIN_PYTHON_VER, sys.version_info[:3], UNTESTED_PYTHON_VER)
|
||||
|
||||
# Test the GTK version
|
||||
try:
|
||||
import gtk
|
||||
|
||||
PrintVersionResult(' GTK+ ', MIN_GTK_VER, gtk.gtk_version, UNTESTED_GTK_VER )
|
||||
|
||||
#test the pyGTK version (which is in the gtk namespace)
|
||||
PrintVersionResult(' pyGTK ', MIN_PYGTK_VER, gtk.pygtk_version, UNTESTED_PYGTK_VER )
|
||||
|
||||
except ImportError:
|
||||
PrintFailedImport(' GTK+ ', MIN_GTK_VER, NOT_FOUND_STR)
|
||||
PrintFailedImport(' pyGTK ', MIN_PYGTK_VER, 'Cannot test, ...GTK+ missing')
|
||||
|
||||
|
||||
#test the gobject version
|
||||
try:
|
||||
import gobject
|
||||
PrintVersionResult(' gobject', MIN_GOBJECT_VER, gobject.pygobject_version, UNTESTED_GOBJECT_VER)
|
||||
|
||||
except ImportError:
|
||||
PrintFailedImport(' gobject', MIN_GOBJECT_VER, NOT_FOUND_STR)
|
||||
|
||||
|
||||
#test the cairo version
|
||||
try:
|
||||
import cairo
|
||||
PrintVersionResult(' cairo ', MIN_CAIRO_VER, cairo.version_info, UNTESTED_CAIRO_VER )
|
||||
|
||||
except ImportError:
|
||||
PrintFailedImport(' cairo ', MIN_CAIRO_VER, NOT_FOUND_STR)
|
||||
|
||||
#test for glade
|
||||
log.info( '\n==== See if libglade installed ====')
|
||||
|
||||
try:
|
||||
import gtk.glade
|
||||
log.info( ' Glade tesing import of libglade .......\tOK\n' )
|
||||
except ImportError, e:
|
||||
log.info( ' Glade importError: %s\n' % e )
|
||||
|
||||
if __name__ == '__main__':
|
||||
usage = '''Check for common problems in GTK/pyGTK installation.
|
||||
Usage:
|
||||
python %s [options] [gtkPath]
|
||||
|
||||
Arguments:
|
||||
gtkPath Path to your GTK installation directory (not the bin dir)
|
||||
|
||||
Options:
|
||||
None
|
||||
''' %(os.path.basename(__file__) )
|
||||
|
||||
gtkPath = None
|
||||
gtkPathInRegistry = NOT_FOUND_STR
|
||||
gtkVersionInRegistry = NOT_FOUND_STR
|
||||
dllPathInRegistry = NOT_FOUND_STR
|
||||
dllPathShort = 'NoShortPath'
|
||||
scriptpath = os.path.dirname(sys.argv[0])
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "",
|
||||
[])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
log.info( usage )
|
||||
sys.exit(0)
|
||||
|
||||
if len(args) > 1:
|
||||
raise getopt.GetoptError, '\nERROR: Too many arguments'
|
||||
for arg in args:
|
||||
if os.path.isdir(arg):
|
||||
gtkPath = arg
|
||||
else:
|
||||
raise getopt.GetoptError, '\nERROR: Not a valid GTK path %s' % arg
|
||||
|
||||
except getopt.GetoptError, msg:
|
||||
log.info( msg )
|
||||
log.info( '\n %s' % usage )
|
||||
sys.exit(2)
|
||||
|
||||
import platform
|
||||
winver = platform.win32_ver()
|
||||
if len(winver) == 4:
|
||||
log.info( '''\n==== platform.win32_ver() reports ====
|
||||
Operating System: %s
|
||||
Version : %s
|
||||
Service Pack : %s
|
||||
OS type : %s''' % winver)
|
||||
else:
|
||||
os.info( winver )
|
||||
|
||||
if gtkPath:
|
||||
gtkPathInRegistry = gtkPath
|
||||
dllPathInRegistry = os.path.join(gtkPath, 'bin')
|
||||
os.info( ' Using %s as GTK install path' % gtkPathInRegistry )
|
||||
os.info( ' Using %s as GTK dll path' % dllPathInRegistry )
|
||||
else:
|
||||
CheckGtkInReg()
|
||||
|
||||
WorkOutShortDosPath()
|
||||
FindLibsWithCtypes()
|
||||
CheckPathForOtherGtkInstalls()
|
||||
Import_pyGtkIntoPython()
|
||||
|
||||
CheckWithDependencyWalker()
|
||||
|
Loading…
Reference in New Issue
Block a user