Last active
April 5, 2025 00:02
-
-
Save raksa/40d777a886538daef38f0426463320fc to your computer and use it in GitHub Desktop.
Build and install Python from source, on Unix like systems, to a custom location
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -ex | |
# Usage: ./build-python.sh [version] [install-dir] | |
# Example1: ./build-python.sh 3.12.9 | |
# Example2: ./build-python.sh 3.12.9 ~/bin/python-original | |
py_version=${1:-3.12.9} | |
base_dir=$(realpath ${2:-$HOME/bin/python-original}) | |
shared_lib_dir="shared-lib" | |
ensure_lib() { | |
if [ -x "$(command -v apt)" ]; then | |
if dpkg -s $1 &> /dev/null; then | |
echo "$1 is already installed" | |
else | |
sudo apt install $1 | |
fi | |
elif [ -x "$(command -v dnf)" ]; then | |
if dnf list installed $2 &> /dev/null; then | |
echo "$2 is already installed" | |
else | |
sudo dnf install $2 | |
fi | |
elif [ -x "$(command -v yum)" ]; then | |
if yum list installed $3 &> /dev/null; then | |
echo "$3 is already installed" | |
else | |
sudo yum install $3 | |
fi | |
else | |
echo "No package manager found" | |
exit 1 | |
fi | |
} | |
check_tools() { | |
for tool in wget tar make gcc pkg-config; do | |
if ! command -v $tool &> /dev/null; then | |
echo "Error: $tool is not installed. Please install it and try again." | |
exit 1 | |
fi | |
done | |
} | |
# Ensure required tools are installed | |
check_tools | |
# Install required libraries | |
ensure_lib build-essential gcc gcc-c++ | |
ensure_lib libsqlite3-dev sqlite-devel sqlite-devel | |
ensure_lib libssl-dev openssl-devel openssl-devel | |
ensure_lib zlib1g-dev zlib-devel zlib-devel | |
temp_dir=/tmp/python-build | |
mkdir -p ${temp_dir} && cd ${temp_dir} | |
# Download Python source code | |
wget https://www.python.org/ftp/python/${py_version}/Python-${py_version}.tgz | |
# Extract and prepare for build | |
rm -rf Python-${py_version} | |
tar -xzf Python-${py_version}.tgz | |
cd Python-${py_version} | |
# Set up installation directory | |
mkdir -p ${base_dir} | |
install_dir=${base_dir}/python-${py_version} | |
rm -rf $install_dir | |
# Configure and build Python | |
./configure --prefix=$install_dir --enable-optimizations \ | |
--enable-shared LDFLAGS="-Wl,-rpath,$install_dir/$shared_lib_dir" \ | |
--with-ensurepip=install | |
make -j "$(nproc)" | |
make install | |
# Ensure shared-lib directory exists before copying | |
mkdir -p $install_dir/$shared_lib_dir | |
cp -n *.so* $install_dir/$shared_lib_dir | |
# Upgrade pip and verify installation | |
$install_dir/bin/python3 -m pip install --upgrade pip | |
echo "Cleaning up temporary files..." | |
rm -rf ${temp_dir} | |
echo "Successfully installed Python ${py_version} to $install_dir" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment