-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathPythonRecipe
More file actions
86 lines (76 loc) · 3.42 KB
/
PythonRecipe
File metadata and controls
86 lines (76 loc) · 3.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# PythonRecipe — standard recipe for Python packages (bits-recipe-tools)
#
# Uses pip to install into an isolated prefix, then patches shebangs for
# relocatability. Mirrors the install pattern used by lcgcmake's
# pyexternals/CMakeLists.txt (pip install --no-deps --root=/ --prefix=...).
#
# Variables exported by this file (available to recipe overrides):
#
# PYTHON_EXE full path to the python3 interpreter
# PYTHON_MAJOR_MINOR e.g. "3.12"
# SITE_PACKAGES $INSTALLROOT/lib/python3.12/site-packages
#
# Requirement: Python must be in the recipe's `requires:` list so that
# Python_ROOT is set in the environment before this file is sourced.
# bits' init.sh exports _ROOT vars using the package: field name verbatim
# (e.g. Python_ROOT for "package: Python"). Module files now generate uppercase
# names (PYTHON_ROOT) but Python itself may not have been rebuilt yet, so we
# fall back to the mixed-case form that bits always provides.
_PYTHON_ROOT="${PYTHON_ROOT:-${Python_ROOT}}"
PYTHON_EXE="${_PYTHON_ROOT}/bin/python3"
PYTHON_MAJOR_MINOR=$(${PYTHON_EXE} -c 'import sys; print("%d.%d" % sys.version_info[:2])')
SITE_PACKAGES="${INSTALLROOT}/lib/python${PYTHON_MAJOR_MINOR}/site-packages"
# Build PYTHONPATH from every dependency that installed Python modules.
# bits sets *_ROOT for each dep via init.sh sourcing; we add any whose
# lib/pythonX.Y/site-packages directory actually exists.
# The regex accepts both mixed-case names from bits init.sh (e.g. meson_python_ROOT,
# Python_ROOT) and uppercase names from new-style module files (MESON_PYTHON_ROOT).
for _root_var in $(env | grep -E '^[A-Za-z][A-Za-z0-9_]*_ROOT=' | cut -d= -f1 | sort -u); do
_root_val="${!_root_var}"
_sp="${_root_val}/lib/python${PYTHON_MAJOR_MINOR}/site-packages"
[ -d "${_sp}" ] || continue
export PYTHONPATH="${_sp}${PYTHONPATH:+:${PYTHONPATH}}"
done
unset _root_var _root_val _sp
function Prepare() {
rsync -av --delete --exclude '**/.git' --delete-excluded "${SOURCEDIR}"/ ./
}
function Configure() { true; }
function Make() { true; }
function MakeInstall() {
mkdir -p "${SITE_PACKAGES}"
# --no-deps deps are managed by bits, not pip
# --no-build-isolation use already-installed build tools (setuptools, etc.)
# --ignore-installed don't try to uninstall system packages before installing;
# avoids "Permission denied" when a system copy exists
# --root=/ --prefix= install directly into our package tree; no staging dir
"${PYTHON_EXE}" -m pip install \
--no-deps --no-build-isolation --ignore-installed \
--root=/ --prefix="${INSTALLROOT}" .
}
function UnitTest() {
true
}
function PostInstall() {
# Replace hardcoded python paths in installed scripts with #!/usr/bin/env python3.
# Mirrors lcgcmake's pyexternals/Python_postinstall.sh.
for _f in "${INSTALLROOT}/bin/"*; do
[ -f "${_f}" ] || continue
head -n1 "${_f}" | grep -q "/python" || continue
sed -i.bak "1s|.*|#!/usr/bin/env python3|" "${_f}"
rm -f "${_f}.bak"
done
unset _f
}
function Clean() { true; }
. ${BITS_RECIPE_TOOLS_ROOT}/ModuleRecipe
. ${BITS_RECIPE_TOOLS_ROOT}/PreloadRecipe
function Run() {
local rc=0
case $1 in
Prepare) Prepare ;;
Build) Configure && Make && UnitTest && MakeInstall && MakeModule && PostInstall && Preload && Clean ;;
*) Prepare && Configure && Make && UnitTest && MakeInstall && MakeModule && PostInstall && Preload && Clean ;;
esac || rc=$?
return $rc
}