升级GCC make centos升级gcc centos升级make

升级GCC make   centos升级gcc   centos升级make

配置 CentOS-SCLo-scl.repo 的方法

 

CentOS-SCLo-scl.repo 是 CentOS 软件集合(Software Collections,简称 SCL)的一部分,用于提供额外的软件包和工具集,例如更新的 GCC 版本或其他开发工具。以下是配置和使用该仓库的详细步骤。

安装 SCL 源

首先,需要安装 SCL 源相关的软件包:

yum install -y centos-release-scl centos-release-scl-rh

安装完成后,系统会在 /etc/yum.repos.d/ 目录下生成两个 .repo 文件:

  • CentOS-SCLo-scl.repo

  • CentOS-SCLo-scl-rh.repo

配置国内镜像源

为了提高下载速度,可以将 .repo 文件中的 baseurl 修改为国内镜像地址,例如阿里云镜像。

编辑 /etc/yum.repos.d/CentOS-SCLo-scl.repo 文件:

[centos-sclo-sclo]
name=CentOS-7 - SCLo sclo
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/sclo/
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

编辑 /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo 文件:

[centos-sclo-rh]
name=CentOS-7 - SCLo rh
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh/
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

刷新 YUM 缓存

完成配置后,刷新 YUM 缓存以确保新源生效:

yum clean all && yum makecache

验证配置是否成功

可以通过安装一个软件包来验证配置是否成功,例如安装 vim:

yum install -y vim

导入 GPG 公钥

为了避免缺少公钥的警告,可以导入 CentOS 官方 GPG 公钥:

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

更新系统

最后,建议更新系统以确保所有软件包都是最新版本:

yum update -y

通过以上步骤,您可以成功配置并使用 CentOS-SCLo-scl.repo 和 CentOS-SCLo-scl-rh.repo 来安装所需的软件包和工具集。

 

 

 

 

 

========================  一键脚本===================================

 

#!/bin/bash
# install_devtoolset-11_fixed.sh
# CentOS 7 使用阿里云镜像安装 devtoolset-11 (修复SCL仓库问题)

set -e

echo "=================================================="
echo "开始安装 devtoolset-11 (使用阿里云镜像)"
echo "=================================================="

# 1. 备份原有repo配置
echo "步骤1: 备份原有yum配置"
sudo cp /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup.$(date +%Y%m%d_%H%M%S) 2>/dev/null || true

# 2. 配置阿里云基础镜像
echo "步骤2: 配置阿里云基础镜像源"
sudo curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

# 3. 安装EPEL仓库
echo "步骤3: 安装EPEL仓库"
sudo yum install -y epel-release

# 4. 配置阿里云EPEL镜像
sudo sed -i 's|^#baseurl=|baseurl=|' /etc/yum.repos.d/epel.repo
sudo sed -i 's|^metalink|#metalink|' /etc/yum.repos.d/epel.repo
sudo sed -i 's|^baseurl=.*https://download.example/pub|baseurl=https://mirrors.aliyun.com|' /etc/yum.repos.d/epel.repo

# 5. 手动创建SCL仓库配置文件
echo "步骤4: 创建SCL仓库配置文件"

# 创建CentOS-SCLo-scl.repo
sudo tee /etc/yum.repos.d/CentOS-SCLo-scl.repo > /dev/null << 'EOF'
[centos-sclo-scl]
name=CentOS-7 - SCLo scl
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/sclo/
gpgcheck=0
enabled=1

[centos-sclo-scl-source]
name=CentOS-7 - SCLo scl - Sources
baseurl=https://mirrors.aliyun.com/centos/7/sclo/Source/sclo/
gpgcheck=0
enabled=0

[centos-sclo-scl-debuginfo]
name=CentOS-7 - SCLo scl - Debuginfo
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/sclo/
gpgcheck=0
enabled=0
EOF

# 创建CentOS-SCLo-scl-rh.repo
sudo tee /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo > /dev/null << 'devnull'
[centos-sclo-scl-rh]
name=CentOS-7 - SCLo rh
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh/
gpgcheck=0
enabled=1

[centos-sclo-scl-rh-source]
name=CentOS-7 - SCLo rh - Sources
baseurl=https://mirrors.aliyun.com/centos/7/sclo/Source/rh/
gpgcheck=0
enabled=0

[centos-sclo-scl-rh-debuginfo]
name=CentOS-7 - SCLo rh - Debuginfo
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh/
gpgcheck=0
enabled=0
devnull

# 6. 导入GPG密钥(避免警告)
echo "步骤5: 导入GPG密钥"
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

# 7. 清理并重建yum缓存
echo "步骤6: 清理和重建yum缓存"
sudo yum clean all
sudo rm -rf /var/cache/yum
sudo yum makecache

# 8. 验证仓库配置
echo "步骤7: 验证仓库配置"
yum repolist enabled | grep -E "(sclo|rh)"

# 9. 安装devtoolset-11及相关工具
echo "步骤8: 安装devtoolset-11及相关开发工具"
sudo yum install -y devtoolset-11
sudo yum install -y devtoolset-11-gcc
sudo yum install -y devtoolset-11-gcc-c++
sudo yum install -y devtoolset-11-gcc-gfortran
sudo yum install -y devtoolset-11-binutils
sudo yum install -y devtoolset-11-make
sudo yum install -y devtoolset-11-libstdc++-devel
sudo yum install -y devtoolset-11-libtool
sudo yum install -y devtoolset-11-elfutils
sudo yum install -y devtoolset-11-systemtap-sdt-devel
sudo yum install -y devtoolset-11-annobin
sudo yum install -y devtoolset-11-dwz

# 10. 创建系统级启用脚本
echo "步骤9: 配置系统级环境变量"
sudo tee /etc/profile.d/devtoolset-11.sh > /dev/null << 'EOF'
#!/bin/bash
# Devtoolset-11 Environment Setup

if [ -f /opt/rh/devtoolset-11/enable ]; then
    source /opt/rh/devtoolset-11/enable
    export PATH="/opt/rh/devtoolset-11/root/usr/bin:$PATH"
    export LD_LIBRARY_PATH="/opt/rh/devtoolset-11/root/usr/lib64:/opt/rh/devtoolset-11/root/usr/lib:$LD_LIBRARY_PATH"
    export MANPATH="/opt/rh/devtoolset-11/root/usr/share/man:$MANPATH"
    export INFOPATH="/opt/rh/devtoolset-11/root/usr/share/info:$INFOPATH"
    export PKG_CONFIG_PATH="/opt/rh/devtoolset-11/root/usr/lib64/pkgconfig:/opt/rh/devtoolset-11/root/usr/lib/pkgconfig:$PKG_CONFIG_PATH"
fi
EOF

# 11. 设置权限并立即生效
sudo chmod +x /etc/profile.d/devtoolset-11.sh
source /etc/profile.d/devtoolset-11.sh

# 12. 创建符号链接(可选)
echo "步骤10: 创建工具符号链接"
sudo mkdir -p /usr/local/devtoolset-11/bin
sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/gcc /usr/local/devtoolset-11/bin/gcc
sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/g++ /usr/local/devtoolset-11/bin/g++
sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/make /usr/local/devtoolset-11/bin/make
sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/gcc /usr/local/bin/gcc-11
sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/g++ /usr/local/bin/g++-11
sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/make /usr/local/bin/make-4.3

# 13. 验证安装
echo "步骤11: 验证安装结果"
echo "GCC版本:"
gcc --version
echo "G++版本:"
g++ --version
echo "Make版本:"
make --version

# 14. 编译测试
echo "步骤12: 编译测试"
cat > /tmp/test_compile.cpp << 'EOF'
#include <iostream>
#include <version>

int main() {
    std::cout << "Devtoolset-11 编译测试成功!" << std::endl;
    std::cout << "GCC版本: " << __VERSION__ << std::endl;
    std::cout << "C++标准: ";
    
#if __cplusplus == 202002L
    std::cout << "C++20" << std::endl;
#elif __cplusplus == 201703L
    std::cout << "C++17" << std::endl;
#elif __cplusplus == 201402L
    std::cout << "C++14" << std::endl;
#else
    std::cout << "C++11或更早: " << __cplusplus << std::endl;
#endif
    
    return 0;
}
EOF

g++ -std=c++17 /tmp/test_compile.cpp -o /tmp/test_compile
/tmp/test_compile
rm -f /tmp/test_compile /tmp/test_compile.cpp

echo "=================================================="
echo "devtoolset-11 安装完成!"
echo "GCC和Make已成功升级到最新版本"
echo "重启后仍然生效"
echo "=================================================="

 

 

主要修复内容:
手动创建SCL仓库文件:避免使用失效的官方仓库

设置gpgcheck=0:避免GPG验证问题

配置阿里云镜像:确保高速下载

导入GPG密钥:避免警告信息

完整的工具链安装:包含所有必要的开发工具

使用方法:
bash
# 给脚本执行权限
chmod +x install_devtoolset-11_fixed.sh

# 执行安装
sudo ./install_devtoolset-11_fixed.sh
验证安装:
bash
# 检查版本
gcc --version
g++ --version  
make --version

# 检查路径
which gcc
which g++
which make

# 测试编译
echo 'int main(){return 0;}' | gcc -x c - && echo "编译成功"
这个修正版本解决了SCL仓库失效的问题,确保可以从阿里云镜像快速可靠地安装devtoolset-11。

  

 

 

chatgpt-gpt5 提供的增强健壮版:

 

#!/usr/bin/env bash
# install_devtoolset-11_fixed.sh
# 适用于 CentOS 7:使用阿里云镜像安装 devtoolset-11(包含 SCL 修复与 GPG 导入容错)

set -euo pipefail

TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
BACKUP_DIR="/etc/yum.repos.d/backup_${TIMESTAMP}"

echo "=================================================="
echo "开始安装 devtoolset-11 (使用阿里云镜像) - $(date)"
echo "=================================================="

# 简单工具检查
for cmd in yum curl tee sed rpm; do
    if ! command -v "$cmd" >/dev/null 2>&1; then
        echo "错误: 需要命令 '$cmd' 未安装,先安装该命令再重试。" >&2
        exit 1
    fi
done

# 1) 备份 yum repo 文件
echo "步骤1: 备份 /etc/yum.repos.d 到 ${BACKUP_DIR}"
sudo mkdir -p "${BACKUP_DIR}"
sudo cp -a /etc/yum.repos.d/* "${BACKUP_DIR}/" 2>/dev/null || true

# 2) 替换 CentOS 基础 repo 为阿里云(安全地覆盖)
echo "步骤2: 使用阿里云 CentOS 7 基础仓库"
sudo curl -sS -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

# 3) 刷新缓存,确保基础 repo 可用
echo "刷新 YUM 缓存(基础源)"
sudo yum clean all
sudo yum makecache -y

# 4) 安装 SCL release 包(生成标准的 SCL .repo)
echo "步骤3: 安装 centos-release-scl 与 centos-release-scl-rh"
sudo yum install -y centos-release-scl centos-release-scl-rh || {
    echo "警告: 安装 centos-release-scl 失败,请检查网络与基础源。" >&2
    # 继续执行后续步骤(因可能后面手动创建 repo)
}

# 5) 将 SCL repo 的 baseurl 替换为阿里云镜像(如果文件存在则替换,否则创建一个最小配置)
SCL_REPO1="/etc/yum.repos.d/CentOS-SCLo-scl.repo"
SCL_REPO2="/etc/yum.repos.d/CentOS-SCLo-scl-rh.repo"

echo "步骤4: 配置 SCL 仓库为阿里云镜像"
if [ -f "${SCL_REPO1}" ]; then
    sudo sed -i -r "s|^(baseurl=).*|baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/sclo/|" "${SCL_REPO1}" || true
    sudo sed -i -r "s|^(gpgkey=).*|gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo|" "${SCL_REPO1}" || true
else
    sudo tee "${SCL_REPO1}" > /dev/null <<'EOF'
[centos-sclo-sclo]
name=CentOS-7 - SCLo sclo
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/sclo/
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
EOF
fi

if [ -f "${SCL_REPO2}" ]; then
    sudo sed -i -r "s|^(baseurl=).*|baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh/|" "${SCL_REPO2}" || true
    sudo sed -i -r "s|^(gpgkey=).*|gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo|" "${SCL_REPO2}" || true
else
    sudo tee "${SCL_REPO2}" > /dev/null <<'EOF'
[centos-sclo-rh]
name=CentOS-7 - SCLo rh
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh/
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
EOF
fi

# 6) 导入 GPG 密钥(容错)
echo "步骤5: 导入 GPG 密钥(若存在则导入;若不存在尝试从镜像/官方下载导入)"
# 本地 key 路径(一般由 centos-release-* 提供)
KEY1="/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7"
KEY2="/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo"

_import_key() {
    local keypath="$1"
    local fallback_url="$2"
    if [ -f "${keypath}" ]; then
        sudo rpm --import "${keypath}" || echo "警告: 导入 ${keypath} 失败,继续。"
    else
        echo "注意: ${keypath} 不存在,尝试从 ${fallback_url} 导入(网络需可达)"
        sudo rpm --import "${fallback_url}" || echo "警告: 从 ${fallback_url} 导入失败,继续。"
    fi
}

# 官方/镜像 key URL(若本地不存在)
# 注:这些 URL 在一般情况下可用;若你所在网络限制,可手工把 key 放到 /etc/pki/rpm-gpg/ 后再运行。
_import_key "${KEY1}" "https://www.centos.org/keys/RPM-GPG-KEY-CentOS-7"
_import_key "${KEY2}" "https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-SIG-SCLo" || true

# 7) 刷新 yum 缓存(包含 SCL)
echo "步骤6: 清理并重建 yum 缓存(包括 SCL)"
sudo yum clean all
sudo rm -rf /var/cache/yum || true
sudo yum makecache -y

# 8) 验证仓库
echo "步骤7: 验证已启用仓库(显示包含 scl 或 rh 的行)"
sudo yum repolist enabled | grep -E "(sclo|rh)" || echo "注意: 未找到 sclo/rh 仓库,检查上面输出或 /etc/yum.repos.d/"

# 9) 安装 devtoolset-11 及常用组件(一次性安装)
echo "步骤8: 安装 devtoolset-11 及常用开发包(若不可用请检查 SCL 源)"
sudo yum install -y devtoolset-11 devtoolset-11-gcc devtoolset-11-gcc-c++ devtoolset-11-gcc-gfortran \
    devtoolset-11-binutils devtoolset-11-make devtoolset-11-libstdc++-devel \
    devtoolset-11-libtool devtoolset-11-elfutils devtoolset-11-systemtap-sdt-devel \
    devtoolset-11-annobin devtoolset-11-dwz || {
        echo "警告: 安装 devtoolset-11 时出现错误,请检查网络和仓库。" >&2
}

# 10) 写入 /etc/profile.d 环境脚本(方便每次登录自动启用)
echo "步骤9: 写入 /etc/profile.d/devtoolset-11.sh"
sudo tee /etc/profile.d/devtoolset-11.sh > /dev/null <<'EOF'
#!/bin/bash
# Devtoolset-11 Environment Setup (sourced at login)
if [ -f /opt/rh/devtoolset-11/enable ]; then
    source /opt/rh/devtoolset-11/enable
fi
EOF

sudo chmod +x /etc/profile.d/devtoolset-11.sh

# 11) 立即在当前 shell 中使用 devtoolset(非必须,但用于验证)
if [ -f /opt/rh/devtoolset-11/enable ]; then
    echo "立即启用 devtoolset-11 以便做后续验证(仅当前 shell)"
    # 采用 scl enable 的方式运行测试命令
else
    echo "注意: /opt/rh/devtoolset-11/enable 未找到。若后续找不到工具,请重启或手动 source /opt/rh/devtoolset-11/enable"
fi

# 12) 可选:创建 /usr/local 符号链接(保持可选性)
echo "步骤10: 创建可选符号链接到 /usr/local/bin(覆盖已有同名文件)"
sudo mkdir -p /usr/local/devtoolset-11/bin
if [ -x /opt/rh/devtoolset-11/root/usr/bin/gcc ]; then
    sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/gcc /usr/local/devtoolset-11/bin/gcc
fi
if [ -x /opt/rh/devtoolset-11/root/usr/bin/g++ ]; then
    sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/g++ /usr/local/devtoolset-11/bin/g++
fi
if [ -x /opt/rh/devtoolset-11/root/usr/bin/make ]; then
    sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/make /usr/local/devtoolset-11/bin/make
fi
# 也创建带 -11 后缀的 /usr/local/bin 链接(可根据需要保留或删除)
sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/gcc /usr/local/bin/gcc-11 || true
sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/g++ /usr/local/bin/g++-11 || true
sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/make /usr/local/bin/make-4.3 || true

# 13) 验证安装并做即时编译测试(使用 scl enable)
echo "步骤11: 验证编译器版本(若 devtoolset 未激活,使用 scl enable 执行)"
echo "GCC (系统默认):"
gcc --version || true
echo "若要查看 devtoolset-11 提供的 gcc,请运行:scl enable devtoolset-11 -- gcc --version"

# 创建简单测试文件
cat > /tmp/test_compile.cpp <<'EOF'
#include <iostream>
int main() {
    std::cout << "Devtoolset-11 编译测试成功!" << std::endl;
    return 0;
}
EOF

echo "使用 'scl enable devtoolset-11 -- g++' 进行编译并运行测试程序..."
if command -v scl >/dev/null 2>&1; then
    scl enable devtoolset-11 -- g++ -std=c++17 /tmp/test_compile.cpp -O2 -o /tmp/test_compile && \
    scl enable devtoolset-11 -- /tmp/test_compile || echo "测试编译/运行失败,请检查 devtoolset 是否安装正确"
else
    echo "警告: 系统未检测到 'scl' 命令,跳过即时编译测试。"
fi

rm -f /tmp/test_compile /tmp/test_compile.cpp || true

echo "=================================================="
echo "脚本执行完成(注意查看上面可能的警告)"
echo "如果要在交互式 shell 中立即启用 devtoolset-11,请运行:"
echo "  source /opt/rh/devtoolset-11/enable"
echo "或者重新登录,使 /etc/profile.d/devtoolset-11.sh 生效。"
echo "=================================================="

 

 

说明(为什么这样改)

  1. 不要直接凭空写 SCL repo:通过 centos-release-scl 包来生成标准配置更安全(该包会把对应的 GPG key 和 repo 配置一起放到系统),再将 baseurl 替换为阿里云镜像可提高稳定性与速度。

  2. GPG 导入容错:你的问题里提到 rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo 失败会导致脚本中断。我让导入失败不会 exit(会打印警告并尝试从 URL 导入),这样脚本更健壮,同时仍提醒用户手动检查。

  3. heredoc 与拼写修正:修正了你原脚本中 << 'devnull'/devnull 这类容易出错的写法,保证文件正确写入。

  4. 即时测试用 scl enable:直接 source /etc/profile.d/... 在当前 shell 有时不可靠(文件可能不存在直到安装包放置),使用 scl enable devtoolset-11 -- <cmd> 是更可靠的运行方式。

  5. 更稳健的缓存与检查:在替换 repo 及安装后刷新缓存并检查 repo 列表,便于发现问题。


运行建议与故障排查

  • 如果在你的网络环境下 mirrors.aliyun.com 不可达,请把脚本中相关 https://mirrors.aliyun.com/... 改为你可访问的国内镜像(如 mirrors.tuna.tsinghua.edu.cn 等)。

  • scl 命令不可用或 devtoolset-11 包在仓库中找不到,先确认 yum repolist allcentos-sclocentos-sclo-rh 已启用且能访问(可 yum clean all && yum makecache -y 再试)。

  • 若 GPG key 导入仍然失败,手工下载 key 文件放在 /etc/pki/rpm-gpg/ 后再运行 sudo rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo


如果你愿意,我可以:

  • 把上面脚本再精简成只做“修复 SCL repo 并导入 key”的小脚本(方便在多台机器上先行分发),

  • 或者把脚本包装成一个可传给运维直接执行的单行命令(考虑到你会在大量机器上运行)。

你想要哪个(或直接要我把脚本打包成可下载的 .sh 文件)?

 

 

====================================================================================================================================

 

我把你要的完整功能都合并回脚本了,并修复了之前出现的问题(彻底替换 SCL repo 内容避免 mirrorlist.centos.orgGPG 导入为可选且非致命,一次性安装你列出的所有 devtoolset-11-* 包,写入系统级环境脚本,创建符号链接,用 scl enable 做即时验证与编译测试)。脚本尽量稳健:网络相关步骤不会因为单次失败直接让整个脚本崩溃,而会给出明确警告,便于你人工干预或重试。

把下面脚本保存为 install_devtoolset-11_complete.sh,以 root 或通过 sudo bash install_devtoolset-11_complete.sh 运行。

快速运行方式(示例):
SKIP_GPG_IMPORT=1 sudo bash install_devtoolset-11_complete.sh
(若你愿意脚本尝试导入 key,请不要设置 SKIP_GPG_IMPORT


脚本:完整(覆盖 SCL repo、安装 devtoolset-11、环境变量、符号链接、验证、编译测试)

 

 

#!/usr/bin/env bash
# install_devtoolset-11_complete.sh
# 完整版:修复 SCL repo(禁止 mirrorlist/metalink)、安装 devtoolset-11 系列包、
# 写入 /etc/profile.d、创建符号链接、即时验证和编译测试。
#
# 使用示例:
#   sudo SKIP_GPG_IMPORT=1 bash install_devtoolset-11_complete.sh

set -euo pipefail

TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
BACKUP_DIR="/etc/yum.repos.d/backup_${TIMESTAMP}"
MIRROR_BASE="https://mirrors.aliyun.com/centos"
SCL_BASE="${MIRROR_BASE}/7/sclo"

echo "=================================================="
echo "开始安装 devtoolset-11 - $(date)"
echo "备份目录: ${BACKUP_DIR}"
echo "如果要跳过 GPG key 导入请在命令前加 SKIP_GPG_IMPORT=1"
echo "=================================================="

# 必要命令检查
for cmd in yum tee sed rpm curl scl; do
    # 不强制要求 scl 存在(只有用于测试),因此仅 warn
    if ! command -v "$cmd" >/dev/null 2>&1; then
        if [ "$cmd" = "scl" ]; then
            echo "注意: 'scl' 未安装(仅用于测试)。若 devtoolset 安装成功,scl 会随之提供。"
        else
            echo "错误: 需要命令 '$cmd' 未安装,请先安装再运行脚本。" >&2
            exit 1
        fi
    fi
done

# 备份原 repo
echo "[1/11] 备份 /etc/yum.repos.d 到 ${BACKUP_DIR}"
sudo mkdir -p "${BACKUP_DIR}"
sudo cp -a /etc/yum.repos.d/* "${BACKUP_DIR}/" 2>/dev/null || true

# 覆盖 CentOS-Base.repo 为阿里云(可提高成功率)
echo "[2/11] 覆盖 /etc/yum.repos.d/CentOS-Base.repo 为阿里云镜像"
sudo curl -fsS -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo || {
  echo "警告: 无法下载阿里云 CentOS-Base.repo(网络问题),请检查网络或手动替换。" >&2
}

# 直接覆盖两个 SCL repo(完全避开 mirrorlist/metalink)
echo "[3/11] 覆盖 SCL repo:/etc/yum.repos.d/CentOS-SCLo-scl.repo"
sudo tee /etc/yum.repos.d/CentOS-SCLo-scl.repo > /dev/null <<'EOF'
[centos-sclo-sclo]
name=CentOS-7 - SCLo sclo
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/sclo/
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

[centos-sclo-sclo-source]
name=CentOS-7 - SCLo sclo - Sources
baseurl=https://mirrors.aliyun.com/centos/7/sclo/Source/sclo/
gpgcheck=0
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

[centos-sclo-sclo-debuginfo]
name=CentOS-7 - SCLo sclo - Debuginfo
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/sclo/
gpgcheck=0
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
EOF

echo "[4/11] 覆盖 SCL repo:/etc/yum.repos.d/CentOS-SCLo-scl-rh.repo"
sudo tee /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo > /dev/null <<'EOF'
[centos-sclo-rh]
name=CentOS-7 - SCLo rh
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh/
gpgcheck=0
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

[centos-sclo-rh-source]
name=CentOS-7 - SCLo rh - Sources
baseurl=https://mirrors.aliyun.com/centos/7/sclo/Source/rh/
gpgcheck=0
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo

[centos-sclo-rh-debuginfo]
name=CentOS-7 - SCLo rh - Debuginfo
baseurl=https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh/
gpgcheck=0
enabled=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo
EOF

# 导入 GPG key(非致命)
if [ "${SKIP_GPG_IMPORT:-0}" = "1" ]; then
    echo "[5/11] SKIP_GPG_IMPORT=1,跳过 GPG 密钥导入"
else
    echo "[5/11] 尝试导入 GPG 密钥(失败不会使脚本退出)"
    sudo mkdir -p /etc/pki/rpm-gpg || true
    # 本地优先,否则从镜像下载到临时文件并导入
    import_key_if_missing() {
        local localpath="$1" url="$2"
        if [ -f "${localpath}" ]; then
            echo "  使用本地 key: ${localpath}"
            sudo rpm --import "${localpath}" >/dev/null 2>&1 || echo "  警告: 导入本地 key 失败(继续)"
            return 0
        fi
        tmpf="$(mktemp)"
        if curl -fsSL "${url}" -o "${tmpf}"; then
            sudo rpm --import "${tmpf}" >/dev/null 2>&1 || echo "  警告: 导入下载 key 失败(继续)"
            sudo mv -f "${tmpf}" "${localpath}" 2>/dev/null || true
            return 0
        else
            echo "  警告: 无法从 ${url} 下载 key(继续)"
            [ -f "${tmpf}" ] && rm -f "${tmpf}"
            return 1
        fi
    }

    import_key_if_missing "/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7" "${MIRROR_BASE}/RPM-GPG-KEY-CentOS-7" || true
    import_key_if_missing "/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-SCLo" "https://mirrors.aliyun.com/centos/RPM-GPG-KEY-CentOS-SIG-SCLo" || true
fi

# 重建 yum 缓存(重试机制)
echo "[6/11] 清理并重建 yum 缓存(最多重试2次)"
sudo yum clean all >/dev/null 2>&1 || true
sudo rm -rf /var/cache/yum || true
if ! sudo yum makecache -y; then
    echo "  第一次 makecache 失败,重试一次..."
    sleep 2
    if ! sudo yum makecache -y; then
        echo "  警告: yum makecache 连续失败,可能镜像不可达或 DNS 有问题。请检查网络或设置 MIRROR_BASE。"
    fi
fi

# 安装 devtoolset-11 及你的那些包(一次性列出)
echo "[7/11] 安装 devtoolset-11 及相关包(若失败会提示,但脚本继续)"
set +e
sudo yum install -y \
    centos-release-scl centos-release-scl-rh \
    devtoolset-11 \
    devtoolset-11-gcc \
    devtoolset-11-gcc-c++ \
    devtoolset-11-gcc-gfortran \
    devtoolset-11-binutils \
    devtoolset-11-make \
    devtoolset-11-libstdc++-devel \
    devtoolset-11-libtool \
    devtoolset-11-elfutils \
    devtoolset-11-systemtap-sdt-devel \
    devtoolset-11-annobin \
    devtoolset-11-dwz \
    -y
RC_INSTALL=$?
set -e
if [ "$RC_INSTALL" -ne 0 ]; then
    echo "  警告: yum install 部分或全部包失败 (rc=${RC_INSTALL})。请检查 SCL 仓库与网络,或运行 'sudo yum install -y devtoolset-11' 手动诊断。"
fi

# 写入系统级 /etc/profile.d 脚本(自动启用 devtoolset)
echo "[8/11] 写入 /etc/profile.d/devtoolset-11.sh(系统级启用脚本)"
sudo tee /etc/profile.d/devtoolset-11.sh > /dev/null <<'EOF'
#!/bin/bash
# Devtoolset-11 Environment Setup (sourced at login)
if [ -f /opt/rh/devtoolset-11/enable ]; then
    # source enable 脚本(保证 PATH/LD_LIBRARY_PATH 等)
    source /opt/rh/devtoolset-11/enable
    # 额外确保 rootless 登录 shell 也能访问到工具(冗余但安全)
    export PATH="/opt/rh/devtoolset-11/root/usr/bin:${PATH}"
    export LD_LIBRARY_PATH="/opt/rh/devtoolset-11/root/usr/lib64:/opt/rh/devtoolset-11/root/usr/lib${LD_LIBRARY_PATH:+:}${LD_LIBRARY_PATH}"
    export MANPATH="/opt/rh/devtoolset-11/root/usr/share/man:${MANPATH:-}"
    export INFOPATH="/opt/rh/devtoolset-11/root/usr/share/info:${INFOPATH:-}"
    export PKG_CONFIG_PATH="/opt/rh/devtoolset-11/root/usr/lib64/pkgconfig:/opt/rh/devtoolset-11/root/usr/lib/pkgconfig${PKG_CONFIG_PATH:+:}${PKG_CONFIG_PATH}"
fi
EOF
sudo chmod 0755 /etc/profile.d/devtoolset-11.sh

# 立即生效(注意:若用 sudo 运行,这只影响本脚本环境;交互 shell 需重新登录或 source)
echo "[9/11] 立即在本脚本环境中尝试 source /opt/rh/devtoolset-11/enable(若存在)"
if [ -f /opt/rh/devtoolset-11/enable ]; then
    # source to current shell (script subshell) so subsequent commands in script use devtoolset
    # shellcheck disable=SC1091
    source /opt/rh/devtoolset-11/enable || true
else
    echo "  注意: /opt/rh/devtoolset-11/enable 不存在(可能未安装或安装路径不同)。"
fi

# 创建可选符号链接(便于脚本或 CI 使用固定路径 /usr/local/bin/gcc-11 等)
echo "[10/11] 创建符号链接到 /usr/local/devtoolset-11/bin 和 /usr/local/bin/gcc-11 等"
sudo mkdir -p /usr/local/devtoolset-11/bin
if [ -x /opt/rh/devtoolset-11/root/usr/bin/gcc ]; then
    sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/gcc /usr/local/devtoolset-11/bin/gcc
    sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/g++ /usr/local/devtoolset-11/bin/g++
    sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/make /usr/local/devtoolset-11/bin/make
    sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/gcc /usr/local/bin/gcc-11
    sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/g++ /usr/local/bin/g++-11
    sudo ln -sf /opt/rh/devtoolset-11/root/usr/bin/make /usr/local/bin/make-4.3
else
    echo "  注意:/opt/rh/devtoolset-11/root/usr/bin/gcc 不可执行,跳过创建符号链接(可能安装失败)。"
fi

# 验证:显示系统 gcc/g++ 以及 devtoolset 提供的版本(使用 scl enable)
echo "[11/11] 验证安装:显示版本并进行编译测试(如可用)"
echo "系统默认 gcc:"
gcc --version || true
echo "系统默认 g++:"
g++ --version || true

if command -v scl >/dev/null 2>&1; then
    echo "devtoolset-11 提供的 gcc:"
    scl enable devtoolset-11 -- bash -c 'gcc --version || true; g++ --version || true'
    # 简单 C++ 编译测试(使用 scl enable 确保使用的是 devtoolset 编译器)
    cat > /tmp/devtoolset_test.cpp <<'EOF'
#include <iostream>
int main(){ std::cout << "devtoolset-11 编译测试成功\\n"; return 0; }
EOF
    echo "正在使用 devtoolset-11 编译并运行测试程序..."
    if scl enable devtoolset-11 -- g++ -std=c++17 /tmp/devtoolset_test.cpp -O2 -o /tmp/devtoolset_test 2>/tmp/devtoolset_test_build.log; then
        scl enable devtoolset-11 -- /tmp/devtoolset_test || echo "警告: 测试程序运行异常"
        rm -f /tmp/devtoolset_test /tmp/devtoolset_test.cpp /tmp/devtoolset_test_build.log || true
    else
        echo "  警告: 使用 devtoolset-11 编译测试失败,详情见 /tmp/devtoolset_test_build.log"
    fi
else
    echo "注意: 未检测到 'scl' 命令,可能 devtoolset 尚未正确安装。若 devtoolset 安装成功,请重新登录或 source /opt/rh/devtoolset-11/enable 后重试。"
fi

echo "=================================================="
echo "脚本执行完毕。请检查上面输出的警告(如有)。"
echo "若需要手动启用 devtoolset:"
echo "  source /opt/rh/devtoolset-11/enable"
echo "或在交互 shell 永久启用请重新登录,使 /etc/profile.d/devtoolset-11.sh 生效。"
echo "=================================================="

 

我做的关键修正与说明(摘要)

  1. 彻底覆盖 SCL .repo 内容:原先只替换 baseurl 有时会残留 mirrorlist 行。现在两个 SCL repo 被直接写为只含 baseurl 的最小可用配置(gpgcheck=0,避免 key 问题阻断安装)。

  2. GPG 导入为可选/容错:脚本会尝试导入 key,但若失败不会 exit。若你明确要跳过导入,可用 SKIP_GPG_IMPORT=1

  3. 安装步骤完整:一次性尝试安装 devtoolset-11 及你列出的所有相关包(gcc/g++/fortran/binutils/make 等),并在失败时给出明确提示(而不会让脚本直接崩溃)。

  4. 系统级环境脚本:写入 /etc/profile.d/devtoolset-11.sh,设置 PATHLD_LIBRARY_PATHMANPATHPKG_CONFIG_PATH 等,确保重启或重新登录后 devtoolset 生效。

  5. 即时验证:脚本用 scl enable devtoolset-11 -- 来进行即时版本显示和编译测试(不会污染系统默认 gcc)。

  6. 创建符号链接:在 /usr/local/devtoolset-11/bin/usr/local/bin/gcc-11 等创建软链,便于 CI 或脚本通过固定路径使用新编译器。

  7. 容错与日志:网络/仓库/安装失败会打印警告并继续执行,其它关键错误仍会退出(例如缺少 yum 等必需命令)。


常见问题 & 解决步骤

    • yum install devtoolset-11 找不到包:sudo yum repolist all | grep scl 检查 SCL 仓库是否启用;确认镜像地址是否可达(curl -I https://mirrors.aliyun.com/centos/7/sclo/x86_64/rh/)。

    • yum makecache 一直失败:检查 DNS(dig mirrors.aliyun.com)、公司防火墙或使用公司内网镜像替换 MIRROR_BASE 变量。

    • 如果你不想修改系统级别的 CentOS-Base.repo,可以手动把脚本第 2 步注释掉;脚本仍会覆盖 SCL repo,这对于安装 devtoolset 是最关键的。

    • 要在当前交互式 shell 立即使用 devtoolset(而不是重新登录),运行:
      source /opt/rh/devtoolset-11/enable
      或执行: scl enable devtoolset-11 -- bash

 

 

 

 

posted @ 2025-10-11 09:53  闻道者  阅读(17)  评论(0)    收藏  举报