Merged wxPython 2.4.x to the 2.5 branch (Finally!!!)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@19793 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2003-03-25 06:35:27 +00:00
parent 9b4e3f352b
commit 1e4a197e4c
586 changed files with 62691 additions and 17740 deletions

View File

@@ -0,0 +1 @@
.DS_Store

View File

@@ -0,0 +1 @@
.DS_Store

View File

@@ -0,0 +1,3 @@
This is a set of build scripts and such for MacPython-OSX 2.3 that I
will use until there are standard distributions from Jack.

View File

@@ -0,0 +1,129 @@
#!/bin/sh -e
#----------------------------------------------------------------------
# Build MacPython 2.3 and make an Installer package of it
# TODO: Parameterize the versions, builddirs, etc...
# Script configs
PYVERSION=2.3a2
PYVER=2.3
BUILDNUM=3
DOCLEANUP=no
PROGDIR="`dirname \"$0\"`"
TMPDIR=/tmp/_py
#TMPDIR=/projects/_py
BUILDROOT=$TMPDIR/build
INSTALLROOT=$TMPDIR/install
DMGDIR=$TMPDIR/dmg
RESOURCEDIR=$PROGDIR/resources
DESTDIR=/projects/wx/wxPython/dist
PYTHONSRC=/projects/Python-$PYVERSION
WASTEDIR=/projects/waste
# Setup
mkdir -p $BUILDROOT
mkdir -p $INSTALLROOT
rm -rf $DMGDIR
mkdir -p $DMGDIR/root
# Configure and build Python
pushd $BUILDROOT
# Check if we should build and install the docs, but only if it
# doesn't appear to be done already. TODO: fix this path to be version independent
if [ ! -e "build/temp.darwin-6.3-Power Macintosh-2.3/build-html/build-html idx" ]; then
read -p "Build the Python docs? (y/N)? " builddocs
fi
# If the filesystem is case-sensitive then "python" will be built, but
# some parts of the install expect "python.exe which is what is built
# on a case-insensitive filesystem. Make a link just in case it is
# needed.
if [ ! -e python.exe ]; then
ln -s python python.exe
fi
# Make a link to the waste dir so that lib can be found. This allows
# the PythonIDE to be built
if [ ! -e waste ]; then
ln -s $WASTEDIR waste
fi
$PYTHONSRC/configure --enable-framework=$INSTALLROOT/Library/Frameworks LDFLAGS=-Wl,-x
make
make frameworkinstall
if [ "$builddocs" = "y" -o "$builddocs" = "Y" ]; then
./python.exe $PYTHONSRC/Mac/OSX/setupDocs.py build
echo ""
read -p "When the help indexer is done press Enter..." ans
./python.exe $PYTHONSRC/Mac/OSX/setupDocs.py install \
--prefix=$INSTALLROOT/Library/Frameworks/Python.framework/Versions/$PYVER
fi
popd
# Make the Installer package:
# First, remove the unix tools as their paths will be wrong. We'll recreate
# them in the postinstall.
rm -r $INSTALLROOT/usr
# Next, remove the .pyc/.pyo files
python $PROGDIR/../zappycfiles.py $INSTALLROOT/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER
# Make the welcome message
cat > $RESOURCEDIR/Welcome.txt <<EOF
Welcome!
This program will install Python $PYVERSION for Mac OS X as a Framework.
Build number: $BUILDNUM
Build date: `date`
EOF
# fix a bug in the IDLE install
IDLERES=$INSTALLROOT/Applications/MacPython-2.3/IDLE.app/Contents/Resources
mv $IDLERES/idlelib/idle $IDLERES
# Finally, build the package...
rm -rf MacPython-OSX.pkg
python $PROGDIR/../buildpkg.py \
--Title=MacPython-OSX \
--Version=$PYVERSION-$BUILDNUM \
--Description="Python $PYVERSION for Mac OS X, framework based" \
--NeedsAuthorization="YES" \
--Relocatable="NO" \
--InstallOnly="YES" \
$INSTALLROOT \
$RESOURCEDIR
## --RootVolumeOnly="YES" \
# ...and then make a disk image containing the package.
mv MacPython-OSX.pkg $DMGDIR/root
$PROGDIR/../makedmg $DMGDIR/root $DMGDIR MacPython-OSX-$PYVERSION-$BUILDNUM
echo Moving $DMGDIR/MacPython-OSX-$PYVERSION-$BUILDNUM to $DESTDIR
mv $DMGDIR/MacPython-OSX-$PYVERSION-$BUILDNUM.dmg $DESTDIR
# Cleanup build/install dirs
if [ $DOCLEANUP = yes ]; then
echo "Cleaning up..."
rm -rf $BUILDROOT
rm -rf $INSTALLROOT
rm -rf $DMGDIR
else
echo "Cleanup is disabled. You should remove these dirs when done:"
echo " $BUILDROOT"
echo " $INSTALLROOT"
echo " $DMGDIR"
fi

View File

@@ -0,0 +1,6 @@
Welcome!
This program will install Python 2.3a2 for Mac OS X as a Framework.
Build number: 3
Build date: Thu Mar 20 18:54:52 PST 2003

View File

@@ -0,0 +1,67 @@
#!/bin/sh
#----------------------------------------------------------------------
# Create the unix tools and compile the .py files after Python has been
# installed.
#----------------------------------------------------------------------
PYVER=2.3
PKG=$1
DEST=$2
# if destination is / then use usr/local/bin, otherwise just bin
if [ "$DEST" = "/" ]; then
TOOLDIR=/usr/local/bin
DEST=
else
TOOLDIR=$DEST/bin
fi
# Make sure the dir exists
mkdir -p $TOOLDIR
# Make some links to the python executable
if [ -e $TOOLDIR/python$PYVER ]; then
rm $TOOLDIR/python$PYVER
fi
ln -fs $DEST/Library/Frameworks/Python.framework/Versions/$PYVER/bin/python $TOOLDIR/python$PYVER
if [ -e $TOOLDIR/python ]; then
rm $TOOLDIR/python
fi
ln -fs python$PYVER $TOOLDIR/python
# make the pythonw script
cat > $TOOLDIR/pythonw <<EOF
#!/bin/sh
exec "$DEST/Library/Frameworks/Python.framework/Versions/$PYVER/Resources/Python.app/Contents/MacOS/python" "\$@"
EOF
chmod +x $TOOLDIR/pythonw
# Compile the .py files in the Python library to .pyc's and then .pyo's
$TOOLDIR/python -Wi -tt \
$DEST/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER/compileall.py \
-x badsyntax -x site-packages $DEST/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER
$TOOLDIR/python -Wi -tt -O \
$DEST/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER/compileall.py \
-x badsyntax -x site-packages $DEST/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER
# Make the site-packages and other dirs writable by the admin.
for d in $DEST/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER/site-packages \
$DEST/Library/Frameworks/Python.framework/Versions/$PYVER/bin \
$DEST/Applications/MacPython-$PYVER; do
chgrp -R admin $d
chmod -R g+w $d
done
# The link in the app bundles needs updated.
for app in BuildApplet IDLE PackageManager PythonIDE; do
ln -s $DEST/Library/Frameworks/Python.framework/Versions/$PYVER/Resources/Python.app/Contents/MacOS/python \
$DEST/Applications/MacPython-$PYVER/$app.app/Contents/MacOS
done

View File

@@ -1,15 +0,0 @@
Title MachoPython
Version 2.2.1
Description The Python Programming Language
DefaultLocation /
DeleteWarning
### Package Flags
NeedsAuthorization YES
Required NO
Relocatable NO
RequiresReboot NO
UseUserMask NO
OverwritePermissions NO
InstallFat NO

View File

@@ -1,264 +0,0 @@
#!/bin/sh -e
#
# build binary wxMacPython package and put it on a disk image
#
# usage: build [-s dir] [-d dir] [--cvs-update] [--force] [--debug]
#
# (C)opyright 2002 Frank Vercruesse
#
# Many modifications by Robin Dunn
PYVER=2.2
curDir=`pwd`
progDir="`dirname \"$0\"`"
defSrcPath="/projects/wx"
defDstPath="/projects/wx/wxPython/dist"
pkgName="wxPythonOSX"
#version=`date +"%Y-%m-%d"`
version=`cd $defSrcPath/wxPython; python$PYVER -c 'import setup;print setup.VERSION'`
dmgRoot="dmg-root"
pkgRoot="pkg-root"
wxWindowsInst="$pkgRoot/usr/local"
wxPythonInst="$pkgRoot/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER/site-packages"
pythonExec="python$PYVER"
makePkgExec="./makepkg"
makeDmgExec="./makedmg"
usage() {
echo `basename $0`: ERROR: $* 1>&2
echo usage: `basename $0` '[-s dir] [-d dir] [--cvs-update] [--force] [--debug]' 1>&2
exit 1
}
quotemeta() {
# probably not quite correct, but seems to work
echo "$1" | sed -e 's/\([^a-zA-z0-9.,--;_/]\)/\\\1/g'
}
msg()
{
echo "---------------------------------------------"
echo $@
}
msgdo() {
echo "--> " $@
$@
}
user=$1
shift
update=
force=
debug=
srcPath=
dstPath=
while :; do
case "$1" in
--cvs-update) update=1;;
--force) force=1;;
--debug) debug=1;;
-s) shift; srcPath="$1";;
-d) shift; dstPath="$1";;
-*) usage "bad argument $1";;
*) break;;
esac
shift
done
#-----------------------------------
msg check and prepare build directories
if ! test "$srcPath"; then
srcPath=$defSrcPath
fi
if ! test -d "$srcPath"; then
echo "no such directory: '$srcPath'" 1>&2
exit
fi
if ! test "$dstPath"; then
dstPath=$defDstPath
fi
if ! test -d "$dstPath"; then
msgdo mkdir -p -m 775 "$dstPath"
msgdo chown ${user}:staff "$dstPath"
fi
temp="tmp$$"
if test -e "$dstPath/$temp"; then
msgdo rm -rf "$dstPath/$temp"
fi
msgdo mkdir -m 775 "$dstPath/$temp"
if test -e "$dstPath/$temp/$pkgRoot"; then
msgdo rm -rf "$dstPath/$temp/$pkgRoot"
fi
msgdo mkdir -m 1775 "$dstPath/$temp/$pkgRoot"
msgdo chown root:admin "$dstPath/$temp/$pkgRoot"
if test -e "$dstPath/$temp/$dmgRoot"; then
msgdo rm -rf "$dstPath/$temp/$dmgRoot"
fi
msgdo mkdir -p -m 775 "$dstPath/$temp/$dmgRoot"
msgdo chown $user:staff "$dstPath/$temp/$dmgRoot"
#-----------------------------------
# update cvs
if [ $update ]; then
msg Updating from CVS
msgdo cd "$srcPath"
msgdo cvs update -dP -A
fi
#-----------------------------------
msg configuring wxWindows
buildDir="$srcPath/build-pkg"
dFlag="--enable-debug_flag --enable-optimise"
if [ $debug ]; then
buildDir="$srcPath/build-pkg-debug"
dFlag="--enable-debug"
fi
if ! test -e "$buildDir"; then
force=1
fi
if [ $force ]; then
if test -e "$buildDir"; then
rm -rf "$buildDir"
fi
msgdo mkdir -m 775 "$buildDir"
msgdo cd "$buildDir"
msgdo ../configure --with-mac --with-opengl --enable-precomp=no $dFlag
cd $curDir
else
echo wxWindows already configured
fi
#-----------------------------------
msg building wxWindows
msgdo cd $buildDir
msgdo make
msgdo cd ../locale
msgdo make allmo
cd $curDir
#-----------------------------------
msg installing wxWindows
msgdo mkdir -p -m 1755 "$dstPath/$temp/$wxWindowsInst"
msgdo cd "$buildDir"
# install once to the package directory, and once to the
# local machine so the wxPython build will get the right wxMac
msgdo make install "prefix=`quotemeta \"$dstPath/$temp/$wxWindowsInst\"`"
msgdo make install
msgdo chown -R root:wheel "$dstPath/$temp/$pkgRoot/usr"
cd $curDir
#-----------------------------------
msg building wxPython
if [ $force ]; then
fFlag="--force"
else
fFlag=
fi
if [ $debug ]; then
dFlag="--debug"
wxpBuildDir="build-pkg-debug"
else
dFlag=
wxpBuildDir="build-pkg"
fi
bbFlag="BUILD_BASE=$wxpBuildDir"
msgdo cd "$srcPath/wxPython"
msgdo $pythonExec setup.py build 'IN_CVS_TREE=1' $bbFlag $fFlag $dFlag
cd $curDir
#-----------------------------------
msg installing wxPython
msgdo mkdir -p -m 775 "$dstPath/$temp/$wxPythonInst"
msgdo cd "$srcPath/wxPython"
msgdo $pythonExec setup.py install $bbFlag --install-lib="$dstPath/$temp/$wxPythonInst"
cd $curDir
msgdo chown -R root:admin "$dstPath/$temp/$pkgRoot/Library"
msgdo chmod -R g+w "$dstPath/$temp/$pkgRoot/Library"
#-----------------------------------
msg copying additional wxPython files
msgdo cp -pR "$srcPath/wxPython/samples" "$dstPath/$temp/$dmgRoot"
msgdo cp -pR "$srcPath/wxPython/demo" "$dstPath/$temp/$dmgRoot"
msgdo cp -pR "$srcPath/wxPython/licence" "$dstPath/$temp/$dmgRoot"
find "$dstPath/$temp/$dmgRoot" -name "CVS" -type d -print0 | xargs -0 rm -rf
find "$dstPath/$temp/$dmgRoot" -name ".DS_Store" -type f -print0 | xargs -0 rm
find "$dstPath/$temp/$dmgRoot" -name ".cvsignore" -type f -print0 | xargs -0 rm
find "$dstPath/$temp/$dmgRoot" -name ".#*" -type f -print0 | xargs -0 rm
find "$dstPath/$temp/$dmgRoot" -name "b" -type f -print0 | xargs -0 rm
find "$dstPath/$temp/$dmgRoot" -name "*~*~" -type f -print0 | xargs -0 rm
msgdo cd "$srcPath/wxPython/scripts"
sFiles=`$pythonExec CreateMacScripts.py`
for f in $sFiles; do
msgdo cp $f "$dstPath/$temp/$wxWindowsInst/bin"
done
cd $curDir
msgdo chown -R ${user}:staff "$dstPath/$temp/$dmgRoot"
#-----------------------------------
msg making installer package
msgdo cp -pR "$progDir/resources" "$dstPath/$temp"
msgdo cp $progDir/$pkgName.info $progDir/$pkgName-$version.info
if [ $debug ]; then
echo "__WXDEBUG__ version." >> "$dstPath/$temp/resources/Welcome.txt"
echo "" >> "$dstPath/$temp/resources/Welcome.txt"
fi
echo "Build date: `date`" >> "$dstPath/$temp/resources/Welcome.txt"
msgdo cd "$progDir"
msgdo "$makePkgExec" $dstPath/$temp/$pkgRoot $pkgName-$version.info -d $dstPath/$temp/$dmgRoot -r $dstPath/$temp/resources
msgdo chown -R ${user}:staff $dstPath/$temp/$dmgRoot/$pkgName-$version.pkg
cd $curDir
#-----------------------------------
msg making disk image
msgdo cd "$progDir"
msgdo "$makeDmgExec" $dstPath/$temp/$dmgRoot $dstPath/$temp $pkgName-$version
if [ $debug ]; then
dmgName="$pkgName-$version-debug"
else
dmgName="$pkgName-$version"
fi
msgdo mv "$dstPath/$temp/$pkgName-$version.dmg" "$dstPath/$dmgName.dmg"
msgdo chown ${user}:staff "$dstPath/$dmgName.dmg"
cd $curDir
#-----------------------------------
msg cleaning up
msgdo chown -R ${user}:staff "$buildDir"
msgdo chown -R ${user}:staff "$srcPath/wxPython/$wxpBuildDir"
msgdo rm $progDir/$pkgName-$version.info
msgdo rm -rf "$dstPath/$temp"

View File

@@ -1,162 +0,0 @@
#!/bin/sh -e
#
# Create a MachoPython package from the currently installed verison
# and put it on a disk image
#
PYVER=2.2
curDir=`pwd`
progDir="`dirname \"$0\"`"
defDstPath="/projects/wx/wxPython/dist"
pkgName="MachoPython"
version=2.2.1-4
dmgRoot="dmg-root"
pkgRoot="pkg-root"
sitePkgDir="$pkgRoot/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER/site-packages"
pythonExec="python$PYVER"
makePkgExec="./makepkg"
makeDmgExec="./makedmg"
usage() {
echo `basename $0`: ERROR: $* 1>&2
echo usage: `basename $0` '[-d dir]' 1>&2
exit 1
}
quotemeta() {
# probably not quite correct, but seems to work
echo "$1" | sed -e 's/\([^a-zA-z0-9.,--;_/]\)/\\\1/g'
}
msg()
{
echo "---------------------------------------------"
echo $@
}
msgdo() {
echo "--> " $@
$@
}
user=$1
shift
dstPath=
while :; do
case "$1" in
-d) shift; dstPath="$1";;
-*) usage "bad argument $1";;
*) break;;
esac
shift
done
#-----------------------------------
msg check and prepare build directories
if ! test "$dstPath"; then
dstPath=$defDstPath
fi
if ! test -d "$dstPath"; then
msgdo mkdir -p -m 775 "$dstPath"
msgdo chown ${user}:staff "$dstPath"
fi
temp="tmp$$"
if test -e "$dstPath/$temp"; then
msgdo rm -rf "$dstPath/$temp"
fi
msgdo mkdir -m 775 "$dstPath/$temp"
if test -e "$dstPath/$temp/$pkgRoot"; then
msgdo rm -rf "$dstPath/$temp/$pkgRoot"
fi
msgdo mkdir -m 1775 "$dstPath/$temp/$pkgRoot"
msgdo chown root:admin "$dstPath/$temp/$pkgRoot"
if test -e "$dstPath/$temp/$dmgRoot"; then
msgdo rm -rf "$dstPath/$temp/$dmgRoot"
fi
msgdo mkdir -p -m 775 "$dstPath/$temp/$dmgRoot"
msgdo chown $user:staff "$dstPath/$temp/$dmgRoot"
#-----------------------------------
msg Copying files to package build dir
for d in Applications/Python.app Library/Frameworks/Python.framework; do
msgdo mkdir -p -m 755 $dstPath/$temp/$pkgRoot/$d
msgdo cp -pR /$d/* $dstPath/$temp/$pkgRoot/$d
done
msgdo mkdir -p -m 755 $dstPath/$temp/$pkgRoot/usr/local/bin
msgdo cd $dstPath/$temp/$pkgRoot/usr/local/bin
for f in pydoc python python$PYVER; do
msgdo ln -s ../../../Library/Frameworks/Python.framework/Versions/Current/bin/$f .
done
cat > pythonw <<EOF
#!/bin/sh
exec /Applications/Python.app/Contents/MacOS/python \$@
EOF
chmod +x pythonw
cd $curDir
#-----------------------------------
msg Removing locally installed extension modules
msgdo cd $dstPath/$temp/$sitePkgDir
for f in *; do
if [ $f != README ]; then
msgdo rm -r $f
fi
done
for f in Numeric numarray; do
rm -r $dstPath/$temp/$pkgRoot/Library/Frameworks/Python.framework/Versions/$PYVER/include/python$PYVER/$f
done
cd $curDir
#-----------------------------------
msg Adjusting ownership and permission
for d in Applications Library; do
msgdo chown -R root:admin "$dstPath/$temp/$pkgRoot/$d"
msgdo chmod -R g+w "$dstPath/$temp/$pkgRoot/$d"
done
msgdo chown -R root:wheel "$dstPath/$temp/$pkgRoot/usr"
#-----------------------------------
msg making installer package
msgdo cp -pR "$progDir/resourcesPython" "$dstPath/$temp/"
msgdo mv "$dstPath/$temp/resourcesPython" "$dstPath/$temp/resources"
msgdo cp $progDir/$pkgName.info $progDir/$pkgName-$version.info
msgdo cd "$progDir"
msgdo "$makePkgExec" $dstPath/$temp/$pkgRoot $pkgName-$version.info -d $dstPath/$temp/$dmgRoot -r $dstPath/$temp/resources
msgdo chown -R ${user}:staff $dstPath/$temp/$dmgRoot/$pkgName-$version.pkg
cd $curDir
#-----------------------------------
msg making disk image
msgdo cd "$progDir"
msgdo "$makeDmgExec" $dstPath/$temp/$dmgRoot $dstPath/$temp $pkgName-$version
dmgName="$pkgName-$version"
msgdo mv "$dstPath/$temp/$pkgName-$version.dmg" "$dstPath/$dmgName.dmg"
msgdo chown ${user}:staff "$dstPath/$dmgName.dmg"
cd $curDir
#-----------------------------------
msg cleaning up
msgdo rm $progDir/$pkgName-$version.info
msgdo rm -rf "$dstPath/$temp"

View File

@@ -1,11 +0,0 @@
#!/bin/sh -e
#
# build binary package and put it on a disk image
#
# usage: build [-s dir] [-d dir] [--cvs-update] [--force] [--debug]
#
# (C)opyright 2002 Frank Vercruesse
prog="`dirname \"$0\"`/_`basename \"$0\"`"
sudo "$prog" "${USER?'USER not set.'}" "$@"

View File

@@ -1,8 +0,0 @@
#!/bin/sh -e
#
# build binary package and put it on a disk image
#
prog="`dirname \"$0\"`/_`basename \"$0\"`"
sudo "$prog" "${USER?'USER not set.'}" "$@"

View File

@@ -0,0 +1,4 @@
# Just a simple shell around bundlebuilder.
from bundlebuilder import buildapp
buildapp()

View File

@@ -0,0 +1,470 @@
#!/usr/bin/env python
"""buildpkg.py -- Build OS X packages for Apple's Installer.app.
This is an experimental command-line tool for building packages to be
installed with the Mac OS X Installer.app application.
It is much inspired by Apple's GUI tool called PackageMaker.app, that
seems to be part of the OS X developer tools installed in the folder
/Developer/Applications. But apparently there are other free tools to
do the same thing which are also named PackageMaker like Brian Hill's
one:
http://personalpages.tds.net/~brian_hill/packagemaker.html
Beware of the multi-package features of Installer.app (which are not
yet supported here) that can potentially screw-up your installation
and are discussed in these articles on Stepwise:
http://www.stepwise.com/Articles/Technical/Packages/InstallerWoes.html
http://www.stepwise.com/Articles/Technical/Packages/InstallerOnX.html
Beside using the PackageMaker class directly, by importing it inside
another module, say, there are additional ways of using this module:
the top-level buildPackage() function provides a shortcut to the same
feature and is also called when using this module from the command-
line.
****************************************************************
NOTE: For now you should be able to run this even on a non-OS X
system and get something similar to a package, but without
the real archive (needs pax) and bom files (needs mkbom)
inside! This is only for providing a chance for testing to
folks without OS X.
****************************************************************
TODO:
- test pre-process and post-process scripts (Python ones?)
- handle multi-volume packages (?)
- integrate into distutils (?)
Dinu C. Gherman,
gherman@europemail.com
November 2001
!! USE AT YOUR OWN RISK !!
"""
__version__ = 0.2
__license__ = "FreeBSD"
import os, sys, glob, fnmatch, shutil, string, copy, getopt
from os.path import basename, dirname, join, islink, isdir, isfile
Error = "buildpkg.Error"
PKG_INFO_FIELDS = """\
Title
Version
Description
DefaultLocation
Diskname
DeleteWarning
NeedsAuthorization
DisableStop
UseUserMask
Application
Relocatable
Required
InstallOnly
RequiresReboot
RootVolumeOnly
InstallFat\
"""
######################################################################
# Helpers
######################################################################
# Convenience class, as suggested by /F.
class GlobDirectoryWalker:
"A forward iterator that traverses files in a directory tree."
def __init__(self, directory, pattern="*"):
self.stack = [directory]
self.pattern = pattern
self.files = []
self.index = 0
def __getitem__(self, index):
while 1:
try:
file = self.files[self.index]
self.index = self.index + 1
except IndexError:
# pop next directory from stack
self.directory = self.stack.pop()
self.files = os.listdir(self.directory)
self.index = 0
else:
# got a filename
fullname = join(self.directory, file)
if isdir(fullname) and not islink(fullname):
self.stack.append(fullname)
if fnmatch.fnmatch(file, self.pattern):
return fullname
######################################################################
# The real thing
######################################################################
class PackageMaker:
"""A class to generate packages for Mac OS X.
This is intended to create OS X packages (with extension .pkg)
containing archives of arbitrary files that the Installer.app
will be able to handle.
As of now, PackageMaker instances need to be created with the
title, version and description of the package to be built.
The package is built after calling the instance method
build(root, **options). It has the same name as the constructor's
title argument plus a '.pkg' extension and is located in the same
parent folder that contains the root folder.
E.g. this will create a package folder /my/space/distutils.pkg/:
pm = PackageMaker("distutils", "1.0.2", "Python distutils.")
pm.build("/my/space/distutils")
"""
packageInfoDefaults = {
'Title': None,
'Version': None,
'Description': '',
'DefaultLocation': '/',
'Diskname': '(null)',
'DeleteWarning': '',
'NeedsAuthorization': 'NO',
'DisableStop': 'NO',
'UseUserMask': 'YES',
'Application': 'NO',
'Relocatable': 'YES',
'Required': 'NO',
'InstallOnly': 'NO',
'RequiresReboot': 'NO',
'RootVolumeOnly' : 'NO',
'InstallFat': 'NO'}
def __init__(self, title, version, desc):
"Init. with mandatory title/version/description arguments."
info = {"Title": title, "Version": version, "Description": desc}
self.packageInfo = copy.deepcopy(self.packageInfoDefaults)
self.packageInfo.update(info)
# variables set later
self.packageRootFolder = None
self.packageResourceFolder = None
self.sourceFolder = None
self.resourceFolder = None
def build(self, root, resources=None, **options):
"""Create a package for some given root folder.
With no 'resources' argument set it is assumed to be the same
as the root directory. Option items replace the default ones
in the package info.
"""
# set folder attributes
self.sourceFolder = root
if resources == None:
self.resourceFolder = root
else:
self.resourceFolder = resources
# replace default option settings with user ones if provided
fields = self. packageInfoDefaults.keys()
for k, v in options.items():
if k in fields:
self.packageInfo[k] = v
elif not k in ["OutputDir"]:
raise Error, "Unknown package option: %s" % k
# Check where we should leave the output. Default is current directory
outputdir = options.get("OutputDir", os.getcwd())
packageName = self.packageInfo["Title"]
self.PackageRootFolder = os.path.join(outputdir, packageName + ".pkg")
# do what needs to be done
self._makeFolders()
self._addInfo()
self._addBom()
self._addArchive()
self._addResources()
self._addSizes()
def _makeFolders(self):
"Create package folder structure."
# Not sure if the package name should contain the version or not...
# packageName = "%s-%s" % (self.packageInfo["Title"],
# self.packageInfo["Version"]) # ??
contFolder = join(self.PackageRootFolder, "Contents")
self.packageResourceFolder = join(contFolder, "Resources")
os.mkdir(self.PackageRootFolder)
os.mkdir(contFolder)
os.mkdir(self.packageResourceFolder)
def _addInfo(self):
"Write .info file containing installing options."
# Not sure if options in PKG_INFO_FIELDS are complete...
info = ""
for f in string.split(PKG_INFO_FIELDS, "\n"):
info = info + "%s %%(%s)s\n" % (f, f)
info = info % self.packageInfo
base = self.packageInfo["Title"] + ".info"
path = join(self.packageResourceFolder, base)
f = open(path, "w")
f.write(info)
def _addBom(self):
"Write .bom file containing 'Bill of Materials'."
# Currently ignores if the 'mkbom' tool is not available.
try:
base = self.packageInfo["Title"] + ".bom"
bomPath = join(self.packageResourceFolder, base)
cmd = "mkbom %s %s" % (self.sourceFolder, bomPath)
res = os.system(cmd)
except:
pass
def _addArchive(self):
"Write .pax.gz file, a compressed archive using pax/gzip."
# Currently ignores if the 'pax' tool is not available.
cwd = os.getcwd()
# create archive
os.chdir(self.sourceFolder)
base = basename(self.packageInfo["Title"]) + ".pax"
self.archPath = join(self.packageResourceFolder, base)
cmd = "pax -w -f %s %s" % (self.archPath, ".")
res = os.system(cmd)
# compress archive
cmd = "gzip %s" % self.archPath
res = os.system(cmd)
os.chdir(cwd)
def _addResources(self):
"Add Welcome/ReadMe/License files, .lproj folders and scripts."
# Currently we just copy everything that matches the allowed
# filenames. So, it's left to Installer.app to deal with the
# same file available in multiple formats...
if not self.resourceFolder:
return
# find candidate resource files (txt html rtf rtfd/ or lproj/)
allFiles = []
for pat in string.split("*.txt *.html *.rtf *.rtfd *.lproj", " "):
pattern = join(self.resourceFolder, pat)
allFiles = allFiles + glob.glob(pattern)
# find pre-process and post-process scripts
# naming convention: packageName.{pre,post}_{upgrade,install}
# Alternatively the filenames can be {pre,post}_{upgrade,install}
# in which case we prepend the package name
packageName = self.packageInfo["Title"]
for pat in ("*upgrade", "*install", "*flight"):
pattern = join(self.resourceFolder, packageName + pat)
pattern2 = join(self.resourceFolder, pat)
allFiles = allFiles + glob.glob(pattern)
allFiles = allFiles + glob.glob(pattern2)
# check name patterns
files = []
for f in allFiles:
for s in ("Welcome", "License", "ReadMe"):
if string.find(basename(f), s) == 0:
files.append((f, f))
if f[-6:] == ".lproj":
files.append((f, f))
elif basename(f) in ["pre_upgrade", "pre_install", "post_upgrade", "post_install"]:
files.append((f, packageName+"."+basename(f)))
elif basename(f) in ["preflight", "postflight"]:
files.append((f, f))
elif f[-8:] == "_upgrade":
files.append((f,f))
elif f[-8:] == "_install":
files.append((f,f))
# copy files
for src, dst in files:
src = basename(src)
dst = basename(dst)
f = join(self.resourceFolder, src)
if isfile(f):
shutil.copy(f, os.path.join(self.packageResourceFolder, dst))
elif isdir(f):
# special case for .rtfd and .lproj folders...
d = join(self.packageResourceFolder, dst)
os.mkdir(d)
files = GlobDirectoryWalker(f)
for file in files:
shutil.copy(file, d)
def _addSizes(self):
"Write .sizes file with info about number and size of files."
# Not sure if this is correct, but 'installedSize' and
# 'zippedSize' are now in Bytes. Maybe blocks are needed?
# Well, Installer.app doesn't seem to care anyway, saying
# the installation needs 100+ MB...
numFiles = 0
installedSize = 0
zippedSize = 0
files = GlobDirectoryWalker(self.sourceFolder)
for f in files:
numFiles = numFiles + 1
installedSize = installedSize + os.lstat(f)[6]
try:
zippedSize = os.stat(self.archPath+ ".gz")[6]
except OSError: # ignore error
pass
base = self.packageInfo["Title"] + ".sizes"
f = open(join(self.packageResourceFolder, base), "w")
format = "NumFiles %d\nInstalledSize %d\nCompressedSize %d\n"
f.write(format % (numFiles, installedSize, zippedSize))
# Shortcut function interface
def buildPackage(*args, **options):
"A Shortcut function for building a package."
o = options
title, version, desc = o["Title"], o["Version"], o["Description"]
pm = PackageMaker(title, version, desc)
apply(pm.build, list(args), options)
######################################################################
# Tests
######################################################################
def test0():
"Vanilla test for the distutils distribution."
pm = PackageMaker("distutils2", "1.0.2", "Python distutils package.")
pm.build("/Users/dinu/Desktop/distutils2")
def test1():
"Test for the reportlab distribution with modified options."
pm = PackageMaker("reportlab", "1.10",
"ReportLab's Open Source PDF toolkit.")
pm.build(root="/Users/dinu/Desktop/reportlab",
DefaultLocation="/Applications/ReportLab",
Relocatable="YES")
def test2():
"Shortcut test for the reportlab distribution with modified options."
buildPackage(
"/Users/dinu/Desktop/reportlab",
Title="reportlab",
Version="1.10",
Description="ReportLab's Open Source PDF toolkit.",
DefaultLocation="/Applications/ReportLab",
Relocatable="YES")
######################################################################
# Command-line interface
######################################################################
def printUsage():
"Print usage message."
format = "Usage: %s <opts1> [<opts2>] <root> [<resources>]"
print format % basename(sys.argv[0])
print
print " with arguments:"
print " (mandatory) root: the package root folder"
print " (optional) resources: the package resources folder"
print
print " and options:"
print " (mandatory) opts1:"
mandatoryKeys = string.split("Title Version Description", " ")
for k in mandatoryKeys:
print " --%s" % k
print " (optional) opts2: (with default values)"
pmDefaults = PackageMaker.packageInfoDefaults
optionalKeys = pmDefaults.keys()
for k in mandatoryKeys:
optionalKeys.remove(k)
optionalKeys.sort()
maxKeyLen = max(map(len, optionalKeys))
for k in optionalKeys:
format = " --%%s:%s %%s"
format = format % (" " * (maxKeyLen-len(k)))
print format % (k, repr(pmDefaults[k]))
def main():
"Command-line interface."
shortOpts = ""
keys = PackageMaker.packageInfoDefaults.keys()
longOpts = map(lambda k: k+"=", keys)
try:
opts, args = getopt.getopt(sys.argv[1:], shortOpts, longOpts)
except getopt.GetoptError, details:
print details
printUsage()
return
optsDict = {}
for k, v in opts:
optsDict[k[2:]] = v
ok = optsDict.keys()
if not (1 <= len(args) <= 2):
print "No argument given!"
elif not ("Title" in ok and \
"Version" in ok and \
"Description" in ok):
print "Missing mandatory option!"
else:
apply(buildPackage, args, optsDict)
return
printUsage()
# sample use:
# buildpkg.py --Title=distutils \
# --Version=1.0.2 \
# --Description="Python distutils package." \
# /Users/dinu/Desktop/distutils
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,816 @@
#! /usr/bin/env python
"""\
bundlebuilder.py -- Tools to assemble MacOS X (application) bundles.
This module contains two classes to build so called "bundles" for
MacOS X. BundleBuilder is a general tool, AppBuilder is a subclass
specialized in building application bundles.
[Bundle|App]Builder objects are instantiated with a bunch of keyword
arguments, and have a build() method that will do all the work. See
the class doc strings for a description of the constructor arguments.
The module contains a main program that can be used in two ways:
% python bundlebuilder.py [options] build
% python buildapp.py [options] build
Where "buildapp.py" is a user-supplied setup.py-like script following
this model:
from bundlebuilder import buildapp
buildapp(<lots-of-keyword-args>)
"""
__all__ = ["BundleBuilder", "BundleBuilderError", "AppBuilder", "buildapp"]
import sys
import os, errno, shutil
import imp, marshal
import re
from copy import deepcopy
import getopt
from plistlib import Plist
from types import FunctionType as function
class BundleBuilderError(Exception): pass
class Defaults:
"""Class attributes that don't start with an underscore and are
not functions or classmethods are (deep)copied to self.__dict__.
This allows for mutable default values.
"""
def __init__(self, **kwargs):
defaults = self._getDefaults()
defaults.update(kwargs)
self.__dict__.update(defaults)
def _getDefaults(cls):
defaults = {}
for name, value in cls.__dict__.items():
if name[0] != "_" and not isinstance(value,
(function, classmethod)):
defaults[name] = deepcopy(value)
for base in cls.__bases__:
if hasattr(base, "_getDefaults"):
defaults.update(base._getDefaults())
return defaults
_getDefaults = classmethod(_getDefaults)
class BundleBuilder(Defaults):
"""BundleBuilder is a barebones class for assembling bundles. It
knows nothing about executables or icons, it only copies files
and creates the PkgInfo and Info.plist files.
"""
# (Note that Defaults.__init__ (deep)copies these values to
# instance variables. Mutable defaults are therefore safe.)
# Name of the bundle, with or without extension.
name = None
# The property list ("plist")
plist = Plist(CFBundleDevelopmentRegion = "English",
CFBundleInfoDictionaryVersion = "6.0")
# The type of the bundle.
type = "BNDL"
# The creator code of the bundle.
creator = None
# List of files that have to be copied to <bundle>/Contents/Resources.
resources = []
# List of (src, dest) tuples; dest should be a path relative to the bundle
# (eg. "Contents/Resources/MyStuff/SomeFile.ext).
files = []
# List of shared libraries (dylibs, Frameworks) to bundle with the app
# will be placed in Contents/Frameworks
libs = []
# Directory where the bundle will be assembled.
builddir = "build"
# Make symlinks instead copying files. This is handy during debugging, but
# makes the bundle non-distributable.
symlink = 0
# Verbosity level.
verbosity = 1
def setup(self):
# XXX rethink self.name munging, this is brittle.
self.name, ext = os.path.splitext(self.name)
if not ext:
ext = ".bundle"
bundleextension = ext
# misc (derived) attributes
self.bundlepath = pathjoin(self.builddir, self.name + bundleextension)
plist = self.plist
plist.CFBundleName = self.name
plist.CFBundlePackageType = self.type
if self.creator is None:
if hasattr(plist, "CFBundleSignature"):
self.creator = plist.CFBundleSignature
else:
self.creator = "????"
plist.CFBundleSignature = self.creator
if not hasattr(plist, "CFBundleIdentifier"):
plist.CFBundleIdentifier = self.name
def build(self):
"""Build the bundle."""
builddir = self.builddir
if builddir and not os.path.exists(builddir):
os.mkdir(builddir)
self.message("Building %s" % repr(self.bundlepath), 1)
if os.path.exists(self.bundlepath):
shutil.rmtree(self.bundlepath)
os.mkdir(self.bundlepath)
self.preProcess()
self._copyFiles()
self._addMetaFiles()
self.postProcess()
self.message("Done.", 1)
def preProcess(self):
"""Hook for subclasses."""
pass
def postProcess(self):
"""Hook for subclasses."""
pass
def _addMetaFiles(self):
contents = pathjoin(self.bundlepath, "Contents")
makedirs(contents)
#
# Write Contents/PkgInfo
assert len(self.type) == len(self.creator) == 4, \
"type and creator must be 4-byte strings."
pkginfo = pathjoin(contents, "PkgInfo")
f = open(pkginfo, "wb")
f.write(self.type + self.creator)
f.close()
#
# Write Contents/Info.plist
infoplist = pathjoin(contents, "Info.plist")
self.plist.write(infoplist)
def _copyFiles(self):
files = self.files[:]
for path in self.resources:
files.append((path, pathjoin("Contents", "Resources",
os.path.basename(path))))
for path in self.libs:
files.append((path, pathjoin("Contents", "Frameworks",
os.path.basename(path))))
if self.symlink:
self.message("Making symbolic links", 1)
msg = "Making symlink from"
else:
self.message("Copying files", 1)
msg = "Copying"
files.sort()
for src, dst in files:
if os.path.isdir(src):
self.message("%s %s/ to %s/" % (msg, src, dst), 2)
else:
self.message("%s %s to %s" % (msg, src, dst), 2)
dst = pathjoin(self.bundlepath, dst)
if self.symlink:
symlink(src, dst, mkdirs=1)
else:
copy(src, dst, mkdirs=1)
def message(self, msg, level=0):
if level <= self.verbosity:
indent = ""
if level > 1:
indent = (level - 1) * " "
sys.stderr.write(indent + msg + "\n")
def report(self):
# XXX something decent
pass
if __debug__:
PYC_EXT = ".pyc"
else:
PYC_EXT = ".pyo"
MAGIC = imp.get_magic()
USE_ZIPIMPORT = "zipimport" in sys.builtin_module_names
# For standalone apps, we have our own minimal site.py. We don't need
# all the cruft of the real site.py.
SITE_PY = """\
import sys
del sys.path[1:] # sys.path[0] is Contents/Resources/
"""
if USE_ZIPIMPORT:
ZIP_ARCHIVE = "Modules.zip"
SITE_PY += "sys.path.append(sys.path[0] + '/%s')\n" % ZIP_ARCHIVE
def getPycData(fullname, code, ispkg):
if ispkg:
fullname += ".__init__"
path = fullname.replace(".", os.sep) + PYC_EXT
return path, MAGIC + '\0\0\0\0' + marshal.dumps(code)
SITE_CO = compile(SITE_PY, "<-bundlebuilder.py->", "exec")
#
# Extension modules can't be in the modules zip archive, so a placeholder
# is added instead, that loads the extension from a specified location.
#
EXT_LOADER = """\
def __load():
import imp, sys, os
for p in sys.path:
path = os.path.join(p, "%(filename)s")
if os.path.exists(path):
break
else:
assert 0, "file not found: %(filename)s"
mod = imp.load_dynamic("%(name)s", path)
__load()
del __load
"""
MAYMISS_MODULES = ['mac', 'os2', 'nt', 'ntpath', 'dos', 'dospath',
'win32api', 'ce', '_winreg', 'nturl2path', 'sitecustomize',
'org.python.core', 'riscos', 'riscosenviron', 'riscospath'
]
STRIP_EXEC = "/usr/bin/strip"
#
# We're using a stock interpreter to run the app, yet we need
# a way to pass the Python main program to the interpreter. The
# bootstrapping script fires up the interpreter with the right
# arguments. os.execve() is used as OSX doesn't like us to
# start a real new process. Also, the executable name must match
# the CFBundleExecutable value in the Info.plist, so we lie
# deliberately with argv[0]. The actual Python executable is
# passed in an environment variable so we can "repair"
# sys.executable later.
#
BOOTSTRAP_SCRIPT = """\
#!%(hashbang)s
import sys, os
execdir = os.path.dirname(sys.argv[0])
executable = os.path.join(execdir, "%(executable)s")
resdir = os.path.join(os.path.dirname(execdir), "Resources")
libdir = os.path.join(os.path.dirname(execdir), "Frameworks")
mainprogram = os.path.join(resdir, "%(mainprogram)s")
sys.argv.insert(1, mainprogram)
os.environ["PYTHONPATH"] = resdir
%(pythonhome)s
os.environ["PYTHONEXECUTABLE"] = executable
os.environ["DYLD_LIBRARY_PATH"] = libdir
os.execve(executable, sys.argv, os.environ)
"""
#
# Optional wrapper that converts "dropped files" into sys.argv values.
#
ARGV_EMULATOR = """\
import argvemulator, os
argvemulator.ArgvCollector().mainloop()
execfile(os.path.join(os.path.split(__file__)[0], "%(realmainprogram)s"))
"""
class AppBuilder(BundleBuilder):
# Override type of the bundle.
type = "APPL"
# platform, name of the subfolder of Contents that contains the executable.
platform = "MacOS"
# A Python main program. If this argument is given, the main
# executable in the bundle will be a small wrapper that invokes
# the main program. (XXX Discuss why.)
mainprogram = None
# The main executable. If a Python main program is specified
# the executable will be copied to Resources and be invoked
# by the wrapper program mentioned above. Otherwise it will
# simply be used as the main executable.
executable = None
# The name of the main nib, for Cocoa apps. *Must* be specified
# when building a Cocoa app.
nibname = None
# The name of the icon file to be copied to Resources and used for
# the Finder icon.
iconfile = None
# Symlink the executable instead of copying it.
symlink_exec = 0
# If True, build standalone app.
standalone = 0
# If True, add a real main program that emulates sys.argv before calling
# mainprogram
argv_emulation = 0
# The following attributes are only used when building a standalone app.
# Exclude these modules.
excludeModules = []
# Include these modules.
includeModules = []
# Include these packages.
includePackages = []
# Strip binaries.
strip = 0
# Found Python modules: [(name, codeobject, ispkg), ...]
pymodules = []
# Modules that modulefinder couldn't find:
missingModules = []
maybeMissingModules = []
# List of all binaries (executables or shared libs), for stripping purposes
binaries = []
def setup(self):
if self.standalone and self.mainprogram is None:
raise BundleBuilderError, ("must specify 'mainprogram' when "
"building a standalone application.")
if self.mainprogram is None and self.executable is None:
raise BundleBuilderError, ("must specify either or both of "
"'executable' and 'mainprogram'")
self.execdir = pathjoin("Contents", self.platform)
if self.name is not None:
pass
elif self.mainprogram is not None:
self.name = os.path.splitext(os.path.basename(self.mainprogram))[0]
elif executable is not None:
self.name = os.path.splitext(os.path.basename(self.executable))[0]
if self.name[-4:] != ".app":
self.name += ".app"
if self.executable is None:
if not self.standalone:
self.symlink_exec = 1
self.executable = sys.executable
if self.nibname:
self.plist.NSMainNibFile = self.nibname
if not hasattr(self.plist, "NSPrincipalClass"):
self.plist.NSPrincipalClass = "NSApplication"
BundleBuilder.setup(self)
self.plist.CFBundleExecutable = self.name
if self.standalone:
self.findDependencies()
def preProcess(self):
resdir = "Contents/Resources"
if self.executable is not None:
if self.mainprogram is None:
execname = self.name
else:
execname = os.path.basename(self.executable)
execpath = pathjoin(self.execdir, execname)
if not self.symlink_exec:
self.files.append((self.executable, execpath))
self.binaries.append(execpath)
self.execpath = execpath
if self.mainprogram is not None:
mainprogram = os.path.basename(self.mainprogram)
self.files.append((self.mainprogram, pathjoin(resdir, mainprogram)))
if self.argv_emulation:
# Change the main program, and create the helper main program (which
# does argv collection and then calls the real main).
# Also update the included modules (if we're creating a standalone
# program) and the plist
realmainprogram = mainprogram
mainprogram = '__argvemulator_' + mainprogram
resdirpath = pathjoin(self.bundlepath, resdir)
mainprogrampath = pathjoin(resdirpath, mainprogram)
makedirs(resdirpath)
open(mainprogrampath, "w").write(ARGV_EMULATOR % locals())
if self.standalone:
self.includeModules.append("argvemulator")
self.includeModules.append("os")
if not self.plist.has_key("CFBundleDocumentTypes"):
self.plist["CFBundleDocumentTypes"] = [
{ "CFBundleTypeOSTypes" : [
"****",
"fold",
"disk"],
"CFBundleTypeRole": "Viewer"}]
# Write bootstrap script
executable = os.path.basename(self.executable)
execdir = pathjoin(self.bundlepath, self.execdir)
bootstrappath = pathjoin(execdir, self.name)
makedirs(execdir)
if self.standalone:
# XXX we're screwed when the end user has deleted
# /usr/bin/python
hashbang = "/usr/bin/python"
pythonhome = 'os.environ["PYTHONHOME"] = resdir'
else:
hashbang = sys.executable
while os.path.islink(hashbang):
hashbang = os.readlink(hashbang)
pythonhome = ''
open(bootstrappath, "w").write(BOOTSTRAP_SCRIPT % locals())
os.chmod(bootstrappath, 0775)
if self.iconfile is not None:
iconbase = os.path.basename(self.iconfile)
self.plist.CFBundleIconFile = iconbase
self.files.append((self.iconfile, pathjoin(resdir, iconbase)))
def postProcess(self):
if self.standalone:
self.addPythonModules()
if self.strip and not self.symlink:
self.stripBinaries()
if self.symlink_exec and self.executable:
self.message("Symlinking executable %s to %s" % (self.executable,
self.execpath), 2)
dst = pathjoin(self.bundlepath, self.execpath)
makedirs(os.path.dirname(dst))
os.symlink(os.path.abspath(self.executable), dst)
if self.missingModules or self.maybeMissingModules:
self.reportMissing()
def addPythonModules(self):
self.message("Adding Python modules", 1)
if USE_ZIPIMPORT:
# Create a zip file containing all modules as pyc.
import zipfile
relpath = pathjoin("Contents", "Resources", ZIP_ARCHIVE)
abspath = pathjoin(self.bundlepath, relpath)
zf = zipfile.ZipFile(abspath, "w", zipfile.ZIP_DEFLATED)
for name, code, ispkg in self.pymodules:
self.message("Adding Python module %s" % name, 2)
path, pyc = getPycData(name, code, ispkg)
zf.writestr(path, pyc)
zf.close()
# add site.pyc
sitepath = pathjoin(self.bundlepath, "Contents", "Resources",
"site" + PYC_EXT)
writePyc(SITE_CO, sitepath)
else:
# Create individual .pyc files.
for name, code, ispkg in self.pymodules:
if ispkg:
name += ".__init__"
path = name.split(".")
path = pathjoin("Contents", "Resources", *path) + PYC_EXT
if ispkg:
self.message("Adding Python package %s" % path, 2)
else:
self.message("Adding Python module %s" % path, 2)
abspath = pathjoin(self.bundlepath, path)
makedirs(os.path.dirname(abspath))
writePyc(code, abspath)
def stripBinaries(self):
if not os.path.exists(STRIP_EXEC):
self.message("Error: can't strip binaries: no strip program at "
"%s" % STRIP_EXEC, 0)
else:
self.message("Stripping binaries", 1)
for relpath in self.binaries:
self.message("Stripping %s" % relpath, 2)
abspath = pathjoin(self.bundlepath, relpath)
assert not os.path.islink(abspath)
rv = os.system("%s -S \"%s\"" % (STRIP_EXEC, abspath))
def findDependencies(self):
self.message("Finding module dependencies", 1)
import modulefinder
mf = modulefinder.ModuleFinder(excludes=self.excludeModules)
if USE_ZIPIMPORT:
# zipimport imports zlib, must add it manually
mf.import_hook("zlib")
# manually add our own site.py
site = mf.add_module("site")
site.__code__ = SITE_CO
mf.scan_code(SITE_CO, site)
# warnings.py gets imported implicitly from C
mf.import_hook("warnings")
includeModules = self.includeModules[:]
for name in self.includePackages:
includeModules.extend(findPackageContents(name).keys())
for name in includeModules:
try:
mf.import_hook(name)
except ImportError:
self.missingModules.append(name)
mf.run_script(self.mainprogram)
modules = mf.modules.items()
modules.sort()
for name, mod in modules:
if mod.__file__ and mod.__code__ is None:
# C extension
path = mod.__file__
filename = os.path.basename(path)
if USE_ZIPIMPORT:
# Python modules are stored in a Zip archive, but put
# extensions in Contents/Resources/.a and add a tiny "loader"
# program in the Zip archive. Due to Thomas Heller.
dstpath = pathjoin("Contents", "Resources", filename)
source = EXT_LOADER % {"name": name, "filename": filename}
code = compile(source, "<dynloader for %s>" % name, "exec")
mod.__code__ = code
else:
# just copy the file
dstpath = name.split(".")[:-1] + [filename]
dstpath = pathjoin("Contents", "Resources", *dstpath)
self.files.append((path, dstpath))
self.binaries.append(dstpath)
if mod.__code__ is not None:
ispkg = mod.__path__ is not None
if not USE_ZIPIMPORT or name != "site":
# Our site.py is doing the bootstrapping, so we must
# include a real .pyc file if USE_ZIPIMPORT is True.
self.pymodules.append((name, mod.__code__, ispkg))
if hasattr(mf, "any_missing_maybe"):
missing, maybe = mf.any_missing_maybe()
else:
missing = mf.any_missing()
maybe = []
self.missingModules.extend(missing)
self.maybeMissingModules.extend(maybe)
def reportMissing(self):
missing = [name for name in self.missingModules
if name not in MAYMISS_MODULES]
if self.maybeMissingModules:
maybe = self.maybeMissingModules
else:
maybe = [name for name in missing if "." in name]
missing = [name for name in missing if "." not in name]
missing.sort()
maybe.sort()
if maybe:
self.message("Warning: couldn't find the following submodules:", 1)
self.message(" (Note that these could be false alarms -- "
"it's not always", 1)
self.message(" possible to distinguish between \"from package "
"import submodule\" ", 1)
self.message(" and \"from package import name\")", 1)
for name in maybe:
self.message(" ? " + name, 1)
if missing:
self.message("Warning: couldn't find the following modules:", 1)
for name in missing:
self.message(" ? " + name, 1)
def report(self):
# XXX something decent
import pprint
pprint.pprint(self.__dict__)
if self.standalone:
self.reportMissing()
#
# Utilities.
#
SUFFIXES = [_suf for _suf, _mode, _tp in imp.get_suffixes()]
identifierRE = re.compile(r"[_a-zA-z][_a-zA-Z0-9]*$")
def findPackageContents(name, searchpath=None):
head = name.split(".")[-1]
if identifierRE.match(head) is None:
return {}
try:
fp, path, (ext, mode, tp) = imp.find_module(head, searchpath)
except ImportError:
return {}
modules = {name: None}
if tp == imp.PKG_DIRECTORY and path:
files = os.listdir(path)
for sub in files:
sub, ext = os.path.splitext(sub)
fullname = name + "." + sub
if sub != "__init__" and fullname not in modules:
modules.update(findPackageContents(fullname, [path]))
return modules
def writePyc(code, path):
f = open(path, "wb")
f.write(MAGIC)
f.write("\0" * 4) # don't bother about a time stamp
marshal.dump(code, f)
f.close()
def copy(src, dst, mkdirs=0):
"""Copy a file or a directory."""
if mkdirs:
makedirs(os.path.dirname(dst))
if os.path.isdir(src):
shutil.copytree(src, dst)
else:
shutil.copy2(src, dst)
def copytodir(src, dstdir):
"""Copy a file or a directory to an existing directory."""
dst = pathjoin(dstdir, os.path.basename(src))
copy(src, dst)
def makedirs(dir):
"""Make all directories leading up to 'dir' including the leaf
directory. Don't moan if any path element already exists."""
try:
os.makedirs(dir)
except OSError, why:
if why.errno != errno.EEXIST:
raise
def symlink(src, dst, mkdirs=0):
"""Copy a file or a directory."""
if not os.path.exists(src):
raise IOError, "No such file or directory: '%s'" % src
if mkdirs:
makedirs(os.path.dirname(dst))
os.symlink(os.path.abspath(src), dst)
def pathjoin(*args):
"""Safe wrapper for os.path.join: asserts that all but the first
argument are relative paths."""
for seg in args[1:]:
assert seg[0] != "/"
return os.path.join(*args)
cmdline_doc = """\
Usage:
python bundlebuilder.py [options] command
python mybuildscript.py [options] command
Commands:
build build the application
report print a report
Options:
-b, --builddir=DIR the build directory; defaults to "build"
-n, --name=NAME application name
-r, --resource=FILE extra file or folder to be copied to Resources
-f, --file=SRC:DST extra file or folder to be copied into the bundle;
DST must be a path relative to the bundle root
-e, --executable=FILE the executable to be used
-m, --mainprogram=FILE the Python main program
-a, --argv add a wrapper main program to create sys.argv
-p, --plist=FILE .plist file (default: generate one)
--nib=NAME main nib name
-c, --creator=CCCC 4-char creator code (default: '????')
--iconfile=FILE filename of the icon (an .icns file) to be used
as the Finder icon
-l, --link symlink files/folder instead of copying them
--link-exec symlink the executable instead of copying it
--standalone build a standalone application, which is fully
independent of a Python installation
--lib=FILE shared library or framework to be copied into
the bundle
-x, --exclude=MODULE exclude module (with --standalone)
-i, --include=MODULE include module (with --standalone)
--package=PACKAGE include a whole package (with --standalone)
--strip strip binaries (remove debug info)
-v, --verbose increase verbosity level
-q, --quiet decrease verbosity level
-h, --help print this message
"""
def usage(msg=None):
if msg:
print msg
print cmdline_doc
sys.exit(1)
def main(builder=None):
if builder is None:
builder = AppBuilder(verbosity=1)
shortopts = "b:n:r:f:e:m:c:p:lx:i:hvqa"
longopts = ("builddir=", "name=", "resource=", "file=", "executable=",
"mainprogram=", "creator=", "nib=", "plist=", "link",
"link-exec", "help", "verbose", "quiet", "argv", "standalone",
"exclude=", "include=", "package=", "strip", "iconfile=",
"lib=")
try:
options, args = getopt.getopt(sys.argv[1:], shortopts, longopts)
except getopt.error:
usage()
for opt, arg in options:
if opt in ('-b', '--builddir'):
builder.builddir = arg
elif opt in ('-n', '--name'):
builder.name = arg
elif opt in ('-r', '--resource'):
builder.resources.append(arg)
elif opt in ('-f', '--file'):
srcdst = arg.split(':')
if len(srcdst) != 2:
usage("-f or --file argument must be two paths, "
"separated by a colon")
builder.files.append(srcdst)
elif opt in ('-e', '--executable'):
builder.executable = arg
elif opt in ('-m', '--mainprogram'):
builder.mainprogram = arg
elif opt in ('-a', '--argv'):
builder.argv_emulation = 1
elif opt in ('-c', '--creator'):
builder.creator = arg
elif opt == '--iconfile':
builder.iconfile = arg
elif opt == "--lib":
builder.libs.append(arg)
elif opt == "--nib":
builder.nibname = arg
elif opt in ('-p', '--plist'):
builder.plist = Plist.fromFile(arg)
elif opt in ('-l', '--link'):
builder.symlink = 1
elif opt == '--link-exec':
builder.symlink_exec = 1
elif opt in ('-h', '--help'):
usage()
elif opt in ('-v', '--verbose'):
builder.verbosity += 1
elif opt in ('-q', '--quiet'):
builder.verbosity -= 1
elif opt == '--standalone':
builder.standalone = 1
elif opt in ('-x', '--exclude'):
builder.excludeModules.append(arg)
elif opt in ('-i', '--include'):
builder.includeModules.append(arg)
elif opt == '--package':
builder.includePackages.append(arg)
elif opt == '--strip':
builder.strip = 1
if len(args) != 1:
usage("Must specify one command ('build', 'report' or 'help')")
command = args[0]
if command == "build":
builder.setup()
builder.build()
elif command == "report":
builder.setup()
builder.report()
elif command == "help":
usage()
else:
usage("Unknown command '%s'" % command)
def buildapp(**kwargs):
builder = AppBuilder(**kwargs)
main(builder)
if __name__ == "__main__":
main()

View File

@@ -1,283 +0,0 @@
#! /bin/csh -ef
#
# original script by Chris Roberts (The OS X Package Manager)
# slightly modified by Frank Vercruesse (mainly fixed quoting issues)
set prog = `/usr/bin/basename $0`
set usage = "Usage: $prog [-f] root-dir info-file [tiff-file] [-d dest-dir] [-r resource-dir] [-traditional | -gnutar]"
set noglob
if (-x /usr/bin/mkbom) then
set mkbom=/usr/bin/mkbom
set lsbom=/usr/bin/lsbom
else
set mkbom=/usr/etc/mkbom
set lsbom=/usr/etc/lsbom
endif
if (-x /usr/bin/awk) then
set awk=/usr/bin/awk
else
set awk=/bin/awk
endif
set gnutar=/usr/bin/gnutar
set tar=/usr/bin/tar
set pax=/bin/pax
# gather parameters
if ($#argv == 0) then
echo $usage
exit(1)
endif
while ( $#argv > 0 )
switch ( "$argv[1]" )
case -d:
if ( $?destDir ) then
echo ${prog}: dest-dir parameter already set to ${destDir}.
echo $usage
exit(1)
else if ( $#argv < 2 ) then
echo ${prog}: -d option requires destination directory.
echo $usage
exit(1)
else
set destDir = "$argv[2]"
shift; shift
breaksw
endif
case -f:
if ( $?rootDir ) then
echo ${prog}: root-dir parameter already set to ${rootDir}.
echo $usage
exit(1)
else if ( $#argv < 2 ) then
echo ${prog}: -f option requires package root directory.
echo $usage
exit(1)
else
set rootDir = "$argv[2]"
set fflag
shift; shift
breaksw
endif
case -r:
if ( $?resDir ) then
echo ${prog}: resource-dir parameter already set to ${resDir}.
echo $usage
exit(1)
else if ( $#argv < 2 ) then
echo ${prog}: -r option requires package resource directory.
echo $usage
exit(1)
else
set resDir = "$argv[2]"
shift; shift
breaksw
endif
case -traditional:
set usetar
unset usegnutar
unset usepax
shift
breaksw
case -gnutar:
set usegnutar
unset usepax
unset usetar
shift
breaksw
case -B:
# We got long file names, better use bigtar instead
#set archiver = /NextAdmin/Installer.app/Resources/installer_bigtar
#echo 2>&1 ${prog}: -B flag is longer relevant.
shift
breaksw
case -*:
echo ${prog}: Unknown option: $argv[1]
echo $usage
exit(1)
case *.info:
if ( $?info ) then
echo ${prog}: info-file parameter already set to ${info}.
echo $usage
exit(1)
else
set info = "$argv[1]"
shift
breaksw
endif
case *.tiff:
if ( $?tiff ) then
echo ${prog}: tiff-file parameter already set to ${tiff}.
echo $usage
exit(1)
else
set tiff = "$argv[1]"
shift
breaksw
endif
default:
if ( $?rootDir ) then
echo ${prog}: unrecognized parameter: $argv[1]
echo $usage
exit(1)
else
set rootDir = "$argv[1]"
shift
breaksw
endif
endsw
end
# check for mandatory parameters
if ( ! $?rootDir ) then
echo ${prog}: missing root-dir parameter.
echo $usage
exit(1)
else if ( ! $?info) then
echo ${prog}: missing info-file parameter.
echo $usage
exit(1)
endif
# destDir gets default value if unset on command line
if ( $?destDir ) then
/bin/mkdir -p "$destDir"
else
set destDir = .
endif
# derive the root name for the package from the root name of the info file
set root = `/usr/bin/basename $info .info`
# create package directory
set pkg = "${destDir}/${root}.pkg"
echo Generating Installer package $pkg ...
if ( -e "$pkg" ) /bin/rm -rf "$pkg"
/bin/mkdir -p -m 755 "$pkg"
/bin/mkdir -p -m 755 "$pkg/Contents"
/bin/mkdir -p -m 755 "$pkg/Contents/Resources"
/bin/mkdir -p -m 755 "$pkg/Contents/Resources/English.lproj/"
echo -n "pmkrpkg1" >"$pkg/Contents/PkgInfo"
chmod 755 "$pkg/Contents/PkgInfo"
# (gnu)tar/pax and compress root directory to package archive
echo -n " creating package archive ... "
if ( $?fflag ) then
set pkgTop = "${rootDir:t}"
set parent = "${rootDir:h}"
if ( "$parent" == "$pkgTop" ) set parent = "."
else
set parent = "$rootDir"
set pkgTop = .
endif
if ( $?usetar ) then
set pkgArchive = "$pkg/Contents/Resources/$root.tar.Z"
(cd "$parent"; $tar -w "$pkgTop") | /usr/bin/tar -f -c > "$pkgArchive"
else if ( $?usegnutar ) then
set pkgArchive = "$pkg/Contents/Resources/$root.tar.gz"
(cd "$parent"; $gnutar zcf "$pkgArchive" "$pkgTop")
else
set pkgArchive = "$pkg/Contents/Resources/$root.pax.gz"
(cd "$parent"; $pax -w -z -x cpio "$pkgTop") > "$pkgArchive"
endif
/bin/chmod 755 "$pkgArchive"
echo done.
# copy info file to package
set pkgInfo = "$pkg/Contents/Resources/English.lproj/$root.info"
echo -n " copying ${info:t} ... "
/bin/cp $info "$pkgInfo"
/bin/chmod 755 "$pkgInfo"
echo done.
# copy tiff file to package
if ( $?tiff ) then
set pkgTiff = "$pkg/$root.tiff"
echo -n " copying ${tiff:t} ... "
/bin/cp $tiff "$pkgTiff"
/bin/chmod 444 "$pkgTiff"
echo done.
endif
# copy resources to package
if ( $?resDir ) then
echo -n " copying ${resDir:t} ... "
# don't want to see push/pop output
pushd "$resDir" > /dev/null
# get lists of resources. We'll want to change
# permissions on just these things later.
set directoriesInResDir = `find . -type d`
set filesInResDir = `find . -type f`
popd > /dev/null
# copy the resource directory contents into the package directory
foreach resFile (`ls "$resDir"`)
cp -r "$resDir/$resFile" "$pkg/Contents/Resources"
end
pushd "$pkg/Contents/Resources" > /dev/null
# Change all directories to +r+x, except the package
# directory itself
foreach resFileItem ($directoriesInResDir)
if ( "$resFileItem" != "." ) then
chmod 755 $resFileItem
endif
end
# change all flat files to read only
foreach resFileItem ($filesInResDir)
if ( "$resFileItem" != "./.DS_Store" ) then
chmod 755 $resFileItem
endif
end
popd > /dev/null
echo done.
endif
# generate bom file
set pkgBom = "$pkg/Contents/Resources/$root.bom"
echo -n " generating bom file ... "
/bin/rm -f "$pkgBom"
if ( $?fflag ) then
$mkbom "$parent" "$pkgBom" >& /dev/null
else
$mkbom "$rootDir" "$pkgBom" >& /dev/null
endif
/bin/chmod 444 "$pkgArchive"
echo done.
# generate sizes file
set pkgSizes = "$pkg/Contents/Resources/$root.sizes"
echo -n " generating sizes file ... "
# compute number of files in package
set numFiles = `$lsbom -s "$pkgBom" | /usr/bin/wc -l`
# compute package size when compressed
@ compressedSize = `/usr/bin/du -k -s "$pkg" | $awk '{print $1}'`
@ compressedSize += 3 # add 1KB each for sizes, location, status files
@ infoSize = `/bin/ls -s "$pkgInfo" | $awk '{print $1}'`
@ bomSize = `/bin/ls -s "$pkgBom" | $awk '{print $1}'`
if ( $?tiff ) then
@ tiffSize = `/bin/ls -s "$pkgTiff" | $awk '{print $1}'`
else
@ tiffSize = 0
endif
@ installedSize = `/usr/bin/du -k -s "$rootDir" | $awk '{print $1}'`
@ installedSize += $infoSize + $bomSize + $tiffSize + 3
# echo size parameters to sizes file
echo NumFiles $numFiles > "$pkgSizes"
echo InstalledSize $installedSize >> "$pkgSizes"
echo CompressedSize $compressedSize >> "$pkgSizes"
echo done.
echo " ... finished generating $pkg."
exit(0)
# end package

View File

@@ -1,2 +0,0 @@
You will be guided through the steps necessary to install wxPython 2.3.3pre (including wxMac) for MachoPython 2.2.x on Mac OS X 10.1 or later.

View File

@@ -1,11 +0,0 @@
#!/bin/sh
/usr/bin/sudo -u $USER /bin/rm -rf \
$2/Library/Frameworks/Python.framework/Versions/2.2/lib/python2.2/site-packages/wxPython \
# $2/usr/local/bin/wx* \
# $2/usr/local/include/wx \
# $2/usr/local/lib/wx \
# $2/usr/local/lib/libwx*
exit 0

View File

@@ -1,25 +0,0 @@
{\rtf1\mac\ansicpg10000\cocoartf100
{\fonttbl\f0\fnil\fcharset77 Monaco;}
{\colortbl;\red255\green255\blue255;}
\margl1440\margr1440\vieww15640\viewh10560\viewkind0
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f0\fs24 \cf0 PSF LICENSE AGREEMENT FOR PYTHON 2.2.1\
--------------------------------------\
\
1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 2.2.1 software in source or binary form and its associated documentation.\
\
2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 2.2.1 alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002 Python Software Foundation; All Rights Reserved" are retained in Python 2.2.1 alone or in any derivative version prepared by Licensee.\
\
3. In the event Licensee prepares a derivative work that is based on or incorporates Python 2.2.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 2.2.1.\
\
4. PSF is making Python 2.2.1 available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.2.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.\
\
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.2.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.2.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.\
\
6. This License Agreement will automatically terminate upon a material breach of its terms and conditions.\
\
7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party.\
\
8. By copying, installing or otherwise using Python 2.2.1, Licensee agrees to be bound by the terms and conditions of this License Agreement.\
}

View File

@@ -1,91 +0,0 @@
{\rtf1\mac\ansicpg10000\cocoartf100
{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;\f2\fnil\fcharset77 Monaco;
}
{\colortbl;\red255\green255\blue255;\red0\green0\blue255;}
\margl1440\margr1440\vieww10820\viewh9000\viewkind0
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f0\b\fs24 \cf0 About\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f1\b0 \cf0 \
This is a Mach-O binary package of Python 2.2.1 (a.k.a. MachoPython) for Mac OS X 10.1 or later. \
\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f0\b \cf0 What files will be installed and where?\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f1\b0 \cf0 \
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f2 \cf0 /Applications\
\
+ Python.app
\fs20 (a double-clickable interpreter)\
\
\fs24 /Library/Frameworks\
\
+ Python.framework
\fs20 (library, headers, tools, etc.)\
\
\fs24 /usr/local/bin\
\
+ pydoc
\fs20 (symbolic link to the pydoc script)
\fs24 \
+ python
\fs20 (symbolic link to the actual binary inside the framework)\
\fs24 + python2.2
\fs20 (symbolic link to the actual binary inside the framework)\
\fs24 + pythonw
\fs20 (a script that can run a GUI app from the command line)\
\f1\fs24 \
\
\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f0\b \cf0 Getting started with Python
\f1\b0 \
\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f2 \cf2 http://www.python.org\cf0 \
\cf2 \
http://www.python.org/sigs/pythonmac-sig\cf0 \
\cf2 \
http://www.cwi.nl/~jack/macpython.html
\f1 \cf0 \
\
\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f0\b \cf0 Credits\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f1\b0 \cf0 \
Python itself is\
\
Copyright (c) 2001, 2002 Python Software Foundation; All Rights Reserved\
\
This binary package was compiled using the build instructions from Jack Jansen and Tony Lownds as found on the net.\
\
\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f0\b \cf0 Disclaimer
\f1\b0 \
\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f2 \cf0 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\f1 \
\
\
Packaged by Robin Dunn\
}

View File

@@ -1,2 +0,0 @@
Mach-O Python 2.2.1 binary package for Mac OS X 10.1 or later.

View File

@@ -1,15 +0,0 @@
Title wxPythonOSX
Version 2.3.3
Description wxMac and wxPython for OSX
DefaultLocation /
DeleteWarning
### Package Flags
NeedsAuthorization YES
Required NO
Relocatable NO
RequiresReboot NO
UseUserMask NO
OverwritePermissions NO
InstallFat NO

View File

@@ -0,0 +1 @@
.DS_Store

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,390 @@
#!/bin/sh -e
#----------------------------------------------------------------------
# Build wxMac and wxPythonOSX from the tarball and then make an
# Installer package out of it.
spectemplate=distrib/wxPythonFull.spec.in
if [ ! -d wxPython -o ! -e ${spectemplate} ]; then
echo "Please run this script from the root wxPython directory."
exit 1
fi
#----------------------------------------------------------------------
# Check Parameters
function usage {
echo ""
echo "Usage: $0 wx_version py_version [command flags...]"
echo " wx_version String to use for version in filenames, etc."
echo " py_version String to append to python (which python version to use.)"
echo ""
echo "command flags:"
echo " skiptar Don't unpack the tarball"
echo " use_cvs Use the CVS workspace instead of a tarfile"
echo " skipconfig Don't run configure"
echo " skipbuild Don't build wxWindows or wxPython"
echo " skipinstall Don't do the installation step"
echo " skipdmg Don't make the package or diskimage"
echo " skipclean Don't do the cleanup at the end"
}
if [ $# -lt 2 ]; then
usage
exit 1
fi
VERSION=$1
PYVER=$2
shift;shift
for flag in $*; do
case ${flag} in
skiptar) skiptar=1 ;;
use_cvs) skiptar=1; use_cvs=1 ;;
skipconfig) skipconfig=1; skiptar=1 ;;
skipbuild) skipbuild=1; skipconfig=1; skiptar=1 ;;
skipinstall) skipinstall=1 ;;
skipdmg) skipdmg=1 ;;
skipclean) skipclean=1 ;;
*) echo "Unknown flag \"${flag}\""
usage
exit 1
esac
done
SRCDIR=/Volumes/Gate.Stuff/Development/wxPython/dist/$VERSION
TARBALL=$SRCDIR/wxPythonSrc-$VERSION.tar.gz
SITEPACKAGES=/Library/Frameworks/Python.framework/Versions/$PYVER/lib/python$PYVER/site-packages
# TODO: Should I change the prefix to /usr?
PREFIX=/usr/local
PROGDIR="`dirname \"$0\"`"
TMPDIR=$PWD/_build_dmg
BUILDROOT=$TMPDIR/build
INSTALLROOT=$TMPDIR/install
INSTALLDEVEL=$TMPDIR/install-devel
DMGDIR=$TMPDIR/dmg
RESOURCEDIR=$PROGDIR/resources
DESTDIR=$PWD/dist
#----------------------------------------------------------------------
# Setup builddirs
mkdir -p $BUILDROOT
mkdir -p $INSTALLROOT
mkdir -p $INSTALLDEVEL
rm -rf $DMGDIR
mkdir -p $DMGDIR/root
pushd $BUILDROOT
#----------------------------------------------------------------------
# Unpack the tarball
if [ -z "$skiptar" ]; then
tar xzvf $TARBALL
fi
if [ "$use_cvs" = 1 ]; then
# copy the cvs workspace, except for build dirs
mkdir -p wxPythonSrc-$VERSION
echo Finding updated files...
if [ -e .last_copy ]; then
FEXPR="-cnewer .last_copy"
fi
find /projects/wx $FEXPR -print \
| grep -v wx/build \
| grep -v wxPython/build \
| grep -v wxPython/_build \
| grep -v CVS \
| cut -b 14- > filelist
for x in `cat filelist`; do
if [ -d "/projects/wx/$x" ]; then
mkdir -p "wxPythonSrc-$VERSION/$x"
else
echo $x
cp -p "/projects/wx/$x" "wxPythonSrc-$VERSION/$x"
fi
done
touch .last_copy
fi
cd wxPythonSrc-$VERSION
WXDIR=`pwd`
mkdir -p $WXDIR/build
cd $WXDIR/build
#----------------------------------------------------------------------
# Configure wxWindows
if [ -z "$skipconfig" ]; then
../configure --with-mac --prefix=$PREFIX \
--with-opengl \
--enable-precomp=no \
--enable-geometry \
--enable-optimise \
--enable-debug_flag \
--with-libjpeg=builtin \
--with-libpng=builtin \
--with-libtiff=builtin \
--with-zlib=builtin
fi
# Build wxWindows and wxPython
if [ -z "$skipbuild" ]; then
make
cd $WXDIR/wxPython
python$PYVER setup.py \
IN_CVS_TREE=1 \
WX_CONFIG="$WXDIR/build/wx-config --prefix=$WXDIR --exec-prefix=$WXDIR/build" \
build
# Build wxrc (XRC resource tool) but don't use the makefiles since they expect
# a shared version of the xrc lib to have been built...
cd $WXDIR/contrib/utils/wxrc
WX_CONFIG="$WXDIR/build/wx-config --prefix=$WXDIR --exec-prefix=$WXDIR/build"
wCC=`$WX_CONFIG --cc`
wCXX=`$WX_CONFIG --cxx`
for f in wxrc.cpp ../../src/xrc/*.cpp; do
echo $f
$wCXX `$WX_CONFIG --cxxflags` -I ../../include -I ../../src/xrc/expat/xmlparse -I ../../src/xrc/expat/xmltok -c $f
done
for f in ../../src/xrc/expat/xmlparse/xmlparse.c ../../src/xrc/expat/xmltok/xmlrole.c ../../src/xrc/expat/xmltok/xmltok.c; do
echo $f
$wCC `$WX_CONFIG --cxxflags` -I ../../include -I ../../src/xrc/expat/xmlparse -I ../../src/xrc/expat/xmltok -c $f
done
# the handlers are not needed
rm xh_*.o xmlrsall.o
$wCXX `$WX_CONFIG --libs` *.o -o wxrc
strip wxrc
fi
#----------------------------------------------------------------------
# Install wxWindows
if [ -z "$skipinstall" ]; then
cd $WXDIR/build
make prefix=$INSTALLROOT/$PREFIX install
# and wxPython
cd $WXDIR/wxPython
python$PYVER setup.py \
IN_CVS_TREE=1 \
WX_CONFIG="$WXDIR/build/wx-config --prefix=$WXDIR --exec-prefix=$WXDIR/build" \
install \
--root=$INSTALLROOT
# install wxPython's tool scripts
cd $WXDIR/wxPython/scripts
python$PYVER CreateMacScripts.py $INSTALLROOT $PREFIX/bin
# Install wxrc
cp $WXDIR/contrib/utils/wxrc/wxrc $INSTALLROOT$PREFIX/bin
# Move wxWindows devel files and save for a separate installer package
mkdir -p $INSTALLDEVEL$PREFIX
mkdir -p $INSTALLDEVEL$PREFIX/bin
mkdir -p $INSTALLDEVEL$PREFIX/lib
mv -f $INSTALLROOT$PREFIX/include $INSTALLDEVEL$PREFIX
mv -f $INSTALLROOT$PREFIX/lib/wx $INSTALLDEVEL$PREFIX/lib
mv -f $INSTALLROOT$PREFIX/bin/wx* $INSTALLDEVEL$PREFIX/bin
fi
popd
#----------------------------------------------------------------------
# Make the Installer packages and disk image
if [ -z "$skipdmg" ]; then
# Remove the .pyc/.pyo files they just take up space and can be recreated
# during the install.
python $PROGDIR/../zappycfiles.py $INSTALLROOT/Library/Frameworks/Python.framework
# Copy the demo, samples, and such to the Applications dir
APPDIR=$INSTALLROOT/Applications/wxPythonOSX-$VERSION
mkdir -p $APPDIR
cp -pR $WXDIR/wxPython/demo $APPDIR
cp -pR $WXDIR/wxPython/samples $APPDIR
# Move sample launchers to .pyw files.
# TODO: A better, more automated way to do this!!!
pushd $APPDIR/samples
for x in StyleEditor/STCStyleEditor \
doodle/superdoodle \
frogedit/FrogEdit \
pySketch/pySketch \
wxProject/wxProject; do
mv $x.py $x.pyw
done
popd
# Make an app to launch the demo
cat > $APPDIR/demo/RunDemo.pyw <<EOF
import sys, os
sys.path.insert(0, "/Applications/wxPythonOSX-$VERSION/demo")
os.chdir("/Applications/wxPythonOSX-$VERSION/demo")
import Main
Main.main()
EOF
pythonw $PROGDIR/../buildapp.py \
--builddir=$APPDIR \
--name=RunDemo \
--mainprogram=$APPDIR/demo/RunDemo.pyw \
--iconfile=$PROGDIR/RunDemo.icns \
build
# Make an app to launch PyShell
pythonw $PROGDIR/../buildapp.py \
--builddir=$APPDIR \
--name=PyShell \
--mainprogram=$INSTALLROOT$PREFIX/bin/pyshell.py \
--iconfile=$PROGDIR/PieShell.icns \
build
# Make an app to launch XRCed
pythonw $PROGDIR/../buildapp.py \
--builddir=$APPDIR \
--name=XRCed \
--mainprogram=$INSTALLROOT$PREFIX/bin/xrced.py \
--iconfile=$PROGDIR/XRCed.icns \
build
# Make the welcome message
cat > $RESOURCEDIR/Welcome.txt <<EOF
Welcome!
This program will install wxPython $VERSION for MacPython-OSX $PYVER.
Build date: `date`
EOF
# make the preflight script
cat > $RESOURCEDIR/preflight <<EOF
#!/bin/sh
# Cleanup any old install of the wxPython package
rm -rf \$2$SITEPACKAGES/wxPython
exit 0
EOF
chmod +x $RESOURCEDIR/preflight
# make the postflight script
cat > $RESOURCEDIR/postflight <<EOF
#!/bin/sh -e
# Compile the .py files in the wxPython pacakge
/usr/local/bin/python \$2$SITEPACKAGES/../compileall.py \$2$SITEPACKAGES/wxPython
/usr/local/bin/python -O \$2$SITEPACKAGES/../compileall.py \$2$SITEPACKAGES/wxPython
# and in the demo
/usr/local/bin/python \$2$SITEPACKAGES/../compileall.py /Applications/wxPythonOSX-$VERSION/demo
# Make the demo/data dir writable
chmod a+w /Applications/wxPythonOSX-$VERSION/demo/data
# and the wxPython pacakge should be group writable
chgrp -R admin \$2$SITEPACKAGES/wxPython
chgrp -R admin /Applications/wxPythonOSX-$VERSION
chmod -R g+w \$2$SITEPACKAGES/wxPython
chmod -R g+w /Applications/wxPythonOSX-$VERSION
exit 0
EOF
chmod +x $RESOURCEDIR/postflight
# Finally, build the main package...
rm -rf wxPythonOSX.pkg
python $PROGDIR/../buildpkg.py \
--Title=wxPythonOSX \
--Version=$VERSION \
--Description="wxPython $VERSION for MacPython-OSX $PYVER" \
--NeedsAuthorization="YES" \
--Relocatable="NO" \
--InstallOnly="YES" \
$INSTALLROOT \
$RESOURCEDIR
mv wxPythonOSX.pkg $DMGDIR/root
# and the devel package
rm -rf wxPythonOSX-devel.pkg
python $PROGDIR/../buildpkg.py \
--Title=wxPythonOSX-devel \
--Version=$VERSION \
--Description="Headers and such that allow you to link with the same wxMac that wxPython does" \
--NeedsAuthorization="YES" \
--Relocatable="NO" \
--InstallOnly="YES" \
$INSTALLROOT
mv wxPythonOSX-devel.pkg $DMGDIR/root
# Make a README.txt to go on the disk image
cat > $DMGDIR/root/README.txt <<EOF
The files on this disk image are Installer packages for wxPythonOSX
$VERSION for MacPython-OSX $PVER. You must already have MacPython-OSX
installed.
The wxPython extension modules, library, demo and samples are
contained in the wxPythonOSX package. You should install at least this
package to use wxPython.
If you have any need to create applicaitons or extension modules that
link with the same wxMac that wxPython does, then you can also install
the wxPythonOSX-devel package to get the necessary header files and
such. Otherwise you don't need it.
Happy Hacking!
EOF
# license files, etc.
cp -pR $WXDIR/wxPython/licence $DMGDIR/root
cp $WXDIR/wxPython/CHANGES.txt $DMGDIR/root
# and then finally make a disk image containing the packages and etc.
$PROGDIR/../makedmg $DMGDIR/root $DMGDIR wxPythonOSX-$VERSION-py$PYVER
echo Moving $DMGDIR/wxPythonOSX-$VERSION-py$PYVER.dmg to $DESTDIR
mv $DMGDIR/wxPythonOSX-$VERSION-py$PYVER.dmg $DESTDIR
fi
# Cleanup build/install dirs
if [ -z "$skipclean" ]; then
echo "Cleaning up..."
rm -rf $TMPDIR
else
echo "Cleanup is disabled. You should remove $TMPDIR when finished"
fi

View File

@@ -1,17 +1,17 @@
{\rtf1\mac\ansicpg10000\cocoartf100
{\rtf1\mac\ansicpg10000\cocoartf102
{\fonttbl\f0\fswiss\fcharset77 Helvetica-Bold;\f1\fswiss\fcharset77 Helvetica;\f2\fnil\fcharset77 Monaco;
\f3\fnil\fcharset77 LucidaGrande;}
{\colortbl;\red255\green255\blue255;\red0\green0\blue255;}
\margl1440\margr1440\vieww10820\viewh9000\viewkind0
\margl1440\margr1440\vieww11800\viewh14740\viewkind0
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f0\b\fs24 \cf0 About\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f1\b0 \cf0 \
This is a binary package of wxPython for MachoPython 2.2.x on Mac OS X 10.1 or later. The wxMac binaries will be installed as well. MachoPython, however, is not included with this package, but is also required to run wxPython. Before you continue you should have already installed the MachoPython framework.\
This is a binary package of wxPython for MacPython on Mac OS X 10.2 or later. The wxMac binaries will be installed as well. MacPython-OSX, however, is not included with this package, but is also required to run wxPython. Before you continue you should have already installed the MacPython-OSX framework.\
\
Please note that the Mac OS ports of wxPython as well as wxWindows (a.k.a. wxMac) are works-in-progress. Report bugs via SourceForge [1] or discuss the problem on the mailing list(s) in question (see below).\
Please note that the Mac OS ports of wxPython as well as wxWindows (a.k.a. wxMac) are works-in-progress. Report bugs via SourceForge [1] or discuss the problem on the mailing list(s) related to your questions (see below).\
\
\fs18 [1] \cf2 http://sf.net/tracker/?atid=109863&group_id=9863
@@ -24,11 +24,11 @@ Please note that the Mac OS ports of wxPython as well as wxWindows (a.k.a. wxMac
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f1\b0 \cf0 \
wxMac goes into
wxMac goes into
\f2 /usr/local
\f1 and wxPython will be installed into the appropriate subfolder of the Python framework. Choose the
\f1 and wxPython will be installed into the appropriate subfolder of the Python framework. Choose the
\f3 Show files
\f1 command from the
\f1 command from the
\f3 File
\f1 menu for a complete file listing. (The menu item becomes available as soon as the license agreement is accepted in the next step.)
\f2 \
@@ -40,9 +40,9 @@ wxMac goes into
\f0\b \cf0 Getting started with wxPython
\f1\b0 \
\
You can verify that wxPython was succesfully installed by running the demo. It resides on the same disk image where you found this package. Just double click the script named
You can verify that wxPython was succesfully installed by running the demo. It resides on the same disk image where you found this package. Just double click the script named
\f2 demo.py
\f1 or drag and drop it onto the Python interpreter in your
\f1 or drag and drop it onto the Python interpreter in your
\f2 Application
\f1 folder.\
\
@@ -50,24 +50,19 @@ The official wxPython site:\
\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f2 \cf2 http://www.wxpython.org\cf0 \
\f2 \cf2 http://wxPython.org\cf0 \
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f1 \cf0 \
Some mailing lists you may want to subscribe to:\
The best way to get help with wxWindows and wxPython is to subscribe to the mail lists and post questions there. You can see info about the mail lists, including how to subscribe, at this website:\
\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f2 \cf2 http://lists.wxwindows.org/mailman/listinfo/wxpython-users\
\f2 \cf2 http://wxPython.org/maillist.php\
\
http://lists.wxwindows.org/mailman/listinfo/wxpython-mac\
\
http://lists.wxwindows.org/mailman/listinfo/wx-users\
\
http://lists.wxwindows.org/mailman/listinfo/wx-dev
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f1 \cf0 \
\
\
\pard\tx1440\tx2880\tx4320\tx5760\tx7200\ql\qnatural
\f0\b \cf0 Disclaimer
@@ -80,5 +75,5 @@ Some mailing lists you may want to subscribe to:\
\
\
Robin Dunn\
Frank Vercruesse\
\
}

View File

@@ -0,0 +1,5 @@
Welcome!
This program will install wxPython 2.4.0.7 for MacPython-OSX 2.3.
Build date: Fri Mar 21 14:00:06 PST 2003

View File

@@ -0,0 +1,18 @@
#!/bin/sh -e
# Compile the .py files in the wxPython pacakge
/usr/local/bin/python $2/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/../compileall.py $2/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/wxPython
/usr/local/bin/python -O $2/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/../compileall.py $2/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/wxPython
# and in the demo
/usr/local/bin/python $2/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/../compileall.py /Applications/wxPythonOSX-2.4.0.7/demo
# Make the demo/data dir writable
chmod a+w /Applications/wxPythonOSX-2.4.0.7/demo/data
# and the wxPython pacakge should be group writable
chgrp -R admin $2/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/wxPython
chgrp -R admin /Applications/wxPythonOSX-2.4.0.7
chmod -R g+w $2/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/wxPython
chmod -R g+w /Applications/wxPythonOSX-2.4.0.7
exit 0

View File

@@ -0,0 +1,4 @@
#!/bin/sh
# Cleanup any old install of the wxPython package
rm -rf $2/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/site-packages/wxPython
exit 0

View File

@@ -0,0 +1,38 @@
#!/usr/local/bin/python
"""Recursively zap all .pyc and .pyo files"""
import os
import sys
# set doit true to actually delete files
# set doit false to just print what would be deleted
doit = 1
def main():
if not sys.argv[1:]:
if os.name == 'mac':
import macfs
fss, ok = macfs.GetDirectory('Directory to zap pyc files in')
if not ok:
sys.exit(0)
dir = fss.as_pathname()
zappyc(dir)
else:
print 'Usage: zappyc dir ...'
sys.exit(1)
for dir in sys.argv[1:]:
zappyc(dir)
def zappyc(dir):
os.path.walk(dir, walker, None)
def walker(dummy, top, names):
for name in names:
if name[-4:] in ('.pyc', '.pyo'):
path = os.path.join(top, name)
print 'Zapping', path
if doit:
os.unlink(path)
if __name__ == '__main__':
main()