1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
import os.path, shutil, zipfile
from .builder import *
from .utils import *
from .curl import *
class PycurlBuilder(Builder):
def __init__(self, **kwargs):
self.python_release = kwargs.pop('python_release')
super(PycurlBuilder, self).__init__(**kwargs)
# vc_version is specified externally for bconf/BuildConfig
assert self.bconf.vc_version == PYTHON_VC_VERSIONS[self.python_release]
@property
def python_path(self):
if self.bconf.build_wheels:
python_path = os.path.join(self.bconf.archives_path, 'venv-%s-%s' % (self.python_release, self.bconf.bitness), 'scripts', 'python')
else:
python_path = PythonBinary(self.python_release, self.bconf.bitness).executable_path
return python_path
@property
def platform_indicator(self):
platform_indicators = {32: 'win32', 64: 'win-amd64'}
return platform_indicators[self.bconf.bitness]
def build(self, targets):
libcurl_builder = LibcurlBuilder(bconf=self.bconf)
libcurl_dir = os.path.join(os.path.abspath(libcurl_builder.output_dir_path), 'dist')
dll_paths = libcurl_builder.dll_paths
if self.bconf.use_zlib:
zlib_builder = ZlibBuilder(bconf=self.bconf)
dll_paths += zlib_builder.dll_paths
dll_paths = [os.path.abspath(dll_path) for dll_path in dll_paths]
with in_dir(self.build_dir_name):
dest_lib_path = 'build/lib.%s-%s' % (self.platform_indicator,
self.python_release)
# exists for building additional targets for the same python version
mkdir_p(dest_lib_path)
if self.use_dlls:
for dll_path in dll_paths:
shutil.copy(dll_path, dest_lib_path)
with self.execute_batch() as b:
b.add("%s setup.py docstrings" % (self.python_path,))
if self.use_dlls:
libcurl_arg = '--use-libcurl-dll'
else:
libcurl_arg = '--libcurl-lib-name=libcurl_a.lib'
if self.bconf.use_openssl:
libcurl_arg += ' --with-openssl'
if self.bconf.openssl_version_tuple >= (1, 1):
libcurl_arg += ' --openssl-lib-name=""'
openssl_builder = OpensslBuilder(bconf=self.bconf)
b.add("set include=%%include%%;%s" % openssl_builder.include_path)
b.add("set lib=%%lib%%;%s" % openssl_builder.lib_path)
#if build_wheels:
#b.add("call %s" % os.path.join('..', 'venv-%s-%s' % (self.python_release, self.bconf.bitness), 'Scripts', 'activate'))
if self.bconf.build_wheels:
targets = targets + ['bdist_wheel']
if self.bconf.libcurl_version_tuple >= (7, 60, 0):
# As of 7.60.0 libcurl does not include its dependencies into
# its static libraries.
# libcurl_a.lib in 7.59.0 is 30 mb.
# libcurl_a.lib in 7.60.0 is 2 mb.
# https://github.com/curl/curl/pull/2474 is most likely culprit.
# As a result we need to specify all of the libraries that
# libcurl depends on here, plus the library paths,
# plus even windows standard libraries for good measure.
if self.bconf.use_zlib:
zlib_builder = ZlibBuilder(bconf=self.bconf)
libcurl_arg += ' --link-arg=/LIBPATH:%s' % zlib_builder.lib_path
libcurl_arg += ' --link-arg=zlib.lib'
if self.bconf.use_openssl:
openssl_builder = OpensslBuilder(bconf=self.bconf)
libcurl_arg += ' --link-arg=/LIBPATH:%s' % openssl_builder.lib_path
# openssl 1.1
libcurl_arg += ' --link-arg=libcrypto.lib'
libcurl_arg += ' --link-arg=libssl.lib'
libcurl_arg += ' --link-arg=crypt32.lib'
libcurl_arg += ' --link-arg=advapi32.lib'
if self.bconf.use_cares:
cares_builder = CaresBuilder(bconf=self.bconf)
libcurl_arg += ' --link-arg=/LIBPATH:%s' % cares_builder.lib_path
libcurl_arg += ' --link-arg=libcares.lib'
if self.bconf.use_libssh2:
libssh2_builder = Libssh2Builder(bconf=self.bconf)
libcurl_arg += ' --link-arg=/LIBPATH:%s' % libssh2_builder.lib_path
libcurl_arg += ' --link-arg=libssh2.lib'
if self.bconf.use_nghttp2:
nghttp2_builder = Nghttp2Builder(bconf=self.bconf)
libcurl_arg += ' --link-arg=/LIBPATH:%s' % nghttp2_builder.lib_path
libcurl_arg += ' --link-arg=nghttp2_static.lib'
if self.bconf.vc_version == 'vc9':
# this is for normaliz.lib
libcurl_builder = LibcurlBuilder(bconf=self.bconf)
libcurl_arg += ' --link-arg=/LIBPATH:%s' % libcurl_builder.lib_path
# We always use normaliz.lib, but it may come from
# "standard" msvc location or from libcurl's lib dir for msvc9
libcurl_arg += ' --link-arg=normaliz.lib'
libcurl_arg += ' --link-arg=user32.lib'
b.add("%s setup.py %s --curl-dir=%s %s" % (
self.python_path, ' '.join(targets), libcurl_dir, libcurl_arg))
# Fixing of bizarre paths in created zip archives,
# no longer relevant because we only keep wheels
if False and 'bdist' in targets:
zip_basename_orig = 'pycurl-%s.%s.zip' % (
self.bconf.pycurl_version, self.platform_indicator)
zip_basename_new = 'pycurl-%s.%s-py%s.zip' % (
self.bconf.pycurl_version, self.platform_indicator, self.python_release)
with zipfile.ZipFile('dist/%s' % zip_basename_orig, 'r') as src_zip:
with zipfile.ZipFile('dist/%s' % zip_basename_new, 'w') as dest_zip:
for name in src_zip.namelist():
parts = name.split('/')
while True:
popped = parts.pop(0)
if popped == 'python%s' % self.python_release.dotless or popped.startswith('venv-'):
break
assert len(parts) > 0
new_name = '/'.join(parts)
print('Recompressing %s -> %s' % (name, new_name))
member = src_zip.open(name)
dest_zip.writestr(new_name, member.read(), zipfile.ZIP_DEFLATED)
@property
def build_dir_name(self):
return 'pycurl-%s-py%s-%s' % (self.bconf.pycurl_version, self.python_release, self.bconf.vc_tag)
def prepare_tree(self):
#fetch('https://dl.bintray.com/pycurl/pycurl/pycurl-%s.tar.gz' % pycurl_version)
if os.path.exists(self.build_dir_name):
# shutil.rmtree is incapable of removing .git directory because it contains
# files marked read-only (tested on python 2.7 and 3.6)
#shutil.rmtree('pycurl-%s' % config.pycurl_version)
rm_rf(self.bconf, self.build_dir_name)
#check_call([tar_path, 'xf', 'pycurl-%s.tar.gz' % pycurl_version])
shutil.copytree('c:/dev/pycurl', self.build_dir_name)
|