61b19ee1b2
Avoid using the full path and instead rely on PATH being correctly set up to find the executable. This fixes byte compilation for python2.7 when doing flatpak module builds where python2.7 can be in either /usr/bin or /app/bin, depending on how it's compiled.
142 lines
5.6 KiB
Bash
Executable File
142 lines
5.6 KiB
Bash
Executable File
#!/bin/bash
|
|
errors_terminate=$2
|
|
|
|
# Usage of %_python_bytecompile_extra is not allowed anymore
|
|
# See: https://fedoraproject.org/wiki/Changes/No_more_automagic_Python_bytecompilation_phase_3
|
|
# Therefore $1 ($default_python) is not needed and is invoked with "" by default.
|
|
# $default_python stays in the arguments for backward compatibility and $extra for the following check:
|
|
extra=$3
|
|
if [ 0$extra -eq 1 ]; then
|
|
echo -e "%_python_bytecompile_extra is discontinued, use %py_byte_compile instead.\nSee: https://fedoraproject.org/wiki/Changes/No_more_automagic_Python_bytecompilation_phase_3" >/dev/stderr
|
|
exit 1
|
|
fi
|
|
|
|
# If using normal root, avoid changing anything.
|
|
if [ -z "$RPM_BUILD_ROOT" -o "$RPM_BUILD_ROOT" = "/" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# Figure out how deep we need to descend. We could pick an insanely high
|
|
# number and hope it's enough, but somewhere, somebody's sure to run into it.
|
|
depth=`(find "$RPM_BUILD_ROOT" -type f -name "*.py" -print0 ; echo /) | \
|
|
xargs -0 -n 1 dirname | sed 's,[^/],,g' | sort -u | tail -n 1 | wc -c`
|
|
if [ -z "$depth" -o "$depth" -le "1" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
# This function now implements Python byte-compilation in three different ways:
|
|
# Python >= 3.4 and < 3.9 uses a new module compileall2 - https://github.com/fedora-python/compileall2
|
|
# Python < 3.4 (inc. Python 2) uses compileall module from stdlib with some hacks
|
|
# When we drop support for Python 2, we'd be able to use all compileall2 features like:
|
|
# - -s and -p options to manipulate with a path baked into pyc files instead of $real_libdir
|
|
# - -o 0 -o 1 to produce multiple files in one run - each with a different optimization level - instead of $options
|
|
# - removed useless $depth - both compileall and compileall2 are limited by sys.getrecursionlimit()
|
|
# These changes will make this script much simpler
|
|
# In Python >= 3.9, compileall2 was merged back to standard library (compileall) so we can use it directly again.
|
|
function python_bytecompile()
|
|
{
|
|
local options=$1
|
|
local python_binary=$2
|
|
local exclude=$3
|
|
local python_libdir=$4
|
|
local depth=$5 # Not used for Python >= 3.4
|
|
local real_libdir=$6 # Not used for Python >= 3.4
|
|
|
|
python_version=$($python_binary -c "import sys; sys.stdout.write('{0.major}{0.minor}'.format(sys.version_info))")
|
|
|
|
#
|
|
# Python 3.9 and higher
|
|
#
|
|
if [ "$python_version" -ge 39 ]; then
|
|
|
|
[ ! -z $exclude ] && exclude="-x '$exclude'"
|
|
# -q disables verbose output
|
|
# -f forces the process to overwrite existing compiled files
|
|
# -x excludes paths defined by regex
|
|
# -e excludes symbolic links pointing outside the build root
|
|
# -x and -e together implements the same functionality as the Filter class below
|
|
# -s strips $RPM_BUILD_ROOT from the path
|
|
# -p prepends the leading slash to the path to make it absolute
|
|
$python_binary -B $options -m compileall -q -f $exclude -s $RPM_BUILD_ROOT -p / -e $RPM_BUILD_ROOT $python_libdir
|
|
|
|
#
|
|
# Python 3.4 and higher
|
|
#
|
|
elif [ "$python_version" -ge 34 ]; then
|
|
|
|
[ ! -z $exclude ] && exclude="-x '$exclude'"
|
|
# /usr/lib/rpm/redhat/ contains compileall2 Python module
|
|
# -q disables verbose output
|
|
# -f forces the process to overwrite existing compiled files
|
|
# -x excludes paths defined by regex
|
|
# -e excludes symbolic links pointing outside the build root
|
|
# -x and -e together implements the same functionality as the Filter class below
|
|
# -s strips $RPM_BUILD_ROOT from the path
|
|
# -p prepends the leading slash to the path to make it absolute
|
|
PYTHONPATH=/usr/lib/rpm/redhat/ $python_binary -B $options -m compileall2 -q -f $exclude -s $RPM_BUILD_ROOT -p / -e $RPM_BUILD_ROOT $python_libdir
|
|
else
|
|
#
|
|
# Python 3.3 and lower (incl. Python 2)
|
|
#
|
|
|
|
cat << EOF | $python_binary $options
|
|
import compileall, sys, os, re
|
|
|
|
python_libdir = "$python_libdir"
|
|
depth = $depth
|
|
real_libdir = "$real_libdir"
|
|
build_root = "$RPM_BUILD_ROOT"
|
|
exclude = r"$exclude"
|
|
|
|
class Filter:
|
|
def search(self, path):
|
|
ret = not os.path.realpath(path).startswith(build_root)
|
|
if exclude:
|
|
ret = ret or re.search(exclude, path)
|
|
return ret
|
|
|
|
sys.exit(not compileall.compile_dir(python_libdir, depth, real_libdir, force=1, rx=Filter(), quiet=1))
|
|
EOF
|
|
|
|
fi
|
|
}
|
|
|
|
# .pyc/.pyo files embed a "magic" value, identifying the ABI version of Python
|
|
# bytecode that they are for.
|
|
#
|
|
# The files below RPM_BUILD_ROOT could be targeting multiple versions of
|
|
# python (e.g. a single build that emits several subpackages e.g. a
|
|
# python26-foo subpackage, a python31-foo subpackage etc)
|
|
#
|
|
# Support this by assuming that below each /usr/lib/python$VERSION/, all
|
|
# .pyc/.pyo files are to be compiled for /usr/bin/python$VERSION.
|
|
#
|
|
# For example, below /usr/lib/python2.6/, we're targeting /usr/bin/python2.6
|
|
# and below /usr/lib/python3.1/, we're targeting /usr/bin/python3.1
|
|
|
|
# Disable Python hash seed randomization
|
|
# This should help with byte-compilation reproducibility: https://bugzilla.redhat.com/show_bug.cgi?id=1686078
|
|
export PYTHONHASHSEED=0
|
|
|
|
shopt -s nullglob
|
|
for python_libdir in `find "$RPM_BUILD_ROOT" -type d|grep -E "/(usr|app)/lib(64)?/python[0-9]\.[0-9]+$"`;
|
|
do
|
|
python_binary=$(basename $python_libdir)
|
|
real_libdir=${python_libdir/$RPM_BUILD_ROOT/}
|
|
echo "Bytecompiling .py files below $python_libdir using $python_binary"
|
|
|
|
# Generate normal (.pyc) byte-compiled files.
|
|
python_bytecompile "" "$python_binary" "" "$python_libdir" "$depth" "$real_libdir"
|
|
if [ $? -ne 0 -a 0$errors_terminate -ne 0 ]; then
|
|
# One or more of the files had a syntax error
|
|
exit 1
|
|
fi
|
|
|
|
# Generate optimized (.pyo) byte-compiled files.
|
|
python_bytecompile "-O" "$python_binary" "" "$python_libdir" "$depth" "$real_libdir"
|
|
if [ $? -ne 0 -a 0$errors_terminate -ne 0 ]; then
|
|
# One or more of the files had a syntax error
|
|
exit 1
|
|
fi
|
|
done
|