pycryptodome/setup.py

207 lines
7.6 KiB
Python
Raw Normal View History

#! /usr/bin/env python
__revision__ = "$Id$"
from distutils import core
from distutils.core import Extension
from distutils.command.build_ext import build_ext
import os, sys
import struct
if sys.version[0:1] == '1':
raise RuntimeError, ("The Python Cryptography Toolkit requires "
"Python 2.x to build.")
if sys.platform == 'win32':
HTONS_LIBS = ['ws2_32']
plat_ext = [
Extension("Crypto.Util.winrandom",
libraries = HTONS_LIBS + ['advapi32'],
include_dirs=['src/'],
sources=["src/winrand.c"])
]
else:
HTONS_LIBS = []
plat_ext = []
# List of pure Python modules that will be excluded from the binary packages.
# The list consists of (package, module_name) tuples
from distutils.command.build_py import build_py
EXCLUDE_PY = [
('Crypto', 'test'), # Top-level test module (it doesn't work outside the source tree anyway)
('Crypto.Hash', 'RIPEMD160'), # Included for your amusement, but the C version is much faster.
]
# Functions for finding libraries and files, copied from Python's setup.py.
def find_file(filename, std_dirs, paths):
"""Searches for the directory where a given file is located,
and returns a possibly-empty list of additional directories, or None
if the file couldn't be found at all.
'filename' is the name of a file, such as readline.h or libcrypto.a.
'std_dirs' is the list of standard system directories; if the
file is found in one of them, no additional directives are needed.
'paths' is a list of additional locations to check; if the file is
found in one of them, the resulting list will contain the directory.
"""
# Check the standard locations
for dir in std_dirs:
f = os.path.join(dir, filename)
if os.path.exists(f): return []
# Check the additional directories
for dir in paths:
f = os.path.join(dir, filename)
if os.path.exists(f):
return [dir]
# Not found anywhere
return None
def find_library_file(compiler, libname, std_dirs, paths):
filename = compiler.library_filename(libname, lib_type='shared')
result = find_file(filename, std_dirs, paths)
if result is not None: return result
filename = compiler.library_filename(libname, lib_type='static')
result = find_file(filename, std_dirs, paths)
return result
def endianness_macro():
s = struct.pack("@L", 0x33221100)
if s == "\x00\x11\x22\x33": # little endian
return ('PCT_LITTLE_ENDIAN', 1)
elif s == "\x33\x22\x11\x00": # big endian
return ('PCT_BIG_ENDIAN', 1)
raise AssertionError("Machine is neither little-endian nor big-endian")
class PCTBuildExt (build_ext):
def build_extensions(self):
self.extensions += [
# Hash functions
Extension("Crypto.Hash.MD4",
include_dirs=['src/'],
sources=["src/MD4.c"]),
Extension("Crypto.Hash.SHA256",
include_dirs=['src/'],
sources=["src/SHA256.c"]),
Extension("Crypto.Hash.RIPEMD160",
include_dirs=['src/'],
sources=["src/RIPEMD160.c"],
define_macros=[endianness_macro()]),
# Block encryption algorithms
Extension("Crypto.Cipher.AES",
include_dirs=['src/'],
sources=["src/AES.c"]),
Extension("Crypto.Cipher.ARC2",
include_dirs=['src/'],
sources=["src/ARC2.c"]),
Extension("Crypto.Cipher.Blowfish",
include_dirs=['src/'],
sources=["src/Blowfish.c"]),
Extension("Crypto.Cipher.CAST",
include_dirs=['src/'],
sources=["src/CAST.c"]),
Extension("Crypto.Cipher.DES",
include_dirs=['src/'],
sources=["src/DES.c"]),
Extension("Crypto.Cipher.DES3",
include_dirs=['src/'],
sources=["src/DES3.c"]),
Extension("Crypto.Cipher.IDEA",
include_dirs=['src/'],
sources=["src/IDEA.c"],
libraries=HTONS_LIBS),
Extension("Crypto.Cipher.RC5",
include_dirs=['src/'],
sources=["src/RC5.c"]),
# Stream ciphers
Extension("Crypto.Cipher.ARC4",
include_dirs=['src/'],
sources=["src/ARC4.c"]),
Extension("Crypto.Cipher.XOR",
include_dirs=['src/'],
sources=["src/XOR.c"]),
# Utility modules
Extension("Crypto.Util.strxor",
include_dirs=['src/'],
sources=['src/strxor.c']),
]
# Platform-specific modules
self.extensions += plat_ext
# Detect which modules should be compiled
self.detect_modules()
build_ext.build_extensions(self)
def detect_modules (self):
lib_dirs = self.compiler.library_dirs + ['/lib', '/usr/lib']
inc_dirs = self.compiler.include_dirs + ['/usr/include']
exts = []
if (self.compiler.find_library_file(lib_dirs, 'gmp')):
exts.append(Extension("Crypto.PublicKey._fastmath",
include_dirs=['src/'],
libraries=['gmp'],
sources=["src/_fastmath.c"]))
self.extensions += exts
class PCTBuildPy(build_py):
def find_package_modules(self, package, package_dir, *args, **kwargs):
modules = build_py.find_package_modules(self, package, package_dir, *args, **kwargs)
# Exclude certain modules
retval = []
for item in modules:
pkg, module = item[:2]
if (pkg, module) in EXCLUDE_PY:
continue
retval.append(item)
return retval
kw = {'name':"pycrypto",
'version':"2.0.2",
'description':"Cryptographic modules for Python.",
'author':"A.M. Kuchling",
'author_email':"amk@amk.ca",
'url':"http://www.amk.ca/python/code/crypto",
'cmdclass' : {'build_ext':PCTBuildExt, 'build_py': PCTBuildPy},
'packages' : ["Crypto", "Crypto.Hash", "Crypto.Cipher", "Crypto.Util",
"Crypto.SelfTest",
"Crypto.SelfTest.Cipher",
"Crypto.SelfTest.Hash",
2008-09-15 18:59:25 -04:00
"Crypto.SelfTest.Util",
"Crypto.Protocol", "Crypto.PublicKey"],
'package_dir' : { "Crypto":"." },
# One module is defined here, because build_ext won't be
# called unless there's at least one extension module defined.
'ext_modules':[Extension("Crypto.Hash.MD2",
include_dirs=['src/'],
sources=["src/MD2.c"])],
}
# If we're running Python 2.3, add extra information
if hasattr(core, 'setup_keywords'):
if 'classifiers' in core.setup_keywords:
kw['classifiers'] = [
'Development Status :: 4 - Beta',
'License :: Public Domain',
'Intended Audience :: Developers',
'Operating System :: Unix',
'Operating System :: Microsoft :: Windows',
'Operating System :: MacOS :: MacOS X',
'Topic :: Security :: Cryptography',
]
if 'download_url' in core.setup_keywords:
kw['download_url'] = ('http://www.amk.ca/files/python/crypto/'
'%s-%s.tar.gz' % (kw['name'], kw['version']) )
core.setup(**kw)