summaryrefslogtreecommitdiff
path: root/python-build-bin
diff options
context:
space:
mode:
authorsrv <enmanuel.saravia.externo@pandero.com.pe>2025-05-19 12:40:23 +0200
committersrv <enmanuel.saravia.externo@pandero.com.pe>2025-05-19 12:40:23 +0200
commitc092428b53c1306252b66b51f49482650ec1f38b (patch)
treeb2cb5436b0552fc966995e4140dfbcf9a22fb14a /python-build-bin
parent4366a7c9a4131d5ab5ce400573275a8f8f41a6c2 (diff)
tlaunch requeriment are compiled, thinkpad touchpad requeriment are compiled, docker requeriment in progress is a long task yet and add validate size
Diffstat (limited to 'python-build-bin')
-rw-r--r--python-build-bin/.gitignore18
-rw-r--r--python-build-bin/PKGBUILD27
-rw-r--r--python-build-bin/README.md2
-rw-r--r--python-build-bin/keys/pgp/2FDEC9863E5E14C7BC429F27B9D0E45146A241E8.asc92
-rw-r--r--python-build-bin/keys/pgp/3DCE51D60930EBA47858BA4146F633CBB0EB4BF2.asc186
-rwxr-xr-xpython-build-bin/python-build2519
6 files changed, 2844 insertions, 0 deletions
diff --git a/python-build-bin/.gitignore b/python-build-bin/.gitignore
new file mode 100644
index 0000000..e4912e4
--- /dev/null
+++ b/python-build-bin/.gitignore
@@ -0,0 +1,18 @@
+# ---> ArchLinuxPackages
+*.tar
+*.tar.*
+*.jar
+*.exe
+*.msi
+*.zip
+*.tgz
+*.log
+*.log.*
+*.sig
+
+pkg/
+src/
+
+*.service
+*.timer
+*.socket
diff --git a/python-build-bin/PKGBUILD b/python-build-bin/PKGBUILD
new file mode 100644
index 0000000..a7dd3ef
--- /dev/null
+++ b/python-build-bin/PKGBUILD
@@ -0,0 +1,27 @@
+# Maintainer: Saravia
+pkgname=python-build-bin
+pkgver=20240515
+pkgrel=1
+pkgdesc="Standalone precompiled python-build from pyenv (minimal wrapper)"
+arch=('x86_64')
+url="https://github.com/pyenv/pyenv"
+license=('MIT')
+depends=('bash')
+source=(
+ "python-build::https://raw.githubusercontent.com/pyenv/pyenv/master/plugins/python-build/bin/python-build"
+)
+sha512sums=('c071c8a70814e7895476ba1d7c4960773b8231a54ea7916d2b05e4021b7efd404be3264466f5e46839d3f210b9841647935cbf86b96b0e0debde3a871ab261cd')
+
+options=('!strip')
+
+prepare() {
+ chmod +x "$srcdir/python-build"
+}
+
+build() {
+ return 0
+}
+
+package() {
+ install -Dm755 "$srcdir/python-build" "$pkgdir/usr/bin/python-build"
+}
diff --git a/python-build-bin/README.md b/python-build-bin/README.md
new file mode 100644
index 0000000..d6ba366
--- /dev/null
+++ b/python-build-bin/README.md
@@ -0,0 +1,2 @@
+# python-build
+
diff --git a/python-build-bin/keys/pgp/2FDEC9863E5E14C7BC429F27B9D0E45146A241E8.asc b/python-build-bin/keys/pgp/2FDEC9863E5E14C7BC429F27B9D0E45146A241E8.asc
new file mode 100644
index 0000000..93b66e5
--- /dev/null
+++ b/python-build-bin/keys/pgp/2FDEC9863E5E14C7BC429F27B9D0E45146A241E8.asc
@@ -0,0 +1,92 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+Kj097u15JQ==
+=om07
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/python-build-bin/keys/pgp/3DCE51D60930EBA47858BA4146F633CBB0EB4BF2.asc b/python-build-bin/keys/pgp/3DCE51D60930EBA47858BA4146F633CBB0EB4BF2.asc
new file mode 100644
index 0000000..a0adeef
--- /dev/null
+++ b/python-build-bin/keys/pgp/3DCE51D60930EBA47858BA4146F633CBB0EB4BF2.asc
@@ -0,0 +1,186 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+JxAAvBrH/nGF1opnde86pHbAM2MtZ48/ZmLkUGghxgXNkgkN1sdOixsY/hS19Fj0
+2MHTWF0CmY2SPczTEKNDm02iosdEPyLSBTokxStjH/H5MZ2Uk4iLybleIBmVsn1o
+qffuUglvzpkPfEnRyCvpybulfP+F8B9H21CMsvG1ljQ9yveOZZGp2n5mNRGqR1Km
+ZrEFsamkQg827qY89ZgNglhvogPl4wTjEkQseZNQAiy4sZsKi54pcNoUq80uh/qc
+VwuV0T17dA3NZ+EjEsPLDJRd8hSRSl45W/LXta+o9OLMCqLUhe+ysC09hFw8p1Im
+8rDh8L56Wesh9NejBeSHfxlCWlDT2s++ZNIsq2tcwtDUq71yzO73UX7hqWVrf+iL
+rbwXiIlOebTutjzujAKDI6b44W6bolD+NHCldqJ+CRxp4vkQQTRdYzglC4bVqpRe
+A4IJlCvuIUenWYB2LZfN8RjmKTZQc8XJwG9gwnRCu5O6xaIs+5x8tlcYNQASM7sK
+J6tsQKb+zs5zogz96IFYtoz2t1x0i62VOtdhd91ber+jlXE9aJpHTMOAacG7ArUJ
+GlR7PDTlcixT2L6HfVdRGGYDJl34UoJcg0R3gIGOI0t/m4fT0c8OIcdUNGN/gGYd
+gtIi5jRI8FdI+T9jJpPLWd6aV5iLwV6I2uVc4EucTeMlH4c=
+=BBWu
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/python-build-bin/python-build b/python-build-bin/python-build
new file mode 100755
index 0000000..b8b1b92
--- /dev/null
+++ b/python-build-bin/python-build
@@ -0,0 +1,2519 @@
+#!/usr/bin/env bash
+#
+# Usage: python-build [-kpv] <definition> <prefix>
+# python-build --definitions
+# python-build --version
+#
+# -k/--keep Do not remove source tree after installation
+# -p/--patch Apply a patch from stdin before building
+# -v/--verbose Verbose mode: print compilation status to stdout
+# -4/--ipv4 Resolve names to IPv4 addresses only
+# -6/--ipv6 Resolve names to IPv6 addresses only
+# --definitions List all built-in definitions
+# --version Show version of python-build
+# -g/--debug Build a debug version
+#
+
+PYTHON_BUILD_VERSION="20180424"
+
+OLDIFS="$IFS"
+
+set -E
+shopt -s extglob
+[ -n "$PYENV_DEBUG" ] && {
+ export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
+ set -x
+}
+
+exec 3<&2 # preserve original stderr at fd 3
+
+
+lib() {
+ parse_options() {
+ OPTIONS=()
+ ARGUMENTS=()
+ local arg option index
+
+ for arg in "$@"; do
+ if [ "${arg:0:1}" = "-" ]; then
+ if [ "${arg:1:1}" = "-" ]; then
+ OPTIONS[${#OPTIONS[*]}]="${arg:2}"
+ else
+ index=1
+ while option="${arg:$index:1}"; do
+ [ -n "$option" ] || break
+ OPTIONS[${#OPTIONS[*]}]="$option"
+ index=$(($index+1))
+ done
+ fi
+ else
+ ARGUMENTS[${#ARGUMENTS[*]}]="$arg"
+ fi
+ done
+ }
+
+ if [ "$1" == "--$FUNCNAME" ]; then
+ declare -f "$FUNCNAME"
+ echo "$FUNCNAME \"\$1\";"
+ exit
+ fi
+}
+lib "$1"
+
+READLINK=$(type -P readlink)
+if [ -z "$READLINK" ]; then
+ echo "pyenv: cannot find readlink - are you missing GNU coreutils?" >&2
+ exit 1
+fi
+
+resolve_link() {
+ $READLINK "$1"
+}
+
+abs_dirname() {
+ local path="$1"
+
+ # Use a subshell to avoid changing the current path
+ (
+ while [ -n "$path" ]; do
+ cd_path="${path%/*}"
+ if [[ "$cd_path" != "$path" ]]; then
+ cd "$cd_path"
+ fi
+ name="${path##*/}"
+ path="$(resolve_link "$name" || true)"
+ done
+
+ echo "$PWD"
+ )
+}
+
+capitalize() {
+ printf "%s" "$1" | tr a-z A-Z
+}
+
+sanitize() {
+ printf "%s" "$1" | sed "s/[^A-Za-z0-9.-]/_/g; s/__*/_/g"
+}
+
+colorize() {
+ if [ -t 1 ]; then printf "\e[%sm%s\e[m" "$1" "$2"
+ else echo -n "$2"
+ fi
+}
+
+os_information() {
+ if type -p lsb_release >/dev/null; then
+ lsb_release -sir | xargs echo
+ elif type -p sw_vers >/dev/null; then
+ echo "OS X ${_PYTHON_BUILD_CACHE_SW_VERS:=$(sw_vers -productVersion)}"
+ elif [ -r /etc/os-release ]; then
+ source /etc/os-release
+ echo "$NAME" $VERSION_ID
+ else
+ local os="$(cat /etc/{centos,redhat,fedora,system}-release /etc/debian_version 2>/dev/null | head -n1)"
+ echo "${os:-$(uname -sr)}"
+ fi
+}
+
+is_mac() {
+ [ "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" = "Darwin" ] || return 1
+ [ $# -eq 0 ] || [ "$(osx_version)" "$@" ]
+}
+
+can_use_homebrew() {
+ [[ -n "$PYTHON_BUILD_USE_HOMEBREW" && -n "$PYTHON_BUILD_SKIP_HOMEBREW" ]] && {
+ echo "error: mutually exclusive environment variables PYTHON_BUILD_USE_HOMEBREW and PYTHON_BUILD_SKIP_HOMEBREW are set" >&3
+ exit 1
+ }
+ [[ -n "$PYTHON_BUILD_USE_HOMEBREW" ]] && return 0
+ [[ -n "$PYTHON_BUILD_SKIP_HOMEBREW" ]] && return 1
+ is_mac && return 0
+ # In Linux, if Pyenv itself is installed with Homebrew,
+ # we assume the user wants to take dependencies from there as well by default
+ command -v brew &>/dev/null && [[ $(abs_dirname "${BASH_SOURCE}") == "$(abs_dirname "$(brew --prefix 2>/dev/null ||true)")"/* ]] && return 0
+ return 1
+}
+
+# 9.1 -> 901
+# 10.9 -> 1009
+# 10.10 -> 1010
+osx_version() {
+ local -a ver
+ IFS=. ver=( ${_PYTHON_BUILD_CACHE_SW_VERS:=$(sw_vers -productVersion)} )
+ IFS="$OLDIFS"
+ echo $(( ${ver[0]}*100 + ${ver[1]} ))
+}
+
+build_failed() {
+ { echo
+ colorize 1 "BUILD FAILED"
+ echo " ($(os_information) using $(version))"
+ echo
+
+ if ! rmdir "${BUILD_PATH}" 2>/dev/null; then
+ echo "Inspect or clean up the working tree at ${BUILD_PATH}"
+ fi
+
+ if file_is_not_empty "$LOG_PATH"; then
+ colorize 33 "Results logged to ${LOG_PATH}"
+ printf "\n\n"
+ echo "Last 10 log lines:"
+ tail -n 10 "$LOG_PATH"
+ fi
+ } >&3
+ exit 1
+}
+
+file_is_not_empty() {
+ local filename="$1"
+ local line_count="$(wc -l "$filename" 2>/dev/null || true)"
+
+ if [ -n "$line_count" ]; then
+ words=( $line_count )
+ [ "${words[0]}" -gt 0 ]
+ else
+ return 1
+ fi
+}
+
+num_cpu_cores() {
+ local num
+ case "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" in
+ Darwin | *BSD )
+ num="$(sysctl -n hw.ncpu 2>/dev/null || true)"
+ ;;
+ SunOS )
+ num="$(getconf NPROCESSORS_ONLN 2>/dev/null || true)"
+ ;;
+ * )
+ num="$({ getconf _NPROCESSORS_ONLN ||
+ grep -c ^processor /proc/cpuinfo; } 2>/dev/null)"
+ num="${num#0}"
+ ;;
+ esac
+ echo "${num:-2}"
+}
+
+install_package() {
+ install_package_using "tarball" 1 "$@"
+}
+
+install_nightly_package() {
+ install_package_using "nightly_tarball" 2 "$@"
+}
+
+install_git() {
+ install_package_using "git" 2 "$@"
+}
+
+install_hg() {
+ install_package_using "hg" 2 "$@"
+}
+
+install_svn() {
+ install_package_using "svn" 2 "$@"
+}
+
+install_jar() {
+ install_package_using "jar" 1 "$@"
+}
+
+install_zip() {
+ install_package_using "zip" 1 "$@"
+}
+
+install_script() {
+ install_package_using "script" 1 "$@"
+}
+
+install_package_using() {
+ local package_type="$1"
+ local package_type_nargs="$2"
+ local package_name="$3"
+ shift 3
+
+ local fetch_args=( "$package_name" "${@:1:$package_type_nargs}" )
+ local make_args=( "$package_name" )
+ local arg last_arg
+
+ for arg in "${@:$(( $package_type_nargs + 1 ))}"; do
+ if [ "$last_arg" = "--if" ]; then
+ "$arg" || return 0
+ elif [ "$arg" != "--if" ]; then
+ make_args["${#make_args[@]}"]="$arg"
+ fi
+ last_arg="$arg"
+ done
+
+ pushd "$BUILD_PATH" >&4
+ "fetch_${package_type}" "${fetch_args[@]}"
+ make_package "${make_args[@]}"
+ popd >&4
+
+ echo "Installed ${package_name} to ${PREFIX_PATH}" >&2
+}
+
+make_package() {
+ local package_name="$1"
+ shift
+
+ pushd "$package_name" >&4
+ setup_builtin_patches "$package_name"
+ before_install_package "$package_name"
+ build_package "$package_name" $*
+ after_install_package "$package_name"
+ cleanup_builtin_patches "$package_name"
+ fix_directory_permissions
+ popd >&4
+}
+
+compute_sha2() {
+ local output
+ if type shasum &>/dev/null; then
+ output="$(shasum -a 256 -b)" || return 1
+ echo "${output% *}"
+ elif type openssl &>/dev/null; then
+ local openssl="$(command -v "$(brew --prefix openssl 2>/dev/null || true)"/bin/openssl openssl | head -n1)"
+ output="$("$openssl" dgst -sha256 2>/dev/null)" || return 1
+ echo "${output##* }"
+ elif type sha256sum &>/dev/null; then
+ output="$(sha256sum -b)" || return 1
+ echo "${output%% *}"
+ else
+ return 1
+ fi
+}
+
+compute_md5() {
+ local output
+ if type md5 &>/dev/null; then
+ md5 -q
+ elif type openssl &>/dev/null; then
+ output="$(openssl md5)" || return 1
+ echo "${output##* }"
+ elif type md5sum &>/dev/null; then
+ output="$(md5sum -b)" || return 1
+ echo "${output%% *}"
+ else
+ return 1
+ fi
+}
+
+has_checksum_support() {
+ local checksum_command="$1"
+ local has_checksum_var="HAS_CHECKSUM_SUPPORT_${checksum_command}"
+
+ if [ -z "${!has_checksum_var+defined}" ]; then
+ printf -v "$has_checksum_var" "$(echo test | "$checksum_command" >/dev/null; echo $?)"
+ fi
+ return "${!has_checksum_var}"
+}
+
+verify_checksum() {
+ local checksum_command
+ local filename="$1"
+ local expected_checksum="$(echo "$2" | tr [A-Z] [a-z])"
+
+ # If the specified filename doesn't exist, return success
+ [ -e "$filename" ] || return 0
+
+ case "${#expected_checksum}" in
+ 0) return 0 ;; # empty checksum; return success
+ 32) checksum_command="compute_md5" ;;
+ 64) checksum_command="compute_sha2" ;;
+ *)
+ { echo
+ echo "unexpected checksum length: ${#expected_checksum} (${expected_checksum})"
+ echo "expected 0 (no checksum), 32 (MD5), or 64 (SHA2-256)"
+ echo
+ } >&4
+ return 1 ;;
+ esac
+
+ # If chosen provided checksum algorithm isn't supported, return success
+ has_checksum_support "$checksum_command" || return 0
+
+ # If the computed checksum is empty, return failure
+ local computed_checksum=`echo "$($checksum_command < "$filename")" | tr [A-Z] [a-z]`
+ [ -n "$computed_checksum" ] || return 1
+
+ if [ "$expected_checksum" != "$computed_checksum" ]; then
+ { echo
+ echo "checksum mismatch: ${filename} (file is corrupt)"
+ echo "expected $expected_checksum, got $computed_checksum"
+ echo
+ } >&4
+ return 1
+ fi
+}
+
+http() {
+ local method="$1"
+ [ -n "$2" ] || return 1
+ shift 1
+
+ PYTHON_BUILD_HTTP_CLIENT="${PYTHON_BUILD_HTTP_CLIENT:-$(detect_http_client)}"
+ [ -n "$PYTHON_BUILD_HTTP_CLIENT" ] || return 1
+
+ "http_${method}_${PYTHON_BUILD_HTTP_CLIENT}" "$@"
+}
+
+detect_http_client() {
+ local client
+ for client in aria2c curl wget; do
+ if type "$client" &>/dev/null; then
+ echo "$client"
+ return
+ fi
+ done
+ echo "error: please install \`aria2c\`, \`curl\`, or \`wget\` and try again" >&2
+ return 1
+}
+
+http_head_aria2c() {
+ aria2c --dry-run --no-conf=true ${ARIA2_OPTS} "$1" >&4 2>&1
+}
+
+http_get_aria2c() {
+ # aria2c always treats -o argument as a relative path
+ local out dir_out;
+ if [[ -n "$2" ]]; then
+ out="$(basename $2)";
+ dir_out="$(dirname $2)";
+ else
+ out="$(mktemp "out.XXXXXX")";
+ dir_out="$TMPDIR";
+ fi
+
+ # In Ubuntu, aria2c is only available as a snap. Snaps cannot read or write /tmp
+ # (files cannot be found, any write result is silently discarded).
+ local aria2c_is_snap;
+ if [[ $(command -v aria2c) == "/snap/"* ]]; then aria2c_is_snap=1; fi
+
+ if [[ -n $aria2c_is_snap ]]; then
+ local real_dir_out="$dir_out"
+ # presumably, snaps can always write to under $HOME
+ dir_out="$HOME"
+ fi
+
+ if aria2c --allow-overwrite=true --no-conf=true -d "${dir_out}" -o "${out}" ${ARIA2_OPTS} "$1" >&4; then
+ [ -n "$2" ] || cat "${dir_out:-.}/${out}"
+ else
+ false
+ fi
+ ret=$?
+
+ if [[ -n "$2" && -n $aria2c_is_snap ]]; then
+ mv "$dir_out/$out" "$real_dir_out/$out"
+ fi
+ return "$ret"
+}
+
+http_head_curl() {
+ curl -qsILf ${CURL_OPTS} "$1" >&4 2>&1
+}
+
+http_get_curl() {
+ curl -q -o "${2:--}" -sSLf ${CURL_OPTS} "$1"
+}
+
+http_head_wget() {
+ wget -q --spider ${WGET_OPTS} "$1" >&4 2>&1
+}
+
+http_get_wget() {
+ wget -nv ${WGET_OPTS} -O "${2:--}" "$1"
+}
+
+fetch_tarball() {
+ local package_name="$1"
+ local package_url="$2"
+ local mirror_url
+ local checksum
+ local extracted_dir
+
+ if [ "$package_url" != "${package_url/\#}" ]; then
+ checksum="${package_url#*#}"
+ package_url="${package_url%%#*}"
+
+ if [ -n "$PYTHON_BUILD_MIRROR_URL" ]; then
+ if [[ -z "$PYTHON_BUILD_DEFAULT_MIRROR" || $package_url != */www.python.org/* ]]; then
+ mirror_url="${PYTHON_BUILD_MIRROR_URL}/$checksum"
+ fi
+ fi
+ fi
+
+ local tar_args="xzf"
+ local package_filename="${package_name}.tar.gz"
+
+ if [ "$package_url" != "${package_url%bz2}" ]; then
+ if ! type -p bzip2 >/dev/null; then
+ echo "warning: bzip2 not found; consider installing \`bzip2\` package" >&4
+ fi
+ package_filename="${package_filename%.gz}.bz2"
+ tar_args="${tar_args/z/j}"
+ fi
+
+ if [ "$package_url" != "${package_url%xz}" ]; then
+ if ! type -p xz >/dev/null; then
+ echo "warning: xz not found; consider installing \`xz\` package" >&4
+ fi
+ package_filename="${package_filename%.gz}.xz"
+ tar_args="${tar_args/z/J}"
+ fi
+
+ if ! reuse_existing_tarball "$package_filename" "$checksum"; then
+ # Report the cached file name -- sometimes, it's useful to know (#1743)
+ echo "Downloading ${package_filename}..." >&2
+ http head "$mirror_url" &&
+ download_tarball "$mirror_url" "$package_filename" "$checksum" ||
+ download_tarball "$package_url" "$package_filename" "$checksum"
+ fi
+
+ { if tar $tar_args "$package_filename"; then
+ if [ ! -d "$package_name" ]; then
+ extracted_dir="$(find_extracted_directory)"
+ mv "$extracted_dir" "$package_name"
+ fi
+
+ if [ -z "$KEEP_BUILD_PATH" ]; then
+ rm -f "$package_filename"
+ else
+ true
+ fi
+ fi
+ } >&4 2>&1
+}
+
+find_extracted_directory() {
+ for f in *; do
+ if [ -d "$f" ]; then
+ echo "$f"
+ return
+ fi
+ done
+ echo "Extracted directory not found" >&2
+ return 1
+}
+
+fetch_nightly_tarball() {
+ local package_name="$1"
+ local package_url="$2"
+ local package_pattern="$3"
+ fetch_tarball "$1" "$2"
+ if [ ! -e "${package_name}" ]; then
+ local nightly_package_name="$(echo ${package_pattern})"
+ if [ -e "${nightly_package_name}" ]; then
+ ln -fs "${nightly_package_name}" "${package_name}"
+ fi
+ fi
+}
+
+reuse_existing_tarball() {
+ local package_filename="$1"
+ local checksum="$2"
+
+ # Reuse existing file in build location
+ if [ -e "$package_filename" ] && verify_checksum "$package_filename" "$checksum"; then
+ return 0
+ fi
+
+ # Reuse previously downloaded file in cache location
+ [ -n "$PYTHON_BUILD_CACHE_PATH" ] || return 1
+ local cached_package_filename="${PYTHON_BUILD_CACHE_PATH}/$package_filename"
+
+ [ -e "$cached_package_filename" ] || return 1
+ verify_checksum "$cached_package_filename" "$checksum" >&4 2>&1 || return 1
+ ln -s "$cached_package_filename" "$package_filename" >&4 2>&1 || return 1
+}
+
+download_tarball() {
+ local official_source="www.python.org/ftp/python"
+ if [ -n "$PYTHON_BUILD_MIRROR_URL_SKIP_CHECKSUM" ]; then
+ local package_url="$(echo "$1" | sed -e "s|.*//${URL_BASE:-$official_source}|$PYTHON_BUILD_MIRROR_URL|g")"
+ else
+ local package_url="$1"
+ fi
+ [ -n "$package_url" ] || return 1
+
+ local package_filename="$2"
+ local checksum="$3"
+
+ echo "-> $package_url" >&2
+
+ if http get "$package_url" "$package_filename" >&4 2>&1; then
+ verify_checksum "$package_filename" "$checksum" >&4 2>&1 || return 1
+ else
+ echo "error: failed to download $package_filename" >&2
+ return 1
+ fi
+
+ if [ -n "$PYTHON_BUILD_CACHE_PATH" ]; then
+ local cached_package_filename="${PYTHON_BUILD_CACHE_PATH}/$package_filename"
+ { mv "$package_filename" "$cached_package_filename"
+ ln -s "$cached_package_filename" "$package_filename"
+ } >&4 2>&1 || return 1
+ fi
+}
+
+has_tar_xz_support() {
+ [[ -z $_PYTHON_BUILD_FORCE_SKIP_XZ ]] && tar Jcf - /dev/null 1>/dev/null 2>&1
+}
+
+fetch_git() {
+ local package_name="$1"
+ local git_url="$2"
+ local git_ref="$3"
+
+ echo "Cloning ${git_url}..." >&2
+
+ if type git &>/dev/null; then
+ if [ -n "$PYTHON_BUILD_CACHE_PATH" ]; then
+ pushd "$PYTHON_BUILD_CACHE_PATH" >&4
+ local clone_name="$(sanitize "$git_url")"
+ if [ -e "${clone_name}" ]; then
+ { cd "${clone_name}"
+ git fetch --force "$git_url" "+${git_ref}:${git_ref}"
+ } >&4 2>&1
+ else
+ git clone --bare --branch "$git_ref" "$git_url" "${clone_name}" >&4 2>&1
+ fi
+ git_url="$PYTHON_BUILD_CACHE_PATH/${clone_name}"
+ popd >&4
+ fi
+
+ if [ -e "${package_name}" ]; then
+ ( cd "${package_name}"
+ git fetch --depth 1 origin "+${git_ref}"
+ git checkout -q -B "$git_ref" "origin/${git_ref}"
+ ) >&4 2>&1
+ else
+ git clone --depth 1 --branch "$git_ref" "$git_url" "${package_name}" >&4 2>&1
+ fi
+ else
+ echo "error: please install \`git\` and try again" >&2
+ exit 1
+ fi
+}
+
+fetch_hg() {
+ local package_name="$1"
+ local hg_url="$2"
+ local hg_ref="$3"
+
+ echo "Cloning ${hg_url}..." >&2
+
+ if type hg &>/dev/null; then
+ if [ -n "$PYTHON_BUILD_CACHE_PATH" ]; then
+ pushd "$PYTHON_BUILD_CACHE_PATH" >&4
+ local clone_name="$(sanitize "$hg_url")"
+ if [ -e "${clone_name}" ]; then
+ { cd "${clone_name}"
+ hg pull --force "$hg_url"
+ } >&4 2>&1
+ else
+ { hg clone --branch "$hg_ref" "$hg_url" "${clone_name}"
+ cd "${clone_name}"
+ hg update null
+ } >&4 2>&1
+ fi
+ hg_url="$PYTHON_BUILD_CACHE_PATH/${clone_name}"
+ popd >&4
+ fi
+
+ hg clone --branch "$hg_ref" "$hg_url" "${package_name}" >&4 2>&1
+ else
+ echo "error: please install \`mercurial\` and try again" >&2
+ exit 1
+ fi
+}
+
+fetch_svn() {
+ local package_name="$1"
+ local svn_url="$2"
+ local svn_rev="$3"
+
+ echo "Checking out ${svn_url}..." >&2
+
+ if type svn &>/dev/null; then
+ svn co -r "$svn_rev" "$svn_url" "${package_name}" >&4 2>&1
+ elif type svnlite &>/dev/null; then
+ svnlite co -r "$svn_rev" "$svn_url" "${package_name}" >&4 2>&1
+ else
+ echo "error: please install Subversion and try again" >&2
+ exit 1
+ fi
+}
+
+fetch_jar() {
+ local package_name="$1"
+ local package_url="$2"
+ local mirror_url
+ local checksum
+
+ if [ "$package_url" != "${package_url/\#}" ]; then
+ checksum="${package_url#*#}"
+ package_url="${package_url%%#*}"
+
+ if [ -n "$PYTHON_BUILD_MIRROR_URL" ]; then
+ mirror_url="${PYTHON_BUILD_MIRROR_URL}/$checksum"
+ fi
+ fi
+
+ local package_filename="${package_name}.jar"
+
+ if ! reuse_existing_tarball "$package_filename" "$checksum"; then
+ echo "Downloading ${package_filename}..." >&2
+ http head "$mirror_url" &&
+ download_tarball "$mirror_url" "$package_filename" "$checksum" ||
+ download_tarball "$package_url" "$package_filename" "$checksum"
+ fi
+
+ # Must use full path to jar and destination directory:
+ # http://bugs.jython.org/issue2350
+ { if $JAVA -jar "$PWD/${package_name}.jar" -s -d "$PWD/${package_name}"; then
+ if [ -z "$KEEP_BUILD_PATH" ]; then
+ rm -f "$package_filename"
+ else
+ true
+ fi
+ fi
+ } >&4 2>&1
+}
+
+fetch_zip() {
+ local package_name="$1"
+ local package_url="$2"
+ local mirror_url
+ local checksum
+
+ if [ "$package_url" != "${package_url/\#}" ]; then
+ checksum="${package_url#*#}"
+ package_url="${package_url%%#*}"
+
+ if [ -n "$PYTHON_BUILD_MIRROR_URL" ]; then
+ mirror_url="${PYTHON_BUILD_MIRROR_URL}/$checksum"
+ fi
+ fi
+
+ local package_filename="${package_name}.zip"
+
+ if ! reuse_existing_tarball "$package_filename" "$checksum"; then
+ echo "Downloading ${package_filename}..." >&2
+ http head "$mirror_url" &&
+ download_tarball "$mirror_url" "$package_filename" "$checksum" ||
+ download_tarball "$package_url" "$package_filename" "$checksum"
+ fi
+
+ { if unzip "$package_filename"; then
+ if [ -z "$KEEP_BUILD_PATH" ]; then
+ rm -f "$package_filename"
+ else
+ true
+ fi
+ fi
+ } >&4 2>&1
+}
+
+fetch_script() {
+ local package_name="$1"
+ local package_url="$2"
+ local mirror_url
+ local checksum
+
+ if [ "$package_url" != "${package_url/\#}" ]; then
+ checksum="${package_url#*#}"
+ package_url="${package_url%%#*}"
+
+ if [ -n "$PYTHON_BUILD_MIRROR_URL" ]; then
+ mirror_url="${PYTHON_BUILD_MIRROR_URL}/$checksum"
+ fi
+ fi
+
+ local package_filename="${package_name}.sh" # TODO: extract suffix from ${package_url}
+
+ if ! reuse_existing_tarball "$package_filename" "$checksum"; then
+ echo "Downloading ${package_filename}..." >&2
+ http head "$mirror_url" &&
+ download_tarball "$mirror_url" "$package_filename" "$checksum" ||
+ download_tarball "$package_url" "$package_filename" "$checksum"
+ fi
+
+ mkdir -p "$(dirname "${package_name}/${package_filename}")"
+ mv -f "${package_filename}" "${package_name}/${package_filename}"
+}
+
+build_package() {
+ local package_name="$1"
+ shift
+
+ if [ "$#" -eq 0 ]; then
+ local commands="standard"
+ else
+ local commands="$*"
+ fi
+
+ echo "Installing ${package_name}..." >&2
+
+ [ -n "$HAS_PATCH" ] && apply_patch "$package_name" <(cat "${package_name}.patch")
+
+ for command in $commands; do
+ "build_package_${command}" "$package_name"
+ done
+}
+
+package_option() {
+ local package_name="$1"
+ local command_name="$2"
+ local variable="$(capitalize "${package_name}_${command_name}")_OPTS_ARRAY"
+ local array="$variable[@]"
+ shift 2
+ local value=( "${!array}" "$@" )
+ eval "$variable=( \"\${value[@]}\" )"
+}
+
+build_package_warn_eol() {
+ local package_name="$1"
+
+ { echo
+ echo "WARNING: $package_name is past its end of life and is now unsupported."
+ echo "It no longer receives bug fixes or critical security updates."
+ echo
+ } >&3
+}
+
+build_package_warn_unsupported() {
+ local package_name="$1"
+
+ { echo
+ echo "WARNING: $package_name is nearing its end of life."
+ echo "It only receives critical security updates, no bug fixes."
+ echo
+ } >&3
+}
+
+build_package_standard_build() {
+ local package_name="$1"
+
+ if [ "${MAKEOPTS+defined}" ]; then
+ MAKE_OPTS="$MAKEOPTS"
+ elif [ -z "${MAKE_OPTS+defined}" ]; then
+ MAKE_OPTS="-j $(num_cpu_cores)"
+ fi
+
+ # Support YAML_CONFIGURE_OPTS, PYTHON_CONFIGURE_OPTS, etc.
+ local package_var_name="$(capitalize "${package_name%%-*}")"
+ local PACKAGE_CONFIGURE="${package_var_name}_CONFIGURE"
+ local PACKAGE_PREFIX_PATH="${package_var_name}_PREFIX_PATH"
+ local PACKAGE_CONFIGURE_OPTS="${package_var_name}_CONFIGURE_OPTS"
+ local PACKAGE_CONFIGURE_OPTS_ARRAY="${package_var_name}_CONFIGURE_OPTS_ARRAY[@]"
+ local PACKAGE_MAKE_OPTS="${package_var_name}_MAKE_OPTS"
+ local PACKAGE_MAKE_OPTS_ARRAY="${package_var_name}_MAKE_OPTS_ARRAY[@]"
+ local PACKAGE_CFLAGS="${package_var_name}_CFLAGS"
+ local PACKAGE_CPPFLAGS="${package_var_name}_CPPFLAGS"
+ local PACKAGE_LDFLAGS="${package_var_name}_LDFLAGS"
+
+ if [ "$package_var_name" = "PYTHON" ]; then
+ use_homebrew || true
+ use_custom_tcltk || use_homebrew_tcltk || true
+ use_homebrew_readline || use_freebsd_pkg || true
+ use_homebrew_ncurses || true
+ if is_mac -ge 1014; then
+ use_xcode_sdk_zlib || use_homebrew_zlib || true
+ else
+ use_homebrew_zlib || true
+ fi
+ use_dsymutil || true
+ use_free_threading || true
+ fi
+
+ ( if [[ -n "${!PACKAGE_CFLAGS}" ]]; then
+ export CFLAGS="${CFLAGS:+$CFLAGS }${!PACKAGE_CFLAGS}"
+ fi
+ if [[ -n "${!PACKAGE_CPPFLAGS}" ]]; then
+ export CPPFLAGS="${CPPFLAGS:+$CPPFLAGS }${!PACKAGE_CPPFLAGS}"
+ fi
+ if [[ -n "${!PACKAGE_LDFLAGS}" ]]; then
+ export LDFLAGS="${LDFLAGS:+$LDFLAGS }${!PACKAGE_LDFLAGS}"
+ fi
+ if [ -z "$CC" ] && is_mac -ge 1010; then
+ export CC=clang
+ fi
+ ${!PACKAGE_CONFIGURE:-./configure} --prefix="${!PACKAGE_PREFIX_PATH:-$PREFIX_PATH}" \
+ "${!PACKAGE_CONFIGURE_OPTS_ARRAY}" $CONFIGURE_OPTS ${!PACKAGE_CONFIGURE_OPTS} || return 1
+ ) >&4 2>&1
+
+ { "$MAKE" "${!PACKAGE_MAKE_OPTS_ARRAY}" $MAKE_OPTS ${!PACKAGE_MAKE_OPTS}
+ } >&4 2>&1
+}
+
+build_package_standard_install() {
+ local package_name="$1"
+ local package_var_name="$(capitalize "${package_name%%-*}")"
+
+ local PACKAGE_MAKE_INSTALL_OPTS="${package_var_name}_MAKE_INSTALL_OPTS"
+ local PACKAGE_MAKE_INSTALL_OPTS_ARRAY="${package_var_name}_MAKE_INSTALL_OPTS_ARRAY[@]"
+ local PACKAGE_MAKE_INSTALL_TARGET="${package_var_name}_MAKE_INSTALL_TARGET"
+
+ { "$MAKE" "${!PACKAGE_MAKE_INSTALL_TARGET:-install}" $MAKE_INSTALL_OPTS ${!PACKAGE_MAKE_INSTALL_OPTS} "${!PACKAGE_MAKE_INSTALL_OPTS_ARRAY}"
+ } >&4 2>&1
+}
+
+# Backward Compatibility for standard function
+build_package_standard() {
+ build_package_standard_build "$@"
+ build_package_standard_install "$@"
+}
+
+build_package_autoconf() {
+ { autoreconf
+ } >&4 2>&1
+}
+
+build_package_python() {
+ local package_name="$1"
+
+ { "$PYTHON_BIN" setup.py install
+ } >&4 2>&1
+}
+
+remove_windows_files() {
+ cd "$PREFIX_PATH"
+ rm -f bin/*.exe bin/*.dll bin/*.bat
+}
+
+build_package_jython() {
+ build_package_copy
+ { if [ -x "${PREFIX_PATH}/bin/jython" ] && [ ! -x "${PREFIX_PATH}/bin/python" ]; then
+ ( cd "${PREFIX_PATH}/bin" && ln -fs jython python )
+ fi
+ } >&4 2>&1
+ fix_jython_shebangs
+}
+
+fix_jython_shebangs() {
+ # Workaround for Jython 2.7+ (#458)
+ for file in "${PREFIX_PATH}/bin"/*; do
+ case "$(head -n1 "${file}")" in
+ "#!"*"/bin/jython" )
+ sed -i.bak "1 s:.*:#\!${PREFIX_PATH}\/bin\/jython:" "${file}"
+ ;;
+ "#!"*"/bin/python2.7"* )
+ sed -i.bak "1 s:.*:#\!\/usr\/bin\/env python:" "${file}"
+ ;;
+ esac
+ rm -f "${file}.bak"
+ done
+}
+
+build_package_jython_builder() {
+ ant >&4 2>&1
+ ( cd "dist" && build_package_jython )
+}
+
+build_package_pyston2_2() {
+ # currently supported version 2.2 and 2.3
+ build_package_copy
+ mkdir -p "${PREFIX_PATH}/bin" "${PREFIX_PATH}/lib"
+ local bin
+ shopt -s nullglob
+ for bin in "bin/"*; do
+ if [ -f "${bin}" ] && [ -x "${bin}" ] && [ ! -L "${bin}" ]; then
+ case "${bin##*/}" in
+ "pyston"* )
+ ( cd "${PREFIX_PATH}/bin" && ln -fs "${bin##*/}" "python" )
+ ;;
+ esac
+ fi
+ done
+ shopt -u nullglob
+}
+
+build_package_pyston() {
+ # currently supported version 2.3.1v2 and higher
+ build_package_copy
+}
+
+build_package_ironpython() {
+ mkdir -p "${PREFIX_PATH}/bin"
+ cp -fR . "${PREFIX_PATH}/bin"
+ chmod +x "${PREFIX_PATH}/bin/"*.exe
+ ( cd "${PREFIX_PATH}/bin" && ln -fs ipy.exe python )
+}
+
+build_package_ironpython_builder() {
+ xbuild Build.proj /t:Stage "/p:Mono=true;BaseConfiguration=Release" >&4 2>&1
+ ( cd "Stage/Release/IronPython-"* && build_package_ironpython )
+}
+
+build_package_micropython_1_9() {
+ # supported version 1.9.3 and 1.9.4
+ build_package_micropython "with_axtls"
+}
+
+build_package_micropython() {
+ # supported version 1.10 and higher
+ if [ "${MAKEOPTS+defined}" ]; then
+ MAKE_OPTS="$MAKEOPTS"
+ elif [ -z "${MAKE_OPTS+defined}" ]; then
+ MAKE_OPTS="-j $(num_cpu_cores)"
+ fi
+ { cd mpy-cross
+ "$MAKE" $MAKE_OPTS
+ cd ../ports/unix
+ [ "$1" = "with_axtls" ] && "$MAKE" $MAKE_OPTS axtls
+ "$MAKE" $MAKE_OPTS CFLAGS_EXTRA="-DMICROPY_PY_SYS_PATH_DEFAULT='\".frozen:${PREFIX_PATH}/lib/micropython\"' $CFLAGS_EXTRA"
+ "$MAKE" install $MAKE_INSTALL_OPTS PREFIX="${PREFIX_PATH}"
+ ln -fs micropython "${PREFIX_PATH}/bin/python"
+ mkdir -p "${PREFIX_PATH}/lib/micropython"
+ }>&4 2>&1
+}
+
+pypy_architecture() {
+ case "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" in
+ "Darwin" )
+ case "$(uname -m)" in
+ "arm64" ) echo "osarm64" ;;
+ "x86_64" ) echo "osx64" ;;
+ * ) return 1 ;;
+ esac
+ ;;
+ "Linux" )
+ case "$(uname -m)" in
+ "armel" ) echo "linux-armel" ;;
+ "armhf" | "armv6l" | "armv7l" ) echo "linux-armhf" ;;
+ "i386" | "i486" | "i586" | "i686" | "i786" ) echo "linux" ;;
+ "ppc64" ) echo "linux-ppc64" ;;
+ "ppc64le" ) echo "linux-ppc64le" ;;
+ "x86_64" ) echo "linux64" ;;
+ "aarch64" ) echo "linux-aarch64" ;;
+ * ) return 1 ;;
+ esac
+ ;;
+ "CYGWIN"* | "MINGW"* ) echo "win32" ;;
+ "FreeBSD" )
+ case "$(uname -m)" in
+ "x86_64" ) echo "freebsd64" ;;
+ * ) return 1 ;;
+ esac
+ ;;
+ * ) return 1 ;;
+ esac
+}
+
+graalpy_architecture() {
+ case "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" in
+ "Darwin" )
+ case "$(uname -m)" in
+ "x86_64" ) echo "macos-amd64" ;;
+ "arm64" ) echo "macos-aarch64" ;;
+ * ) return 1 ;;
+ esac
+ ;;
+ "Linux" )
+ case "$(uname -m)" in
+ "x86_64" ) echo "linux-amd64" ;;
+ "aarch64" ) echo "linux-aarch64" ;;
+ * ) return 1 ;;
+ esac
+ ;;
+ esac
+}
+
+pyston_architecture() {
+ pypy_architecture
+}
+
+# Note: not used by graalpy >= 23.3.0 anymore
+build_package_graalpython() {
+ build_package_copy
+ ln -fs "${PREFIX_PATH}/bin/graalpython" "${PREFIX_PATH}/bin/python"
+}
+
+build_package_pypy() {
+ build_package_copy
+ mkdir -p "${PREFIX_PATH}/bin" "${PREFIX_PATH}/lib"
+ local bin
+ shopt -s nullglob
+ for bin in "bin/"*; do
+ if [ -f "${bin}" ] && [ -x "${bin}" ] && [ ! -L "${bin}" ]; then
+ case "${bin##*/}" in
+ "libpypy"* )
+ ( cd "${PREFIX_PATH}/lib" && ln -fs "../bin/${bin##*/}" "${bin##*/}" )
+ ;;
+ "pypy"* )
+ ( cd "${PREFIX_PATH}/bin" && ln -fs "${bin##*/}" "python" )
+ ;;
+ esac
+ fi
+ done
+ shopt -u nullglob
+}
+
+build_package_pypy_builder() {
+ if [ -f "rpython/bin/rpython" ]; then # pypy 2.x
+ if [ -z "${PYPY_OPTS}" ]; then
+ local PYPY_OPTS="--opt=jit --batch --make-jobs=$(num_cpu_cores)"
+ fi
+ python "rpython/bin/rpython" ${PYPY_OPTS} "pypy/goal/targetpypystandalone.py" >&4 2>&1
+ elif [ -f "pypy/translator/goal/translate.py" ]; then # pypy 1.x
+ if [ -z "${PYPY_OPTS}" ]; then
+ local PYPY_OPTS="--opt=jit"
+ fi
+ ( cd "pypy/translator/goal" && python "translate.py" ${PYPY_OPTS} "targetpypystandalone.py" ) 1>&4 2>&1
+ else
+ echo "not a pypy source tree" 1>&3
+ return 1
+ fi
+ { mkdir -p "bin" "lib"
+ local pypy
+ for pypy in "pypy"*; do
+ if [ -f "${pypy}" ] && [ -x "${pypy}" ] && [ ! -L "${pypy}" ]; then
+ mv -f "${pypy}" "bin/${pypy##*/}"
+ fi
+ done
+ local libpypy
+ for libpypy in "libpypy"*; do
+ if [ -f "${libpypy}" ] && [ -x "${libpypy}" ] && [ ! -L "${libpypy}" ]; then
+ mv -f "${libpypy}" "bin/${libpypy##*/}"
+ fi
+ done
+ } >&4 2>&1
+ build_package_pypy
+}
+
+activepython_architecture() {
+ case "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" in
+ "Darwin" ) echo "macosx10.9-i386-x86_64" ;;
+ "Linux" )
+ case "$(uname -m)" in
+ "i386" | "i486" | "i586" | "i686" | "i786" ) echo "linux-x86" ;;
+ "x86_64" ) echo "linux-x86_64" ;;
+ * ) return 1 ;;
+ esac
+ ;;
+ * ) return 1 ;;
+ esac
+}
+
+build_package_activepython() {
+ local package_name="$1"
+ { bash "install.sh" --install-dir "${PREFIX_PATH}"
+ } >&4 2>&1
+}
+
+anaconda_architecture() {
+ case "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" in
+ "Darwin" )
+ case "$(uname -m)" in
+ "arm64" ) echo "MacOSX-arm64" ;;
+ * ) echo "MacOSX-x86_64" ;;
+ esac
+ ;;
+ "Linux" )
+ case "$(uname -m)" in
+ "armv7l" ) echo "Linux-armv7l" ;;
+ "aarch64" ) echo "Linux-aarch64" ;;
+ "i386" | "i486" | "i586" | "i686" | "i786" ) echo "Linux-x86" ;;
+ "ppc64le" ) echo "Linux-ppc64le" ;;
+ "x86_64" ) echo "Linux-x86_64" ;;
+ * ) return 1 ;;
+ esac
+ ;;
+ * ) return 1 ;;
+ esac
+}
+
+build_package_anaconda() {
+ local package_name="$1"
+ { bash "${package_name}.sh" -f -b -p "${PREFIX_PATH}"
+ } >&4 2>&1
+}
+
+build_package_miniconda() {
+ build_package_anaconda "$@"
+ # Workaround to not upgrade conda when installing pip
+ # see https://github.com/pyenv/pyenv/issues/2070
+ "${PREFIX_PATH}/bin/conda" install --yes "pip" "conda=$(${PREFIX_PATH}/bin/conda --version | cut -d ' ' -f 2)"
+}
+
+build_package_copy() {
+ mkdir -p "$PREFIX_PATH"
+ cp -fR . "$PREFIX_PATH"
+}
+
+before_install_package() {
+ local stub=1
+}
+
+after_install_package() {
+ local stub=1
+}
+
+setup_builtin_patches() {
+ local package_name="$1"
+ local package_patch_path="${DEFINITION_PATH%/*}/patches/${DEFINITION_PATH##*/}/${package_name}"
+
+# Apply built-in patches if patch was not given from stdin
+ if [[ -n "$HAS_STDIN_PATCH" ]] && package_is_python "${package_name}"; then
+ cat >"${package_name}.patch"
+ HAS_PATCH=true
+ elif [[ -d "${package_patch_path}" ]]; then
+ { find "${package_patch_path}" -maxdepth 1 -type f
+ } 2>/dev/null | sort | xargs cat 1>"${package_name}.patch"
+ HAS_PATCH=true
+ fi
+}
+
+cleanup_builtin_patches() {
+ local package_name="$1"
+ rm -f "${package_name}.patch"
+ unset HAS_PATCH
+}
+
+fix_directory_permissions() {
+ # Ensure installed directories are not world-writable
+ find "$PREFIX_PATH" -type d \( -perm -020 -o -perm -002 \) -exec chmod go-w {} \;
+}
+
+require_java7() {
+ local version="$(java -version 2>&1 | grep '\(java\|openjdk\) version' | head -n1)"
+ if [[ $version != *[789]* ]]; then
+ colorize 1 "ERROR" >&3
+ echo ": Java 7 required. Please install a 1.7-compatible JRE." >&3
+ return 1
+ fi
+}
+
+require_gcc() {
+ local gcc="$(locate_gcc || true)"
+
+ if [ -z "$gcc" ]; then
+ { echo
+ colorize 1 "ERROR"
+ echo ": This package must be compiled with GCC, but python-build couldn't"
+ echo "find a suitable \`gcc\` executable on your system. Please install GCC"
+ echo "and try again."
+ echo
+
+ if is_mac; then
+ colorize 1 "DETAILS"
+ echo ": Apple no longer includes the official GCC compiler with Xcode"
+ echo "as of version 4.2. Instead, the \`gcc\` executable is a symlink to"
+ echo "\`llvm-gcc\`, a modified version of GCC which outputs LLVM bytecode."
+ echo
+ echo "For most programs the \`llvm-gcc\` compiler works fine. However,"
+ echo "versions of CPython newer than 3.3.0 are incompatible with"
+ echo "\`llvm-gcc\`. To build newer versions of CPython you must have the official"
+ echo "GCC compiler installed on your system."
+ echo
+
+ colorize 1 "TO FIX THE PROBLEM"
+ if type brew &>/dev/null; then
+ echo ": Install Homebrew's GCC package with this"
+ echo -n "command: "
+ colorize 4 "brew install gcc@4.9"
+ else
+ echo ": Install the official GCC compiler using these"
+ echo -n "packages: "
+ colorize 4 "https://github.com/kennethreitz/osx-gcc-installer/downloads"
+ fi
+
+ echo
+ echo
+ echo "You will need to install the official GCC compiler to build newer"
+ echo "versions of CPython even if you have installed Apple's Command Line Tools"
+ echo "for Xcode package. The Command Line Tools for Xcode package only"
+ echo "includes \`llvm-gcc\`."
+ fi
+ } >&3
+ return 1
+ fi
+
+ export CC="$gcc"
+ if is_mac -ge 1010; then
+ export MACOSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET:-10.9}
+ fi
+}
+
+locate_gcc() {
+ local gcc gccs
+ IFS=: gccs=($(gccs_in_path))
+ IFS="$OLDIFS"
+
+ verify_gcc "$CC" ||
+ verify_gcc "$(command -v gcc || true)" || {
+ for gcc in "${gccs[@]}"; do
+ verify_gcc "$gcc" && break || true
+ done
+ }
+
+ return 1
+}
+
+gccs_in_path() {
+ local gcc path paths
+ local gccs=()
+ IFS=: paths=($PATH)
+ IFS="$OLDIFS"
+
+ shopt -s nullglob
+ for path in "${paths[@]}"; do
+ for gcc in "$path"/gcc-*; do
+ gccs["${#gccs[@]}"]="$gcc"
+ done
+ done
+ shopt -u nullglob
+
+ printf :%s "${gccs[@]}"
+}
+
+verify_gcc() {
+ local gcc="$1"
+ if [ -z "$gcc" ]; then
+ return 1
+ fi
+
+ local version="$("$gcc" --version 2>/dev/null || true)"
+ if [ -z "$version" ]; then
+ return 1
+ fi
+
+ if echo "$version" | grep LLVM >/dev/null; then
+ return 1
+ fi
+
+ echo "$gcc"
+}
+
+require_llvm() {
+ local llvm_version="$1"
+ if is_mac -ge 1010; then
+ if [[ "$PYTHON_CONFIGURE_OPTS" != *--llvm-* ]]; then
+ case "$llvm_version" in
+ 3.2 )
+ package_option python configure --prebuilt-name="llvm-3.2-x86_64-apple-darwin13.tar.bz2"
+ ;;
+ 3.[56] )
+ local llvm_config="$(locate_llvm "$llvm_version")"
+ if [ -n "$llvm_config" ]; then
+ package_option python configure --llvm-config="$llvm_config"
+ else
+ local homebrew_package="llvm@$llvm_version"
+ { echo
+ colorize 1 "ERROR"
+ echo ": Rubinius will not be able to compile using Apple's LLVM-based "
+ echo "build tools on OS X. You will need to install LLVM $llvm_version first."
+ echo
+ colorize 1 "TO FIX THE PROBLEM"
+ echo ": Install Homebrew's llvm package with this"
+ echo -n "command: "
+ colorize 4 "brew install $homebrew_package"
+ echo
+ } >&3
+ return 1
+ fi
+ ;;
+ esac
+ fi
+ fi
+}
+
+locate_llvm() {
+ local llvm_version="$1"
+ local package llvm_config
+ shopt -s nullglob
+ for package in `brew list 2>/dev/null | grep "^llvm"`; do
+ llvm_config="$(echo "$(brew --prefix "$package")/bin/llvm-config"*)"
+ if [ -n "$llvm_config" ] && [[ "$("$llvm_config" --version)" = "$llvm_version"* ]]; then
+ echo "$llvm_config"
+ break
+ fi
+ done
+ shopt -u nullglob
+}
+
+require_java() {
+ local java="$(command -v java || true)"
+
+ if [ -z "$java" ]; then
+ { echo
+ colorize 1 "ERROR"
+ echo ": This package must be installed with java, but python-build couldn't"
+ echo "find a suitable \`java\` executable on your system. Please install Java"
+ echo "and try again."
+ echo
+ } >&3
+ return 1
+ fi
+
+ export JAVA="$java"
+}
+
+# Let Jython installer to generate shell script instead of python script even if there's `python2.7` available in `$PATH` (#800)
+# FIXME: better function naming
+unrequire_python27() {
+ export PATH="${BUILD_PATH}/bin:${PATH}"
+ mkdir -p "${BUILD_PATH}/bin"
+ if command -v python2.7 1>/dev/null 2>&1; then
+ echo false > "${BUILD_PATH}/bin/python2.7"
+ chmod +x "${BUILD_PATH}/bin/python2.7"
+ fi
+}
+
+require_distro() {
+ for arg; do
+ if [[ "$(cat /etc/issue 2>/dev/null || true)" == "$arg"* ]]; then
+ return 0
+ fi
+ done
+ { echo
+ colorize 1 "WARNING"
+ echo ": This binary distribution is built for the following distro(s): $@."
+ echo "installed binary may not run expectedly on other platforms."
+ echo
+ } >&2
+ return 1
+}
+
+require_osx_version() {
+ function version { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
+
+ local required_version="$@"
+ local osx_version="${_PYTHON_BUILD_CACHE_SW_VERS:=$(sw_vers -productVersion)}"
+ if [[ $(version $osx_version) -ge $(version $required_version) ]]; then
+ return 0
+ fi
+ return 1
+}
+
+configured_with_package_dir() {
+ local package_var_name="$(capitalize "$1")"
+ shift 1
+ local PACKAGE_CONFIGURE_OPTS="${package_var_name}_CONFIGURE_OPTS"
+ local PACKAGE_CONFIGURE_OPTS_ARRAY="${package_var_name}_MAKE_OPTS_ARRAY[@]"
+ local arg flag
+ for arg in ${CONFIGURE_OPTS} ${!PACKAGE_CONFIGURE_OPTS} "${!PACKAGE_CONFIGURE_OPTS_ARRAY}"; do
+ if [[ "$arg" == "CPPFLAGS="* ]]; then
+ for flag in ${CPPFLAGS} ${arg##CPPFLAGS=}; do
+ if [[ "$flag" == "-I"* ]]; then
+ local header
+ for header in "$@"; do
+ if [ -e "${flag##-I}/${header#/}" ]; then
+ return 0
+ fi
+ done
+ fi
+ done
+ fi
+ done
+ return 1
+}
+
+# `python-config` ignores LDFLAGS envvar. Adding to LIBS is the only way to add extra stuff
+# to `python-config --ldflags` output
+append_ldflags_libs() {
+ local args="$1"
+ export LDFLAGS="${LDFLAGS:+$LDFLAGS }$args"
+ export LIBS="${LIBS:+${LIBS% } }$args"
+}
+prepend_ldflags_libs() {
+ local args="$1"
+ export LDFLAGS="$args${LDFLAGS:+ $LDFLAGS}"
+ export LIBS="$args${LIBS:+ $LIBS}"
+}
+
+use_homebrew() {
+ can_use_homebrew || return 1
+ # unless Homebrew is at the default /usr/local, need to add its paths to
+ # compiler search to be able to use non-keg-only deps from there
+ if command -v brew &>/dev/null; then
+ local brew_prefix="$(brew --prefix 2>/dev/null || true)"
+ # /usr/local/lib:/usr/lib is the default library search path
+ if [[ -n $brew_prefix && $brew_prefix != "/usr" && $brew_prefix != "/usr/local" ]]; then
+ export CPPFLAGS="${CPPFLAGS:+$CPPFLAGS }-I${brew_prefix}/include"
+ append_ldflags_libs "-L${brew_prefix}/lib -Wl,-rpath,${brew_prefix}/lib"
+ fi
+ fi
+}
+
+needs_yaml() {
+ ! configured_with_package_dir "python" "yaml.h" &&
+ ! use_homebrew_yaml
+}
+
+use_homebrew_yaml() {
+ can_use_homebrew || return 1
+ local libdir="$(brew --prefix libyaml 2>/dev/null || true)"
+ if [ -d "$libdir" ]; then
+ echo "python-build: use libyaml from homebrew"
+ export CPPFLAGS="-I$libdir/include${CPPFLAGS:+ $CPPFLAGS}"
+ export LDFLAGS="-L$libdir/lib${LDFLAGS:+ ${LDFLAGS% }}"
+ else
+ return 1
+ fi
+}
+
+use_freebsd_pkg() {
+ # check if FreeBSD
+ if [ "FreeBSD" = "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" ]; then
+ # use openssl if installed from Ports Collection
+ if pkg info -e openssl; then
+ package_option python configure --with-openssl="/usr/local"
+ fi
+
+ # check if 11-R or later
+ release="${_PYTHON_BUILD_CACHE_UNAME_R:=$(uname -r)}"
+ if [ "${release%%.*}" -ge 11 ]; then
+ # Use packages from Ports Collection.
+ #
+ # Unlike Linux, BSD's cc does not look in /usr/local by default
+ # where Ports-installed packages are, but they are available via pkg-config.
+ # Surprisingly, CPython's Configure only uses pkg-config
+ # to locate some of the dependencies and not others.
+ # Here we detect those that are (as of this writing) known
+ # to not be searched via pkg-config.
+ #
+ # XXX: As a side effect, this would pick up any other libs from Ports
+ # that are searched via compiler
+ if pkg info -e readline || pkg info -e sqlite3; then
+ export CPPFLAGS="${CPPFLAGS:+$CPPFLAGS }-I/usr/local/include"
+ export LDFLAGS="${LDFLAGS:+$LDFLAGS }-L/usr/local/lib -Wl,-rpath,/usr/local/lib"
+ fi
+ fi
+ fi
+}
+
+has_broken_mac_readline() {
+ # Mac OS X 10.4 has broken readline.
+ # https://github.com/pyenv/pyenv/issues/23
+ is_mac &&
+ ! configured_with_package_dir "python" "readline/rlconf.h" &&
+ ! use_homebrew_readline
+}
+
+use_homebrew_readline() {
+ can_use_homebrew || return 1
+ if ! configured_with_package_dir "python" "readline/rlconf.h"; then
+ local libdir="$(brew --prefix readline 2>/dev/null || true)"
+ if [ -d "$libdir" ]; then
+ echo "python-build: use readline from homebrew"
+ export CPPFLAGS="-I$libdir/include${CPPFLAGS:+ $CPPFLAGS}"
+ export LDFLAGS="-L$libdir/lib${LDFLAGS:+ $LDFLAGS}"
+ else
+ return 1
+ fi
+ fi
+}
+
+use_homebrew_ncurses() {
+ can_use_homebrew || return 1
+ local libdir="$(brew --prefix ncurses 2>/dev/null || true)"
+ if [ -d "$libdir" ]; then
+ echo "python-build: use ncurses from homebrew"
+ export CPPFLAGS="-I$libdir/include${CPPFLAGS:+ $CPPFLAGS}"
+ export LDFLAGS="-L$libdir/lib${LDFLAGS:+ $LDFLAGS}"
+ else
+ return 1
+ fi
+}
+
+prefer_openssl11() {
+ # Allow overriding the preference of OpenSSL version per definition basis (#1302, #1325, #1326)
+ PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA="${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl@1.1 openssl}"
+ export PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA
+}
+
+prefer_openssl3() {
+ # Allow overriding the preference of OpenSSL version per definition basis (#1302, #1325, #1326)
+ PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA="${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl@3 openssl@1.1 openssl}"
+ export PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA
+}
+
+build_package_mac_readline() {
+ # Install to a subdirectory since we don't want shims for bin/readline.
+ READLINE_PREFIX_PATH="${PREFIX_PATH}/readline"
+
+ # Tell Python to use this readline for its extension.
+ export CPPFLAGS="-I${READLINE_PREFIX_PATH}/include${CPPFLAGS:+ $CPPFLAGS}"
+ export LDFLAGS="-L${READLINE_PREFIX_PATH}/lib${LDFLAGS:+ $LDFLAGS}"
+
+ # Make sure pkg-config finds our build first.
+ export PKG_CONFIG_PATH="${READLINE_PREFIX_PATH}/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
+
+ build_package_standard "$@"
+}
+
+has_broken_mac_openssl() {
+ is_mac || return 1
+ local openssl_version="$(/usr/bin/openssl version 2>/dev/null || true)"
+ [[ $openssl_version = "OpenSSL 0.9.8"?* || $openssl_version = "LibreSSL"* ]] &&
+ ! use_homebrew_openssl
+}
+
+use_homebrew_openssl() {
+ can_use_homebrew || return 1
+ command -v brew >/dev/null || return 1
+ for openssl in ${PYTHON_BUILD_HOMEBREW_OPENSSL_FORMULA:-openssl}; do
+ local ssldir="$(brew --prefix "${openssl}" || true)"
+ if [ -d "$ssldir" ]; then
+ echo "python-build: use ${openssl} from homebrew"
+ if [[ -n "${PYTHON_BUILD_CONFIGURE_WITH_OPENSSL:-}" ]]; then
+ # configure script of newer CPython versions support `--with-openssl`
+ # https://bugs.python.org/issue21541
+ package_option python configure --with-openssl="${ssldir}"
+ else
+ export CPPFLAGS="-I$ssldir/include ${CPPFLAGS:+ $CPPFLAGS}"
+ export LDFLAGS="-L$ssldir/lib${LDFLAGS:+ $LDFLAGS}"
+ fi
+ export PKG_CONFIG_PATH="$ssldir/lib/pkgconfig/:${PKG_CONFIG_PATH}"
+ return
+ fi
+ done
+ return 1
+}
+
+build_package_mac_openssl() {
+ # Install to a subdirectory since we don't want shims for bin/openssl.
+ OPENSSL_PREFIX_PATH="${PREFIX_PATH}/openssl"
+
+ # Put openssl.conf, certs, etc in ~/.pyenv/versions/*/openssl/ssl
+ OPENSSLDIR="${OPENSSLDIR:-$OPENSSL_PREFIX_PATH/ssl}"
+
+ # Tell Python to use this openssl for its extension.
+ if [[ -n "${PYTHON_BUILD_CONFIGURE_WITH_OPENSSL:-}" ]]; then
+ # configure script of newer CPython versions support `--with-openssl`
+ # https://bugs.python.org/issue21541
+ package_option python configure --with-openssl="${OPENSSL_PREFIX_PATH}"
+ else
+ export CPPFLAGS="-I${OPENSSL_PREFIX_PATH}/include ${CPPFLAGS:+ $CPPFLAGS}"
+ export LDFLAGS="-L${OPENSSL_PREFIX_PATH}/lib${LDFLAGS:+ $LDFLAGS}"
+ fi
+
+ # Make sure pkg-config finds our build first.
+ export PKG_CONFIG_PATH="${OPENSSL_PREFIX_PATH}/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
+
+ # Hint OpenSSL that we prefer a 64-bit build.
+ export KERNEL_BITS="64"
+ OPENSSL_CONFIGURE="${OPENSSL_CONFIGURE:-./config}"
+
+ local nokerberos
+ [[ "$1" != openssl-1.0.* ]] || nokerberos=1
+
+ # switches introduced in OpenSSL 3.2
+ local extra_no_features
+ [[ $(openssl_version $1) -ge 30200 ]] && extra_no_features=1
+
+ # Compile a shared lib with zlib dynamically linked.
+ package_option openssl configure --openssldir="$OPENSSLDIR" zlib-dynamic no-ssl3 shared ${nokerberos:+no-ssl2 no-krb5} ${extra_no_features:+no-docs no-apps} no-tests
+
+ build_package_standard "$@"
+
+ # Extract root certs from the system keychain in .pem format and rehash.
+ local pem_file="$OPENSSLDIR/cert.pem"
+ security find-certificate -a -p /Library/Keychains/System.keychain > "$pem_file"
+ security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain >> "$pem_file"
+}
+
+# openssl-1.0.1k -> 10001
+# openssl-3.2.1 -> 30201
+openssl_version() {
+ local -a ver
+ IFS=- ver=( ${1:?} )
+ IFS=. ver=( ${ver[1]} )
+ [[ ${ver[2]} =~ ^([[:digit:]]+)[[:alpha:]]$ ]] && ver[2]="${BASH_REMATCH[1]}"
+ echo $(( ${ver[0]}*10000 + ${ver[1]}*100 + ${ver[2]} ))
+}
+
+# Post-install check that the openssl extension was built.
+build_package_verify_openssl() {
+ "$RUBY_BIN" -e '
+ manager = ARGV[0]
+ packages = {
+ "apt-get" => Hash.new {|h,k| "lib#{k}-dev" }.update(
+ "openssl" => "libssl-dev",
+ "zlib" => "zlib1g-dev"
+ ),
+ "yum" => Hash.new {|h,k| "#{k}-devel" }.update(
+ "yaml" => "libyaml-devel"
+ )
+ }
+
+ failed = %w[openssl readline zlib yaml].reject do |lib|
+ begin
+ require lib
+ rescue LoadError
+ $stderr.puts "The Ruby #{lib} extension was not compiled."
+ end
+ end
+
+ if failed.size > 0
+ $stderr.puts "ERROR: Ruby install aborted due to missing extensions"
+ $stderr.print "Try running `%s install -y %s` to fetch missing dependencies.\n\n" % [
+ manager,
+ failed.map { |lib| packages.fetch(manager)[lib] }.join(" ")
+ ] unless manager.empty?
+ $stderr.puts "Configure options used:"
+ require "rbconfig"; require "shellwords"
+ RbConfig::CONFIG.fetch("configure_args").shellsplit.each { |arg| $stderr.puts " #{arg}" }
+ exit 1
+ end
+ ' "$(basename "$(type -P yum apt-get | head -n1)")" >&4 2>&1
+}
+
+use_homebrew_zlib() {
+ can_use_homebrew || return 1
+ local brew_zlib="$(brew --prefix zlib 2>/dev/null || true)"
+ if [ -d "$brew_zlib" ]; then
+ echo "python-build: use zlib from homebrew"
+ export CFLAGS="-I${brew_zlib} ${CFLAGS}"
+ fi
+}
+
+use_xcode_sdk_zlib() {
+ # If a custom compiler is used, including XCode SDK will likely break it
+ [[ "${CC:-clang}" != "clang" || "$(command -v clang 2>/dev/null || true)" != "/usr/bin/clang" ]] && return 1
+ local xc_sdk_path="$(xcrun --show-sdk-path 2>/dev/null || true)"
+ if [ -d "$xc_sdk_path" ]; then
+ echo "python-build: use zlib from xcode sdk"
+ # Even though SDK's compiler uses the SDK dirs implicitly,
+ # CPython's setup.py has to have nonstandard paths specified explicitly
+ # to search for zlib.h in them
+ export CPPFLAGS="${CPPFLAGS:+$CPPFLAGS }-I${xc_sdk_path}/usr/include"
+ if is_mac -ge 1100; then
+ export LDFLAGS="${LDFLAGS:+$LDFLAGS }-L${xc_sdk_path}/usr/lib"
+ fi
+ fi
+}
+
+use_homebrew_tcltk() {
+ can_use_homebrew || return 1
+ # Since https://github.com/Homebrew/homebrew-core/commit/f10e88617b41555193c22fdcba6109fe82155ee2 (10.11.2024),
+ # tcl-tk is 9.0 which is not compatible with CPython as of this writing
+ # but we'll keep it as backup for cases like non-updated Homebrew
+ local tcltk
+ for tcltk in "tcl-tk@8" "tcl-tk"; do
+ local tcltk_libdir="$(brew --prefix "${tcltk}" 2>/dev/null || true)"
+ if [ -d "$tcltk_libdir" ]; then
+ echo "python-build: use tcl-tk from homebrew"
+ if [[ -z "$PYTHON_BUILD_TCLTK_USE_PKGCONFIG" ]]; then
+ local tcltk_version="$(sh -c '. '"$tcltk_libdir"'/lib/tclConfig.sh; echo $TCL_VERSION')"
+ package_option python configure --with-tcltk-libs="-L$tcltk_libdir/lib -ltcl$tcltk_version -ltk$tcltk_version"
+ # In Homebrew Tcl/Tk 8.6.13, headers have been moved to the 'tcl-tk' subdir.
+ # We're not using tclConfig.sh here 'cuz it produces the version-specific path to <brew prefix>/Cellar
+ # and we'd rather have rpath set to <brew prefix>/opt/<...> to allow micro release upgrades without rebuilding
+ # XXX: do use tclConfig.sh and translate the paths if more path shenanigans appear in later releases
+ if [ -d "$tcltk_libdir/include/tcl-tk" ]; then
+ package_option python configure --with-tcltk-includes="-I$tcltk_libdir/include/tcl-tk"
+ else
+ package_option python configure --with-tcltk-includes="-I$tcltk_libdir/include"
+ fi
+ fi
+ export PKG_CONFIG_PATH="${tcltk_libdir}/lib/pkgconfig${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
+ return 0
+ fi
+ done
+ return 1
+}
+
+# FIXME: this function is a workaround for #1125
+# once fixed, it should be removed.
+# if tcltk_ops_flag is in PYTHON_CONFIGURE_OPTS, use user provided tcltk
+use_custom_tcltk() {
+ local tcltk_ops="$(get_tcltk_flag_from "$PYTHON_CONFIGURE_OPTS")"
+
+ if [[ -z "$tcltk_ops" ]]; then
+ return 1
+ fi
+ local tcltk_ops_flag="--with-tcltk-libs="
+ # get tcltk libs
+ local tcltk_libs="${tcltk_ops//$tcltk_ops_flag/}"
+ # remove tcltk-flag from configure_opts
+ # this allows for weird input such as
+ # --with-tcltk-libs=' -L/custom-tcl-tk/lib -ltcl8.6 -ltk8.4 '
+ PYTHON_CONFIGURE_OPTS="${PYTHON_CONFIGURE_OPTS//"$tcltk_ops_flag"/}"
+ PYTHON_CONFIGURE_OPTS="${PYTHON_CONFIGURE_OPTS//$tcltk_libs/}"
+
+ # remove quotes, because there mess up compilations
+ PYTHON_CONFIGURE_OPTS="${PYTHON_CONFIGURE_OPTS//"''"/}"
+ PYTHON_CONFIGURE_OPTS="${PYTHON_CONFIGURE_OPTS//'""'/}"
+
+ echo "python-build: use tcl-tk from \$PYTHON_CONFIGURE_OPTS"
+ # echo "PYTHON_CONFIGURE_OPTS=${PYTHON_CONFIGURE_OPTS}"
+ package_option python configure --with-tcltk-libs="${tcltk_libs}"
+ # IFS="$OLDIFS"
+}
+
+# FIXME: this function is a workaround for #1125
+# once fixed, it should be removed.
+# Get tcltk-flag and options from `$1`
+# expects one argument containing a string of configure opts, eg. `PYTHON_CONFIGURE_OPTS`
+# returns tcl_tk flag or an empty string if nothing was found.
+get_tcltk_flag_from() {
+ IFS=$'\n'
+ # parse input string into array
+ local opts_arr=( $(xargs -n1 <<<"$1") )
+
+ # iterate through `opts_arr`, break if `--with-tcltk-libs=` was found.
+ for opts in ${opts_arr[@]}; do
+ # `--with-tcltk-libs=` must be the prefix.
+ if [[ "$opts" == "--with-tcltk-libs="* ]]; then
+ # return
+ echo "$opts"
+ break
+ fi
+ done
+
+ IFS="$OLDIFS"
+}
+
+# Since 3.12, CPython can add DWARF debug information in MacOS
+# using Apple's nonstandard way, `dsymutil', that creates a "dSYM bundle"
+# that's supposed to be installed alongside executables
+# (https://github.com/python/cpython/issues/95973).
+use_dsymutil() {
+ if [[ -n "$PYTHON_BUILD_CONFIGURE_WITH_DSYMUTIL" ]] && is_mac; then
+ package_option python configure --with-dsymutil
+ fi
+}
+
+use_free_threading() {
+ if [[ -n "$PYTHON_BUILD_FREE_THREADING" ]]; then
+ package_option python configure --disable-gil
+ fi
+}
+
+build_package_enable_shared() {
+ package_option python configure --enable-shared
+}
+
+build_package_auto_tcltk() {
+ if is_mac && [ ! -d /usr/include/X11 ]; then
+ if [ -d /opt/X11/include ]; then
+ if [[ "$CPPFLAGS" != *-I/opt/X11/include* ]]; then
+ export CPPFLAGS="-I/opt/X11/include${CPPFLAGS:+ $CPPFLAGS}"
+ fi
+ else
+ package_option python configure --without-tk
+ fi
+ fi
+}
+
+package_is_python() {
+ case "$1" in
+ Python-* | jython-* | pypy-* | pypy[0-9].+([0-9])-* | stackless-* )
+ return 0
+ ;;
+ esac
+ return 1
+}
+
+apply_patch() {
+ local package_name="$1"
+ local patchfile
+ patchfile="$(mktemp "${TMP}/python-patch.XXXXXX")"
+ cat "${2:--}" >"$patchfile"
+
+ local striplevel=0
+ grep -q '^diff --git a/' "$patchfile" && striplevel=1
+ patch -p$striplevel --force -i "$patchfile"
+}
+
+
+build_package_symlink_version_suffix() {
+ if [[ "${PYTHON_CONFIGURE_OPTS_ARRAY[*]} $CONFIGURE_OPTS $PYTHON_CONFIGURE_OPTS" == *"--enable-framework"* ]]; then
+ if [ -e "${PREFIX_PATH}/bin" ]; then
+ # Always create `bin` as symlink to framework path if the version was built with `--enable-framework` (#590)
+ rm -rf "${PREFIX_PATH}/bin.orig"
+ mv -f "${PREFIX_PATH}/bin" "${PREFIX_PATH}/bin.orig"
+ fi
+ # Only symlinks are installed in ${PREFIX_PATH}/bin
+ ln -fs "${PREFIX_PATH}/Library/Frameworks/Python.framework/Versions/Current/bin" "${PREFIX_PATH}/bin"
+ fi
+
+ # Not create symlinks on `altinstall` (#255)
+ if [[ "$PYTHON_MAKE_INSTALL_TARGET" != *"altinstall"* ]]; then
+ shopt -s nullglob
+ local version_bin="$(ls -1 "${PREFIX_PATH}/bin/python"* | grep '[0-9]$' | sort | tail -1)"
+ suffix="$(basename "${version_bin}" | sed -e 's/^python//')"
+ if [ -n "${suffix}" ]; then
+ local file link
+ for file in "${PREFIX_PATH}/bin"/*; do
+ unset link
+ case "${file}" in
+ */"python${suffix}-config" )
+ # Symlink `pythonX.Y-config` to `python-config` if `python-config` is missing (#296)
+ link="${file%/*}/python-config"
+ ;;
+ */*"-${suffix}" )
+ link="${file%%-${suffix}}"
+ ;;
+ */*"${suffix}" )
+ link="${file%%${suffix}}"
+ ;;
+ esac
+ if [ -n "$link" ] && [ ! -e "$link" ]; then
+ ( cd "${file%/*}" && ln -fs "${file##*/}" "${link##*/}" )
+ fi
+ done
+ fi
+ shopt -u nullglob
+ fi
+}
+
+verify_python() {
+ build_package_symlink_version_suffix
+
+ if [ ! -x "${PYTHON_BIN}" ]; then
+ { colorize 1 "ERROR"
+ echo ": invalid Python executable: ${PYTHON_BIN}"
+ echo
+ echo "The python-build could not find proper executable of Python after successful build."
+ echo "Please open an issue for future improvements."
+ echo "https://github.com/pyenv/pyenv/issues"
+ return 1
+ } >&3
+ fi
+}
+
+try_python_module() {
+ if ! "$PYTHON_BIN" -c "import $1"; then
+ { colorize 1 "WARNING"
+ echo ": The Python $1 extension was not compiled${3:+ $3}. Missing the ${2:-$1}?"
+ return 0
+ } >&3
+ fi
+}
+
+verify_python_module() {
+ if ! "$PYTHON_BIN" -c "import $1"; then
+ { colorize 1 "ERROR"
+ echo ": The Python $1 extension was not compiled. Missing the ${2:-$1}?"
+ echo
+ echo "Please consult to the Wiki page to fix the problem."
+ echo "https://github.com/pyenv/pyenv/wiki/Common-build-problems"
+ echo
+ return 1
+ } >&3
+ fi
+}
+
+# Post-install check for Python 2.1.x
+build_package_verify_py21() {
+ verify_python "${2:-python2.1}"
+ try_python_module "readline" "GNU readline lib"
+ verify_python_module "binascii" "binascii"
+ # fixme: zlib doesn't link correctly on 64-bit Linux, due to being in
+ # /usr/x86_64-linux-gnu instead of /usr/lib
+ try_python_module "zlib" "zlib"
+ try_python_module "bz2" "bzip2 lib"
+}
+
+# Post-install check for Python 2.2.x
+build_package_verify_py22() {
+ verify_python "${2:-python2.2}"
+ try_python_module "readline" "GNU readline lib"
+ verify_python_module "binascii" "binascii"
+ # fixme: zlib doesn't link correctly on 64-bit Linux, due to being in
+ # /usr/x86_64-linux-gnu instead of /usr/lib
+ try_python_module "zlib" "zlib"
+ try_python_module "bz2" "bzip2 lib"
+}
+
+# Post-install check for Python 2.3.x
+build_package_verify_py23() {
+ verify_python "${2:-python2.3}"
+ try_python_module "readline" "GNU readline lib"
+ verify_python_module "binascii" "binascii"
+ # fixme: zlib doesn't link correctly on 64-bit Linux, due to being in
+ # /usr/x86_64-linux-gnu instead of /usr/lib
+ try_python_module "zlib" "zlib"
+ try_python_module "bz2" "bzip2 lib"
+}
+
+# Post-install check for Python 2.4.x
+build_package_verify_py24() {
+ verify_python "${2:-2.4}"
+ try_python_module "readline" "GNU readline lib"
+ verify_python_module "zlib" "zlib"
+ try_python_module "bz2" "bzip2 lib"
+}
+
+# Post-install check for Python 2.5.x
+build_package_verify_py25() {
+ build_package_verify_py24 "$1" "${2:-2.5}"
+ try_python_module "sqlite3" "SQLite3 lib"
+}
+
+# Post-install check for Python 2.6.x
+build_package_verify_py26() {
+ build_package_verify_py25 "$1" "${2:-2.6}"
+ verify_python_module "ssl" "OpenSSL lib"
+}
+
+# Post-install check for Python 2.7.x
+build_package_verify_py27() {
+ build_package_verify_py26 "$1" "${2:-2.7}"
+}
+
+# Post-install check for Python 3.0.x
+build_package_verify_py30() {
+ verify_python "${2:-3.0}"
+ try_python_module "bz2" "bzip2 lib"
+ try_python_module "curses" "ncurses lib"
+ try_python_module "ctypes" "libffi lib"
+ try_python_module "readline" "GNU readline lib"
+ verify_python_module "ssl" "OpenSSL lib"
+ try_python_module "sqlite3" "SQLite3 lib"
+ if [[ -n $DISPLAY ]]; then
+ try_python_module "tkinter" "Tk toolkit" "and GUI subsystem has been detected"
+ fi
+ verify_python_module "zlib" "zlib"
+}
+
+# Post-install check for Python 3.1.x
+build_package_verify_py31() {
+ build_package_verify_py30 "$1" "${2:-3.1}"
+}
+
+# Post-install check for Python 3.2.x
+build_package_verify_py32() {
+ build_package_verify_py31 "$1" "${2:-3.2}"
+}
+
+# Post-install check for Python 3.3.x
+build_package_verify_py33() {
+ build_package_verify_py32 "$1" "${2:-3.3}"
+ try_python_module "lzma" "lzma lib"
+}
+
+# Post-install check for Python 3.4.x
+build_package_verify_py34() {
+ build_package_verify_py33 "$1" "${2:-3.4}"
+}
+
+# Post-install check for Python 3.5.x
+build_package_verify_py35() {
+ build_package_verify_py34 "$1" "${2:-3.5}"
+}
+
+# Post-install check for Python 3.6.x
+build_package_verify_py36() {
+ build_package_verify_py35 "$1" "${2:-3.6}"
+}
+
+# Post-install check for Python 3.7.x
+build_package_verify_py37() {
+ build_package_verify_py36 "$1" "${2:-3.7}"
+}
+
+# Post-install check for Python 3.8.x
+build_package_verify_py38() {
+ build_package_verify_py37 "$1" "${2:-3.8}"
+}
+
+# Post-install check for Python 3.9.x
+build_package_verify_py39() {
+ build_package_verify_py38 "$1" "${2:-3.9}"
+}
+
+# Post-install check for Python 3.10.x
+build_package_verify_py310() {
+ build_package_verify_py39 "$1" "${2:-3.10}"
+}
+
+# Post-install check for Python 3.11.x
+build_package_verify_py311() {
+ build_package_verify_py310 "$1" "${2:-3.11}"
+}
+
+# Post-install check for Python 3.12.x
+build_package_verify_py312() {
+ build_package_verify_py311 "$1" "${2:-3.12}"
+}
+
+# Post-install check for Python 3.13.x
+build_package_verify_py313() {
+ build_package_verify_py312 "$1" "${2:-3.13}"
+}
+
+# Post-install check for Python 3.14.x
+build_package_verify_py314() {
+ build_package_verify_py313 "$1" "${2:-3.14}"
+}
+
+# Post-install check for Python 3.15.x
+build_package_verify_py315() {
+ build_package_verify_py314 "$1" "${2:-3.15}"
+}
+
+# Post-install check for Python 3.x rolling release scripts
+# XXX: Will need splitting into project-specific ones if there emerge
+# multiple rolling-release scripts with different checks needed
+build_package_verify_py3_latest() {
+ build_package_verify_py311 "$1" "3"
+}
+
+# Copy Tools/gdb/libpython.py to pythonX.Y-gdb.py (#1190)
+build_package_copy_python_gdb() {
+ if [ -e "$BUILD_PATH/$1/Tools/gdb/libpython.py" ]; then
+ local version_re='-([0-9]\.[0-9]+)'
+ [[ "$1" =~ $version_re ]]
+ local python_bin="$PREFIX_PATH/bin/python${BASH_REMATCH[1]}"
+ cp "$BUILD_PATH/$1/Tools/gdb/libpython.py" "$python_bin-gdb.py"
+ fi
+}
+
+build_package_ez_setup() {
+ local ez_setup="ez_setup.py"
+ rm -f "${ez_setup}"
+ { if [ "${EZ_SETUP+defined}" ] && [ -f "${EZ_SETUP}" ]; then
+ echo "Installing setuptools from ${EZ_SETUP}..." 1>&2
+ cat "${EZ_SETUP}"
+ else
+ [ -n "${EZ_SETUP_URL}" ]
+ echo "Installing setuptools from ${EZ_SETUP_URL}..." 1>&2
+ http get "${EZ_SETUP_URL}"
+ fi
+ } 1> "${ez_setup}"
+ "${PYTHON_BIN}" "${ez_setup}" ${EZ_SETUP_OPTS} 1>&4 2>&1 || {
+ echo "error: failed to install setuptools via ez_setup.py" >&2
+ return 1
+ }
+ build_package_symlink_version_suffix
+}
+
+build_package_get_pip() {
+ local get_pip="get-pip.py"
+ rm -f "${get_pip}"
+ { if [ "${GET_PIP+defined}" ] && [ -f "${GET_PIP}" ]; then
+ echo "Installing pip from ${GET_PIP}..." 1>&2
+ cat "${GET_PIP}"
+ else
+ [ -n "${GET_PIP_URL}" ]
+ echo "Installing pip from ${GET_PIP_URL}..." 1>&2
+ http get "${GET_PIP_URL}"
+ fi
+ } 1> "${get_pip}"
+ "${PYTHON_BIN}" -s "${get_pip}" ${GET_PIP_OPTS} 1>&4 2>&1 || {
+ echo "error: failed to install pip via get-pip.py" >&2
+ return 1
+ }
+ build_package_symlink_version_suffix
+}
+
+# Pip <21 (in 2.7 and derivatives like PyPy-2.7) doesn't support -I
+build_package_ensurepip_lt21() {
+ build_package_ensurepip lt21
+}
+
+build_package_ensurepip() {
+ local mode="$1"
+ local ensurepip_opts
+ # Install as `--altinstall` if the Python is installed as `altinstall` (#255)
+ if [[ "$PYTHON_MAKE_INSTALL_TARGET" == *"altinstall"* ]]; then
+ ensurepip_opts="--altinstall"
+ fi
+ local python_opts="-I"
+ if [[ $mode == "lt21" ]]; then python_opts="-s"; fi
+
+ # FIXME: `--altinstall` with `get-pip.py`
+ "$PYTHON_BIN" $python_opts -m ensurepip ${ensurepip_opts} 1>/dev/null 2>&1 || build_package_get_pip "$@" || return 1
+ build_package_symlink_version_suffix
+}
+
+version() {
+ local git_revision
+ # Read the revision from git if the remote points to "python-build" repository
+ if GIT_DIR="$PYTHON_BUILD_INSTALL_PREFIX/../../.git" git remote -v 2>/dev/null | grep -q /pyenv; then
+ git_revision="$(GIT_DIR="$PYTHON_BUILD_INSTALL_PREFIX/../../.git" git describe --tags HEAD 2>/dev/null || true)"
+ git_revision="${git_revision#v}"
+ fi
+ echo "python-build ${git_revision:-$PYTHON_BUILD_VERSION}"
+}
+
+usage() {
+ sed -ne '/^#/!q;s/.\{1,2\}//;1,2d;p' < "$0"
+ [ -z "$1" ] || exit "$1"
+}
+
+list_definitions() {
+ { for DEFINITION_DIR in "${PYTHON_BUILD_DEFINITIONS[@]}"; do
+ [ -d "$DEFINITION_DIR" ] && ls "$DEFINITION_DIR" | grep -xv patches
+ done
+ } | sort_versions | uniq
+}
+
+sort_versions() {
+ sed 'h; s/[+-]/./g; s/.p\([[:digit:]]\)/.z.\1/; s/$/.z/; G; s/\n/ /' | \
+ LC_ALL=C sort -t. -k 1,1 -k 2,2n -k 3,3n -k 4,4n -k 5,5n | awk '{print $2}'
+}
+
+
+unset VERBOSE
+unset KEEP_BUILD_PATH
+unset HAS_PATCH
+unset DEBUG
+unset IPV4
+unset IPV6
+
+PYTHON_BUILD_INSTALL_PREFIX="$(abs_dirname "$0")/.."
+
+IFS=: PYTHON_BUILD_DEFINITIONS=($PYTHON_BUILD_DEFINITIONS ${PYTHON_BUILD_ROOT:-$PYTHON_BUILD_INSTALL_PREFIX}/share/python-build)
+IFS="$OLDIFS"
+
+parse_options "$@"
+
+for option in "${OPTIONS[@]}"; do
+ case "$option" in
+ "h" | "help" )
+ version
+ echo
+ usage 0
+ ;;
+ "definitions" )
+ list_definitions
+ exit 0
+ ;;
+ "k" | "keep" )
+ KEEP_BUILD_PATH=true
+ ;;
+ "v" | "verbose" )
+ VERBOSE=true
+ ;;
+ "p" | "patch" )
+ HAS_STDIN_PATCH=true
+ ;;
+ "g" | "debug" )
+ DEBUG=true
+ # Disable optimization (#808)
+ PYTHON_CFLAGS="-O0 ${PYTHON_CFLAGS}"
+ ;;
+ "4" | "ipv4")
+ IPV4=true
+ ;;
+ "6" | "ipv6")
+ IPV6=true
+ ;;
+ "version" )
+ version
+ exit 0
+ ;;
+ esac
+done
+
+[ "${#ARGUMENTS[@]}" -eq 2 ] || usage 1 >&2
+
+DEFINITION_PATH="${ARGUMENTS[0]}"
+if [ -z "$DEFINITION_PATH" ]; then
+ usage 1 >&2
+elif [ ! -f "$DEFINITION_PATH" ]; then
+ for DEFINITION_DIR in "${PYTHON_BUILD_DEFINITIONS[@]}"; do
+ if [ -f "${DEFINITION_DIR}/${DEFINITION_PATH}" ]; then
+ DEFINITION_PATH="${DEFINITION_DIR}/${DEFINITION_PATH}"
+ break
+ fi
+ done
+
+ if [ ! -f "$DEFINITION_PATH" ]; then
+ echo "python-build: definition not found: ${DEFINITION_PATH}" >&2
+ exit 2
+ fi
+fi
+
+PREFIX_PATH="${ARGUMENTS[1]}"
+if [ -z "$PREFIX_PATH" ]; then
+ usage 1 >&2
+elif [ "${PREFIX_PATH#/}" = "$PREFIX_PATH" ]; then
+ PREFIX_PATH="${PWD}/${PREFIX_PATH}"
+fi
+
+if [ -z "$TMPDIR" ]; then
+ TMP="/tmp"
+else
+ TMP="${TMPDIR%/}"
+fi
+
+# Check if TMPDIR is accessible and can hold executables.
+tmp_executable="${TMP}/python-build-test.$$"
+noexec=""
+if mkdir -p "$TMP" && touch "$tmp_executable" 2>/dev/null; then
+ cat > "$tmp_executable" <<-EOF
+ #!${BASH}
+ exit 0
+ EOF
+ chmod +x "$tmp_executable"
+else
+ echo "python-build: TMPDIR=$TMP is set to a non-accessible location" >&2
+ exit 1
+fi
+"$tmp_executable" 2>/dev/null || noexec=1
+rm -f "$tmp_executable"
+if [ -n "$noexec" ]; then
+ echo "python-build: TMPDIR=$TMP cannot hold executables (partition possibly mounted with \`noexec\`)" >&2
+ exit 1
+fi
+
+if [ -z "$MAKE" ]; then
+ if [ "FreeBSD" = "${_PYTHON_BUILD_CACHE_UNAME_S:=$(uname -s)}" ]; then
+ if [ "$(echo $1 | sed 's/-.*$//')" = "jruby" ]; then
+ export MAKE="gmake"
+ else
+ # var assignment inside $() does not propagate due to being in subshell
+ : "${_PYTHON_BUILD_CACHE_UNAME_R:=$(uname -r)}"
+ if [ "$(echo "$_PYTHON_BUILD_CACHE_UNAME_R" | sed 's/[^[:digit:]].*//')" -lt 10 ]; then
+ export MAKE="gmake"
+ else
+ export MAKE="make"
+ fi
+ fi
+ else
+ export MAKE="make"
+ fi
+fi
+
+if [ -n "$PYTHON_BUILD_CACHE_PATH" ] && [ -d "$PYTHON_BUILD_CACHE_PATH" ]; then
+ PYTHON_BUILD_CACHE_PATH="${PYTHON_BUILD_CACHE_PATH%/}"
+else
+ unset PYTHON_BUILD_CACHE_PATH
+fi
+
+if [ -z "$PYTHON_BUILD_MIRROR_URL" ]; then
+ PYTHON_BUILD_MIRROR_URL="https://pyenv.github.io/pythons"
+ PYTHON_BUILD_DEFAULT_MIRROR=1
+else
+ PYTHON_BUILD_MIRROR_URL="${PYTHON_BUILD_MIRROR_URL%/}"
+ PYTHON_BUILD_DEFAULT_MIRROR=
+fi
+
+if [ -n "$PYTHON_BUILD_SKIP_MIRROR" ]; then
+ unset PYTHON_BUILD_MIRROR_URL
+fi
+
+if ! has_checksum_support compute_sha2 && ! [ -n "$PYTHON_BUILD_MIRROR_URL_SKIP_CHECKSUM" ] ; then
+ unset PYTHON_BUILD_MIRROR_URL
+fi
+
+ARIA2_OPTS="${PYTHON_BUILD_ARIA2_OPTS} ${IPV4+--disable-ipv6=true} ${IPV6+--disable-ipv6=false}"
+CURL_OPTS="${PYTHON_BUILD_CURL_OPTS} ${IPV4+--ipv4} ${IPV6+--ipv6}"
+WGET_OPTS="${PYTHON_BUILD_WGET_OPTS} ${IPV4+--inet4-only} ${IPV6+--inet6-only}"
+
+# Add an option to build a debug version of Python (#11)
+if [ -n "$DEBUG" ]; then
+ package_option python configure --with-pydebug
+fi
+
+if [[ "$CONFIGURE_OPTS $PYTHON_CONFIGURE_OPTS" != *"--enable-framework"* && "$CONFIGURE_OPTS $PYTHON_CONFIGURE_OPTS" != *"--disable-shared"* ]]; then
+ package_option python configure --enable-shared
+fi
+
+# python-build: Specify `--libdir` on configure to fix build on openSUSE (#36)
+package_option python configure --libdir="${PREFIX_PATH}/lib"
+
+# python-build: Set `RPATH` if `--enable-shared` was given (#65, #66, #82)
+if [[ "$CONFIGURE_OPTS $PYTHON_CONFIGURE_OPTS ${PYTHON_CONFIGURE_OPTS_ARRAY[@]}" == *"--enable-shared"* ]]; then
+ # The ld on Darwin embeds the full paths to each dylib by default
+ if [[ "$LDFLAGS" != *"-rpath="* ]] ; then
+ prepend_ldflags_libs "-Wl,-rpath,${PREFIX_PATH}/lib"
+ fi
+fi
+
+# python-build: Set `RPATH` if --shared` was given for PyPy (#244)
+if [[ "$PYPY_OPTS" == *"--shared"* ]]; then
+ prepend_ldflags_libs "-Wl,-rpath=${PREFIX_PATH}/lib"
+fi
+
+# Add support for framework installation (`--enable-framework`) of CPython (#55, #99)
+if [[ "$CONFIGURE_OPTS $PYTHON_CONFIGURE_OPTS" == *"--enable-framework"* ]]; then
+ if ! is_mac; then
+ echo "python-build: framework installation is not supported outside of MacOS." >&2
+ exit 1
+ fi
+ create_framework_dirs() {
+ local version="$(echo "$1" | sed -E 's/^[^0-9]*([0-9]+\.[0-9]+).*$/\1/')"
+ mkdir -p "${PREFIX_PATH}/Library/Frameworks/Python.framework/Versions/${version}"
+ ( cd "${PREFIX_PATH}/Library/Frameworks/Python.framework/Versions" && ln -fs "${version}" "Current")
+ local path
+ for path in include lib share; do
+ mkdir -p "${PREFIX_PATH}/Library/Frameworks/Python.framework/Versions/Current/${path}"
+ ln -fs "${PREFIX_PATH}/Library/Frameworks/Python.framework/Versions/Current/${path}" "${PREFIX_PATH}/${path}"
+ done
+ }
+ create_framework_dirs "${DEFINITION_PATH##*/}"
+ # the `/Library/Frameworks` suffix makes CPython build install apps under prefix rather than into /Applications (#1003)
+ package_option python configure --enable-framework="${PREFIX_PATH}/Library/Frameworks"
+
+ #FIXME: doesn't properly handle paths with spaces. Fix by parsing *OPTS into arrays.
+ CONFIGURE_OPTS="${CONFIGURE_OPTS//--enable-framework?(=*([^ ]))?( )/}";
+ CONFIGURE_OPTS="${CONFIGURE_OPTS% }"
+ PYTHON_CONFIGURE_OPTS="${PYTHON_CONFIGURE_OPTS//--enable-framework?(=*([^ ]))?( )/}";
+ PYTHON_CONFIGURE_OPTS="${PYTHON_CONFIGURE_OPTS% }"
+fi
+
+# Build against universal SDK
+if [[ "$CONFIGURE_OPTS $PYTHON_CONFIGURE_OPTS" == *"--enable-universalsdk"* ]]; then
+ if ! is_mac; then
+ echo "python-build: universal installation is not supported outside of MacOS." >&2
+ exit 1
+ fi
+ package_option python configure --enable-universalsdk=/
+ #FIXME: doesn't properly handle paths with spaces. Fix by parsing *OPTS into arrays.
+ CONFIGURE_OPTS="${CONFIGURE_OPTS//--enable-universalsdk?(=*([^ ]))?( )/}"
+ CONFIGURE_OPTS="${CONFIGURE_OPTS% }"
+ PYTHON_CONFIGURE_OPTS="${PYTHON_CONFIGURE_OPTS//--enable-universalsdk?(=*([^ ]))?( )/}"
+ PYTHON_CONFIGURE_OPTS="${PYTHON_CONFIGURE_OPTS% }"
+
+ if [[ "$CONFIGURE_OPTS $PYTHON_CONFIGURE_OPTS" != *"--with-universal-archs"* ]]; then
+ # in CPython's configure.ac, --with-universal-archs defaults to 'intel' which means i386 + x86_64
+ # since 2.7.5 and 3.3.0 -- i.e. in all non-EOL versions
+ # Apple Silicon cannot build these, in it, it rather makes sense to default to Universal2 binaries
+ if [[ $(arch) == "arm64" ]]; then
+ package_option python configure --with-universal-archs=universal2
+ fi
+ fi
+fi
+
+# Compile with `--enable-unicode=ucs4` by default (#257)
+if [[ "$PYTHON_CONFIGURE_OPTS" != *"--enable-unicode="* ]]; then
+ if ! is_mac; then
+ # Skip specifying `--enable-unicode` for CPython 3.3+ (#912)
+ case "${DEFINITION_PATH##*/}" in
+ "2."* | \
+ "3.0" | "3.0."* | "3.0-"* | \
+ "3.1" | "3.1."* | "3.1-"* | \
+ "3.2" | "3.2."* | "3.2-"* )
+ package_option python configure --enable-unicode=ucs4
+ ;;
+ esac
+ fi
+fi
+
+# Unset `PIP_REQUIRE_VENV` during build (#216)
+unset PIP_REQUIRE_VENV
+unset PIP_REQUIRE_VIRTUALENV
+
+# pydistutils.cfg may corrupt install location of Python libraries (#35, #111)
+if [ -e "$HOME/.pydistutils.cfg" ]; then
+ { colorize 1 "WARNING"
+ echo ": Please make sure you remove any previous custom paths from your $HOME/.pydistutils.cfg file."
+ } >&2
+fi
+
+# Download specified version of ez_setup.py/get-pip.py (#202)
+if [ -z "${EZ_SETUP_URL}" ]; then
+ if [ -n "${SETUPTOOLS_VERSION}" ]; then
+ EZ_SETUP_URL="https://bitbucket.org/pypa/setuptools/raw/${SETUPTOOLS_VERSION}/ez_setup.py"
+ unset SETUPTOOLS_VERSION
+ else
+ EZ_SETUP_URL="https://bootstrap.pypa.io/ez_setup.py"
+ fi
+fi
+if [ -z "${GET_PIP_URL}" ]; then
+ if [ -n "${PIP_VERSION}" ]; then
+ { colorize 1 "WARNING"
+ echo ": Setting PIP_VERSION=${PIP_VERSION} is no longer supported and may cause failures during the install process."
+ } 1>&2
+ GET_PIP_URL="https://raw.githubusercontent.com/pypa/pip/${PIP_VERSION}/contrib/get-pip.py"
+ # Unset `PIP_VERSION` from environment before invoking `get-pip.py` to deal with "ValueError: invalid truth value" (pypa/pip#4528)
+ unset PIP_VERSION
+ else
+ # Use custom get-pip URL based on the target version (#1127)
+ case "${DEFINITION_PATH##*/}" in
+ 2.6 | 2.6.* )
+ GET_PIP_URL="https://bootstrap.pypa.io/pip/2.6/get-pip.py"
+ ;;
+ 2.7 | 2.7.* | pypy2.7 | pypy2.7-* )
+ GET_PIP_URL="https://bootstrap.pypa.io/pip/2.7/get-pip.py"
+ ;;
+ 3.2 | 3.2.* )
+ GET_PIP_URL="https://bootstrap.pypa.io/pip/3.2/get-pip.py"
+ ;;
+ 3.3 | 3.3.* )
+ GET_PIP_URL="https://bootstrap.pypa.io/pip/3.3/get-pip.py"
+ ;;
+ 3.4 | 3.4.* )
+ GET_PIP_URL="https://bootstrap.pypa.io/pip/3.4/get-pip.py"
+ ;;
+ 3.5 | 3.5.* | pypy3.5 | pypy3.5-* )
+ GET_PIP_URL="https://bootstrap.pypa.io/pip/3.5/get-pip.py"
+ ;;
+ 3.6 | 3.6.* | pypy3.6 | pypy3.6-* )
+ GET_PIP_URL="https://bootstrap.pypa.io/pip/3.6/get-pip.py"
+ ;;
+ 3.7 | 3.7.* | pypy3.7 | pypy3.7-* )
+ GET_PIP_URL="https://bootstrap.pypa.io/pip/3.7/get-pip.py"
+ ;;
+ 3.8 | 3.8.* | pypy3.8 | pypy3.8-* | pyston* )
+ GET_PIP_URL="https://bootstrap.pypa.io/pip/3.8/get-pip.py"
+ ;;
+ * )
+ GET_PIP_URL="https://bootstrap.pypa.io/get-pip.py"
+ ;;
+ esac
+ fi
+fi
+
+# Set MACOSX_DEPLOYMENT_TARGET from the product version of OS X (#219, #220)
+if is_mac; then
+ if [ -z "${MACOSX_DEPLOYMENT_TARGET}" ]; then
+ MACOS_VERSION="${_PYTHON_BUILD_CACHE_SW_VERS:=$(sw_vers -productVersion)}"
+ MACOS_VERSION_ARRAY=(${MACOS_VERSION//\./ })
+ if [ "${#MACOS_VERSION_ARRAY[@]}" -ge 2 ]; then
+ export MACOSX_DEPLOYMENT_TARGET="${MACOS_VERSION_ARRAY[0]}.${MACOS_VERSION_ARRAY[1]}"
+ fi
+ fi
+fi
+
+python_bin_suffix() {
+ local version_name version_info
+ case "$1" in
+ 2.* | 3.* )
+ version_name="$1"
+ version_name="${version_name%-dev}"
+ version_name="${version_name%-rc*}"
+ version_name="${version_name%rc*}"
+ version_name="${version_name%%*([^0-9])}"
+ version_info=(${version_name//./ })
+ echo "${version_info[0]}.${version_info[1]}"
+ ;;
+ stackless-2.* | stackless-3.* )
+ version_name="${1#stackless-}"
+ version_name="${version_name%-dev}"
+ version_name="${version_name%-rc*}"
+ version_name="${version_name%rc*}"
+ version_info=(${version_name//./ })
+ echo "${version_info[0]}.${version_info[1]}"
+ ;;
+ esac
+}
+
+SEED="$(date "+%Y%m%d%H%M%S").$$"
+LOG_PATH="${TMP}/python-build.${SEED}.log"
+PYTHON_BIN="${PREFIX_PATH}/bin/python$(python_bin_suffix "${DEFINITION_PATH##*/}")"
+CWD="$(pwd)"
+
+if [ -z "$PYTHON_BUILD_BUILD_PATH" ]; then
+ BUILD_PATH="${TMP}/python-build.${SEED}"
+else
+ BUILD_PATH="$PYTHON_BUILD_BUILD_PATH"
+fi
+
+exec 4<> "$LOG_PATH" # open the log file at fd 4
+if [ -n "$VERBOSE" ]; then
+ tail -f "$LOG_PATH" &
+ TAIL_PID=$!
+ trap "kill $TAIL_PID" SIGINT SIGTERM EXIT
+fi
+
+prepend_ldflags_libs "-L${PREFIX_PATH}/lib"
+export CPPFLAGS="-I${PREFIX_PATH}/include${CPPFLAGS:+ $CPPFLAGS}"
+
+unset PYTHONHOME
+unset PYTHONPATH
+
+trap build_failed ERR
+mkdir -p "$BUILD_PATH"
+source "$DEFINITION_PATH"
+[ -z "${KEEP_BUILD_PATH}" ] && rm -fr "$BUILD_PATH"
+trap - ERR