Remove old Windows directory
This commit is contained in:
parent
0f73812b2e
commit
36ef045f02
|
@ -20,7 +20,6 @@ recursive-include images *
|
|||
recursive-include mac *
|
||||
recursive-include po *
|
||||
recursive-include test *
|
||||
recursive-include windows *
|
||||
|
||||
# Remove files created in the build
|
||||
global-exclude *.pyc
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,97 +0,0 @@
|
|||
|
||||
HOW TO CREATE A WINDOWS INSTALLER
|
||||
|
||||
Introduction.
|
||||
=============
|
||||
It is possible to build two types of installer
|
||||
|
||||
- Release installer, intended for end user. The release installer is built from the
|
||||
release tarball.
|
||||
|
||||
- Development installer, used for testing nsis install script, and packaging issues.
|
||||
This installer is not intended for end user. Instalation of a Development installer
|
||||
will overwrite an already installed released Gramps application. Running a development
|
||||
installer will warn with dialog that the installer is not an official release.
|
||||
|
||||
The following procedure is capable of creating a Windows installer from either Windows
|
||||
or Linux OS's as long as the correct tools are installed.
|
||||
|
||||
The following programs are required to be installed and on the path
|
||||
- python (currently only tested on python 2.6 - not ready for python 3.x yet)
|
||||
- nsis at least V2.42 (http://nsis.sourceforge.net or apt-get install nsis)
|
||||
- msgfmt (for windows http://gnuwin32.sourceforge.net/packages/gettext.htm)
|
||||
|
||||
Extra tools for development installer build
|
||||
- svn (subversion )
|
||||
|
||||
Release Installer
|
||||
=================
|
||||
To create an offical release of gramps download the required tarball for a release
|
||||
from sourceforge. The files that are contained within the tarball consist of the files
|
||||
that make up an offical release.
|
||||
|
||||
i.e.
|
||||
|
||||
WINDOWS
|
||||
[PATH_TO_SCRIPT]\build_GrampsWin32.py -t TARBALL_PATH
|
||||
or
|
||||
c:\python26\python [PATH_TO_SCRIPT]\build_GrampsWin32.py -t TARBALL_PATH
|
||||
|
||||
LINUX
|
||||
python2.6 [PATH_TO_SCRIPT]/build_GrampsWin32.py -t TARBALL_PATH
|
||||
|
||||
where TARBALL path is the path to the tarball including the tarball name.
|
||||
The build will happen on the dir you run the script from, you can also
|
||||
control the build dir with the -oDIR, --out=DIR options
|
||||
|
||||
|
||||
Development installer - Build from within SVN version tree.
|
||||
===========================================================
|
||||
NOTE: This installer will package ALL plugins that are part of SVN version
|
||||
control into the installer, even if it's not intended for end user.
|
||||
|
||||
** The offical RELEASE of GRAMPS is built from tarball. (see above)**
|
||||
|
||||
It works with a subversion working copy of Gramps, it automatically
|
||||
queries configure.in to get the correct gramps version number that
|
||||
includes the SVN revision number.
|
||||
|
||||
Procedure:
|
||||
From the command prompt, change to the path
|
||||
[GRAMPS_SVN]\windows\builder
|
||||
|
||||
Run the build script with no arguments, the script will assume it's being run
|
||||
from a gramps subversion working copy, and then commence the build.
|
||||
|
||||
It will export the sources from svn to create the correct directory image,
|
||||
complile the langauage files, and package all up into the installer.
|
||||
|
||||
i.e.
|
||||
WINDOWS
|
||||
build_GrampsWin32.py
|
||||
or
|
||||
c:\python26\python build_GrampsWin32.py
|
||||
|
||||
LINUX
|
||||
python2.6 build_GrampsWin32.py
|
||||
|
||||
============== Build Script Options ================================================
|
||||
>build_GrampsWin32.py --help
|
||||
|
||||
Create Gramps Windows Installer.
|
||||
Usage:
|
||||
python build_GrampsWin32.py [options] [repository_path]
|
||||
|
||||
Arguments:
|
||||
repository_path Path to the repository to build GRAMPS from, this can be either
|
||||
- The root path of a SVN working copy
|
||||
- A tarball that has been saved on local disk
|
||||
- Left blank to build the SVN working copy this file is part of
|
||||
Options:
|
||||
-h, --help This help message.
|
||||
-oDIR, --out=DIR Directory to build files (optional)
|
||||
--nsis_only Build NSIS only (does not Clean & Build All)
|
||||
-t --tarball Build release version from Tarball.
|
||||
-mDIR, --msgdir=DIR Directory to msgfmt.exe
|
||||
|
||||
==========================================================================================
|
|
@ -1,639 +0,0 @@
|
|||
#
|
||||
# Gramps - a GTK+ based genealogy program
|
||||
#
|
||||
# Copyright (C) 2006 Brian Matherly
|
||||
# Copyright (C) 2008 Stephen George
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $Id: $
|
||||
|
||||
import os, glob, sys, shutil
|
||||
import string
|
||||
import os.path as path
|
||||
import subprocess
|
||||
|
||||
CONFIGURE_IN = 'configure.in'
|
||||
CONST_PY_IN = 'src/const.py.in'
|
||||
TRANSLATE_FOLDER = 'po'
|
||||
|
||||
EXTRA_FILES = [ 'COPYING', 'NEWS', 'FAQ', 'AUTHORS']
|
||||
|
||||
FULL_COLON_SUBST = "~"
|
||||
|
||||
#min required version of NSIS
|
||||
MIN_NSIS_VERSION = (2,42)
|
||||
|
||||
#tools used during build
|
||||
MAKENSIS_exe = None
|
||||
SVN_exe = None
|
||||
po_errs = []
|
||||
po_oks = []
|
||||
|
||||
import gobject
|
||||
|
||||
|
||||
#==== 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='%(asctime)s %(name)-10s %(levelname)-8s %(message)s',
|
||||
datefmt='%H:%M',
|
||||
filename= 'build.log', #path.join(out_dir,'build.log'),
|
||||
filemode='w')
|
||||
#create a Handler for the console
|
||||
console = logging.StreamHandler()
|
||||
console.setLevel(logging.INFO)
|
||||
#Set a simle format for console
|
||||
formatter = logging.Formatter('%(levelname)-8s %(message)s')
|
||||
console.setFormatter(formatter)
|
||||
#add the console handler to the root handler
|
||||
log = logging.getLogger('BuildApp')
|
||||
log.addHandler(console)
|
||||
|
||||
|
||||
class buildbase(GObject.GObject):
|
||||
__gsignals__={
|
||||
"build_progresstext" : (GObject.SignalFlags.RUN_LAST, None, [GObject.TYPE_STRING]),
|
||||
"build_progressfraction" : (GObject.SignalFlags.RUN_LAST, None, [GObject.TYPE_FLOAT]),
|
||||
}
|
||||
|
||||
def __init(self):
|
||||
GObject.GObject.__init__(self)
|
||||
self.gramps_version = 'VERSION-UNKNOWN'
|
||||
self.bTarball = bTarball
|
||||
self.build_root = '.' # the directory were the build source is located
|
||||
self.out_dir = '.' # the directory to output final installer to, and the expand source to
|
||||
self.repository_path = '.' #where the source comes from, either SVN root or a tarball
|
||||
self.bBuildInstaller = True
|
||||
self.tarbase3 = '.'
|
||||
|
||||
def getbuild_src(self):
|
||||
return os.path.join(self.build_root, 'src')
|
||||
|
||||
build_src = property(getbuild_src)
|
||||
|
||||
def isGrampsRoot(self, root ):
|
||||
log.debug( 'isGrampsRoot: %s' % root )
|
||||
if path.isfile(path.join(root, CONFIGURE_IN)):
|
||||
if path.isfile(path.join(root, CONST_PY_IN)):
|
||||
if path.isdir(path.join(root, TRANSLATE_FOLDER)):
|
||||
return True
|
||||
return False
|
||||
|
||||
def getSVNRevision(self, dir ):
|
||||
log.debug('========== getSVNRevision(%s)' % dir)
|
||||
cmd = 'svnversion -n %s' % dir
|
||||
log.debug( "Running: %s" % cmd )
|
||||
|
||||
proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
|
||||
(out, err) = proc.communicate()
|
||||
output = string.strip(out)
|
||||
log.debug( output )
|
||||
if err:
|
||||
for line in err.split('\n'):
|
||||
log.error(line)
|
||||
if not stdout:
|
||||
output = '-UNKNOWN'
|
||||
return 'SVN' + output
|
||||
|
||||
def exportSVN(self, svn_dir, destdir):
|
||||
'''
|
||||
svn export PATH1 PATH2
|
||||
exports a clean directory tree from the working copy specified by PATH1 into PATH2.
|
||||
All local changes will be preserved, but files not under version control will not be copied.
|
||||
|
||||
destdir cannot exist, script will clean up dir first
|
||||
'''
|
||||
log.debug('========== exportSVN(%s, %s)' % (svn_dir, destdir) )
|
||||
# cmd = '"%s" export %s %s' % (SVN_exe ,svn_dir, destdir)
|
||||
cmd = [SVN_exe, 'export' ,svn_dir, destdir] #'"%s" export %s %s' % (SVN_exe ,svn_dir, destdir)
|
||||
|
||||
log.info( "Running: %s" % cmd)
|
||||
|
||||
proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
|
||||
(out, err) = proc.communicate()
|
||||
output = string.strip(out)
|
||||
log.info( output )
|
||||
if err:
|
||||
log.error(err)
|
||||
|
||||
def copyExtraFilesToBuildDir(self, source_path):
|
||||
'''
|
||||
A few extra files not in src directory needs to be copied to the build dir
|
||||
'''
|
||||
log.debug('========== copyExtraFilesToBuildDir(%s)' % (source_path))
|
||||
for file in EXTRA_FILES:
|
||||
outfile = file
|
||||
if file == 'NEWS':
|
||||
#Jump through hoops tomake sure the end of line charactors are windows format (wont work on linux!!)
|
||||
outfile = 'NEWS.TXT' #Lets add .TXT suffix to filename so installer knows to call notepad
|
||||
fnews = open(os.path.join(source_path,file), 'r')
|
||||
newslines = fnews.readlines()
|
||||
newsout = open(os.path.join(self.build_src,outfile), 'w')
|
||||
newsout.writelines(newslines)
|
||||
newsout.close()
|
||||
fnews.close()
|
||||
else:
|
||||
shutil.copy(os.path.join(source_path,file), os.path.join(self.build_src,outfile) )
|
||||
|
||||
def compileInstallScript(self):
|
||||
'''
|
||||
Now we got a build directory, lets create the installation program
|
||||
'''
|
||||
log.debug('========== compileInstallScript()')
|
||||
log.info('Compiling NullSoft install script .... be patient')
|
||||
# calc path to gramps2.nsi
|
||||
# need to ensure __file__ has full path, under linux it does not.
|
||||
thisfilepath = os.path.abspath(__file__)
|
||||
pth = os.path.relpath(os.path.dirname( thisfilepath ), os.getcwd())
|
||||
pth2nsis_script = os.path.join(pth, 'gramps2.nsi')
|
||||
|
||||
#should tests be more along lines of os.name which returns 'posix', 'nt', 'mac', 'os2', 'ce', 'java', 'riscos'
|
||||
if sys.platform == 'win32':
|
||||
# cmd = '"%s" /V3 %s' % (MAKENSIS_exe, pth2nsis_script)
|
||||
cmd = [MAKENSIS_exe, '/V3',pth2nsis_script]
|
||||
elif sys.platform == 'linux2':
|
||||
#assumption makensis is installed and on the path
|
||||
cmd = '%s -V3 %s' % (MAKENSIS_exe, pth2nsis_script)
|
||||
|
||||
log.info( "Running: %s" % cmd)
|
||||
# Need to define the following enviroment variables for NSIS script
|
||||
os.environ['GRAMPS_VER'] = self.gramps_version
|
||||
os.environ['GRAMPS_BUILD_DIR'] = os.path.abspath(self.build_src)
|
||||
os.environ['GRAMPS_OUT_DIR'] = os.path.abspath(self.out_dir)
|
||||
|
||||
proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
|
||||
(out, err) = proc.communicate()
|
||||
output = string.strip(out)
|
||||
log.info( output )
|
||||
if err:
|
||||
log.error(err)
|
||||
|
||||
def getVersionFromConfigureIn(self, repository_path):
|
||||
log.debug('========== read_config_in(%s)' % repository_path)
|
||||
fin = open('%s/configure.in' % repository_path, 'r')
|
||||
conf_lines = fin.readlines()
|
||||
fin.close()
|
||||
return self.getVersionFromLines(conf_lines)
|
||||
|
||||
def getVersionFromLines(self, conf_lines):
|
||||
log.debug('========== getVersionFromLines()')
|
||||
for line in conf_lines:
|
||||
if 'AC_INIT(gramps' in line:
|
||||
junk, ver, junk2 = line.split(',')
|
||||
elif line[:7] == 'RELEASE':
|
||||
junk,release = line.split('=')
|
||||
if 'SVN$' in release:#not a release version
|
||||
release = self.getSVNRevision( repository_path )
|
||||
elif not self.bTarball: # This is aRelease, lets make sure svn working copy is prestine
|
||||
# elif not bTarball: # This is aRelease, lets make sure svn working copy is prestine
|
||||
test_num = getSVNRevision( repository_path )
|
||||
if test_num.endswith('M'): # in test_num: #endsWith
|
||||
log.warning('*==========================================================')
|
||||
log.warning('* Building a Release from modified SVN Working Copy ')
|
||||
log.warning('* ===> Creating %s-%s from %s-%s <==' % (ver.strip(), release.strip(),ver.strip(), test_num.strip()) )
|
||||
log.warning('*==========================================================')
|
||||
gversion = '%s-%s' % (ver.strip(), release.strip())
|
||||
gversion = gversion.replace(":", FULL_COLON_SUBST) # if it's a mixed version, then need to replace the : with something else
|
||||
log.info( 'GrampsVersion: %s' % gversion )
|
||||
return gversion
|
||||
|
||||
def processPO( self ):
|
||||
log.debug('========== processPO( )')
|
||||
po_dir = os.path.join(self.build_root, "po")
|
||||
mo_dir = os.path.join(self.build_src, "lang")
|
||||
if not os.path.exists(mo_dir):
|
||||
os.makedirs(mo_dir)
|
||||
#TODO: find a better way to handle different platforms
|
||||
if sys.platform == 'win32':
|
||||
po_files = glob.glob(po_dir + r"\*.po")
|
||||
# no longer using python msgfmt as it doesn't handle plurals (april 2010)
|
||||
# msgfmtCmd = path.normpath(path.join(sys.prefix, "Tools/i18n/msgfmt.py") )
|
||||
|
||||
# GetText Win 32 obtained from http://gnuwin32.sourceforge.net/packages/gettext.htm
|
||||
# ....\gettext\bin\msgfmt.exe needs to be on the path
|
||||
msgfmtCmd = 'msgfmt.exe'
|
||||
#print('msgfmtCmd = %s' % msgfmtCmd)
|
||||
elif sys.platform == 'linux2':
|
||||
po_files = glob.glob(po_dir + "/*.po")
|
||||
msgfmtCmd = "%s/bin/msgfmt" % sys.prefix
|
||||
else:
|
||||
po_files = [] #empty list
|
||||
msgfmtCmd = "UNKNOWN_PLATFORM"
|
||||
log.debug( msgfmtCmd )
|
||||
#if not os.path.exists(msgfmtCmd):
|
||||
# log.error( "msgfmt not found - unable to generate mo files")
|
||||
# return
|
||||
log.info( "Generating mo files" )
|
||||
global po_errs, po_oks
|
||||
po_total = len(po_files)
|
||||
po_count = 0
|
||||
for po_file in po_files:
|
||||
po_count = po_count + 1
|
||||
#This will be interesting
|
||||
self.emit("build_progresstext", 'compiling %s' % po_file)
|
||||
self.emit("build_progressfraction", po_count/po_total)
|
||||
|
||||
lan = os.path.basename(po_file).replace( ".po", "" )
|
||||
lan_path = os.path.join(mo_dir,lan,"LC_MESSAGES")
|
||||
if not os.path.exists(lan_path):
|
||||
os.makedirs(lan_path)
|
||||
mo_file = os.path.join(lan_path,"gramps.mo")
|
||||
log.info( mo_file )
|
||||
|
||||
cmd = [msgfmtCmd, '--statistics','-o', mo_file, po_file]
|
||||
log.debug( cmd )
|
||||
|
||||
proc = subprocess.Popen( cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
|
||||
(out, err) = proc.communicate()
|
||||
output = string.strip(out)
|
||||
log.info( output )
|
||||
# log.debug( output ) Nothing coming out here, statistics come out stderr ??
|
||||
if err:
|
||||
log.info(err) # statistics comming out stderr
|
||||
po_errs.append(lan)
|
||||
else:
|
||||
po_oks.append(lan)
|
||||
|
||||
def generateConstPy(self ):
|
||||
log.debug('========== generate_const.py()')
|
||||
fin = open(os.path.join(self.build_src,'const.py.in'), 'r')
|
||||
in_lines = fin.readlines()
|
||||
fin.close()
|
||||
fout = open(os.path.join(self.build_src,'const.py'), 'w')
|
||||
for line in in_lines:
|
||||
if '@VERSIONSTRING@' in line: #VERSION = "@VERSIONSTRING@"
|
||||
corrline = line.replace('@VERSIONSTRING@', self.gramps_version.replace(FULL_COLON_SUBST,":") )
|
||||
fout.write(corrline)
|
||||
#fout.write('VERSION = "%s"\n'% self.gramps_version.replace(FULL_COLON_SUBST,":"))
|
||||
|
||||
#elif '@prefix@' in line: #PREFIXDIR = "@prefix@"
|
||||
# what to do? , doesnt seem to matter on windows
|
||||
|
||||
#elif '@sysconfdir@' in line: #SYSCONFDIR = "@sysconfdir@"
|
||||
# what to do? , doesnt seem to matter on windows
|
||||
|
||||
else:
|
||||
fout.write(line)
|
||||
fout.close()
|
||||
|
||||
def cleanBuildDir(self):
|
||||
log.debug( '========== cleanBuildDir()' )
|
||||
log.info( 'Cleaning build and output directories' )
|
||||
if sys.platform == 'win32': #both platforms emit different exceptions for the same operation, map the exception here
|
||||
MY_EXCEPTION = WindowsError
|
||||
elif sys.platform == 'linux2':
|
||||
MY_EXCEPTION = OSError
|
||||
if os.path.exists(self.build_root):
|
||||
try:
|
||||
log.info('removing directory: %s' % self.build_root )
|
||||
shutil.rmtree(self.build_root)
|
||||
except MY_EXCEPTION as e:
|
||||
log.error( e )
|
||||
|
||||
for file in ['gramps-%s.exe'%self.gramps_version ]: #, 'build.log']:
|
||||
fname = os.path.join(self.out_dir, file)
|
||||
if os.path.isfile(fname):
|
||||
try:
|
||||
log.info('removing file: %s' % fname )
|
||||
os.remove(fname)
|
||||
except MY_EXCEPTION as e:
|
||||
log.error( e )
|
||||
|
||||
def getNSISVersionNumber(self):
|
||||
#Check version of NSIS, to ensure NSIS is compatible with script features
|
||||
# >"c:\Program Files\NSIS\makensis.exe" /version
|
||||
# v2.42
|
||||
cmd = '"%s" -VERSION' % (MAKENSIS_exe)
|
||||
log.debug(cmd)
|
||||
|
||||
proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
|
||||
(out, err) = proc.communicate()
|
||||
output = string.strip(out)
|
||||
log.info( output )
|
||||
if err:
|
||||
log.error(err)
|
||||
if sys.platform == 'win32': #'not recognized' in err:
|
||||
minor =0
|
||||
major =0
|
||||
return (major, minor)
|
||||
|
||||
#parse the output to get version number into tuple
|
||||
ver = output[1:].split('.')
|
||||
major = int(ver[0])
|
||||
try:
|
||||
minor = int(ver[1])
|
||||
except ValueError as e:
|
||||
m = ver[1]
|
||||
minor = int(m[:2])
|
||||
return (major, minor)
|
||||
|
||||
def checkForBuildTools(self):
|
||||
global MAKENSIS_exe, SVN_exe
|
||||
log.debug( '========== checkForBuildTools()' )
|
||||
if sys.platform == 'win32':
|
||||
import _winreg as winreg
|
||||
# Find NSIS on system
|
||||
try:
|
||||
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\NSIS') as key:
|
||||
nsispath = winreg.QueryValue(key, '')
|
||||
makensisexe = path.join( nsispath, 'makensis.exe')
|
||||
if path.isfile( makensisexe ):
|
||||
MAKENSIS_exe = makensisexe
|
||||
except WindowsError as e:
|
||||
log.warning('NSIS not found, in registory')
|
||||
log.warning('..Testing if makensis is on the path')
|
||||
MAKENSIS_exe = 'makensis'
|
||||
#cmd = os.path.join(nsis_dir, MAKENSIS_exe)
|
||||
|
||||
cmd = '%s /VERSION' % MAKENSIS_exe
|
||||
proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
|
||||
(out, err) = proc.communicate()
|
||||
output = string.strip(out)
|
||||
log.info( output )
|
||||
if err:
|
||||
log.error(err)
|
||||
log.error('....makensis.exe not found on path')
|
||||
sys.exit(0)
|
||||
#else:
|
||||
# log.info("makensis version %s" % output)
|
||||
|
||||
# Find msgfmt on system
|
||||
cmd = os.path.join(msg_dir, 'msgfmt.exe')
|
||||
|
||||
proc = subprocess.Popen( cmd, shell = True, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
|
||||
(out, err) = proc.communicate()
|
||||
output = string.strip(out)
|
||||
log.info( output )
|
||||
if not err.startswith(cmd):
|
||||
#log.error(err)
|
||||
log.error('msgfmt.exe not found on path')
|
||||
log.error(' try the -m DIR , --msgdir=DIR option to specify the directory or put it on the path')
|
||||
sys.exit(0)
|
||||
|
||||
# Find SVN on system - optional, if building from tarball
|
||||
if not bTarball:
|
||||
try:
|
||||
with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\svn.exe') as key:
|
||||
svnpath = winreg.QueryValue(key, '')
|
||||
if path.isfile(svnpath):
|
||||
SVN_exe = svnpath
|
||||
except WindowsError as e:
|
||||
log.warning('SVN not found, in registory')
|
||||
log.warning('... Hoping svn is on the path')
|
||||
SVN_exe = 'svn'
|
||||
|
||||
elif sys.platform == 'linux2':
|
||||
#ASSUMPTION: these tools are on the path
|
||||
#TODO: check for svn on Linux
|
||||
log.info( 'TODO: Check for svn' )
|
||||
SVN_exe = 'svn'
|
||||
#TODO: check for nsis on Linux
|
||||
log.info( 'TODO: Check for nsis' )
|
||||
MAKENSIS_exe = 'makensis'
|
||||
|
||||
# Check if we are running a compatible vesion of NSIS
|
||||
vers = self.getNSISVersionNumber()
|
||||
if vers < MIN_NSIS_VERSION:
|
||||
log.error( "Require NSIS version %d.%d or later ..... found NSIS version %d.%d" % (MIN_NSIS_VERSION[0],MIN_NSIS_VERSION[1], vers[0], vers[1]) )
|
||||
log.info("Disabling NSIS compilation ... Please upgrade your NSIS version")
|
||||
self.bBuildInstaller = False
|
||||
else:
|
||||
self.bBuildInstaller = True
|
||||
log.info( "NSIS version %d.%d" % vers )
|
||||
|
||||
def expandTarBall(self, tarball, expand_dir):
|
||||
# gramps-3.1.0.tar.gz
|
||||
log.info( 'expandTarBall(%s, %s)' % (tarball, expand_dir) )
|
||||
if tarfile.is_tarfile(self.repository_path):
|
||||
tar = tarfile.open(self.repository_path)
|
||||
tar.extractall(self.out_dir)
|
||||
tar.close()
|
||||
#base = os.path.basename(self.repository_path)
|
||||
extractDir = os.path.join(self.out_dir, self.tarbase3 )
|
||||
try:
|
||||
os.rename( extractDir, self.build_root)
|
||||
except WindowsError as e:
|
||||
log.error("FAILED: \n\t extractDir=%s \n\t build_root=%s" % (extractDir, self.build_root))
|
||||
raise WindowsError(e)
|
||||
else:
|
||||
log.error( "Sorry %s is not a tar file" % self.repository_path )
|
||||
|
||||
def getVersionFromTarBall(self, tarball):
|
||||
log.debug( 'getVersionFromTarBall(%s)' % (tarball))
|
||||
|
||||
if tarfile.is_tarfile(self.repository_path):
|
||||
tar = tarfile.open(self.repository_path)
|
||||
members = tar.getnames()
|
||||
for member in members:
|
||||
if 'configure.in' in member:
|
||||
log.debug('Reading version from: %s' % member)
|
||||
file = tar.extractfile(member)
|
||||
lines = file.readlines()
|
||||
vers = self.getVersionFromLines(lines)
|
||||
if 'TODO' in member: #need to get path this will extract too, grab it of one of the files
|
||||
self.tarbase3, rest = member.split('/', 1)
|
||||
print('==ExtractPath', self.tarbase3)
|
||||
tar.close()
|
||||
log.debug( 'Version (%s)' % (vers) )
|
||||
return vers
|
||||
|
||||
def copyPatchTreeToDest(self, src, dst):
|
||||
'''Patch a tarball build with alternate files as required.
|
||||
At this stage do not allow new directories to be made or
|
||||
new files to be added, just replace existing files.
|
||||
'''
|
||||
log.info('Patching: now in %s', src)
|
||||
names = os.listdir(src)
|
||||
#os.makedirs(dst) - not creating new dir
|
||||
errors = []
|
||||
for name in names:
|
||||
srcname = os.path.join(src, name)
|
||||
dstname = os.path.join(dst, name)
|
||||
try:
|
||||
if os.path.isfile(srcname) and os.path.isfile(dstname):
|
||||
log.info('Overwriting %s -> %s' % (srcname, dstname))
|
||||
shutil.copyfile(srcname, dstname)
|
||||
elif os.path.isdir(srcname) and os.path.isdir(dstname):
|
||||
self.copyPatchTreeToDest(srcname, dstname)
|
||||
else:
|
||||
log.error('UNDEFINED: %s -> %s' % (srcname, dstname))
|
||||
except (IOError, os.error) as why:
|
||||
errors.append((srcname, dstname, str(why)))
|
||||
# catch the Error from the recursive copytree so that we can
|
||||
# continue with other files
|
||||
except Error as err:
|
||||
errors.extend(err.args[0])
|
||||
if errors:
|
||||
raise Error(errors)
|
||||
|
||||
def buildGRAMPS( base, out_dir, bTarball):
|
||||
bo = buildbase()
|
||||
|
||||
bo.repository_path = base
|
||||
bo.out_dir = out_dir
|
||||
bo.bTarball = bTarball
|
||||
bo.bBuildInstaller = bBuildInstaller
|
||||
|
||||
if not bo.bTarball and not bo.isGrampsRoot(bo.repository_path):
|
||||
log.error( '$$$$ BAD Gramps Root specified $$$$')
|
||||
else:
|
||||
bo.checkForBuildTools()
|
||||
if bo.bTarball:
|
||||
bo.gramps_version = bo.getVersionFromTarBall( bo.repository_path )
|
||||
bo.build_root = path.normpath(os.path.join(bo.out_dir, 'gramps-%s' % bo.gramps_version))
|
||||
if bBuildAll:
|
||||
bo.cleanBuildDir()
|
||||
bo.expandTarBall(base, bo.out_dir)
|
||||
bo.copyExtraFilesToBuildDir(bo.build_root )
|
||||
else: #SVN Build
|
||||
bo.gramps_version = bo.getVersionFromConfigureIn( base )
|
||||
bo.build_root = path.normpath(os.path.join(bo.out_dir, 'gramps-%s' % bo.gramps_version))
|
||||
if bBuildAll:
|
||||
bo.cleanBuildDir()
|
||||
os.mkdir(bo.build_root)
|
||||
bo.exportSVN(os.path.join(base, 'src'), os.path.join(bo.build_root, 'src') )
|
||||
bo.exportSVN(os.path.join(base, 'po'), os.path.join(bo.build_root, 'po') )
|
||||
bo.exportSVN(os.path.join(base, 'example'), os.path.join(bo.build_root, 'examples') )
|
||||
bo.generateConstPy( )
|
||||
bo.copyExtraFilesToBuildDir(base)
|
||||
|
||||
if bPatchBuild:
|
||||
bo.copyPatchTreeToDest( patch_dir, bo.build_root )
|
||||
if bBuildAll:
|
||||
bo.processPO( )
|
||||
if bo.bBuildInstaller:
|
||||
bo.compileInstallScript()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import getopt
|
||||
import os
|
||||
import sys
|
||||
import tarfile
|
||||
|
||||
usage = '''Create Gramps Windows Installer.
|
||||
Usage:
|
||||
python build_GrampsWin32.py [options] [repository_path]
|
||||
|
||||
Arguments:
|
||||
repository_path Path to the repository to build GRAMPS from, this can be either
|
||||
- The root path of a SVN working copy
|
||||
- A tarball that has been saved on local disk
|
||||
- Left blank to build the SVN working copy this file is part of
|
||||
Options:
|
||||
-h, --help This help message.
|
||||
-oDIR, --out=DIR Directory to build files (optional)
|
||||
--nsis_only Build NSIS only (does not Clean & Build All)
|
||||
-t --tarball Build release version from Tarball.
|
||||
-mDIR, --msgdir=DIR Directory to msgfmt.exe
|
||||
-pDIR, --patch=DIR Specify a directory to patch files into the build.
|
||||
only valid for a tarball build.
|
||||
This directory will allow you to patch the release after expanding
|
||||
from tarball and before creating installer.
|
||||
(n.b. each file to be replaced needs to be specified with full path
|
||||
to exactly mimic the paths in the expanded tarball)
|
||||
'''
|
||||
# TODO: nsis_dir option - a path to nsismake (for occasions script cannot work it out)
|
||||
# TODO: svn_dir option - a path to svn (for occasions script cannot work it out)
|
||||
# TODO: tortoise_dir Option - accommodate windows user who dont have svn but use tortoiseSVN
|
||||
|
||||
repository_path = '.' # Repository - either SVN working copy dir or Tarball file
|
||||
out_dir = None
|
||||
bBuildAll = True
|
||||
bBuildInstaller = True
|
||||
bTarball = False
|
||||
msg_dir = ""
|
||||
bPatchBuild = False
|
||||
patch_dir = ""
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], "ho:tm:p:",
|
||||
["help", "out=", "nsis_only", "tarball", "msgdir=", "patch="])
|
||||
|
||||
for o, a in opts:
|
||||
if o in ("-h", "--help"):
|
||||
print(usage)
|
||||
sys.exit(0)
|
||||
|
||||
if o in ("-o", "--out"):
|
||||
out_dir = a
|
||||
if o in ("--nsis_only"):
|
||||
bBuildAll = False
|
||||
if o in ('-t', "--tarball"):
|
||||
print('This is a tarball build')
|
||||
bTarball = True
|
||||
if o in ("-m", "--msgdir"):
|
||||
if os.path.isdir( a ):
|
||||
msg_dir = a
|
||||
else:
|
||||
raise getopt.GetoptError('\nERROR: msgfmt dir does not exist')
|
||||
if o in ("-p", "--patch"):
|
||||
if os.path.isdir( a ):
|
||||
patch_dir = a
|
||||
bPatchBuild = True
|
||||
else:
|
||||
raise getopt.GetoptError('\nERROR: Patch directory does not exist')
|
||||
|
||||
if args: #got args use first one as base dir
|
||||
repository_path = path.normpath(args[0])
|
||||
else: # no base dir passed in, work out one from current working dir
|
||||
repository_path = path.normpath("%s/../.." % os.getcwd() )
|
||||
|
||||
if bPatchBuild and not bTarball:
|
||||
log.warning("Cannot specify patch for SVN build, resetting patch option")
|
||||
patch_dir = None
|
||||
# raise getopt.GetoptError, '\nERROR: No base directory specified'
|
||||
|
||||
if len(args) > 1:
|
||||
raise getopt.GetoptError('\nERROR: Too many arguments')
|
||||
|
||||
except getopt.GetoptError as msg:
|
||||
print(msg)
|
||||
print('\n %s' % usage)
|
||||
sys.exit(2)
|
||||
|
||||
if bTarball:
|
||||
if not tarfile.is_tarfile(repository_path):
|
||||
print("Tarball %s not a valid Tarball" % repository_path)
|
||||
sys.exit(1)
|
||||
|
||||
else:
|
||||
if not os.path.isdir(repository_path):
|
||||
print("WC root directory not found; %s " % repository_path)
|
||||
sys.exit(1)
|
||||
|
||||
if out_dir == None:
|
||||
if bTarball:
|
||||
out_dir = path.normpath(os.getcwd())
|
||||
else:
|
||||
out_dir = path.normpath(os.path.join(repository_path, 'windows'))
|
||||
log.info("Setting outdir to %s", out_dir)
|
||||
|
||||
|
||||
s_args = ''
|
||||
for value in sys.argv[1:]:
|
||||
s_args = s_args + ' %s'%value
|
||||
|
||||
print("======= build_GrampsWin32.py %s ========" % s_args)
|
||||
log.debug('Using %s to find python tools' % sys.prefix)
|
||||
log.info('Platform: %s' % sys.platform)
|
||||
#==========================
|
||||
sys.exit(buildGRAMPS(repository_path,out_dir, bTarball))
|
||||
|
||||
GObject.type_register(buildbase)
|
|
@ -1,373 +0,0 @@
|
|||
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 as 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, r'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 as 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 as 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 as 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()
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,748 +0,0 @@
|
|||
#
|
||||
# Gramps - a GTK+ based genealogy program
|
||||
#
|
||||
# Copyright (C) 2006-2008 Steve Hall <digitect dancingpaper com>
|
||||
# Copyright (C) 2008 Stephen George
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# $Id: $
|
||||
#
|
||||
# Description: Nullsoft Installer (NSIS) file to build Windows installer:
|
||||
#
|
||||
# Requires: NSIS version 2.0 or later.
|
||||
# Notes:
|
||||
# o WARNING: if you make changes to this script, look out for $INSTDIR
|
||||
# to be valid, because this line is very dangerous: RMDir /r $INSTDIR
|
||||
# o WARNING: Except the uninstaller. That re-paths for some reason.
|
||||
#
|
||||
!define GRAMPS_VERSION $%GRAMPS_VER%
|
||||
!define GRAMPS_BUILD_PATH "$%GRAMPS_BUILD_DIR%"
|
||||
!define GRAMPS_OUT_PATH "$%GRAMPS_OUT_DIR%"
|
||||
|
||||
!define MIN_PYTHON_VERSION "2.6.0"
|
||||
!define MIN_GTK_VERSION "2.12.9"
|
||||
!define MIN_PYGTK_VERSION "2.12.1"
|
||||
!define MIN_GOBJECT_VERSION "2.12.3"
|
||||
!define MIN_CAIRO_VERSION "1.2.6"
|
||||
|
||||
; HM NIS Edit Wizard helper defines
|
||||
!define PRODUCT_NAME "GRAMPS"
|
||||
!define PRODUCT_VERSION ${GRAMPS_VERSION}
|
||||
!define PRODUCT_PUBLISHER "The GRAMPS project"
|
||||
!define PRODUCT_WEB_SITE "http://gramps-project.org"
|
||||
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
|
||||
|
||||
!define DESKTOP_LINK "$DESKTOP\${PRODUCT_NAME} ${PRODUCT_VERSION}.lnk"
|
||||
|
||||
# output file
|
||||
Name ${PRODUCT_NAME}
|
||||
OutFile "${GRAMPS_OUT_PATH}\gramps-${PRODUCT_VERSION}.exe"
|
||||
|
||||
# self ensure we don't have a corrupted file
|
||||
CRCCheck on
|
||||
# don't allow installation into C:\ directory
|
||||
AllowRootDirInstall false
|
||||
|
||||
!include "WordFunc.nsh"
|
||||
!include nsDialogs.nsh
|
||||
!insertmacro StrFilter
|
||||
|
||||
# adds an XP manifest
|
||||
XPStyle on
|
||||
# self ensure we don't have a corrupted file
|
||||
CRCCheck on
|
||||
|
||||
# splash, header graphics (same for both!)
|
||||
!define MUI_HEADERIMAGE
|
||||
#!define MUI_HEADERIMAGE_BITMAP "win.bmp"
|
||||
#!define MUI_WELCOMEFINISHPAGE_BITMAP "nsis-splash.bmp"
|
||||
|
||||
|
||||
; MUI 1.67 compatible ------
|
||||
!include "MUI2.nsh"
|
||||
|
||||
; Request application privileges for Windows Vista
|
||||
RequestExecutionLevel admin
|
||||
|
||||
; MUI Settings
|
||||
!define MUI_ABORTWARNING
|
||||
!define MUI_ICON "${NSISDIR}\Contrib\Graphics\Icons\modern-install.ico"
|
||||
!define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico"
|
||||
|
||||
; Language Selection Dialog Settings
|
||||
!define MUI_LANGDLL_REGISTRY_ROOT "${PRODUCT_UNINST_ROOT_KEY}"
|
||||
!define MUI_LANGDLL_REGISTRY_KEY "${PRODUCT_UNINST_KEY}"
|
||||
!define MUI_LANGDLL_REGISTRY_VALUENAME "NSIS:Language"
|
||||
|
||||
Var PythonPath
|
||||
Var PythonExe
|
||||
|
||||
;------------ Pages
|
||||
; Welcome page
|
||||
!insertmacro MUI_PAGE_WELCOME
|
||||
|
||||
PageEx directory
|
||||
;!insertmacro MUI_HEADER_TEXT "page title" " sub title"
|
||||
DirVar $PythonPath
|
||||
PageCallbacks skipPythonPathDialog "" processAfterPythonDialog
|
||||
Caption ": Python installation directory"
|
||||
;SubCaption "This is the best I can be"
|
||||
#DirText [text] [subtext] [browse_button_text] [browse_dlg_text]
|
||||
DirText "Installer cannot find a python installation, python is needed for GRAMPS to run.$\n$\nIf python is already installed please select the location of python below, otherwise cancel the installation and install python before proceeding.$\n$\nObtain Python from http:\\www.python.org" "Select location of python" "" "Browse to location python is installed"
|
||||
PageExEnd
|
||||
;Custom page - for dependancy checking
|
||||
Page custom DependenciesPageFunction DependenciesPageLeave
|
||||
; License page
|
||||
!insertmacro MUI_PAGE_LICENSE "${GRAMPS_BUILD_PATH}\COPYING"
|
||||
; Component Page
|
||||
;!insertmacro MUI_PAGE_COMPONENTS
|
||||
; Directory page
|
||||
!insertmacro MUI_PAGE_DIRECTORY
|
||||
; Instfiles page
|
||||
!insertmacro MUI_PAGE_INSTFILES
|
||||
; Finish page
|
||||
!define MUI_FINISHPAGE_SHOWREADME "$INSTDIR\NEWS.TXT"
|
||||
!insertmacro MUI_PAGE_FINISH
|
||||
|
||||
; Uninstaller pages
|
||||
!insertmacro MUI_UNPAGE_INSTFILES
|
||||
|
||||
; Language files
|
||||
!insertmacro MUI_LANGUAGE "English"
|
||||
!insertmacro MUI_LANGUAGE "Greek"
|
||||
|
||||
; MUI end ------
|
||||
|
||||
Function skipPythonPathDialog
|
||||
; Search for pythonw.exe on the path (returns the full path + exe)
|
||||
SearchPath $3 pythonw.exe
|
||||
IfFileExists $3 HavePython 0
|
||||
; Handle the case where python is installed but not on the path - So check Registry keys
|
||||
|
||||
; reg key (Python version 2.7)
|
||||
ReadRegStr $3 HKLM 'Software\Python\PythonCore\2.7\InstallPath' ""
|
||||
StrCpy $3 "$3pythonw.exe" ; append "pythonw.exe"
|
||||
IfFileExists $3 HavePython 0
|
||||
|
||||
; reg key (Python version 2.6)
|
||||
ReadRegStr $3 HKLM 'Software\Python\PythonCore\2.6\InstallPath' ""
|
||||
StrCpy $3 "$3pythonw.exe" ; append "pythonw.exe"
|
||||
IfFileExists $3 HavePython 0
|
||||
|
||||
; reg key (Python version 2.5)
|
||||
ReadRegStr $3 HKLM 'Software\Python\PythonCore\2.5\InstallPath' ""
|
||||
StrCpy $3 "$3pythonw.exe" ; append "pythonw.exe"
|
||||
IfFileExists $3 HavePython 0
|
||||
|
||||
; reg key (Python version 2.4)
|
||||
ReadRegStr $3 HKLM 'Software\Python\PythonCore\2.4\InstallPath' ""
|
||||
StrCpy $3 "$3pythonw.exe" ; append "pythonw.exe"
|
||||
IfFileExists $3 HavePython NoPython
|
||||
|
||||
HavePython:
|
||||
StrCpy $PythonExe $3
|
||||
Call TestDependancies
|
||||
Abort
|
||||
NoPython: ; show the dialog querying the path
|
||||
FunctionEnd
|
||||
|
||||
Function processAfterPythonDialog
|
||||
StrCpy $PythonExe "$PythonPath\pythonw.exe"
|
||||
IfFileExists $PythonExe GotPython 0
|
||||
MessageBox MB_OK "Sorry cannot find pythonw.exe at $PythonPath$\n$\nPlease re-enter a valid python path"
|
||||
Abort
|
||||
GotPython:
|
||||
Call TestDependancies
|
||||
FunctionEnd
|
||||
; fileassoc.nsh
|
||||
; File association helper macros
|
||||
; Written by Saivert
|
||||
;
|
||||
; Features automatic backup system and UPDATEFILEASSOC macro for
|
||||
; shell change notification.
|
||||
;
|
||||
; |> How to use <|
|
||||
; To associate a file with an application so you can double-click it in explorer, use
|
||||
; the APP_ASSOCIATE macro like this:
|
||||
;
|
||||
; Example:
|
||||
; !insertmacro APP_ASSOCIATE \
|
||||
; "txt" \
|
||||
; "myapp.textfile" \
|
||||
; "myapp tiny description" \
|
||||
; "$INSTDIR\myapp.exe,0" \
|
||||
; "Open with myapp" \
|
||||
; "$INSTDIR\myapp.exe $\"%1$\""
|
||||
;
|
||||
; Never insert the APP_ASSOCIATE macro multiple times, it is only ment
|
||||
; to associate an application with a single file and using the
|
||||
; the "open" verb as default. To add more verbs (actions) to a file
|
||||
; use the APP_ASSOCIATE_ADDVERB macro.
|
||||
;
|
||||
; Example:
|
||||
; !insertmacro APP_ASSOCIATE_ADDVERB "myapp.textfile" "edit" "Edit with myapp" \
|
||||
; "$INSTDIR\myapp.exe /edit $\"%1$\""
|
||||
;
|
||||
; To have access to more options when registering the file association use the
|
||||
; APP_ASSOCIATE_EX macro. Here you can specify the verb and what verb is to be the
|
||||
; standard action (default verb).
|
||||
;
|
||||
; And finally: To remove the association from the registry use the APP_UNASSOCIATE
|
||||
; macro. Here is another example just to wrap it up:
|
||||
; !insertmacro APP_UNASSOCIATE "txt" "myapp.textfile"
|
||||
;
|
||||
; |> Note <|
|
||||
; When defining your file class string always use the short form of your application title
|
||||
; then a period (dot) and the type of file. This keeps the file class sort of unique.
|
||||
; Examples:
|
||||
; Winamp.Playlist
|
||||
; NSIS.Script
|
||||
; Photoshop.JPEGFile
|
||||
;
|
||||
; |> Tech info <|
|
||||
; The registry key layout for a file association is:
|
||||
; HKEY_CLASSES_ROOT
|
||||
; <applicationID> = <"description">
|
||||
; shell
|
||||
; <verb> = <"menu-item text">
|
||||
; command = <"command string">
|
||||
;
|
||||
|
||||
!macro APP_ASSOCIATE EXT FILECLASS DESCRIPTION ICON COMMANDTEXT COMMAND
|
||||
; Backup the previously associated file class
|
||||
ReadRegStr $R0 HKCR ".${EXT}" ""
|
||||
WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0"
|
||||
|
||||
WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}"
|
||||
|
||||
WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}`
|
||||
WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}`
|
||||
WriteRegStr HKCR "${FILECLASS}\shell" "" "open"
|
||||
WriteRegStr HKCR "${FILECLASS}\shell\open" "" `${COMMANDTEXT}`
|
||||
WriteRegStr HKCR "${FILECLASS}\shell\open\command" "" `${COMMAND}`
|
||||
!macroend
|
||||
|
||||
!macro APP_ASSOCIATE_EX EXT FILECLASS DESCRIPTION ICON VERB DEFAULTVERB SHELLNEW COMMANDTEXT COMMAND
|
||||
; Backup the previously associated file class
|
||||
ReadRegStr $R0 HKCR ".${EXT}" ""
|
||||
WriteRegStr HKCR ".${EXT}" "${FILECLASS}_backup" "$R0"
|
||||
|
||||
WriteRegStr HKCR ".${EXT}" "" "${FILECLASS}"
|
||||
StrCmp "${SHELLNEW}" "0" +2
|
||||
WriteRegStr HKCR ".${EXT}\ShellNew" "NullFile" ""
|
||||
|
||||
WriteRegStr HKCR "${FILECLASS}" "" `${DESCRIPTION}`
|
||||
WriteRegStr HKCR "${FILECLASS}\DefaultIcon" "" `${ICON}`
|
||||
WriteRegStr HKCR "${FILECLASS}\shell" "" `${DEFAULTVERB}`
|
||||
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
|
||||
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
|
||||
!macroend
|
||||
|
||||
!macro APP_ASSOCIATE_ADDVERB FILECLASS VERB COMMANDTEXT COMMAND
|
||||
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}" "" `${COMMANDTEXT}`
|
||||
WriteRegStr HKCR "${FILECLASS}\shell\${VERB}\command" "" `${COMMAND}`
|
||||
!macroend
|
||||
|
||||
!macro APP_ASSOCIATE_REMOVEVERB FILECLASS VERB
|
||||
DeleteRegKey HKCR `${FILECLASS}\shell\${VERB}`
|
||||
!macroend
|
||||
|
||||
|
||||
!macro APP_UNASSOCIATE EXT FILECLASS
|
||||
; Backup the previously associated file class
|
||||
ReadRegStr $R0 HKCR ".${EXT}" `${FILECLASS}_backup`
|
||||
WriteRegStr HKCR ".${EXT}" "" "$R0"
|
||||
|
||||
DeleteRegKey HKCR `${FILECLASS}`
|
||||
!macroend
|
||||
|
||||
!macro APP_ASSOCIATE_GETFILECLASS OUTPUT EXT
|
||||
ReadRegStr ${OUTPUT} HKCR ".${EXT}" ""
|
||||
!macroend
|
||||
|
||||
|
||||
; !defines for use with SHChangeNotify
|
||||
!ifdef SHCNE_ASSOCCHANGED
|
||||
!undef SHCNE_ASSOCCHANGED
|
||||
!endif
|
||||
!define SHCNE_ASSOCCHANGED 0x08000000
|
||||
!ifdef SHCNF_FLUSH
|
||||
!undef SHCNF_FLUSH
|
||||
!endif
|
||||
!define SHCNF_FLUSH 0x1000
|
||||
|
||||
!macro UPDATEFILEASSOC
|
||||
; Using the system.dll plugin to call the SHChangeNotify Win32 API function so we
|
||||
; can update the shell.
|
||||
System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
|
||||
!macroend
|
||||
|
||||
;EOF
|
||||
|
||||
Section "File Association" FileAssoc
|
||||
SectionIn 1 3
|
||||
# depends on FileAssoc.nsh, by Saivert (http://nsis.sourceforge.net/FileAssoc)
|
||||
|
||||
# .grdb
|
||||
!insertmacro APP_ASSOCIATE \
|
||||
"grdb" \
|
||||
"application/x-gramps-database" \
|
||||
"GRAMPS database file" \
|
||||
"$INSTDIR\images\ped24.ico" \
|
||||
"Open with GRAMPS" \
|
||||
"$\"$3$\" $\"$INSTDIR\gramps.py$\" $\"%1$\""
|
||||
|
||||
# .gramps
|
||||
!insertmacro APP_ASSOCIATE \
|
||||
"gramps" \
|
||||
"application/x-gramps-file" \
|
||||
"GRAMPS application file" \
|
||||
"$INSTDIR\images\ped24.ico" \
|
||||
"Open with GRAMPS" \
|
||||
"$\"$3$\" $\"$INSTDIR\gramps.py$\" $\"%1$\""
|
||||
|
||||
# .gpkg
|
||||
!insertmacro APP_ASSOCIATE \
|
||||
"gpkg" \
|
||||
"application/x-gramps-package" \
|
||||
"GRAMPS package file" \
|
||||
"$INSTDIR\images\ped24.ico" \
|
||||
"Open with GRAMPS" \
|
||||
"$\"$3$\" $\"$INSTDIR\gramps.py$\" $\"%1$\""
|
||||
|
||||
# .ged
|
||||
!insertmacro APP_ASSOCIATE \
|
||||
"ged" \
|
||||
"application/x-gramps-gedcom" \
|
||||
"GEnealogical Data COMmunication (GEDCOM) file" \
|
||||
"$INSTDIR\images\ped24.ico" \
|
||||
"Open with GRAMPS" \
|
||||
"$\"$3$\" $\"$INSTDIR\gramps.py$\" $\"%1$\""
|
||||
|
||||
SectionEnd
|
||||
|
||||
|
||||
|
||||
#Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
|
||||
#OutFile ${GRAMPS_OUT_PATH}\gramps-${GRAMPS_VERSION}.exe
|
||||
# default install path
|
||||
InstallDir "$PROGRAMFILES\Gramps"
|
||||
ShowInstDetails show
|
||||
ShowUnInstDetails show
|
||||
|
||||
Function .onInit
|
||||
!insertmacro MUI_LANGDLL_DISPLAY
|
||||
|
||||
SetOutPath $TEMP
|
||||
|
||||
# default install directory ($INSTDIR)
|
||||
StrCpy $INSTDIR $PROGRAMFILES\gramps
|
||||
Call WarnSVNVersion
|
||||
Call RemovePrevious ;Move to a page leave function
|
||||
# set our installed directory to the same as last version?
|
||||
FunctionEnd
|
||||
|
||||
Var PythonVerText
|
||||
Var GTKVerText
|
||||
Var pyGTKVerText
|
||||
Var GObjectVerText
|
||||
Var CairoVerText
|
||||
|
||||
!insertmacro WordFind2X
|
||||
|
||||
Function TestDependancies
|
||||
SetOutPath $TEMP
|
||||
|
||||
File test_dependencies.py
|
||||
|
||||