diff options
author | Jean-Paul Calderone <exarkun@divmod.com> | 2009-11-11 10:10:57 -0500 |
---|---|---|
committer | Jean-Paul Calderone <exarkun@divmod.com> | 2009-11-11 10:10:57 -0500 |
commit | bcd4545f70a2439c6f5d54938b057cf00734e8ab (patch) | |
tree | 8142c0ab289f839d36712858f630200fa3e5f337 | |
parent | 2953db8a56fa9c2ffc4fe2994efa83498ca24ae5 (diff) | |
download | pyopenssl-bcd4545f70a2439c6f5d54938b057cf00734e8ab.tar.gz |
Some changes to setup.py
-rw-r--r-- | INSTALL | 84 | ||||
-rwxr-xr-x | setup.py | 154 |
2 files changed, 199 insertions, 39 deletions
@@ -38,31 +38,77 @@ to find out more about how to use the script. -- Building the Module on a Windows System -- -pyOpenSSL is known to build with mingw32 for Python 2.3 through Python 2.5. -For Python 2.6, the official Windows installer of which is built with -Microsoft Visual Studio 2008 (version 9.0), Microsoft Visual Studio 2008 -(version 9.0) is required. You can specify that mingw32 be used by passing -the --compiler argument to build_ext. You will also need to specify the -location of the OpenSSL headers and libraries: - - C:\pyOpenSSL-X.Y> setup.py build_ext -c mingw32 -I C:\OpenSSL\include ^ - -L C:\OpenSSL bdist_msi - -The correct header and library paths depend on how you have OpenSSL -installed. The above paths are correct for the default installation of -(<http://www.slproweb.com/products/Win32OpenSSL.html>). +First you should get OpenSSL linked with the same runtime library that Python +uses. If you are using Python 2.6 you can use the installer at: + + http://www.slproweb.com/products/Win32OpenSSL.html + +The binaries in the installer are built with Visual Studio 2008 at the +time of this writing, which is the same compiler used for building the +official Python 2.6 installers. + +If you want to build PyOpenSSL for an older Python version, it is preferred +to build OpenSSL yourself, either with the Visual Studio 2003 compiler or +with the MinGW compiler. This way you avoid all potential incompatibilities +between different versions of runtime library (msvcrt.dll). To build OpenSSL +folow the instructions in its source distribution and make sure that you build +a shared library, not a static one. PyOpenSSL fails some of its tests when +linked with the static OpenSSL libraries. Use the same compiler for OpenSSL +that you will use for PyOpenSSL later. Make sure that OpenSSL is properly +installed before continuing. To install OpenSSL when building with MinGW, use +the folowing script: + +set OPENSSL_INSTALL_DIR=%1 +mkdir %OPENSSL_INSTALL_DIR% +mkdir %OPENSSL_INSTALL_DIR%\bin +mkdir %OPENSSL_INSTALL_DIR%\include +mkdir %OPENSSL_INSTALL_DIR%\include\openssl +mkdir %OPENSSL_INSTALL_DIR%\lib +copy /b .\*.dll %OPENSSL_INSTALL_DIR%\bin +copy /b .\out\openssl.exe %OPENSSL_INSTALL_DIR%\bin +copy /b .\outinc\openssl\* %OPENSSL_INSTALL_DIR%\include\openssl +copy /b .\out\*.a %OPENSSL_INSTALL_DIR%\lib + +Ensure that OpenSSL's openssl.exe executable can be found on PATH before +running PyOpenSSL's setup script. The setup script finds OpenSSL's include dir +and lib dir based on the location of openssl.exe, and the test suite requires +openssl.exe for output comparison. Alternatively, you can specify the +--with-openssl option to setup.py's build_ext command with the path to the +OpenSSL installation dir: + + > python setup.py build_ext --with-openssl=C:\path\to\openssl build + +PyOpenSSL is known to build with mingw32 for Python 2.3 through Python 2.5. +Before using the mingw32 compiler for Python 2.3, you will have to create +a Python library that MinGW understands. Find and download the pexports +program, put it and MinGW's bin directory on path, then run from Python's +install dir: + +> pexports python23.dll > libs\python23.def +> dlltool --dllname python23.dll --def libs\python23.def \ + --output-lib libs\libpython23.a + +For Python 2.4 and 2.5, no special preparation is needed, just make sure that +MinGW's gcc is on PATH. You can specify that mingw32 be used by passing +the --compiler argument to build_ext: + + C:\pyOpenSSL-X.Y> setup.py build_ext -c mingw32 bdist_msi The bdist_msi command will build an MSI installer. It can be substituted -with another bdist command if another kind of installer is desired. +with another bdist command if another kind of installer is desired or with +the install command if you want to install directly. + +For Python 2.4 and 2.5 you can use Visual Studio 2003 in addition to MinGW. +For Python 2.6, the official Windows installer of which is built with +Microsoft Visual Studio 2008 (version 9.0), Microsoft Visual Studio 2008 +(version 9.0) is required. -To build with MSVC instead, omit the -c option and pass a slightly different -library directory: +To build with MSVC, just omit the compiler specific option: - C:\pyOpenSSL-X.Y> setup.py build_ext -I C:\OpenSSL\include ^ - -L C:\OpenSSL\lib bdist_msi + C:\pyOpenSSL-X.Y> setup.py bdist_msi The resulting binary distribution will be placed in the dist directory. To -install it, dDepending on what kind of distribution you create, run it, +install it, depending on what kind of distribution you create, run it, unzip it, or copy it to Python installation's site-packages. And similarily, you can do @@ -13,8 +13,8 @@ Installation script for the OpenSSL module import sys, os from distutils.core import Extension, setup - -from glob import glob +from distutils.errors import DistutilsFileError +from distutils.command.build_ext import build_ext from version import __version__ @@ -44,25 +44,139 @@ LibraryDirs = None if os.name == 'nt' or sys.platform == 'win32': Libraries = ['Ws2_32'] - def makeTellMeIf(original, what): - class tellMeIf(original): - def __init__(*a, **kw): - Libraries.extend(what) - return original.__init__(*a, **kw) - return tellMeIf - - from distutils import cygwinccompiler - cygwinccompiler.Mingw32CCompiler = makeTellMeIf(cygwinccompiler.Mingw32CCompiler, ['eay32', 'ssl32']) - from distutils import msvccompiler - msvccompiler.MSVCCompiler = makeTellMeIf(msvccompiler.MSVCCompiler, ['libeay32', 'ssleay32']) - - import shutil - shutil.copy("C:\\OpenSSL\\ssleay32.dll", os.path.split(os.path.abspath(__file__))[0]) - shutil.copy("C:\\OpenSSL\\libeay32.dll", os.path.split(os.path.abspath(__file__))[0]) - package_data = {'': ['ssleay32.dll', 'libeay32.dll']} + + + + class BuildExtension(build_ext): + """ + A custom command that semiautomatically finds dependencies required by + PyOpenSSL. + """ + + user_options = (build_ext.user_options + + [("with-openssl=", None, + "directory where OpenSSL is installed")]) + with_openssl = None + openssl_dlls = () + openssl_mingw = False + + + def finalize_options(self): + """ + Update build options with details about OpenSSL. + """ + build_ext.finalize_options(self) + if self.with_openssl is None: + self.find_openssl() + self.find_openssl_dlls() + self.add_openssl_compile_info() + + + def find_openssl(self): + """ + Find OpenSSL's install directory. + """ + dirs = os.environ.get("PATH").split(os.pathsep) + for d in dirs: + if os.path.exists(os.path.join(d, "openssl.exe")): + ssldir, bin = os.path.split(d) + if not bin: + ssldir, bin = os.path.split(ssldir) + childdirs = os.listdir(ssldir) + if (not os.path.isdir(os.path.join(ssldir, "lib")) or + not os.path.isdir(os.path.join(ssldir, "include"))): + msg = "'%s' is not a proper OpenSSL install dir" + raise DistutilsFileError(msg % ssldir) + self.with_openssl = ssldir + return + raise DistutilsFileError("could not find 'openssl.exe'") + + + def find_openssl_dlls(self): + """ + Find OpenSSL's shared libraries. + """ + self.openssl_dlls = [] + self.find_openssl_dll("libssl32.dll", False) + if self.openssl_dlls: + self.openssl_mingw = True + else: + self.find_openssl_dll("ssleay32.dll", True) + self.find_openssl_dll("libeay32.dll", True) + # add zlib to the mix if it looks like OpenSSL + # was linked with a private copy of it + self.find_openssl_dll("zlib1.dll", False) + + + def find_openssl_dll(self, name, required): + """ + Find OpenSSL's shared library and its path after installation. + """ + dllpath = os.path.join(self.with_openssl, "bin", name) + if not os.path.exists(dllpath): + if required: + raise DistutilsFileError("could not find '%s'" % name) + else: + return + newpath = os.path.join(self.build_lib, "OpenSSL", name) + self.openssl_dlls.append((dllpath, newpath)) + + + def add_openssl_compile_info(self): + """ + Set up various compile and link parameters. + """ + if self.compiler == "mingw32": + if self.openssl_mingw: + # Library path and library names are sane when OpenSSL is + # built with MinGW . + libdir = "lib" + libs = ["eay32", "ssl32"] + else: + libdir = "" + libs = [] + # Unlike when using the binary installer, which creates + # an atypical shared library name 'ssleay32', so we have + # to use this workaround. + if self.link_objects is None: + self.link_objects = [] + for dllpath, _ in self.openssl_dlls: + dllname = os.path.basename(dllpath) + libname = os.path.splitext(dllname)[0] + ".a" + libpath = os.path.join(self.with_openssl, + "lib", "MinGW", libname) + self.link_objects.append(libpath) + else: + libdir = "lib" + libs = ["libeay32", "ssleay32"] + self.include_dirs.append(os.path.join(self.with_openssl, "include")) + self.library_dirs.append(os.path.join(self.with_openssl, libdir)) + self.libraries.extend(libs) + + + def run(self): + """ + Build extension modules and copy shared libraries. + """ + build_ext.run(self) + for dllpath, newpath in self.openssl_dlls: + self.copy_file(dllpath, newpath) + + + def get_outputs(self): + """ + Return a list of file paths built by this comand. + """ + output = [pathpair[1] for pathpair in self.openssl_dlls] + output.extend(build_ext.get_outputs(self)) + return output + + + else: Libraries = ['ssl', 'crypto'] - package_data = {} + BuildExtension = build_ext + def mkExtension(name): @@ -85,7 +199,7 @@ setup(name='pyOpenSSL', version=__version__, 'OpenSSL.test.test_rand', 'OpenSSL.test.test_ssl'], zip_safe = False, - package_data = package_data, + cmdclass = {"build_ext": BuildExtension}, description = 'Python wrapper module around the OpenSSL library', author = 'Martin Sjögren, AB Strakt', author_email = 'msjogren@gmail.com', |