build_ssl.py revision aee643b01fe4cb3993efcc2e06639e5cbf684c94
1# Script for building the _ssl module for Windows. 2# Uses Perl to setup the OpenSSL environment correctly 3# and build OpenSSL, then invokes a simple nmake session 4# for _ssl.pyd itself. 5 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# 13# it should configure and build SSL, then build the ssl Python extension 14# without intervention. 15 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 45 print "Can not find a suitable PERL:" 46 if perls: 47 print " the following perl interpreters were found:" 48 for p in perls: 49 print " ", p 50 print " None of these versions appear suitable for building OpenSSL" 51 else: 52 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" 55 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: 62 s = os.path.abspath(s) 63 fnames = os.listdir(s) 64 except os.error: 65 fnames = [] 66 for fname in fnames: 67 fqn = os.path.join(s, fname) 68 if os.path.isdir(fqn) and fname.startswith("openssl-"): 69 candidates.append(fqn) 70 # Now we have all the candidates, locate the best. 71 best_parts = [] 72 best_name = None 73 for c in candidates: 74 parts = re.split("[.-]", os.path.basename(c))[1:] 75 # eg - openssl-0.9.7-beta1 - ignore all "beta" or any other qualifiers 76 if len(parts) >= 4: 77 continue 78 if parts > best_parts: 79 best_parts = parts 80 best_name = c 81 if best_name is not None: 82 print "Found an SSL directory at '%s'" % (best_name,) 83 else: 84 print "Could not find an SSL directory in '%s'" % (sources,) 85 return best_name 86 87def main(): 88 debug = "-d" in sys.argv 89 build_all = "-a" in sys.argv 90 make_flags = "" 91 if build_all: 92 make_flags = "-a" 93 # perl should be on the path, but we also look in "\perl" and "c:\\perl" 94 # as "well known" locations 95 perls = find_all_on_path("perl.exe", ["\\perl\\bin", "C:\\perl\\bin"]) 96 perl = find_working_perl(perls) 97 if perl is None: 98 sys.exit(1) 99 100 print "Found a working perl at '%s'" % (perl,) 101 # Look for SSL 3 levels up from pcbuild - ie, same place zlib etc all live. 102 ssl_dir = find_best_ssl_dir(("../../..",)) 103 if ssl_dir is None: 104 sys.exit(1) 105 106 old_cd = os.getcwd() 107 try: 108 os.chdir(ssl_dir) 109 # If the ssl makefiles do not exist, we invoke Perl to generate them. 110 if not os.path.isfile(os.path.join(ssl_dir, "32.mak")) or \ 111 not os.path.isfile(os.path.join(ssl_dir, "d32.mak")): 112 print "Creating the makefiles..." 113 # Put our working Perl at the front of our path 114 os.environ["PATH"] = os.path.split(perl)[0] + \ 115 os.pathsep + \ 116 os.environ["PATH"] 117 # ms\32all.bat will reconfigure OpenSSL and then try to build 118 # all outputs (debug/nondebug/dll/lib). So we filter the file 119 # to exclude any "nmake" commands and then execute. 120 tempname = "ms\\32all_py.bat" 121 122 in_bat = open("ms\\32all.bat") 123 temp_bat = open(tempname,"w") 124 while 1: 125 cmd = in_bat.readline() 126 print 'cmd', repr(cmd) 127 if not cmd: break 128 if cmd.strip()[:5].lower() == "nmake": 129 continue 130 temp_bat.write(cmd) 131 in_bat.close() 132 temp_bat.close() 133 os.system(tempname) 134 try: 135 os.remove(tempname) 136 except: 137 pass 138 139 # Now run make. 140 print "Executing nmake over the ssl makefiles..." 141 if debug: 142 rc = os.system("nmake /nologo -f d32.mak") 143 if rc: 144 print "Executing d32.mak failed" 145 print rc 146 sys.exit(rc) 147 else: 148 rc = os.system("nmake /nologo -f 32.mak") 149 if rc: 150 print "Executing 32.mak failed" 151 print rc 152 sys.exit(rc) 153 finally: 154 os.chdir(old_cd) 155 # And finally, we can build the _ssl module itself for Python. 156 defs = "SSL_DIR=%s" % (ssl_dir,) 157 if debug: 158 defs = defs + " " + "DEBUG=1" 159 rc = os.system('nmake /nologo -f _ssl.mak ' + defs + " " + make_flags) 160 sys.exit(rc) 161 162if __name__=='__main__': 163 main() 164