当前位置:首页>python>一键编译安装Python3.12脚本

一键编译安装Python3.12脚本

  • 2026-09-02 19:30:39
一键编译安装Python3.12脚本
# Python 3.12 编译安装脚本
# 使用清华源加速 pip
# 特性:自动检测并优先使用同目录的源码包(支持 .tgz 或 .tar.xz 格式)

set -e  # 遇到错误立即退出

echo "========================================"
echo "  Python 3.12 编译安装脚本"
echo "  pip 使用清华源"
echo "========================================"

# 检查是否为 root 用户
if [ "$EUID" -ne 0 ]; then 
    echo "请使用 root 权限运行此脚本 (sudo ./install_python312.sh)"
    exit 1
fi

PYTHON_VERSION="3.12.13"
INSTALL_PREFIX="/usr/local"
SRC_DIR="/usr/local/src"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"  # 获取脚本所在目录

echo ""
echo "[1/7] 安装编译依赖..."
if command -v apt-get &> /dev/null; then
    # Debian/Ubuntu
    apt-get update
    apt-get install -y build-essential libssl-dev zlib1g-dev         libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm         libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev         libffi-dev liblzma-dev git
elif command -v dnf &> /dev/null; then
    # RHEL 8+/CentOS 8+/Rocky Linux/AlmaLinux (使用 dnf)
    echo "检测到 DNF 包管理器 (RHEL/CentOS 8+)..."

    # 尝试启用 CRB 仓库 (CodeReady Builder)
    if ! dnf repolist | grep -q "crb"; then
        echo "启用 CRB 仓库以获取 xmlsec1-devel..."
        dnf install -y yum-utils || true
        dnf config-manager --set-enabled crb || true
        # 备选方案:尝试使用 subscription-manager (RHEL) 或直接安装 epel
        subscription-manager repos --enable codeready-builder-for-rhel-9-x86_64-rpms 2>/dev/null || true
    fi

    dnf groupinstall -y "Development Tools"
    dnf install -y openssl-devel bzip2-devel libffi-devel zlib-devel         readline-devel sqlite-devel wget curl xz-devel tk-devel         libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel         libxslt-devel || {
            echo "警告: 部分包安装失败,尝试继续..."
        }
elif command -v yum &> /dev/null; then
    # CentOS 7/RHEL 7 (使用 yum)
    echo "检测到 YUM 包管理器..."

    # 尝试启用 CRB/CodeReady Builder 仓库
    if yum repolist | grep -q "extras"; then
        yum install -y yum-utils
        yum-config-manager --enable crb 2>/dev/null || true
    fi

    yum groupinstall -y "Development Tools"
    yum install -y openssl-devel bzip2-devel libffi-devel zlib-devel         readline-devel sqlite-devel wget curl xz-devel tk-devel         libxml2-devel xmlsec1-devel xmlsec1-openssl-devel libtool-ltdl-devel         libxslt-devel || {
            echo "警告: 部分包安装失败,尝试继续..."
        }
else
    echo "不支持的包管理器,请手动安装编译依赖"
    exit 1
fi

echo ""
echo "[2/7] 准备 Python ${PYTHON_VERSION} 源码..."

# 定义可能的本地源码包文件名
TARBALL_TGZ="Python-${PYTHON_VERSION}.tgz"
TARBALL_XZ="Python-${PYTHON_VERSION}.tar.xz"
LOCAL_TGZ="${SCRIPT_DIR}/${TARBALL_TGZ}"
LOCAL_XZ="${SCRIPT_DIR}/${TARBALL_XZ}"

# 检查脚本同目录是否有源码包(优先使用 .tar.xz,其次 .tgz)
if [ -f "${LOCAL_XZ}" ]; then
    echo "✓ 在脚本同目录发现源码包: ${LOCAL_XZ}"
    echo "  将使用该本地文件,跳过下载"
    SOURCE_TARBALL="${TARBALL_XZ}"
    mkdir -p ${SRC_DIR}
    cp "${LOCAL_XZ}" ${SRC_DIR}/
    USE_LOCAL=true
elif [ -f "${LOCAL_TGZ}" ]; then
    echo "✓ 在脚本同目录发现源码包: ${LOCAL_TGZ}"
    echo "  将使用该本地文件,跳过下载"
    SOURCE_TARBALL="${TARBALL_TGZ}"
    mkdir -p ${SRC_DIR}
    cp "${LOCAL_TGZ}" ${SRC_DIR}/
    USE_LOCAL=true
else
    echo "  本地未找到源码包,将从官网下载 .tar.xz 版本..."
    SOURCE_TARBALL="${TARBALL_XZ}"
    mkdir -p ${SRC_DIR}
    cd ${SRC_DIR}
    wget https://www.python.org/ftp/python/${PYTHON_VERSION}/${SOURCE_TARBALL}
    USE_LOCAL=false
fi

cd ${SRC_DIR}

echo ""
echo "[3/7] 解压源码..."
if [ -d "Python-${PYTHON_VERSION}" ]; then
    echo "  检测到已解压的源码目录,将重新使用"
    rm -rf Python-${PYTHON_VERSION}
fi

# 根据文件扩展名选择解压方式
if [[ "${SOURCE_TARBALL}" == *.tar.xz ]]; then
    tar -xf ${SOURCE_TARBALL}
else
    tar -xzf ${SOURCE_TARBALL}
fi

cd Python-${PYTHON_VERSION}

echo ""
echo "[4/7] 配置编译选项..."
./configure --prefix=${INSTALL_PREFIX}     --enable-optimizations     --with-ensurepip=install     --enable-shared     --with-system-ffi     --enable-loadable-sqlite-extensions

echo ""
echo "[5/7] 编译 (这可能需要几分钟)..."
make -j$(nproc)

echo ""
echo "[6/7] 安装 Python..."
make altinstall

echo ""
echo "[7/7] 配置环境..."

# 配置动态链接库路径
echo "配置动态链接库..."

# 方法1: 创建 ldconfig 配置文件
echo "${INSTALL_PREFIX}/lib" > /etc/ld.so.conf.d/python3.12.conf

# 方法2: 更新动态链接库缓存
ldconfig

# 验证库文件是否存在
if [ -f "${INSTALL_PREFIX}/lib/libpython3.12.so.1.0" ]; then
    echo "✓ 库文件已安装: ${INSTALL_PREFIX}/lib/libpython3.12.so.1.0"
else
    echo "警告: 未找到 libpython3.12.so.1.0"
fi

# 方法3: 创建软链接到系统库目录(备选方案)
if [ -d "/usr/lib64" ] && [ ! -f "/usr/lib64/libpython3.12.so.1.0" ]; then
    ln -sf ${INSTALL_PREFIX}/lib/libpython3.12.so.1.0 /usr/lib64/libpython3.12.so.1.0 2>/dev/null || true
    ln -sf ${INSTALL_PREFIX}/lib/libpython3.12.so /usr/lib64/libpython3.12.so 2>/dev/null || true
    ldconfig
fi

# 配置 pip 使用清华源
PIP_CONFIG_DIR="/etc/pip"
mkdir -p ${PIP_CONFIG_DIR}

cat > ${PIP_CONFIG_DIR}/pip.conf << 'EOF'
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn

[install]
use-mirrors = true
mirrors = https://pypi.tuna.tsinghua.edu.cn
EOF

# 为当前用户也配置 pip
if [ -n "$SUDO_USER" ]; then
    USER_HOME=$(eval echo ~$SUDO_USER)
    USER_PIP_DIR="${USER_HOME}/.config/pip"
    mkdir -p ${USER_PIP_DIR}
    cp ${PIP_CONFIG_DIR}/pip.conf ${USER_PIP_DIR}/pip.conf
    chown -R $SUDO_USER:$SUDO_USER ${USER_PIP_DIR}
fi

echo ""
echo "========================================"
echo "  安装完成!"
echo "========================================"
echo ""

# 测试 Python 是否能正常运行
if ${INSTALL_PREFIX}/bin/python3.12 --version &>/dev/null; then
    echo "Python 版本:"
    ${INSTALL_PREFIX}/bin/python3.12 --version
else
    echo "⚠️  Python 运行测试失败,尝试修复..."
    export LD_LIBRARY_PATH=${INSTALL_PREFIX}/lib:$LD_LIBRARY_PATH
    echo "临时设置 LD_LIBRARY_PATH=${INSTALL_PREFIX}/lib"
    ${INSTALL_PREFIX}/bin/python3.12 --version || true
fi

echo ""
echo "pip 版本:"
${INSTALL_PREFIX}/bin/pip3.12 --version || true
echo ""
echo "pip 配置 (清华源):"
${INSTALL_PREFIX}/bin/pip3.12 config list 2>/dev/null || true
echo ""
echo "使用说明:"
echo "  - Python 路径: ${INSTALL_PREFIX}/bin/python3.12"
echo "  - pip 路径: ${INSTALL_PREFIX}/bin/pip3.12"
echo ""
echo "添加到 PATH (可选):"
echo '  export PATH="${INSTALL_PREFIX}/bin:$PATH"'
echo ""
echo "如果运行时提示找不到库,请执行:"
echo "  export LD_LIBRARY_PATH=${INSTALL_PREFIX}/lib:\$LD_LIBRARY_PATH"
echo ""
echo "卸载方法:"
echo "  cd ${SRC_DIR}/Python-${PYTHON_VERSION} && make uninstall"
echo "========================================"

最新文章

随机文章