Move fetch and build of Python versions into pymultic, and remove
acquire_pythons script. pymultic now accepts an arbitrary list of python versions, instead of requiring all of a specific class to be included.
This commit is contained in:
@@ -1,93 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# NOTE: This script has only been tested on a Debian 9 x86_64 system -- it
|
||||
# is probably not as robust as it should be...
|
||||
|
||||
old_pythons=('1.0.1' '1.1' '1.2' '1.3' '1.4' '1.5.2')
|
||||
old_pyurl='https://legacy.python.org/download/releases/src'
|
||||
|
||||
pythons=('2.0.1' '2.1.3' '2.2.3' '2.3.7' '2.4.6' '2.5.6' '2.6.9' '2.7.15'
|
||||
'3.0.1' '3.1.5' '3.2.6' '3.3.7' '3.4.8' '3.5.5' '3.6.5')
|
||||
py_url='https://www.python.org/ftp/python'
|
||||
|
||||
|
||||
set -e
|
||||
|
||||
srcdir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
startdir="$(pwd)"
|
||||
|
||||
fetch_python() {
|
||||
local url="$1"
|
||||
local tarball="${url##*/}"
|
||||
local version="$2"
|
||||
|
||||
if [[ ! -d "Python-${version}" ]]; then
|
||||
local tarfile="${srcdir}/tarballs/${tarball}"
|
||||
if [[ ! -f "$tarfile" ]]; then
|
||||
if [[ "$version" == "1.6.1" ]]; then
|
||||
echo "Python 1.6.1 cannot be downloaded automatically due to a license agreement"
|
||||
echo "which must be manually accepted."
|
||||
echo "Please download it from https://www.python.org/download/releases/1.6.1/download/"
|
||||
echo "and place the tarball in ${srcdir}/tarballs"
|
||||
exit 1
|
||||
fi
|
||||
echo "Downloading Python-${version}..."
|
||||
( cd "${srcdir}/tarballs" && curl -LfO# "$url" )
|
||||
fi
|
||||
echo "Extracting Python-${version}..."
|
||||
tar xaf "${srcdir}/tarballs/${tarball}"
|
||||
[[ -d "python-${version}" ]] && mv "python-${version}" "Python-${version}"
|
||||
if [[ -f "${srcdir}/python-builds/Python-${version}.patch" ]]; then
|
||||
(
|
||||
cd "Python-${version}" &&
|
||||
patch -p1 -i "${srcdir}/python-builds/Python-${version}.patch"
|
||||
)
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
build_python() {
|
||||
local version="$1"
|
||||
|
||||
if [[ ! -x "Python-${version}/python" ]]; then
|
||||
echo "Configuring Python-${version}..."
|
||||
rm -f "${startdir}/Python-${version}.conf.log"
|
||||
(
|
||||
cd "Python-${version}"
|
||||
if ! ./configure > "${startdir}/Python-${version}.conf.log" 2>&1; then
|
||||
echo "... Configuration failed. See Python-${version}.conf.log for details"
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
|
||||
echo "Building Python-${version}..."
|
||||
rm -f "${startdir}/Python-${version}.build.log"
|
||||
(
|
||||
cd "Python-${version}"
|
||||
if ! make > "${startdir}/Python-${version}.build.log" 2>&1; then
|
||||
echo "... Configuration failed. See Python-${version}.build.log for details"
|
||||
exit 1
|
||||
fi
|
||||
)
|
||||
fi
|
||||
}
|
||||
|
||||
mkdir -p "${startdir}/tarballs"
|
||||
|
||||
for ver in ${old_pythons[@]:0:2}; do
|
||||
fetch_python "${old_pyurl}/python${ver}.tar.gz" "$ver"
|
||||
build_python "$ver"
|
||||
done
|
||||
for ver in ${old_pythons[@]:2}; do
|
||||
fetch_python "${old_pyurl}/python-${ver}.tar.gz" "$ver"
|
||||
build_python "$ver"
|
||||
done
|
||||
|
||||
# 1.6.1 must be downloaded manually
|
||||
fetch_python "https://INVALID_URL_FOR/Python-1.6.1.tar.gz" "1.6.1"
|
||||
build_python "1.6.1"
|
||||
|
||||
for ver in ${pythons[@]}; do
|
||||
fetch_python "${py_url}/${ver}/Python-${ver}.tgz" "$ver"
|
||||
build_python "$ver"
|
||||
done
|
197
scripts/pymultic
197
scripts/pymultic
@@ -5,67 +5,140 @@ import os
|
||||
import sys
|
||||
import subprocess
|
||||
import shutil
|
||||
import re
|
||||
|
||||
pythons1 = [
|
||||
'Python-1.0.1',
|
||||
'Python-1.1',
|
||||
'Python-1.2',
|
||||
'Python-1.3',
|
||||
'Python-1.4',
|
||||
'Python-1.5.2',
|
||||
'Python-1.6.1',
|
||||
]
|
||||
PYVERS = {
|
||||
'1.0': '1.0.1',
|
||||
'1.1': '1.1',
|
||||
'1.2': '1.2',
|
||||
'1.3': '1.3',
|
||||
'1.4': '1.4',
|
||||
'1.5': '1.5.2',
|
||||
'1.6': '1.6.1',
|
||||
'2.0': '2.0.1',
|
||||
'2.1': '2.1.3',
|
||||
'2.2': '2.2.3',
|
||||
'2.3': '2.3.7',
|
||||
'2.4': '2.4.6',
|
||||
'2.5': '2.5.6',
|
||||
'2.6': '2.6.9',
|
||||
'2.7': '2.7.16',
|
||||
'3.0': '3.0.1',
|
||||
'3.1': '3.1.5',
|
||||
'3.2': '3.2.6',
|
||||
'3.3': '3.3.7',
|
||||
'3.4': '3.4.10',
|
||||
'3.5': '3.5.7',
|
||||
'3.6': '3.6.9',
|
||||
'3.7': '3.7.4',
|
||||
}
|
||||
|
||||
pythons2 = [
|
||||
'Python-2.0.1',
|
||||
'Python-2.1.3',
|
||||
'Python-2.2.3',
|
||||
'Python-2.3.7',
|
||||
'Python-2.4.6',
|
||||
'Python-2.5.6',
|
||||
'Python-2.6.9',
|
||||
'Python-2.7.15',
|
||||
]
|
||||
OLD_PYTHONS = ('1.0', '1.1', '1.2', '1.3', '1.4', '1.5')
|
||||
OLD_PYURL = 'https://legacy.python.org/download/releases/src'
|
||||
PYURL = 'https://www.python.org/ftp/python'
|
||||
|
||||
|
||||
def fetch_python(snekdir, version):
|
||||
realver = PYVERS[version]
|
||||
if version in ('1.0', '1.1'):
|
||||
tarball = 'python{}.tar.gz'.format(realver)
|
||||
url = '{}/{}'.format(OLD_PYURL, tarball)
|
||||
elif version in ('1.2', '1.3', '1.4', '1.5'):
|
||||
tarball = 'python-{}.tar.gz'.format(realver)
|
||||
url = '{}/{}'.format(OLD_PYURL, tarball)
|
||||
elif version == '1.6':
|
||||
tarball = 'Python-{}.tar.gz'.format(realver)
|
||||
url = None
|
||||
else:
|
||||
tarball = 'Python-{}.tgz'.format(realver)
|
||||
url = '{}/{}/{}'.format(PYURL, realver, tarball)
|
||||
|
||||
pyver_dir = 'Python-{}'.format(realver)
|
||||
if os.path.exists(pyver_dir):
|
||||
return
|
||||
|
||||
tb_dir = os.path.join(snekdir, 'tarballs')
|
||||
tarfile = os.path.join(tb_dir, tarball)
|
||||
if not os.path.exists(tarfile):
|
||||
if version == '1.6':
|
||||
print('Python 1.6.1 cannot be downloaded automatically due to a license agreement')
|
||||
print('which must be manually accepted.')
|
||||
print('Please download it from https://www.python.org/download/releases/1.6.1/download/')
|
||||
print('and place the tarball in {}'.format(tb_dir))
|
||||
sys.exit(1)
|
||||
|
||||
print('Downloading Python {}...'.format(realver))
|
||||
if subprocess.call(['curl', '-LfO#', url], cwd=tb_dir) != 0:
|
||||
sys.exit(1)
|
||||
|
||||
print('Extracting Python {}...'.format(realver))
|
||||
if subprocess.call(['tar', 'xaf', tarfile]) != 0:
|
||||
sys.exit(1)
|
||||
|
||||
if os.path.exists('python-{}'.format(realver)) \
|
||||
and not os.path.exists(pyver_dir):
|
||||
# The dual check prevents useless renames on case-insensitive
|
||||
# file systems
|
||||
os.rename('python-{}'.format(realver), pyver_dir)
|
||||
|
||||
patch_file = '{}/python-builds/Python-{}.patch'.format(snekdir, realver)
|
||||
if os.path.exists(patch_file):
|
||||
if subprocess.call(['patch', '-p1', '-i', patch_file], cwd=pyver_dir) != 0:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def build_python(snekdir, version):
|
||||
realver = PYVERS[version]
|
||||
snek = 'Python-{}'.format(realver)
|
||||
builddir = os.path.join(snekdir, snek)
|
||||
|
||||
# NOTE: This has only been tested on a Debian 10 x86_64 system -- it is
|
||||
# probably not as robust as it should be...
|
||||
print('Configuring Python {}...'.format(realver))
|
||||
logfile = os.path.join(snekdir, '{}.conf.log'.format(snek))
|
||||
with open(logfile, 'wb') as log:
|
||||
if subprocess.call(['./configure'], stdout=log, stderr=log, cwd=builddir) != 0:
|
||||
print('... Configuration failed. See {} for details'.format(logfile))
|
||||
sys.exit(1)
|
||||
|
||||
print('Building Python {}...'.format(realver))
|
||||
logfile = os.path.join(snekdir, '{}.build.log'.format(snek))
|
||||
with open(logfile, 'wb') as log:
|
||||
if subprocess.call(['make'], stdout=log, stderr=log, cwd=builddir) != 0:
|
||||
print('... Build failed. See {} for details'.format(logfile))
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def acquire_python(snekdir, version):
|
||||
snek = 'Python-{}'.format(PYVERS[version])
|
||||
pyexe = os.path.join(snekdir, snek, 'python')
|
||||
if not os.path.exists(pyexe):
|
||||
fetch_python(snekdir, version)
|
||||
build_python(snekdir, version)
|
||||
return pyexe
|
||||
|
||||
pythons3 = [
|
||||
'Python-3.0.1',
|
||||
'Python-3.1.5',
|
||||
'Python-3.2.6',
|
||||
'Python-3.3.7',
|
||||
'Python-3.4.8',
|
||||
'Python-3.5.5',
|
||||
'Python-3.6.5',
|
||||
]
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print('Usage: {} [options] input.py'.format(sys.argv[0]))
|
||||
print('Compile input.py for many pythons')
|
||||
print('Usage: {} [versions] input.py'.format(sys.argv[0]))
|
||||
print('Compile input.py for one or more python versions')
|
||||
print('Output is written to input.<version>.pyc for each version successfully compiled')
|
||||
print()
|
||||
print('Options:')
|
||||
print(' -1 Compile for Python 1.x only')
|
||||
print(' -2 Compile for Python 2.x only')
|
||||
print(' -12 Compile for Python 1.x and 2.x versions (default)')
|
||||
print(' -3 Compile for Python 3.x only')
|
||||
print(' -23 Compile for Python 2.x and 3.x versions')
|
||||
print(' -A Attempt to compile for all known python versions')
|
||||
print('Version is X.Y (e.g. 3.4), not including the patch version')
|
||||
sys.exit(1)
|
||||
|
||||
pythons = pythons1 + pythons2
|
||||
RE_PYVER = re.compile(r'\d\.\d')
|
||||
|
||||
pythons = []
|
||||
infile = None
|
||||
for arg in sys.argv[1:]:
|
||||
if arg == '-1':
|
||||
pythons = pythons1
|
||||
elif arg == '-2':
|
||||
pythons = pythons2
|
||||
elif arg == '-12':
|
||||
pythons = pythons1 + pythons2
|
||||
elif arg == '-3':
|
||||
pythons = pythons3
|
||||
elif arg == '-23':
|
||||
pythons = pythons2 + pythons3
|
||||
elif arg == '-A':
|
||||
pythons = pythons1 + pythons2 + pythons3
|
||||
if RE_PYVER.match(arg):
|
||||
if arg in PYVERS.keys():
|
||||
pythons.append(arg)
|
||||
else:
|
||||
print('Unknown Python version: {}'.format(arg))
|
||||
sys.exit(1)
|
||||
elif arg.startswith('-'):
|
||||
print("WARNING: Unrecognized argument '{}'".format(arg))
|
||||
else:
|
||||
infile = arg
|
||||
|
||||
@@ -76,26 +149,34 @@ elif not os.path.exists(infile):
|
||||
print('Error: Input file {} does not exist'.format(infile))
|
||||
sys.exit(1)
|
||||
|
||||
if len(pythons) == 0:
|
||||
print('At least one Python version is required')
|
||||
sys.exit(1)
|
||||
|
||||
snekdir = os.path.dirname(os.path.realpath(__file__))
|
||||
for snek in pythons:
|
||||
pyexe = os.path.join(snekdir, snek, 'python')
|
||||
for ver in pythons:
|
||||
pyexe = acquire_python(snekdir, ver)
|
||||
proc = subprocess.Popen([pyexe, '-c', 'import sys; print(sys.version)'],
|
||||
stdout=subprocess.PIPE)
|
||||
out, _ = proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
print('Could not determine Python version for {}'.format(snek))
|
||||
print('Could not determine Python version for {}'.format(ver))
|
||||
continue
|
||||
|
||||
bcver = str(out, 'iso-8859-1').split(' ', 1)[0]
|
||||
if not bcver.startswith(ver):
|
||||
print('Python {} reported itself as version {}!'.format(ver, bcver))
|
||||
continue
|
||||
|
||||
bcver = str(out[:3], 'iso-8859-1')
|
||||
if '.py' in infile:
|
||||
outfile = infile.replace('.py', '.{}.pyc'.format(bcver))
|
||||
outfile = infile.replace('.py', '.{}.pyc'.format(ver))
|
||||
else:
|
||||
outfile = infile + '.{}.pyc'.format(bcver)
|
||||
outfile = infile + '.{}.pyc'.format(ver)
|
||||
if os.path.exists(outfile):
|
||||
os.unlink(outfile)
|
||||
|
||||
print('*** Compiling for {}'.format(snek))
|
||||
if bcver in {'1.0', '1.1', '1.2', '1.3', '1.4'}:
|
||||
print('*** Compiling for Python {}'.format(bcver))
|
||||
if ver in {'1.0', '1.1', '1.2', '1.3', '1.4'}:
|
||||
# The hard way -- hope your code is safe...
|
||||
srcdir = os.path.dirname(os.path.realpath(infile))
|
||||
comptmp = os.path.join(srcdir, 'pymc_temp.py')
|
||||
|
Reference in New Issue
Block a user