Commit b21b1d6b authored by Tim Peters's avatar Tim Peters

Merge tim-2.9-windows-installer branch.

This is the code used to build the Zope 2.9.0 Windows installer.

It bundles Python 2.4.2, lives in peace with zpkgtools, moves
to InnoSetup 5, and simplifies most parts of the build-the-
installer process.
parents 1a3f6448 5d1319ae
Quick instructions:
The buildout has been tested under Windows 2K and XP Pro SP2. It "almost
works" on Win98SE (see bottom of file for discussion).
The buildout has been tested under Windows 2K and XP Pro SP2.
Setup Environment
------------------
Install Python 2.4.2 (or whatever is most current) by running its native
Windows installer from python.org.
Note: Python 2.4 switched from using a Wise installer to using a
Microsoft .msi installer, and the latter is harder to work with. The
buildout used to extract Python source and binaries (.exe, .pyd, .dll)
from the Wise installer (which could be treated much like a zip file).
Now the Python installer isn't used at all. Instead, the Python
source is taken from the Python tarball release, and the binaries are
copied from your installed Python.
Install Cygwin from cygwin.org (the default installation should give
you everything you need).
Install Microsoft Visual C++ 6.0 (or MSVC 7 once we get to Python 2.4)
Install Microsoft Visual C++ 7.1 (aka Visual Studio .NET 2003). This is
needed to compile Zope's Python C extensions compatible with Python 2.4
(and 2.5, when that's released).
Install InnoSetup 4.2 from www.jrsofware.org (into its default location).
Versions earlier than 4.0.11 are known to not work; any 4.2.x release
or later should be fine. Inno 5.x versions do *not* work (it appears the
Inno "custom dialog" mechanism has changed in an incompatible way)
Install InnoSetup 5.1.5 (or later) from www.jrsoftware.org, into its
default location. Inno 4.x (or earlier) cannot work: Inno 5 introduced a
vastly simpler way to create the custom dialog pages we want.
'svn switch' to, or check out, the Zope tag for which an installer is to be
built. You want a native Windows checkout here, so that the text files have
Windows-appropriate line ends.
built.
Within a Zope checkout, parent directory of this package is inst. Make a
"tmp" directory, inst/tmp. Place the necessary pre-requisites in the tmp
directory. At the time of this writing, this includes:
Within a Zope checkout, the parent directory of this package is inst. Make
a "tmp" directory, inst/tmp. Place the necessary pre-requisites in the tmp
directory. At the time of this writing, these are:
- Python-2.3.5.tgz
- Python-2.3.5.exe (used for binary modules)
- pywin32-205.win32-py2.3.exe (extracts binaries and sources)
- Zope.tgz
- Python-2.4.2.tgz
- pywin32-205.win32-py2.4.exe
- Zope-2.9.0.tgz
As time marches on, these version numbers will obviously change. See/edit
mk/python.mk and mk/zope.mk for the exact versions required.
You also need to install the same Windows Python that Zope will repackage.
There doesn't appear to be a sane way to extract binaries (.exe, .pyd,
.dll, .lib) from an .msi installer, and building Python from source is a long
& messy process on Windows. So python.mk just copies them from an installed
Python instead. Cautions:
- If you didn't accept the Python installer's default directory, or if
you did but it's on a different drive, you'll need to change
WIN_PYINSTALLEDDIR in python.mk.
- The main Python DLL must live in WIN_PYINSTALLEDDIR too. Depending on
how you installed Python, that may be sitting in some Windows system
directory instead; if so, make a copy in the root of your Python
installation.
Building
--------
......@@ -85,21 +109,44 @@ now required, or the files you've downloaded are not in 'tmp'.
Testing Zope
------------
The test suite can be run from inst\build\:
XXX This doesn't work right starting with Zope 2.9: it's clumsier than it
XXX should be, and the functional tests don't even try to run (just the
XXX unit tests).
XXX Someone who understands how Zope3 testing from a zpkgtools-tarball build
XXX was made to work again may be able to help here.
The test suite can be run from inst\build\, after building the installer.
- Open a native (not Cygwin) DOS box. We want to test with the Python the
Zope installer includes.
- cd to inst\build
- Copy log.ini from the root of the Zope checkout. This isn't necessary for
the tests to pass, but if you don't do it a great many spurious log
messages will be displayed on the console, some of which "look like"
errors (some of the tests deliberately provoke errors).
- Enter
Zope installer includes, in an all-native environment, to match what
the installer-installed code will do as closely as possible.
- cd inst\build
- Copy log.ini from the root of the Zope _checkout_ -- it's not included
in the tarball::
bin\python bin\test.py -v --all
copy ..\..\log.ini .
Copying log.ini isn't necessary for the tests to pass, but if you don't
do it a great many spurious log messages will be displayed on the
console, some of which "look like" errors (some of the tests deliberately
provoke errors).
- Copy test.py from the unpacked tarball::
copy ..\src\$(ZOPE_VERSION)\test.py .
- Enter::
bin\python test.py -vv -m "!^zope[.]app[.]" --all
or whatever variation you like best. All tests should pass.
Note that zope.app tests should be excluded because not all of them _can_
pass (this isn't "a Windows thing", it's a temporary all-platform wart
due to missing bits from Zope3).
Also run the Windows installer, and play with the Zope it installs.
......@@ -116,24 +163,3 @@ All platform notes
root of your Cygwin installation -- the same thing the Cygwin shell
desktop shortcut resolves to, so you can get the exact path by looking
at the icon's Properties).
Win98SE notes
-------------
- Every time a makefile runs xcopy, there's a segfault in kernel32.dll,
which hangs the bash shell with an endless succession of error boxes.
The only way I found to break out of this was to bring up the debugger,
close it, then type Ctrl+C at the hung bash shell. The bash shell
appears to be fine at that point, but you can never close it (short of
killing it via the task manager).
Same thing if xcopy32 is used instead.
xcopy works OK directly from a bash shell. The segfaults occur if it's
run via a makefile, or via a shell script. Guessing a problem with I/O
redirection, since some other apps can't see keyboard input before the
hung stuff is killed.
Workaround: xxcopy works fine <http://www.xxcopy.com/>; free for
personal use, but not for commercial use. Rename it to xcopy.exe and
get it into your path before the native xcopy, or fiddle the XCOPY
defn in common.mk to use xxcopy instead of xcopy.
cd %1%
set MAKEFLAGS=
nmake build
nmake install
......@@ -8,9 +8,13 @@ AppUpdatesURL=http://www.zope.org
DefaultDirName={pf}\Zope-<<VERSION>>
DefaultGroupName=Zope <<VERSION>>
OutputBaseFilename=Zope-<<VERSION>>-win32
SolidCompression=yes
WizardImageFile=<<MAKEFILEDIR>>\etc\zlogo_left.bmp
WizardSmallImageFile=<<MAKEFILEDIR>>\etc\zlogo_top.bmp
SolidCompression=yes
; Starting w/ Inno 4.1.3, Inno decided to stretch the .bmp files in various
; ways. Hard to know why, but it looks terrible on my vanilla boxes.
; Luckily, 4.1.3 also added WizardImageStretch to turn that off.
WizardImageStretch=no
SourceDir=.
OutputDir=.
......@@ -27,13 +31,13 @@ Name: service; Description: "Run your Zope instance as a Windows service (start
Source: "<<MAKEFILEDIR>>\etc\README.html"; DestDir: "{app}"; Flags: ignoreversion
Source:"bin\*.*"; DestDir: "{app}\bin"; Flags: ignoreversion recursesubdirs
Source:"doc\*.*"; DestDir: "{app}\doc"; Flags: ignoreversion recursesubdirs
Source:"import\*.*"; DestDir: "{app}\import"; Flags: ignoreversion recursesubdirs
Source:"lib\*.*"; DestDir: "{app}\lib"; Flags: ignoreversion recursesubdirs
Source:"skel\*.*"; DestDir: "{app}\skel"; Flags: ignoreversion recursesubdirs
Source:"zopeskel\*.*"; DestDir: "{app}\zopeskel"; Flags: ignoreversion recursesubdirs
; these are required to be put into the bin directory for proper function of NT services
Source:"bin\Lib\site-packages\win32\PythonService.exe"; DestDir: "{app}\bin"; Flags: ignoreversion
Source:"bin\Lib\site-packages\pywin32_system32\PyWinTypes23.dll"; DestDir: "{app}\bin"; Flags: ignoreversion
Source:"bin\Lib\site-packages\pywin32_system32\PythonCOM23.dll"; DestDir: "{app}\bin"; Flags: ignoreversion
Source:"bin\Lib\site-packages\pywin32_system32\PyWinTypes24.dll"; DestDir: "{app}\bin"; Flags: ignoreversion
Source:"bin\Lib\site-packages\pywin32_system32\PythonCOM24.dll"; DestDir: "{app}\bin"; Flags: ignoreversion
; This is a helper module for manging registry entries at uninstall time
Source: "<<MAKEFILEDIR>>\bin\fixreg.py"; DestDir: "{app}\bin"; Flags: ignoreversion
......@@ -65,157 +69,129 @@ Root: HKLM; Subkey: "Software\Zope Corporation\Zope\<<VERSION>>"; Flags: uninsde
[Code]
var
PasswordPrompts, PasswordValues : array of String;
PasswordChars : array of char;
DataDirValues: array of String;
Password : string;
DataDir : String;
function InitializeSetup(): Boolean;
begin
{ set up password data structures }
SetArrayLength(PasswordPrompts, 1);
PasswordPrompts[0] := 'Password:';
SetArrayLength(PasswordValues, 1);
PasswordValues[0] := '';
SetArrayLength(PasswordChars, 1);
PasswordChars[0] := '*';
Password := '';
{ set up data dir data structures }
SetArrayLength(DataDirValues, 1);
DataDir := '';
Result := True;
end;
{ custom dialog pages }
function CollectInstanceDir(): Boolean;
{ for selecting an instance home directory }
InstanceDirPage: TInputDirWizardPage;
var
Next: Boolean;
DirOk: Boolean;
{ for specifying the password for the "admin" account }
AdminPwdPage: TInputQueryWizardPage;
procedure InitializeWizard;
begin
DirOk := True;
ScriptDlgPageSetSubCaption1('Select where Zope instance files should be installed');
ScriptDlgPageSetSubCaption2('Select the folder to which you would like Setup to install Zope "instance" files, then click Next.');
if DataDir = '' then DataDir:= 'C:\Zope-Instance';
if DataDirValues[0] <> '' then DataDirValues[0]:= '';
{ Ask for a dir until the user has approved one or clicked Back or Cancel }
Next:= InputDir(False, DataDirValues[0], DataDir);
if Next and FileOrDirExists(DataDir) then DirOk := False;
while Next and not DirOk do begin
if DataDir = '' then begin
DirOk := False;
MsgBox(SetupMessage(msgInvalidPath), mbError, MB_OK);
end;
if FileOrDirExists(DataDir) then begin
DirOk := MsgBox('Directory Exists' #13#13 'The directory ' + DataDir + ' already exists. Would you like to create instance files in that directory anyway?', mbConfirmation, MB_YESNO) = idYes;
end;
if not DirOk then Next := InputDir(False, DataDirValues[0], DataDir);
end;
Result:=Next;
{ The instance directory page follows the standard "select additional
tasks" page. }
InstanceDirPage := CreateInputDirPage(wpSelectTasks,
'Instance Setup',
'Select where Zope instance files should be installed',
'Select the folder to which you would like Setup to install ' +
'Zope "instance" files, then click Next.',
False,
'');
InstanceDirPage.Add('');
{ The admin password page follows our instance directory page. }
AdminPwdPage := CreateInputQueryPage(InstanceDirPage.ID,
'Instance Setup',
'Specify administrator password',
'The login name for your Zope administrator ' +
'account is "admin". When you first connect to the Zope ' +
'management interface, you will need to login using the ' +
'"admin" username and the password you specify below.');
AdminPwdPage.Add('Password:', True);
AdminPwdPage.Add('Confirm password:', True);
{ Set default values; use settings from last time when possible. }
InstanceDirPage.Values[0] := GetPreviousData('InstanceDir',
'C:\Zope-Instance');
AdminPwdPage.Values[0] := '';
AdminPwdPage.Values[1] := '';
end;
function CollectPassword(): Boolean;
var
Next: Boolean;
procedure RegisterPreviousData(PreviousDataKey: Integer);
begin
ScriptDlgPageSetSubCaption1('Specify administrator password');
ScriptDlgPageSetSubCaption2('The login name for your Zope administrator account is "admin". When you first connect to the Zope management interface, you will need to login using the "admin" username and the password you specify below.');
Next := InputQueryArrayEx(PasswordPrompts, PasswordChars, PasswordValues);
while Next and (PasswordValues[0] = '') do begin
MsgBox('You must enter an administrator password', mbError, MB_OK)
Next := InputQueryArrayEx(PasswordPrompts, PasswordChars, PasswordValues);
end;
Password := PasswordValues[0];
Result:=Next;
{ Store settings so we can restore them next time. }
{ Note that we deliberately don't store the admin password across
runs! We want that to vanish when the installer finishes. }
SetPreviousData(PreviousDataKey, 'InstanceDir', InstanceDirPage.Values[0]);
end;
function DoInstanceHome():Boolean;
function DoInstanceHome(): Boolean;
var
S : String;
S: String;
begin
S := WizardSelectedComponents(False);
Result := Pos('instance', S) <> 0;
S := WizardSelectedComponents(False);
Result := Pos('instance', S) <> 0;
end;
function DoService(): Boolean;
var
S : String;
function ShouldSkipPage(PageID: Integer): Boolean;
begin
S := WizardSelectedTasks(False);
Result := Pos('service', S) <> 0;
end;
function DontDoService(): Boolean;
begin
Result := not DoService();
{ Skip pages that shouldn't be shown. }
if (PageID = InstanceDirPage.ID) or (PageID = AdminPwdPage.ID) then
Result := not DoInstanceHome()
else
Result := False;
end;
function ScriptDlgPages(CurPage: Integer; BackClicked: Boolean): Boolean;
function NextButtonClick(CurPageID: Integer): Boolean;
var
Next : Boolean;
CurSubPage : Integer;
temp: String;
begin
Next:=True;
if ( (not BackClicked and (CurPage = wpSelectTasks)) or (BackClicked and (CurPage = wpReady)) )
and DoInstanceHome() then begin
if not BackClicked then CurSubPage:=0 else CurSubPage:=1;
ScriptDlgPageOpen();
ScriptDlgPageSetCaption('Instance Setup');
while (CurSubPage >=0) and (CurSubPage <=1) and not Terminated do begin
case CurSubPage of
0: Next:=CollectInstanceDir();
1: Next:=CollectPassword();
end;
if Next then CurSubPage := CurSubPage +1 else CurSubPage := CurSubPage -1;
end;
if not BackClicked then
Result := Next
else
Result := not Next;
ScriptDlgPageClose(not Result);
end;
Result:=Next;
{ Validate pages before allowing the user to proceed. }
Result := True; // innocent until proven guilty
if CurPageID = InstanceDirPage.ID then begin
temp := InstanceDirPage.Values[0];
if temp = '' then begin
Result := False;
MsgBox(SetupMessage(msgInvalidPath), mbError, MB_OK);
end
else if FileOrDirExists(temp) then begin
Result := MsgBox('Directory Exists' #13#13 'The directory ' +
temp + ' already exists. Would you like to create ' +
'instance files in that directory anyway?',
mbConfirmation, MB_YESNO) = idYes;
end
end
else if CurPageID = AdminPwdPage.ID then begin
temp := AdminPwdPage.Values[0];
if temp = '' then begin
Result := False;
MsgBox('You must enter an administrator password',
mbError, MB_OK);
end
else if temp <> AdminPwdPage.Values[1] then begin
Result := False;
MsgBox('Please try again -- the passwords don''t match',
mbError, MB_OK)
end
end
end;
function NextButtonClick(CurPage: Integer): Boolean;
function DoService(): Boolean;
var
S: String;
begin
Result := ScriptDlgPages(CurPage, False);
S := WizardSelectedTasks(False);
Result := Pos('service', S) <> 0;
end;
function BackButtonClick(CurPage: Integer): Boolean;
function DontDoService(): Boolean;
begin
Result := ScriptDlgPages(CurPage, True);
Result := not DoService();
end;
function GetPassword(Default: String): String;
begin
Result := Password;
Result := AdminPwdPage.Values[0];
end;
function GetDataDir(Default : String):String;
function GetDataDir(Default: String):String;
begin
Result := DataDir;
end; { GetInstanceDir }
Result := InstanceDirPage.Values[0];
end;
function IsAdministrator(): Boolean;
begin
Result := IsAdminLoggedOn();
Result := IsAdminLoggedOn();
end;
BASE_DIR=$(shell pwd)
WIN_BASE_DIR=$(shell cygpath -w $(BASE_DIR))
BUILD_DIR=$(BASE_DIR)/build
WIN_BUILD_DIR=$(shell cygpath -w $(BUILD_DIR))
SRC_DIR=$(BASE_DIR)/src
WIN_SRC_DIR=$(shell cygpath -w $(SRC_DIR))
TMP_DIR=$(BASE_DIR)/tmp
WIN_TMP_DIR=$(shell cygpath -w $(TMP_DIR))
WIN_MAKEFILEDIR=$(shell cygpath -w $(MAKEFILEDIR))
# Use immediate assignment to avoid calling out to the shell a zillion times.
BASE_DIR := $(shell pwd)
WIN_BASE_DIR := $(shell cygpath -w $(BASE_DIR))
BUILD_DIR := $(BASE_DIR)/build
WIN_BUILD_DIR := $(shell cygpath -w $(BUILD_DIR))
SRC_DIR := $(BASE_DIR)/src
WIN_SRC_DIR := $(shell cygpath -w $(SRC_DIR))
TMP_DIR := $(BASE_DIR)/tmp
WIN_TMP_DIR := $(shell cygpath -w $(TMP_DIR))
WIN_MAKEFILEDIR := $(shell cygpath -w $(MAKEFILEDIR))
# Root of the Windows drive you're working on. The setting here is for
# the C: drive and using a default out-of-the-box Cygwin.
......@@ -16,7 +17,17 @@ RM=rm -f
RMRF=rm -rf
CD=cd
XCOPY=xcopy /i /s /e /y
# xcopy args:
# /i = if dest doesn't exist and source has more than one file, assume
# dest shoud be a directory
# /y = don't prompt about overwriting dest if it exists -- just do it
# /s = recurse, copying non-empty subdirectories too
# CAUTION: don't use /e unless you have to! /e copies empty subdirectories
# too, but has another truly bizarre behavior: if you use xcopy to copy
# a single file, and use /e, it creates empty subdirectories in the target's
# directory with the same names as the subdirectories in the source's
# directory. This is worse than useless.
XCOPY=xcopy /i /s /y
CPR=cp -r
CP=cp
......@@ -26,9 +37,10 @@ TAR=tar
SED=sed
TOUCH=touch
NMAKE=nmake
CURL=curl -N
CSCRIPT=cscript
ECHO=echo
ISS_DIR=$(CYGROOT)/Progra~1/Inno Setup 4
ISS_DIR=$(CYGROOT)/Progra~1/Inno Setup 5
ISS_COMPILER=$(ISS_DIR)/Compil32.exe
# We need a version that understands cygwin paths, so /bin/
UNZIP=/bin/unzip
......@@ -63,4 +75,4 @@ define COPY_AND_WINDOWIZE_LINEENDS
$(CP) $< $@
unix2dos $@
$(TOUCH) $@
endef
\ No newline at end of file
endef
# The Python and pywin32 versions. For Python, both the source tarball
# and the Windows installer must be in tmp/. For pywin32 (previously known
# as win32all), the Windows installer must be in tmp/. Nothing beyond those
# is required to build Python, and you don't even need a compiler.
PYVERSION_MAJOR=2
PYVERSION_MINOR=3
PYVERSION_PATCH=5
PYVERSION=$(PYVERSION_MAJOR).$(PYVERSION_MINOR).$(PYVERSION_PATCH)
W32ALLVERSION=205
# CAUTION: Extracting files from Wise installers doesn't really do what
# you expect. While a Wise installer is a zip file, the zip file
# structure is flat (Wise reconstructs the intended directory structure
# from metadata stored in proprietary FILEnnnn.DAT files also in the
# zip file). Consequently, the package structure of Python packages is
# lost, and if there's more than one file with the same name, you only
# get "the last one" to be extracted (all files are extracted to the
# same directory).
# The Python and pywin32 versions.
#
# For Python, this doesn't matter, because we're only sucking out the
# precompiled .pyd and .exe files from the Python installer -- there
# are no name clashes in that set, and it's a pretty safe bet there never
# will be (else Python wouldn't be able to decide which to use!). We
# use the Python source tarball to get all the non-executable parts we
# need.
# For Python, the source tarball must be in tmp/. You must also install the
# appropriate Python on Windows, and set WIN_PYINSTALLEDDIR here to its root
# directory. A copy of the main Python DLL must also be in the root (you
# may need to copy it from your Windows system directory). Earlier versions
# of this extracted .dll, .exe, and .pyd files from Python's Wise installer,
# but Python 2.4 uses an .msi installer, and there doesn't appear to be a
# way to _just_ extract files from one of those.
#
# pywin32 doesn't have this problem as it now uses
# a standard distutils 'bdist_wininst' installation .exe. These executables are
# valid .zip files with a "PLATLIB" directory being the complete directory
# structure as installed into "site-packages". These recent pywin32 builds have
# no dependencies on registry settings etc so will work directly as copied out of
# the .exe. The only concerns are the pywintypes/pythoncom dlls, which is
# handled by the Inno installer
PYDIRNAME=Python-$(PYVERSION)
# Standard bdist_wininst name - eg: pywin32-203.win32-py2.3[.exe]
W32ALLDIRNAME=pywin32-$(W32ALLVERSION).win32-py$(PYVERSION_MAJOR).$(PYVERSION_MINOR)
W32EXCLUDE=*.chm
# For pywin32 (previously known as win32all), the Windows installer must be
# in tmp/.
#
# Nothing beyond those is required to build Python, and you don't even need
# a compiler.
PYVERSION_MAJOR := 2
PYVERSION_MINOR := 4
PYVERSION_PATCH := 2
W32ALLVERSION := 205
PYVERSION := $(PYVERSION_MAJOR).$(PYVERSION_MINOR).$(PYVERSION_PATCH)
PYMAJORMINOR := python$(PYVERSION_MAJOR)$(PYVERSION_MINOR)
# This is the default directory into which a Python installs.
WIN_PYINSTALLEDDIR := \$(PYMAJORMINOR)
# pywin32 now uses a standard distutils 'bdist_wininst' installation .exe.
# These executables are valid .zip files with a "PLATLIB" directory being
# the complete directory structure as installed into "site-packages". These
# recent pywin32 builds have no dependencies on registry settings etc so
# will work directly as copied out of the .exe. The only concerns are the
# pywintypes/pythoncom dlls, which are handled by the Inno installer.
PYDIRNAME := Python-$(PYVERSION)
# Standard bdist_wininst name - eg: pywin32-203.win32-py2.3
W32ALLDIRNAME := pywin32-$(W32ALLVERSION).win32-py$(PYVERSION_MAJOR).$(PYVERSION_MINOR)
W32EXCLUDE := *.chm
# The Python tarball is extracted to PYSRCDIR.
# The contents of the Python installer get extracted to PYEXTRACTDIR.
# The " " " win32all " " " " W32EXTRACTDIR.
PYSRCDIR=$(BASE_DIR)/src/$(PYDIRNAME)
PYEXTRACTDIR=$(BASE_DIR)/src/$(PYDIRNAME)-extract
W32EXTRACTDIR=$(BASE_DIR)/src/$(W32ALLDIRNAME)
# pywin32 is extracted to W32EXTRACTDIR.
PYSRCDIR := $(BASE_DIR)/src/$(PYDIRNAME)
W32EXTRACTDIR := $(BASE_DIR)/src/$(W32ALLDIRNAME)
WIN_PYSRCDIR=$(shell cygpath -w $(PYSRCDIR))
WIN_PYEXTRACTDIR=$(shell cygpath -w $(PYEXTRACTDIR))
WIN_W32EXTRACTDIR=$(shell cygpath -w $(W32EXTRACTDIR))
WIN_PYSRCDIR := $(shell cygpath -w $(PYSRCDIR))
WIN_W32EXTRACTDIR := $(shell cygpath -w $(W32EXTRACTDIR))
PYTHON_REQUIRED_FILES=tmp/$(W32ALLDIRNAME).exe \
tmp/$(PYDIRNAME).tgz \
tmp/$(PYDIRNAME).exe
PYTHON_REQUIRED_FILES := tmp/$(W32ALLDIRNAME).exe \
tmp/$(PYDIRNAME).tgz
# Arbitrary files from each of the installers and tarballs, to use as
# targets to force them to get unpacked.
ARB_PYSRCDIR=$(PYSRCDIR)/PCbuild/pcbuild.dsw
ARB_PYEXTRACTDIR=$(PYEXTRACTDIR)/zlib.pyd
ARB_W32EXTRACTDIR=$(W32EXTRACTDIR)/PLATLIB
ARB_PYSRCDIR := $(PYSRCDIR)/PCbuild/pcbuild.dsw
ARB_W32EXTRACTDIR := $(W32EXTRACTDIR)/PLATLIB
# Building Python just consists of extracting files.
build_python: $(ARB_PYSRCDIR) $(ARB_PYEXTRACTDIR) $(ARB_W32EXTRACTDIR)
build_python: $(ARB_PYSRCDIR) $(ARB_W32EXTRACTDIR)
# Installing Python consists of copying oodles of files into
# $(BUILD_DIR).
......@@ -67,21 +62,27 @@ install_python: $(BUILD_DIR)/bin/python.exe
clean_python:
$(RMRF) $(PYSRCDIR)
$(RMRF) $(PYEXTRACTDIR)
clean_libs:
$(RMRF) $(W32EXTRACTDIR)
# Fetch dependencies
tmp:
$(MKDIR) tmp
tmp/$(W32ALLDIRNAME).exe: tmp
$(CURL) -o tmp/$(W32ALLDIRNAME).exe http://easynews.dl.sourceforge.net/sourceforge/pywin32/$(W32ALLDIRNAME).exe
$(TOUCH) tmp/$(W32ALLDIRNAME).exe
tmp/$(PYDIRNAME).tgz: tmp
$(CURL) -o tmp/$(PYDIRNAME).tgz http://python.org/ftp/python/$(PYVERSION)/$(PYDIRNAME).tgz
$(TOUCH) tmp/$(PYDIRNAME).tgz
$(ARB_PYSRCDIR): tmp/$(PYDIRNAME).tgz
$(MKDIR) "$(SRC_DIR)"
$(CD) "$(SRC_DIR)" && $(TAR) xvzf ../tmp/$(PYDIRNAME).tgz
$(TOUCH) "$(ARB_PYSRCDIR)"
$(ARB_PYEXTRACTDIR): tmp/$(PYDIRNAME).exe
$(MKDIR) "$(PYEXTRACTDIR)"
"tmp/$(PYDIRNAME).exe" /S /X "$(WIN_PYEXTRACTDIR)"
$(TOUCH) "$(ARB_PYEXTRACTDIR)"
# unzip warns about .exe not being exactly a .zip, then succeeds in
# extracting the files, then returns with exit != 0 - ignore exit code
$(ARB_W32EXTRACTDIR): tmp/$(W32ALLDIRNAME).exe
......@@ -96,9 +97,8 @@ $(BUILD_DIR)/bin/python.exe:
$(CP) "$(MAKEFILEDIR)/doc/ZC_PY_DIST_README.txt" "$(BUILD_DIR)/doc"
$(CP) "$(PYSRCDIR)/LICENSE" "$(BUILD_DIR)/doc/PYTHON_LICENSE.txt"
unix2dos "$(BUILD_DIR)/doc/PYTHON_LICENSE.txt"
$(MKDIR) "$(BUILD_DIR)/bin/DLLs"
$(XCOPY) "$(WIN_PYEXTRACTDIR)\*.pyd" "$(WIN_BUILD_DIR)\bin\DLLs"
$(CP) "$(SRC_DIR)/$(W32ALLDIRNAME)/PLATLIB/pythonwin/License.txt" \
"$(BUILD_DIR)/doc/PYWIN32_LICENSE.txt"
$(MKDIR) "$(BUILD_DIR)/bin/Lib"
$(XCOPY) "$(WIN_PYSRCDIR)\Lib\*.py" "$(WIN_BUILD_DIR)\bin\Lib"
......@@ -115,13 +115,17 @@ $(BUILD_DIR)/bin/python.exe:
$(XCOPY) "$(WIN_PYSRCDIR)\Include\*.h" "$(WIN_BUILD_DIR)\bin\Include"
$(XCOPY) "$(WIN_PYSRCDIR)\PC\*.h" "$(WIN_BUILD_DIR)\bin\Include"
$(MKDIR) "$(BUILD_DIR)/bin"
$(MKDIR) "$(BUILD_DIR)/bin/libs"
$(CP) "$(PYEXTRACTDIR)/python23.lib" "$(BUILD_DIR)/bin/libs"
$(MKDIR) "$(BUILD_DIR)/bin/DLLs"
$(XCOPY) "$(WIN_PYINSTALLEDDIR)\python.exe" "$(WIN_BUILD_DIR)\bin"
$(XCOPY) "$(WIN_PYINSTALLEDDIR)\pythonw.exe" "$(WIN_BUILD_DIR)\bin"
$(XCOPY) "$(WIN_PYINSTALLEDDIR)\w9xpopen.exe" "$(WIN_BUILD_DIR)\bin"
$(XCOPY) "$(WIN_PYINSTALLEDDIR)\$(PYMAJORMINOR).dll" \
"$(WIN_BUILD_DIR)\bin"
$(XCOPY) "$(WIN_MAKEFILEDIR)\bin\msvcr71.dll" "$(WIN_BUILD_DIR)\bin"
$(XCOPY) "$(WIN_PYINSTALLEDDIR)\libs" "$(WIN_BUILD_DIR)\bin\libs"
$(XCOPY) "$(WIN_PYINSTALLEDDIR)\DLLs\*.pyd" \
"$(WIN_BUILD_DIR)\bin\DLLs"
$(MKDIR) "$(BUILD_DIR)/bin"
$(CP) "$(PYEXTRACTDIR)/pythonw.exe" "$(BUILD_DIR)/bin"
$(CP) "$(PYEXTRACTDIR)/w9xpopen.exe" "$(BUILD_DIR)/bin"
$(CP) "$(PYEXTRACTDIR)/python23.dll" "$(BUILD_DIR)/bin"
$(CP) "$(PYEXTRACTDIR)/python.exe" "$(BUILD_DIR)/bin"
$(TOUCH) "$(BUILD_DIR)/bin/python.exe"
ZOPEVERSION := 2.10.0-b1
ZOPEDIRNAME := Zope-$(ZOPEVERSION)
ZOPE_REQUIRED_FILES=tmp/$(ZOPEDIRNAME).tgz
REQUIRED_FILES=$(PYTHON_REQUIRED_FILES)\
$(ZOPE_REQUIRED_FILES)
ZOPEVERSION=2.10.0-b1
ZOPEDIRNAME=Zope-$(ZOPEVERSION)
MAKEZOPE="$(MAKEFILEDIR)/bin/makezope.bat" "$(WIN_BUILD_DIR)"
# run the Zope tests
test_zope:
$(CD) "$(BASE_DIR)/src/Zope"
"$(PYPCBUILDDIR)/python.exe" utilities/testrunner.py -a
$(CD) "$(BASE_DIR)"
clean_zope:
$(RMRF) src/$(ZOPEDIRNAME)
install_zope: src/$(ZOPEDIRNAME)/inst/configure.py \
$(BUILD_DIR)/lib/python/version.txt install_python \
install_zope: src/$(ZOPEDIRNAME)/install.py \
install_python \
$(BUILD_DIR)/lib/python/Zope2/version.txt \
$(BUILD_DIR)/Zope-$(ZOPEVERSION)-win32.exe
ESCAPED=$(shell sh $(MAKEFILEDIR)/bin/escape.sh '$(WIN_MAKEFILEDIR)')
SEDSCRIPT="s@<<VERSION>>@$(ZOPEVERSION)@g;s@<<MAKEFILEDIR>>@$(ESCAPED)@g"
$(BUILD_DIR)/Zope-$(ZOPEVERSION)-win32.exe: $(BUILD_DIR)/lib/python/version.txt
$(BUILD_DIR)/Zope-$(ZOPEVERSION)-win32.exe: $(BUILD_DIR)/lib/python/Zope2/version.txt
$(SED) $(SEDSCRIPT) < "$(MAKEFILEDIR)/etc/zope.iss.in" | unix2dos > "$(BUILD_DIR)/zope.iss"
# Remove CVS directories from the build tree.
# Remove CVS directories and compiled Python files from the build tree.
find $(BUILD_DIR) -name CVS -type d -exec $(RMRF) {} \; -prune
find $(BUILD_DIR) -name "*.pyc" -o -name "*.pyo" | xargs $(RM)
# Convert text files to Windows line ends. unix2dos has the nice
# property that it leaves lines with \r\n alone, so it doesn't hurt
# to do this on files already converted to Windows convention.
find $(BUILD_DIR) -name "*.py" -o -name "*.txt" -o -name "*.bat" | \
xargs unix2dos
find $(BUILD_DIR) -name "*.bat" | xargs unix2dos
find $(BUILD_DIR) -name "*.conf" | xargs unix2dos
find $(BUILD_DIR) -name "*.html" | xargs unix2dos
find $(BUILD_DIR) -name "*.in" | xargs unix2dos
find $(BUILD_DIR) -name "*.py" | xargs unix2dos
find $(BUILD_DIR) -name "*.stx" | xargs unix2dos
find $(BUILD_DIR) -name "*.txt" | xargs unix2dos
find $(BUILD_DIR) -name "*.xml" | xargs unix2dos
find $(BUILD_DIR) -name "*.zcml" | xargs unix2dos
# Build the Inno installer.
$(CD) "$(BUILD_DIR)";"$(ISS_COMPILER)" /cc "$(WIN_BUILD_DIR)\zope.iss"
$(BUILD_DIR)/lib/python/Zope2/Startup/run.py:
$(CD) "$(BUILD_DIR)"; \
bin/python.exe \
"$(WIN_SRC_DIR)\$(ZOPEDIRNAME)\inst\configure.py" \
--prefix="$(WIN_BUILD_DIR)" --no-compile
$(MAKEZOPE)
$(TOUCH) "$(BUILD_DIR)/lib/python/Zope2/Startup/run.py"
# This builds Zope, then installs it into the build directory, then
# creates lib/python/Zope2/version.txt in the build directory.
#
# Yuck: for whatever reason, distutils refuses to allow an absolute
# path for the --home option, so this hardcodes "build" as the name of
# the build directory, and assumes "build" is a sibling of SRC_DIR.
#
# Yuck: the --no-compile option here has no effect: the install step
# creates oodles of unwanted .pyc files. They're removed by the
# $(BUILD_DIR)/Zope-$(ZOPEVERSION)-win32.exe target, though, before
# building the installer.
#
# Yuck: no matter what I pass to --install-headers, it throws away the
# last path component. We actually want to copy the Zope/ZODB headers
# into bin/Include. The "nonsense" at the end gets thrown away, and that
# smells like a bug. When it gets fixed, I suppose this will copy the
# headers to bin/Include/nonsense/.
$(BUILD_DIR)/lib/python/Zope2/version.txt: $(BUILD_DIR)/bin/python.exe
cd "$(SRC_DIR)/$(ZOPEDIRNAME)" && \
"$<" install.py install --no-compile --home=../../build \
--install-headers=../../build/bin/Include/nonsense
echo Zope $(ZOPEVERSION) > $@
$(TOUCH) $@
$(BUILD_DIR)/lib/python/version.txt: $(BUILD_DIR)/lib/python/Zope2/Startup/run.py
@echo Zope $(ZOPEVERSION) > "$(BUILD_DIR)/lib/python/version.txt"
$(TOUCH) "$(BUILD_DIR)/lib/python/version.txt"
tmp/$(ZOPEDIRNAME).tgz:
$(CURL) -o tmp/$(ZOPEDIRNAME).tgz http://www.zope.org/Products/Zope/$(ZOPEVERSION)/$(ZOPEDIRNAME).tgz
$(TOUCH) tmp/$(ZOPEDIRNAME).tgz
src/$(ZOPEDIRNAME)/inst/configure.py:
# This merely unpacks the Zope tarball.
src/$(ZOPEDIRNAME)/install.py: tmp/$(ZOPEDIRNAME).tgz
$(MKDIR) "$(SRC_DIR)"
$(CD) "$(SRC_DIR)" && $(TAR) xvzf ../tmp/$(ZOPEDIRNAME).tgz \
&& $(TOUCH) $(ZOPEDIRNAME)/inst/configure.py
$(CD) "$(SRC_DIR)" && $(TAR) xvzf ../tmp/$(ZOPEDIRNAME).tgz
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment