blob: 12a78e0cd0341b51c924036180328d24c1dadabb [file] [log] [blame]
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00001# Script for building the _ssl and _hashlib modules for Windows.
Mark Hammondf229f9f2002-12-03 05:47:26 +00002# Uses Perl to setup the OpenSSL environment correctly
3# and build OpenSSL, then invokes a simple nmake session
Thomas Wouters00ee7ba2006-08-21 19:07:27 +00004# for the actual _ssl.pyd and _hashlib.pyd DLLs.
Mark Hammondf229f9f2002-12-03 05:47:26 +00005
6# THEORETICALLY, you can:
7# * Unpack the latest SSL release one level above your main Python source
8# directory. It is likely you will already find the zlib library and
9# any other external packages there.
10# * Install ActivePerl and ensure it is somewhere on your path.
11# * Run this script from the PCBuild directory.
12#
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000013# it should configure and build SSL, then build the _ssl and _hashlib
14# Python extensions without intervention.
Mark Hammondf229f9f2002-12-03 05:47:26 +000015
16import os, sys, re
17
18# Find all "foo.exe" files on the PATH.
19def find_all_on_path(filename, extras = None):
20 entries = os.environ["PATH"].split(os.pathsep)
21 ret = []
22 for p in entries:
23 fname = os.path.abspath(os.path.join(p, filename))
24 if os.path.isfile(fname) and fname not in ret:
25 ret.append(fname)
26 if extras:
27 for p in extras:
28 fname = os.path.abspath(os.path.join(p, filename))
29 if os.path.isfile(fname) and fname not in ret:
30 ret.append(fname)
31 return ret
32
33# Find a suitable Perl installation for OpenSSL.
34# cygwin perl does *not* work. ActivePerl does.
35# Being a Perl dummy, the simplest way I can check is if the "Win32" package
36# is available.
37def find_working_perl(perls):
38 for perl in perls:
39 fh = os.popen(perl + ' -e "use Win32;"')
40 fh.read()
41 rc = fh.close()
42 if rc:
43 continue
44 return perl
Thomas Heller8cef8a82007-08-27 09:42:33 +000045 print("Can not find a suitable PERL:")
Mark Hammondf229f9f2002-12-03 05:47:26 +000046 if perls:
Thomas Heller8cef8a82007-08-27 09:42:33 +000047 print(" the following perl interpreters were found:")
Mark Hammondf229f9f2002-12-03 05:47:26 +000048 for p in perls:
Thomas Heller8cef8a82007-08-27 09:42:33 +000049 print(" ", p)
50 print(" None of these versions appear suitable for building OpenSSL")
Mark Hammondf229f9f2002-12-03 05:47:26 +000051 else:
Thomas Heller8cef8a82007-08-27 09:42:33 +000052 print(" NO perl interpreters were found on this machine at all!")
53 print(" Please install ActivePerl and ensure it appears on your path")
54 print("The Python SSL module was not built")
Mark Hammondf229f9f2002-12-03 05:47:26 +000055 return None
56
57# Locate the best SSL directory given a few roots to look into.
58def find_best_ssl_dir(sources):
59 candidates = []
60 for s in sources:
61 try:
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000062 # note: do not abspath s; the build will fail if any
63 # higher up directory name has spaces in it.
Mark Hammondf229f9f2002-12-03 05:47:26 +000064 fnames = os.listdir(s)
65 except os.error:
66 fnames = []
67 for fname in fnames:
68 fqn = os.path.join(s, fname)
69 if os.path.isdir(fqn) and fname.startswith("openssl-"):
70 candidates.append(fqn)
71 # Now we have all the candidates, locate the best.
72 best_parts = []
73 best_name = None
74 for c in candidates:
75 parts = re.split("[.-]", os.path.basename(c))[1:]
76 # eg - openssl-0.9.7-beta1 - ignore all "beta" or any other qualifiers
77 if len(parts) >= 4:
78 continue
79 if parts > best_parts:
80 best_parts = parts
81 best_name = c
82 if best_name is not None:
Thomas Heller8cef8a82007-08-27 09:42:33 +000083 print("Found an SSL directory at '%s'" % (best_name,))
Mark Hammondf229f9f2002-12-03 05:47:26 +000084 else:
Thomas Heller8cef8a82007-08-27 09:42:33 +000085 print("Could not find an SSL directory in '%s'" % (sources,))
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000086 sys.stdout.flush()
Mark Hammondf229f9f2002-12-03 05:47:26 +000087 return best_name
88
Thomas Wouters0e3f5912006-08-11 14:57:12 +000089def run_configure(configure, do_script):
90 os.system("perl Configure "+configure)
91 os.system(do_script)
92
Mark Hammondf229f9f2002-12-03 05:47:26 +000093def main():
Mark Hammondf229f9f2002-12-03 05:47:26 +000094 build_all = "-a" in sys.argv
Thomas Wouters0e3f5912006-08-11 14:57:12 +000095 if sys.argv[1] == "Release":
96 arch = "x86"
97 debug = False
98 configure = "VC-WIN32"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000099 do_script = "ms\\do_masm"
100 makefile = "ms\\nt.mak"
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000101 elif sys.argv[1] == "Debug":
102 arch = "x86"
103 debug = True
104 configure = "VC-WIN32"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000105 do_script = "ms\\do_masm"
106 makefile="ms\\d32.mak"
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000107 elif sys.argv[1] == "ReleaseItanium":
108 arch = "ia64"
109 debug = False
110 configure = "VC-WIN64I"
111 do_script = "ms\\do_win64i"
112 makefile = "ms\\nt.mak"
113 os.environ["VSEXTCOMP_USECL"] = "MS_ITANIUM"
114 elif sys.argv[1] == "ReleaseAMD64":
115 arch="amd64"
116 debug=False
117 configure = "VC-WIN64A"
118 do_script = "ms\\do_win64a"
119 makefile = "ms\\nt.mak"
120 os.environ["VSEXTCOMP_USECL"] = "MS_OPTERON"
Mark Hammondf229f9f2002-12-03 05:47:26 +0000121 make_flags = ""
122 if build_all:
123 make_flags = "-a"
124 # perl should be on the path, but we also look in "\perl" and "c:\\perl"
125 # as "well known" locations
126 perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"])
127 perl = find_working_perl(perls)
128 if perl is None:
129 sys.exit(1)
130
Thomas Heller8cef8a82007-08-27 09:42:33 +0000131 print("Found a working perl at '%s'" % (perl,))
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000132 sys.stdout.flush()
Mark Hammondf229f9f2002-12-03 05:47:26 +0000133 # Look for SSL 2 levels up from pcbuild - ie, same place zlib etc all live.
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000134 ssl_dir = find_best_ssl_dir(("..\\..",))
Mark Hammondf229f9f2002-12-03 05:47:26 +0000135 if ssl_dir is None:
136 sys.exit(1)
137
138 old_cd = os.getcwd()
139 try:
140 os.chdir(ssl_dir)
141 # If the ssl makefiles do not exist, we invoke Perl to generate them.
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000142 # Due to a bug in this script, the makefile sometimes ended up empty
143 # Force a regeneration if it is.
144 if not os.path.isfile(makefile) or os.path.getsize(makefile)==0:
Thomas Heller8cef8a82007-08-27 09:42:33 +0000145 print("Creating the makefiles...")
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000146 sys.stdout.flush()
Mark Hammondf229f9f2002-12-03 05:47:26 +0000147 # Put our working Perl at the front of our path
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000148 os.environ["PATH"] = os.path.dirname(perl) + \
Mark Hammondf229f9f2002-12-03 05:47:26 +0000149 os.pathsep + \
150 os.environ["PATH"]
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000151 run_configure(configure, do_script)
152 if arch=="x86" and debug:
153 # the do_masm script in openssl doesn't generate a debug
154 # build makefile so we generate it here:
155 os.system("perl util\mk1mf.pl debug "+configure+" >"+makefile)
Mark Hammondf229f9f2002-12-03 05:47:26 +0000156
157 # Now run make.
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000158 makeCommand = "nmake /nologo PERL=\"%s\" -f \"%s\"" %(perl, makefile)
Thomas Heller8cef8a82007-08-27 09:42:33 +0000159 print("Executing ssl makefiles:", makeCommand)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000160 sys.stdout.flush()
161 rc = os.system(makeCommand)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000162 if rc:
Thomas Heller8cef8a82007-08-27 09:42:33 +0000163 print("Executing "+makefile+" failed")
164 print(rc)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000165 sys.exit(rc)
Mark Hammondf229f9f2002-12-03 05:47:26 +0000166 finally:
167 os.chdir(old_cd)
168 # And finally, we can build the _ssl module itself for Python.
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000169 defs = "SSL_DIR=\"%s\"" % (ssl_dir,)
Mark Hammondf229f9f2002-12-03 05:47:26 +0000170 if debug:
171 defs = defs + " " + "DEBUG=1"
Thomas Woutersb2137042007-02-01 18:02:27 +0000172 if arch in ('amd64', 'ia64'):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000173 defs = defs + " EXTRA_CFLAGS=/GS- EXTRA_LIBS=bufferoverflowU.lib"
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000174 makeCommand = 'nmake /nologo -f _ssl.mak ' + defs + " " + make_flags
Thomas Heller8cef8a82007-08-27 09:42:33 +0000175 print("Executing:", makeCommand)
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000176 sys.stdout.flush()
177 rc = os.system(makeCommand)
Mark Hammondf229f9f2002-12-03 05:47:26 +0000178 sys.exit(rc)
179
180if __name__=='__main__':
181 main()