|
rpm-build |
d9acb6 |
import os, re, sys, subprocess
|
|
rpm-build |
d9acb6 |
import tarfile
|
|
rpm-build |
d9acb6 |
from distutils import log, version
|
|
rpm-build |
d9acb6 |
from contextlib import closing
|
|
rpm-build |
d9acb6 |
from ftplib import FTP
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
from urlparse import urljoin, unquote, urlparse
|
|
rpm-build |
d9acb6 |
from urllib import urlretrieve, urlopen, urlcleanup
|
|
rpm-build |
d9acb6 |
except ImportError:
|
|
rpm-build |
d9acb6 |
from urllib.parse import urljoin, unquote, urlparse
|
|
rpm-build |
d9acb6 |
from urllib.request import urlretrieve, urlopen, urlcleanup
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
multi_make_options = []
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
import multiprocessing
|
|
rpm-build |
d9acb6 |
cpus = multiprocessing.cpu_count()
|
|
rpm-build |
d9acb6 |
if cpus > 1:
|
|
rpm-build |
d9acb6 |
if cpus > 5:
|
|
rpm-build |
d9acb6 |
cpus = 5
|
|
rpm-build |
d9acb6 |
multi_make_options = ['-j%d' % (cpus+1)]
|
|
rpm-build |
d9acb6 |
except:
|
|
rpm-build |
d9acb6 |
pass
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
# use pre-built libraries on Windows
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def download_and_extract_windows_binaries(destdir):
|
|
rpm-build |
d9acb6 |
url = "https://github.com/mhils/libxml2-win-binaries/releases"
|
|
rpm-build |
d9acb6 |
filenames = list(_list_dir_urllib(url))
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
release_path = "/download/%s/" % find_max_version(
|
|
rpm-build |
d9acb6 |
"library release", filenames, re.compile(r"/releases/tag/([0-9.]+[0-9])$"))
|
|
rpm-build |
d9acb6 |
url += release_path
|
|
rpm-build |
d9acb6 |
filenames = [
|
|
rpm-build |
d9acb6 |
filename.rsplit('/', 1)[1]
|
|
rpm-build |
d9acb6 |
for filename in filenames
|
|
rpm-build |
d9acb6 |
if release_path in filename
|
|
rpm-build |
d9acb6 |
]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
arch = "win64" if sys.maxsize > 2**32 else "win32"
|
|
rpm-build |
d9acb6 |
if sys.version_info < (3, 5):
|
|
rpm-build |
d9acb6 |
arch = 'vs2008.' + arch
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
libs = {}
|
|
rpm-build |
d9acb6 |
for libname in ['libxml2', 'libxslt', 'zlib', 'iconv']:
|
|
rpm-build |
d9acb6 |
libs[libname] = "%s-%s.%s.zip" % (
|
|
rpm-build |
d9acb6 |
libname,
|
|
rpm-build |
d9acb6 |
find_max_version(libname, filenames),
|
|
rpm-build |
d9acb6 |
arch,
|
|
rpm-build |
d9acb6 |
)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
if not os.path.exists(destdir):
|
|
rpm-build |
d9acb6 |
os.makedirs(destdir)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
for libname, libfn in libs.items():
|
|
rpm-build |
d9acb6 |
srcfile = urljoin(url, libfn)
|
|
rpm-build |
d9acb6 |
destfile = os.path.join(destdir, libfn)
|
|
rpm-build |
d9acb6 |
if os.path.exists(destfile + ".keep"):
|
|
rpm-build |
d9acb6 |
print('Using local copy of "{}"'.format(srcfile))
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
print('Retrieving "%s" to "%s"' % (srcfile, destfile))
|
|
rpm-build |
d9acb6 |
urlcleanup() # work around FTP bug 27973 in Py2.7.12+
|
|
rpm-build |
d9acb6 |
urlretrieve(srcfile, destfile)
|
|
rpm-build |
d9acb6 |
d = unpack_zipfile(destfile, destdir)
|
|
rpm-build |
d9acb6 |
libs[libname] = d
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
return libs
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def find_top_dir_of_zipfile(zipfile):
|
|
rpm-build |
d9acb6 |
topdir = None
|
|
rpm-build |
d9acb6 |
files = [f.filename for f in zipfile.filelist]
|
|
rpm-build |
d9acb6 |
dirs = [d for d in files if d.endswith('/')]
|
|
rpm-build |
d9acb6 |
if dirs:
|
|
rpm-build |
d9acb6 |
dirs.sort(key=len)
|
|
rpm-build |
d9acb6 |
topdir = dirs[0]
|
|
rpm-build |
d9acb6 |
topdir = topdir[:topdir.index("/")+1]
|
|
rpm-build |
d9acb6 |
for path in files:
|
|
rpm-build |
d9acb6 |
if not path.startswith(topdir):
|
|
rpm-build |
d9acb6 |
topdir = None
|
|
rpm-build |
d9acb6 |
break
|
|
rpm-build |
d9acb6 |
assert topdir, (
|
|
rpm-build |
d9acb6 |
"cannot determine single top-level directory in zip file %s" %
|
|
rpm-build |
d9acb6 |
zipfile.filename)
|
|
rpm-build |
d9acb6 |
return topdir.rstrip('/')
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def unpack_zipfile(zipfn, destdir):
|
|
rpm-build |
d9acb6 |
assert zipfn.endswith('.zip')
|
|
rpm-build |
d9acb6 |
import zipfile
|
|
rpm-build |
d9acb6 |
print('Unpacking %s into %s' % (os.path.basename(zipfn), destdir))
|
|
rpm-build |
d9acb6 |
f = zipfile.ZipFile(zipfn)
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
extracted_dir = os.path.join(destdir, find_top_dir_of_zipfile(f))
|
|
rpm-build |
d9acb6 |
f.extractall(path=destdir)
|
|
rpm-build |
d9acb6 |
finally:
|
|
rpm-build |
d9acb6 |
f.close()
|
|
rpm-build |
d9acb6 |
assert os.path.exists(extracted_dir), 'missing: %s' % extracted_dir
|
|
rpm-build |
d9acb6 |
return extracted_dir
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def get_prebuilt_libxml2xslt(download_dir, static_include_dirs, static_library_dirs):
|
|
rpm-build |
d9acb6 |
assert sys.platform.startswith('win')
|
|
rpm-build |
d9acb6 |
libs = download_and_extract_windows_binaries(download_dir)
|
|
rpm-build |
d9acb6 |
for libname, path in libs.items():
|
|
rpm-build |
d9acb6 |
i = os.path.join(path, 'include')
|
|
rpm-build |
d9acb6 |
l = os.path.join(path, 'lib')
|
|
rpm-build |
d9acb6 |
assert os.path.exists(i), 'does not exist: %s' % i
|
|
rpm-build |
d9acb6 |
assert os.path.exists(l), 'does not exist: %s' % l
|
|
rpm-build |
d9acb6 |
static_include_dirs.append(i)
|
|
rpm-build |
d9acb6 |
static_library_dirs.append(l)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
## Routines to download and build libxml2/xslt from sources:
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
LIBXML2_LOCATION = 'ftp://xmlsoft.org/libxml2/'
|
|
rpm-build |
d9acb6 |
LIBICONV_LOCATION = 'ftp://ftp.gnu.org/pub/gnu/libiconv/'
|
|
rpm-build |
d9acb6 |
ZLIB_LOCATION = 'http://zlib.net/'
|
|
rpm-build |
d9acb6 |
match_libfile_version = re.compile('^[^-]*-([.0-9-]+)[.].*').match
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _find_content_encoding(response, default='iso8859-1'):
|
|
rpm-build |
d9acb6 |
from email.message import Message
|
|
rpm-build |
d9acb6 |
content_type = response.headers.get('Content-Type')
|
|
rpm-build |
d9acb6 |
if content_type:
|
|
rpm-build |
d9acb6 |
msg = Message()
|
|
rpm-build |
d9acb6 |
msg.add_header('Content-Type', content_type)
|
|
rpm-build |
d9acb6 |
charset = msg.get_content_charset(default)
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
charset = default
|
|
rpm-build |
d9acb6 |
return charset
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def remote_listdir(url):
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
return _list_dir_urllib(url)
|
|
rpm-build |
d9acb6 |
except IOError:
|
|
rpm-build |
d9acb6 |
assert url.lower().startswith('ftp://')
|
|
rpm-build |
d9acb6 |
print("Requesting with urllib failed. Falling back to ftplib. Proxy argument will be ignored")
|
|
rpm-build |
d9acb6 |
return _list_dir_ftplib(url)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _list_dir_ftplib(url):
|
|
rpm-build |
d9acb6 |
parts = urlparse(url)
|
|
rpm-build |
d9acb6 |
ftp = FTP(parts.netloc)
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
ftp.login()
|
|
rpm-build |
d9acb6 |
ftp.cwd(parts.path)
|
|
rpm-build |
d9acb6 |
data = []
|
|
rpm-build |
d9acb6 |
ftp.dir(data.append)
|
|
rpm-build |
d9acb6 |
finally:
|
|
rpm-build |
d9acb6 |
ftp.quit()
|
|
rpm-build |
d9acb6 |
return parse_text_ftplist("\n".join(data))
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def _list_dir_urllib(url):
|
|
rpm-build |
d9acb6 |
with closing(urlopen(url)) as res:
|
|
rpm-build |
d9acb6 |
charset = _find_content_encoding(res)
|
|
rpm-build |
d9acb6 |
content_type = res.headers.get('Content-Type')
|
|
rpm-build |
d9acb6 |
data = res.read()
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
data = data.decode(charset)
|
|
rpm-build |
d9acb6 |
if content_type and content_type.startswith('text/html'):
|
|
rpm-build |
d9acb6 |
files = parse_html_filelist(data)
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
files = parse_text_ftplist(data)
|
|
rpm-build |
d9acb6 |
return files
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def http_listfiles(url, re_pattern):
|
|
rpm-build |
d9acb6 |
with closing(urlopen(url)) as res:
|
|
rpm-build |
d9acb6 |
charset = _find_content_encoding(res)
|
|
rpm-build |
d9acb6 |
data = res.read()
|
|
rpm-build |
d9acb6 |
files = re.findall(re_pattern, data.decode(charset))
|
|
rpm-build |
d9acb6 |
return files
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def parse_text_ftplist(s):
|
|
rpm-build |
d9acb6 |
for line in s.splitlines():
|
|
rpm-build |
d9acb6 |
if not line.startswith('d'):
|
|
rpm-build |
d9acb6 |
# -rw-r--r-- 1 ftp ftp 476 Sep 1 2011 md5sum.txt
|
|
rpm-build |
d9acb6 |
# Last (9th) element is 'md5sum.txt' in the above example, but there
|
|
rpm-build |
d9acb6 |
# may be variations, so we discard only the first 8 entries.
|
|
rpm-build |
d9acb6 |
yield line.split(None, 8)[-1]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def parse_html_filelist(s):
|
|
rpm-build |
d9acb6 |
re_href = re.compile(
|
|
rpm-build |
d9acb6 |
r'<a\s+(?:[^>]*\s+)?href=["\']([^;?"\']+?)[;?"\']',
|
|
rpm-build |
d9acb6 |
re.I|re.M)
|
|
rpm-build |
d9acb6 |
links = set(re_href.findall(s))
|
|
rpm-build |
d9acb6 |
for link in links:
|
|
rpm-build |
d9acb6 |
if not link.endswith('/'):
|
|
rpm-build |
d9acb6 |
yield unquote(link)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def tryint(s):
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
return int(s)
|
|
rpm-build |
d9acb6 |
except ValueError:
|
|
rpm-build |
d9acb6 |
return s
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def download_libxml2(dest_dir, version=None):
|
|
rpm-build |
d9acb6 |
"""Downloads libxml2, returning the filename where the library was downloaded"""
|
|
rpm-build |
d9acb6 |
version_re = re.compile(r'LATEST_LIBXML2_IS_([0-9.]+[0-9])')
|
|
rpm-build |
d9acb6 |
filename = 'libxml2-%s.tar.gz'
|
|
rpm-build |
d9acb6 |
return download_library(dest_dir, LIBXML2_LOCATION, 'libxml2',
|
|
rpm-build |
d9acb6 |
version_re, filename, version=version)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def download_libxslt(dest_dir, version=None):
|
|
rpm-build |
d9acb6 |
"""Downloads libxslt, returning the filename where the library was downloaded"""
|
|
rpm-build |
d9acb6 |
version_re = re.compile(r'LATEST_LIBXSLT_IS_([0-9.]+[0-9])')
|
|
rpm-build |
d9acb6 |
filename = 'libxslt-%s.tar.gz'
|
|
rpm-build |
d9acb6 |
return download_library(dest_dir, LIBXML2_LOCATION, 'libxslt',
|
|
rpm-build |
d9acb6 |
version_re, filename, version=version)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def download_libiconv(dest_dir, version=None):
|
|
rpm-build |
d9acb6 |
"""Downloads libiconv, returning the filename where the library was downloaded"""
|
|
rpm-build |
d9acb6 |
version_re = re.compile(r'^libiconv-([0-9.]+[0-9]).tar.gz$')
|
|
rpm-build |
d9acb6 |
filename = 'libiconv-%s.tar.gz'
|
|
rpm-build |
d9acb6 |
return download_library(dest_dir, LIBICONV_LOCATION, 'libiconv',
|
|
rpm-build |
d9acb6 |
version_re, filename, version=version)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def download_zlib(dest_dir, version):
|
|
rpm-build |
d9acb6 |
"""Downloads zlib, returning the filename where the library was downloaded"""
|
|
rpm-build |
d9acb6 |
version_re = re.compile(r'zlib-([0-9.]+[0-9]).tar.gz')
|
|
rpm-build |
d9acb6 |
filename = 'zlib-%s.tar.gz'
|
|
rpm-build |
d9acb6 |
return download_library(dest_dir, ZLIB_LOCATION, 'zlib',
|
|
rpm-build |
d9acb6 |
version_re, filename, version=version)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def find_max_version(libname, filenames, version_re=None):
|
|
rpm-build |
d9acb6 |
if version_re is None:
|
|
rpm-build |
d9acb6 |
version_re = re.compile(r'%s-([0-9.]+[0-9])' % libname)
|
|
rpm-build |
d9acb6 |
versions = []
|
|
rpm-build |
d9acb6 |
for fn in filenames:
|
|
rpm-build |
d9acb6 |
match = version_re.search(fn)
|
|
rpm-build |
d9acb6 |
if match:
|
|
rpm-build |
d9acb6 |
version_string = match.group(1)
|
|
rpm-build |
d9acb6 |
versions.append((tuple(map(tryint, version_string.split('.'))),
|
|
rpm-build |
d9acb6 |
version_string))
|
|
rpm-build |
d9acb6 |
if not versions:
|
|
rpm-build |
d9acb6 |
raise Exception(
|
|
rpm-build |
d9acb6 |
"Could not find the most current version of %s from the files: %s" % (
|
|
rpm-build |
d9acb6 |
libname, filenames))
|
|
rpm-build |
d9acb6 |
versions.sort()
|
|
rpm-build |
d9acb6 |
version_string = versions[-1][-1]
|
|
rpm-build |
d9acb6 |
print('Latest version of %s is %s' % (libname, version_string))
|
|
rpm-build |
d9acb6 |
return version_string
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def download_library(dest_dir, location, name, version_re, filename, version=None):
|
|
rpm-build |
d9acb6 |
if version is None:
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
if location.startswith('ftp://'):
|
|
rpm-build |
d9acb6 |
fns = remote_listdir(location)
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
fns = http_listfiles(location, filename.replace('%s', '(?:[0-9.]+[0-9])'))
|
|
rpm-build |
d9acb6 |
version = find_max_version(name, fns, version_re)
|
|
rpm-build |
d9acb6 |
except IOError:
|
|
rpm-build |
d9acb6 |
# network failure - maybe we have the files already?
|
|
rpm-build |
d9acb6 |
latest = (0,0,0)
|
|
rpm-build |
d9acb6 |
fns = os.listdir(dest_dir)
|
|
rpm-build |
d9acb6 |
for fn in fns:
|
|
rpm-build |
d9acb6 |
if fn.startswith(name+'-'):
|
|
rpm-build |
d9acb6 |
match = match_libfile_version(fn)
|
|
rpm-build |
d9acb6 |
if match:
|
|
rpm-build |
d9acb6 |
version_tuple = tuple(map(tryint, match.group(1).split('.')))
|
|
rpm-build |
d9acb6 |
if version_tuple > latest:
|
|
rpm-build |
d9acb6 |
latest = version_tuple
|
|
rpm-build |
d9acb6 |
filename = fn
|
|
rpm-build |
d9acb6 |
version = None
|
|
rpm-build |
d9acb6 |
if latest == (0,0,0):
|
|
rpm-build |
d9acb6 |
raise
|
|
rpm-build |
d9acb6 |
if version:
|
|
rpm-build |
d9acb6 |
filename = filename % version
|
|
rpm-build |
d9acb6 |
full_url = urljoin(location, filename)
|
|
rpm-build |
d9acb6 |
dest_filename = os.path.join(dest_dir, filename)
|
|
rpm-build |
d9acb6 |
if os.path.exists(dest_filename):
|
|
rpm-build |
d9acb6 |
print(('Using existing %s downloaded into %s '
|
|
rpm-build |
d9acb6 |
'(delete this file if you want to re-download the package)') % (
|
|
rpm-build |
d9acb6 |
name, dest_filename))
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
print('Downloading %s into %s from %s' % (name, dest_filename, full_url))
|
|
rpm-build |
d9acb6 |
urlcleanup() # work around FTP bug 27973 in Py2.7.12
|
|
rpm-build |
d9acb6 |
urlretrieve(full_url, dest_filename)
|
|
rpm-build |
d9acb6 |
return dest_filename
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def unpack_tarball(tar_filename, dest):
|
|
rpm-build |
d9acb6 |
print('Unpacking %s into %s' % (os.path.basename(tar_filename), dest))
|
|
rpm-build |
d9acb6 |
tar = tarfile.open(tar_filename)
|
|
rpm-build |
d9acb6 |
base_dir = None
|
|
rpm-build |
d9acb6 |
for member in tar:
|
|
rpm-build |
d9acb6 |
base_name = member.name.split('/')[0]
|
|
rpm-build |
d9acb6 |
if base_dir is None:
|
|
rpm-build |
d9acb6 |
base_dir = base_name
|
|
rpm-build |
d9acb6 |
elif base_dir != base_name:
|
|
rpm-build |
d9acb6 |
print('Unexpected path in %s: %s' % (tar_filename, base_name))
|
|
rpm-build |
d9acb6 |
tar.extractall(dest)
|
|
rpm-build |
d9acb6 |
tar.close()
|
|
rpm-build |
d9acb6 |
return os.path.join(dest, base_dir)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def call_subprocess(cmd, **kw):
|
|
rpm-build |
d9acb6 |
import subprocess
|
|
rpm-build |
d9acb6 |
cwd = kw.get('cwd', '.')
|
|
rpm-build |
d9acb6 |
cmd_desc = ' '.join(cmd)
|
|
rpm-build |
d9acb6 |
log.info('Running "%s" in %s' % (cmd_desc, cwd))
|
|
rpm-build |
d9acb6 |
returncode = subprocess.call(cmd, **kw)
|
|
rpm-build |
d9acb6 |
if returncode:
|
|
rpm-build |
d9acb6 |
raise Exception('Command "%s" returned code %s' % (cmd_desc, returncode))
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def safe_mkdir(dir):
|
|
rpm-build |
d9acb6 |
if not os.path.exists(dir):
|
|
rpm-build |
d9acb6 |
os.makedirs(dir)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def cmmi(configure_cmd, build_dir, multicore=None, **call_setup):
|
|
rpm-build |
d9acb6 |
print('Starting build in %s' % build_dir)
|
|
rpm-build |
d9acb6 |
call_subprocess(configure_cmd, cwd=build_dir, **call_setup)
|
|
rpm-build |
d9acb6 |
if not multicore:
|
|
rpm-build |
d9acb6 |
make_jobs = multi_make_options
|
|
rpm-build |
d9acb6 |
elif int(multicore) > 1:
|
|
rpm-build |
d9acb6 |
make_jobs = ['-j%s' % multicore]
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
make_jobs = []
|
|
rpm-build |
d9acb6 |
call_subprocess(
|
|
rpm-build |
d9acb6 |
['make'] + make_jobs,
|
|
rpm-build |
d9acb6 |
cwd=build_dir, **call_setup)
|
|
rpm-build |
d9acb6 |
call_subprocess(
|
|
rpm-build |
d9acb6 |
['make'] + make_jobs + ['install'],
|
|
rpm-build |
d9acb6 |
cwd=build_dir, **call_setup)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def configure_darwin_env(env_setup):
|
|
rpm-build |
d9acb6 |
import platform
|
|
rpm-build |
d9acb6 |
# check target architectures on MacOS-X (ppc, i386, x86_64)
|
|
rpm-build |
d9acb6 |
major_version, minor_version = tuple(map(int, platform.mac_ver()[0].split('.')[:2]))
|
|
rpm-build |
d9acb6 |
if major_version > 7:
|
|
rpm-build |
d9acb6 |
# Check to see if ppc is supported (XCode4 drops ppc support)
|
|
rpm-build |
d9acb6 |
include_ppc = True
|
|
rpm-build |
d9acb6 |
if os.path.exists('/usr/bin/xcodebuild'):
|
|
rpm-build |
d9acb6 |
pipe = subprocess.Popen(['/usr/bin/xcodebuild', '-version'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
rpm-build |
d9acb6 |
out, _ = pipe.communicate()
|
|
rpm-build |
d9acb6 |
xcode_version = (out.decode('utf8').splitlines() or [''])[0]
|
|
rpm-build |
d9acb6 |
# Also parse only first digit, because 3.2.1 can't be parsed nicely
|
|
rpm-build |
d9acb6 |
if (xcode_version.startswith('Xcode') and
|
|
rpm-build |
d9acb6 |
version.StrictVersion(xcode_version.split()[1]) >= version.StrictVersion('4.0')):
|
|
rpm-build |
d9acb6 |
include_ppc = False
|
|
rpm-build |
d9acb6 |
arch_string = ""
|
|
rpm-build |
d9acb6 |
if include_ppc:
|
|
rpm-build |
d9acb6 |
arch_string = "-arch ppc "
|
|
rpm-build |
d9acb6 |
if minor_version < 6:
|
|
rpm-build |
d9acb6 |
env_default = {
|
|
rpm-build |
d9acb6 |
'CFLAGS': arch_string + "-arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -O2",
|
|
rpm-build |
d9acb6 |
'LDFLAGS': arch_string + "-arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk",
|
|
rpm-build |
d9acb6 |
'MACOSX_DEPLOYMENT_TARGET': "10.3"
|
|
rpm-build |
d9acb6 |
}
|
|
rpm-build |
d9acb6 |
else:
|
|
rpm-build |
d9acb6 |
env_default = {
|
|
rpm-build |
d9acb6 |
'CFLAGS': arch_string + "-arch i386 -arch x86_64 -O2",
|
|
rpm-build |
d9acb6 |
'LDFLAGS': arch_string + "-arch i386 -arch x86_64",
|
|
rpm-build |
d9acb6 |
'MACOSX_DEPLOYMENT_TARGET': "10.6"
|
|
rpm-build |
d9acb6 |
}
|
|
rpm-build |
d9acb6 |
env = os.environ.copy()
|
|
rpm-build |
d9acb6 |
env_default.update(env)
|
|
rpm-build |
d9acb6 |
env_setup['env'] = env_default
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
def build_libxml2xslt(download_dir, build_dir,
|
|
rpm-build |
d9acb6 |
static_include_dirs, static_library_dirs,
|
|
rpm-build |
d9acb6 |
static_cflags, static_binaries,
|
|
rpm-build |
d9acb6 |
libxml2_version=None,
|
|
rpm-build |
d9acb6 |
libxslt_version=None,
|
|
rpm-build |
d9acb6 |
libiconv_version=None,
|
|
rpm-build |
d9acb6 |
zlib_version=None,
|
|
rpm-build |
d9acb6 |
multicore=None):
|
|
rpm-build |
d9acb6 |
safe_mkdir(download_dir)
|
|
rpm-build |
d9acb6 |
safe_mkdir(build_dir)
|
|
rpm-build |
d9acb6 |
zlib_dir = unpack_tarball(download_zlib(download_dir, zlib_version), build_dir)
|
|
rpm-build |
d9acb6 |
libiconv_dir = unpack_tarball(download_libiconv(download_dir, libiconv_version), build_dir)
|
|
rpm-build |
d9acb6 |
libxml2_dir = unpack_tarball(download_libxml2(download_dir, libxml2_version), build_dir)
|
|
rpm-build |
d9acb6 |
libxslt_dir = unpack_tarball(download_libxslt(download_dir, libxslt_version), build_dir)
|
|
rpm-build |
d9acb6 |
prefix = os.path.join(os.path.abspath(build_dir), 'libxml2')
|
|
rpm-build |
d9acb6 |
safe_mkdir(prefix)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
call_setup = {}
|
|
rpm-build |
d9acb6 |
if sys.platform == 'darwin':
|
|
rpm-build |
d9acb6 |
configure_darwin_env(call_setup)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
configure_cmd = ['./configure',
|
|
rpm-build |
d9acb6 |
'--disable-dependency-tracking',
|
|
rpm-build |
d9acb6 |
'--disable-shared',
|
|
rpm-build |
d9acb6 |
'--prefix=%s' % prefix,
|
|
rpm-build |
d9acb6 |
]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
# build zlib
|
|
rpm-build |
d9acb6 |
zlib_configure_cmd = [
|
|
rpm-build |
d9acb6 |
'./configure',
|
|
rpm-build |
d9acb6 |
'--prefix=%s' % prefix,
|
|
rpm-build |
d9acb6 |
]
|
|
rpm-build |
d9acb6 |
cmmi(zlib_configure_cmd, zlib_dir, multicore, **call_setup)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
# build libiconv
|
|
rpm-build |
d9acb6 |
cmmi(configure_cmd, libiconv_dir, multicore, **call_setup)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
# build libxml2
|
|
rpm-build |
d9acb6 |
libxml2_configure_cmd = configure_cmd + [
|
|
rpm-build |
d9acb6 |
'--without-python',
|
|
rpm-build |
d9acb6 |
'--with-iconv=%s' % prefix,
|
|
rpm-build |
d9acb6 |
'--with-zlib=%s' % prefix,
|
|
rpm-build |
d9acb6 |
]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
if not libxml2_version:
|
|
rpm-build |
d9acb6 |
libxml2_version = os.path.basename(libxml2_dir).split('-', 1)[-1]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
if tuple(map(tryint, libxml2_version.split('-', 1)[0].split('.'))) >= (2, 9, 5):
|
|
rpm-build |
d9acb6 |
libxml2_configure_cmd.append('--without-lzma') # can't currently build that
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
try:
|
|
rpm-build |
d9acb6 |
if tuple(map(tryint, libxml2_version.split('-', 1)[0].split('.'))) >= (2, 7, 3):
|
|
rpm-build |
d9acb6 |
libxml2_configure_cmd.append('--enable-rebuild-docs=no')
|
|
rpm-build |
d9acb6 |
except Exception:
|
|
rpm-build |
d9acb6 |
pass # this isn't required, so ignore any errors
|
|
rpm-build |
d9acb6 |
cmmi(libxml2_configure_cmd, libxml2_dir, multicore, **call_setup)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
# build libxslt
|
|
rpm-build |
d9acb6 |
libxslt_configure_cmd = configure_cmd + [
|
|
rpm-build |
d9acb6 |
'--without-python',
|
|
rpm-build |
d9acb6 |
'--with-libxml-prefix=%s' % prefix,
|
|
rpm-build |
d9acb6 |
]
|
|
rpm-build |
d9acb6 |
if sys.platform in ('darwin',):
|
|
rpm-build |
d9acb6 |
libxslt_configure_cmd += [
|
|
rpm-build |
d9acb6 |
'--without-crypto',
|
|
rpm-build |
d9acb6 |
]
|
|
rpm-build |
d9acb6 |
cmmi(libxslt_configure_cmd, libxslt_dir, multicore, **call_setup)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
# collect build setup for lxml
|
|
rpm-build |
d9acb6 |
xslt_config = os.path.join(prefix, 'bin', 'xslt-config')
|
|
rpm-build |
d9acb6 |
xml2_config = os.path.join(prefix, 'bin', 'xml2-config')
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
lib_dir = os.path.join(prefix, 'lib')
|
|
rpm-build |
d9acb6 |
static_include_dirs.extend([
|
|
rpm-build |
d9acb6 |
os.path.join(prefix, 'include'),
|
|
rpm-build |
d9acb6 |
os.path.join(prefix, 'include', 'libxml2'),
|
|
rpm-build |
d9acb6 |
os.path.join(prefix, 'include', 'libxslt'),
|
|
rpm-build |
d9acb6 |
os.path.join(prefix, 'include', 'libexslt')])
|
|
rpm-build |
d9acb6 |
static_library_dirs.append(lib_dir)
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
listdir = os.listdir(lib_dir)
|
|
rpm-build |
d9acb6 |
static_binaries += [os.path.join(lib_dir, filename)
|
|
rpm-build |
d9acb6 |
for lib in ['libxml2', 'libexslt', 'libxslt', 'iconv', 'libz']
|
|
rpm-build |
d9acb6 |
for filename in listdir
|
|
rpm-build |
d9acb6 |
if lib in filename and filename.endswith('.a')]
|
|
rpm-build |
d9acb6 |
|
|
rpm-build |
d9acb6 |
return (xml2_config, xslt_config)
|