Different approach for building pycryptodomex

This commit is contained in:
Helder Eijs 2018-02-03 22:33:01 +01:00
parent 71dbe289d8
commit 12599d6aa7

266
setup.py
View file

@ -26,11 +26,14 @@ except ImportError:
from distutils.core import Extension, Command, setup from distutils.core import Extension, Command, setup
from distutils.command.build_ext import build_ext from distutils.command.build_ext import build_ext
from distutils.command.build import build from distutils.command.build import build
from distutils.command.install_lib import install_lib
from distutils.errors import CCompilerError from distutils.errors import CCompilerError
import distutils import distutils
import platform import platform
import re, os, sys, shutil, struct import re
import os
import sys
import shutil
import struct
use_separate_namespace = os.path.isfile(".separate_namespace") use_separate_namespace = os.path.isfile(".separate_namespace")
@ -112,7 +115,7 @@ if version_tuple[2] is not None:
version_string += str(version_tuple[2]) version_string += str(version_tuple[2])
if sys.version[0:1] == '1': if sys.version[0:1] == '1':
raise RuntimeError ("The Python Cryptography Toolkit requires " raise RuntimeError("The Python Cryptography Toolkit requires "
"Python 2.x or 3.x to build.") "Python 2.x or 3.x to build.")
try: try:
@ -122,6 +125,7 @@ except ImportError:
# Python 2 # Python 2
from distutils.command.build_py import build_py from distutils.command.build_py import build_py
# Work around the print / print() issue with Python 2.x and 3.x. We only need # Work around the print / print() issue with Python 2.x and 3.x. We only need
# to print at one point of the code, which makes this easy # to print at one point of the code, which makes this easy
def PrintErr(*args, **kwd): def PrintErr(*args, **kwd):
@ -154,7 +158,7 @@ def test_compilation(program, extra_cc_options=None, extra_libraries=None, msg='
# Mute the compiler and the linker # Mute the compiler and the linker
if msg: if msg:
PrintErr("Testing support for %s" % msg) PrintErr("Testing support for %s" % msg)
if not (debug or os.name=='nt'): if not (debug or os.name == 'nt'):
old_stdout = os.dup(sys.stdout.fileno()) old_stdout = os.dup(sys.stdout.fileno())
old_stderr = os.dup(sys.stderr.fileno()) old_stderr = os.dup(sys.stderr.fileno())
dev_null = open(os.devnull, "w") dev_null = open(os.devnull, "w")
@ -201,73 +205,10 @@ def test_compilation(program, extra_cc_options=None, extra_libraries=None, msg='
return result return result
def change_module_name(file_name):
"""Change any occurrance of 'Crypto' to 'Cryptodome'."""
fd = open(file_name, "rt")
content = (fd.read().
replace("Crypto.", "Cryptodome.").
replace("Crypto ", "Cryptodome ").
replace("'Crypto'", "'Cryptodome'").
replace('"Crypto"', '"Cryptodome"'))
fd.close()
os.remove(file_name)
fd = open(file_name, "wt")
fd.write(content)
fd.close()
def rename_crypto_dir(build_lib):
"""Move all files from the 'Crypto' package to the
'Cryptodome' package in the given build directory"""
source = os.path.join(build_lib, "Crypto")
target = os.path.join(build_lib, "Cryptodome")
if not os.path.exists(target):
PrintErr("Creating directory %s" % target)
os.makedirs(target)
else:
PrintErr("Directory %s already exists" % target)
# Crypto package becomes Cryptodome
for root_src, dirs, files in os.walk(source):
root_dst, nr_repl = re.subn('Crypto', 'Cryptodome', root_src)
assert nr_repl == 1
for dir_name in dirs:
full_dir_name_dst = os.path.join(root_dst, dir_name)
if not os.path.exists(full_dir_name_dst):
os.makedirs(full_dir_name_dst)
for file_name in files:
full_file_name_src = os.path.join(root_src, file_name)
full_file_name_dst = os.path.join(root_dst, file_name)
PrintErr("Copying file %s to %s" % (full_file_name_src, full_file_name_dst))
shutil.copy2(full_file_name_src, full_file_name_dst)
if file_name.endswith(".py"):
change_module_name(full_file_name_dst)
class PCTBuildExt (build_ext): class PCTBuildExt (build_ext):
aesni_mod_names = "Crypto.Cipher._raw_aesni", aesni_mod_names = package_root + ".Cipher._raw_aesni",
def run(self):
build_ext.run(self)
if use_separate_namespace:
rename_crypto_dir(self.build_lib)
# Clean-up (extensions are built last)
crypto_dir = os.path.join(self.build_lib, "Crypto")
PrintErr("Deleting directory %s" % crypto_dir)
shutil.rmtree(crypto_dir)
# Avoid linking Python's dynamic library # Avoid linking Python's dynamic library
def get_libraries(self, ext): def get_libraries(self, ext):
@ -402,11 +343,6 @@ class PCTBuildPy(build_py):
retval.append(item) retval.append(item)
return retval return retval
def run(self):
build_py.run(self)
if use_separate_namespace:
rename_crypto_dir(self.build_lib)
class TestCommand(Command): class TestCommand(Command):
@ -475,76 +411,8 @@ class TestCommand(Command):
sub_commands = [ ('build', None) ] sub_commands = [ ('build', None) ]
class InstallLibCommand(install_lib): # Parameters for setup
packages = [
# Return the list of installed files
def get_outputs(self):
res = install_lib.get_outputs(self)
if not use_separate_namespace:
return res
# On some older distutils, the compiled objects are not included
# if they don't exist on the filesystem (which is not a check
# get_outputs() should do)
def norm(filename):
return os.path.normcase(out_file)
pure_outputs = []
for out_file in res:
out_file_norm = norm(out_file)
if out_file_norm.endswith('.py'):
pure_outputs.append(out_file_norm)
if self.compile and not [ pyc for pyc in res if norm(out_file).endswith('.pyc') ]:
res.extend([ (pure_py + 'c') for pure_py in pure_outputs ])
if self.optimize > 0 and not [ pyo for pyo in res if norm(out_file).endswith('.pyo') ]:
res.extend([ (pure_py + 'o') for pure_py in pure_outputs ])
# ---- end of fix ----
res2 = []
for full_fn in res:
if full_fn.startswith(self.install_dir):
partial_fn = full_fn[len(self.install_dir):].replace("Crypto","Cryptodome")
res2.append(self.install_dir + partial_fn)
else:
res2.append(full_fn)
return res2
system_bits = 8 * struct.calcsize("P")
if system_bits == 32:
multiply_cmod = [ 'src/multiply_32.c' ]
else:
multiply_cmod = [ 'src/multiply_64.c' ]
setup(
name = project_name,
version = version_string,
description = "Cryptographic library for Python",
long_description = longdesc,
author = "Helder Eijs",
author_email = "helderijs@gmail.com",
url = "http://www.pycryptodome.org",
platforms = 'Posix; MacOS X; Windows',
zip_safe = False,
classifiers = [
'Development Status :: 4 - Beta',
'License :: OSI Approved :: BSD License',
'License :: Public Domain',
'Intended Audience :: Developers',
'Operating System :: Unix',
'Operating System :: Microsoft :: Windows',
'Operating System :: MacOS :: MacOS X',
'Topic :: Security :: Cryptography',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.4',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
],
packages = [
"Crypto", "Crypto",
"Crypto.Cipher", "Crypto.Cipher",
"Crypto.Hash", "Crypto.Hash",
@ -565,9 +433,9 @@ setup(
"Crypto.SelfTest.Signature", "Crypto.SelfTest.Signature",
"Crypto.SelfTest.Util", "Crypto.SelfTest.Util",
"Crypto.SelfTest.Math", "Crypto.SelfTest.Math",
], ]
package_dir = { "Crypto": "lib/Crypto" }, package_dir = { "Crypto": "lib/Crypto" }
package_data = { package_data = {
"Crypto.SelfTest.Cipher" : [ "Crypto.SelfTest.Cipher" : [
"test_vectors/AES/*.rsp", "test_vectors/AES/*.rsp",
"test_vectors/TDES/*.rsp", "test_vectors/TDES/*.rsp",
@ -588,14 +456,15 @@ setup(
"test_vectors/ECC/*.*", "test_vectors/ECC/*.*",
], ],
"Crypto.Math" : [ "mpir.dll" ], "Crypto.Math" : [ "mpir.dll" ],
}, }
cmdclass = {
'build_ext':PCTBuildExt, system_bits = 8 * struct.calcsize("P")
'build_py': PCTBuildPy, if system_bits == 32:
'test': TestCommand, multiply_cmod = [ 'src/multiply_32.c' ]
'install_lib' : InstallLibCommand, else:
}, multiply_cmod = [ 'src/multiply_64.c' ]
ext_modules = [
ext_modules = [
# Hash functions # Hash functions
Extension("Crypto.Hash._MD2", Extension("Crypto.Hash._MD2",
include_dirs=['src/'], include_dirs=['src/'],
@ -703,6 +572,93 @@ setup(
include_dirs=['src/'], include_dirs=['src/'],
sources=['src/montgomery.c', 'src/siphash.c', 'src/montgomery_utils.c'] + multiply_cmod, sources=['src/montgomery.c', 'src/siphash.c', 'src/montgomery_utils.c'] + multiply_cmod,
), ),
]
]
if use_separate_namespace:
# Fix-up setup information
for i in range(len(packages)):
packages[i] = packages[i].replace("Crypto", "Cryptodome")
package_dir = { "Cryptodome": "lib/Cryptodome" }
new_package_data = {}
for k,v in package_data.items():
new_package_data[k.replace("Crypto", "Cryptodome")] = v
package_data = new_package_data
for ext in ext_modules:
ext.name = ext.name.replace("Crypto", "Cryptodome")
# Recreate lib/Cryptodome from scratch
try:
shutil.rmtree("lib/Cryptodome")
except OSError:
pass
for root_src, dirs, files in os.walk("lib/Crypto"):
root_dst, nr_repl = re.subn('Crypto', 'Cryptodome', root_src)
assert nr_repl == 1
for dir_name in dirs:
full_dir_name_dst = os.path.join(root_dst, dir_name)
if not os.path.exists(full_dir_name_dst):
os.makedirs(full_dir_name_dst)
for file_name in files:
full_file_name_src = os.path.join(root_src, file_name)
full_file_name_dst = os.path.join(root_dst, file_name)
PrintErr("Copying file %s to %s" % (full_file_name_src, full_file_name_dst))
shutil.copy2(full_file_name_src, full_file_name_dst)
if not full_file_name_dst.endswith(".py"):
continue
fd = open(full_file_name_dst, "rt")
content = (fd.read().
replace("Crypto.", "Cryptodome.").
replace("Crypto ", "Cryptodome ").
replace("'Crypto'", "'Cryptodome'").
replace('"Crypto"', '"Cryptodome"'))
fd.close()
os.remove(full_file_name_dst)
fd = open(full_file_name_dst, "wt")
fd.write(content)
fd.close()
setup(
name = project_name,
version = version_string,
description = "Cryptographic library for Python",
long_description = longdesc,
author = "Helder Eijs",
author_email = "helderijs@gmail.com",
url = "http://www.pycryptodome.org",
platforms = 'Posix; MacOS X; Windows',
zip_safe = False,
classifiers = [
'Development Status :: 4 - Beta',
'License :: OSI Approved :: BSD License',
'License :: Public Domain',
'Intended Audience :: Developers',
'Operating System :: Unix',
'Operating System :: Microsoft :: Windows',
'Operating System :: MacOS :: MacOS X',
'Topic :: Security :: Cryptography',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.4',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
],
packages = packages,
package_dir = package_dir,
package_data = package_data,
cmdclass = {
'build_ext':PCTBuildExt,
'build_py': PCTBuildPy,
'test': TestCommand,
},
ext_modules = ext_modules,
) )