Skip to content

Instantly share code, notes, and snippets.

@raksa
Last active April 5, 2025 00:02
Show Gist options
  • Save raksa/40d777a886538daef38f0426463320fc to your computer and use it in GitHub Desktop.
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
#!/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