133 lines
4.0 KiB
Bash
133 lines
4.0 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
|
||
|
|
# --- Configuration ---
|
||
|
|
PYTHON_VERSIONS=("3.8.10" "3.9.13" "3.10.11" "3.11.9" "3.12.3" "3.13.0" "3.14.0")
|
||
|
|
|
||
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||
|
|
BASE_OUTPUT_DIR="$SCRIPT_DIR/../../cross/python_includes"
|
||
|
|
|
||
|
|
# --- OS Detection ---
|
||
|
|
OS="$(uname -s)"
|
||
|
|
echo "Detected OS: $OS"
|
||
|
|
|
||
|
|
# --- Dependency Check ---
|
||
|
|
check_dependencies() {
|
||
|
|
if [ "$OS" == "Linux" ]; then
|
||
|
|
if ! command -v 7z &> /dev/null; then
|
||
|
|
echo "Error: '7z' (p7zip-full) is required on Linux."
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
if ! command -v cpio &> /dev/null; then
|
||
|
|
echo "Error: 'cpio' is required."
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
# --- Extraction Logic (OS Specific) ---
|
||
|
|
extract_pkg() {
|
||
|
|
local pkg_file="$1"
|
||
|
|
local extract_root="$2"
|
||
|
|
local major_ver="$3" # e.g., 3.11
|
||
|
|
|
||
|
|
echo " -> Extracting..."
|
||
|
|
|
||
|
|
if [ "$OS" == "Darwin" ]; then
|
||
|
|
pkgutil --expand "$pkg_file" "$extract_root/expanded"
|
||
|
|
local payload_path="$extract_root/expanded/Python_Framework.pkg/Payload"
|
||
|
|
|
||
|
|
if [ ! -f "$payload_path" ]; then
|
||
|
|
echo " -> Error: Could not find Payload in package."
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
mkdir -p "$extract_root/root"
|
||
|
|
pushd "$extract_root/root" > /dev/null
|
||
|
|
cat "$payload_path" | gunzip | cpio -id "*include/python${major_ver}/*" 2>/dev/null
|
||
|
|
popd > /dev/null
|
||
|
|
|
||
|
|
else
|
||
|
|
7z x "$pkg_file" -o"$extract_root/expanded" -y > /dev/null
|
||
|
|
local payload_path="$extract_root/expanded/Python_Framework.pkg/Payload"
|
||
|
|
|
||
|
|
if [ ! -f "$payload_path" ]; then
|
||
|
|
echo " -> Error: Could not find Payload in package."
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
|
||
|
|
mkdir -p "$extract_root/root"
|
||
|
|
pushd "$extract_root/root" > /dev/null
|
||
|
|
cat "$payload_path" | gunzip | cpio -id "*include/python${major_ver}/*" 2>/dev/null
|
||
|
|
popd > /dev/null
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
check_dependencies
|
||
|
|
|
||
|
|
mkdir -p "$BASE_OUTPUT_DIR"
|
||
|
|
|
||
|
|
for FULL_VER in "${PYTHON_VERSIONS[@]}"; do
|
||
|
|
MAJOR_VER=$(echo "$FULL_VER" | cut -d. -f1,2)
|
||
|
|
|
||
|
|
TARGET_DIR="$BASE_OUTPUT_DIR/python-$MAJOR_VER"
|
||
|
|
TEMP_DIR="$BASE_OUTPUT_DIR/tmp_$FULL_VER"
|
||
|
|
PKG_NAME="python-${FULL_VER}-macos11.pkg"
|
||
|
|
|
||
|
|
if [[ "$MAJOR_VER" == "3.8" ]]; then
|
||
|
|
PKG_NAME="python-${FULL_VER}-macosx10.9.pkg"
|
||
|
|
fi
|
||
|
|
|
||
|
|
DOWNLOAD_URL="https://www.python.org/ftp/python/${FULL_VER}/$PKG_NAME"
|
||
|
|
|
||
|
|
echo "Processing Python $FULL_VER..."
|
||
|
|
|
||
|
|
if [ -d "$TARGET_DIR" ] && [ "$(ls -A $TARGET_DIR)" ]; then
|
||
|
|
echo " -> Headers already exist in $TARGET_DIR. Skipping."
|
||
|
|
continue
|
||
|
|
fi
|
||
|
|
|
||
|
|
mkdir -p "$TEMP_DIR"
|
||
|
|
|
||
|
|
echo " -> Downloading from $DOWNLOAD_URL"
|
||
|
|
curl -L -s -o "$TEMP_DIR/python.pkg" "$DOWNLOAD_URL"
|
||
|
|
|
||
|
|
if [ $? -ne 0 ]; then
|
||
|
|
echo " -> Download failed! Check version number or internet connection."
|
||
|
|
rm -rf "$TEMP_DIR"
|
||
|
|
continue
|
||
|
|
fi
|
||
|
|
|
||
|
|
# 2. Extract
|
||
|
|
extract_pkg "$TEMP_DIR/python.pkg" "$TEMP_DIR" "$MAJOR_VER"
|
||
|
|
|
||
|
|
# 3. Move Headers to Final Location
|
||
|
|
# The cpio extraction usually results in: ./Versions/X.Y/include/pythonX.Y
|
||
|
|
# We want to move that specific include folder to our target dir
|
||
|
|
|
||
|
|
FOUND_HEADERS=$(find "$TEMP_DIR/root" -type d -path "*/include/python${MAJOR_VER}" | head -n 1)
|
||
|
|
|
||
|
|
if [ -n "$FOUND_HEADERS" ]; then
|
||
|
|
echo " -> Found headers at: $FOUND_HEADERS"
|
||
|
|
|
||
|
|
# Move the content to the final destination
|
||
|
|
# We want the folder to be .../python-3.11/include/python3.11
|
||
|
|
mkdir -p "$TARGET_DIR/include"
|
||
|
|
mv "$FOUND_HEADERS" "$TARGET_DIR/include/"
|
||
|
|
|
||
|
|
# Verify pyconfig.h exists (sanity check)
|
||
|
|
if [ -f "$TARGET_DIR/include/python${MAJOR_VER}/pyconfig.h" ]; then
|
||
|
|
echo " -> Success: Headers installed to $TARGET_DIR"
|
||
|
|
else
|
||
|
|
echo " -> Warning: Header move seemed successful, but pyconfig.h is missing."
|
||
|
|
fi
|
||
|
|
else
|
||
|
|
echo " -> Error: Could not locate header files after extraction."
|
||
|
|
fi
|
||
|
|
|
||
|
|
# 4. Cleanup
|
||
|
|
rm -rf "$TEMP_DIR"
|
||
|
|
echo "---------------------------------------------------"
|
||
|
|
done
|
||
|
|
|
||
|
|
echo "Done. All headers stored in $BASE_OUTPUT_DIR"
|
||
|
|
|