Redhat、Centos、Rocky8安装常用EDA工具系统依赖库

常用脚本 0 16 团子精英 收藏

用途:为 Rocky Linux 8.10 x86_64 上的 Synopsys / Cadence / Siemens EDA 工具准备 OS 级基础依赖(编译器、64 位运行时、X11/OpenGL、CAD 基础设施),并生成安装日志与依赖报告。

内容说明:

  • root / OS / 架构检查提前到日志目录创建之前,普通用户执行会直接看到权限提示。

  • DNF 元数据刷新加了容错,失败记录后继续,不再因 set -e 中断。

  • 必需动态库(libc、libstdc++、libgcc_s、libnsl.so.1、libssl.so.1.1、libcrypto.so.1.1)缺失会真正导致最终失败,不再出现“报告 SUCCESS 但库缺失”。

  • 必需软件包拆成多个小事务,单包不可用只影响所在小组。

  • 可选包保留 DNF 错误输出到主日志,最终以逐包 rpm -q 为准。

  • Motif 只列 motif(已 Obsoletes: openmotif);移除 compat-openssl11(Rocky 8 原生即 1.1.1k),保留 compat-openssl10 供旧工具 .so.10 需求。

  • DB 4.7 兼容链接仍默认关闭,启用时用 readelf -h 验证目标为 x86-64 ELF。

使用方法:

chmod +x rocky810-eda-base.sh
sudo ./rocky810-eda-base.sh
# 需要 DB 4.7 兼容链接时(有 ABI 风险,非厂商支持)
sudo EDA_DB47_COMPAT=1 ./rocky810-eda-base.sh
# 必装组失败即停(默认是记录后继续)
sudo EDA_CONTINUE_ON_REQUIRED_FAIL=0 ./rocky810-eda-base.sh

注意事项:

  • i686 库默认可选,是否安装应由 readelf -d <工具二进制> | grep NEEDED 和 ldd 决定,不要盲目全装。

  • DB 4.7 → 5.3 软链接只是链接器层面的变通,不保证 ABI 兼容。

  • 脚本已在真实 Rocky 8.10 主机上执行过,包名是否全部存在于你启用的仓库、依赖是否冲突,但仍需单独确认。

脚本内容:

#!/usr/bin/env bash
#
# el8 (Rocky / RHEL / AlmaLinux 8.x) x86_64 - EDA base runtime preparation
# For Synopsys / Cadence / Siemens EDA environments.
#
# Create by Fasteda.cn
#
# Revision notes:
#   - root check before any log-directory creation.
#   - DNF metadata refresh wrapped with explicit error handling.
#   - Missing REQUIRED runtime libraries fail the final status.
#   - Required package groups split into smaller transactions.
#   - Optional installs are per-package (el8 dnf has no
#     `dnf install --skip-unavailable`; that flag is for history replay).
#   - Motif / OpenSSL compat aligned with Rocky 8 reality:
#       * motif obsoletes openmotif; only motif is listed.
#       * compat-openssl11 removed (native OpenSSL is already 1.1.1k).
#       * motif + compat-openssl10 are REQUIRED for typical EDA GUI/legacy.
#   - Bare package name `libelf` removed; use elfutils-libelf only.
#   - Common GUI/media deps added (gtk2, libpng12, libxslt, alsa, cups, LSB).
#   - OS gate accepts rocky/rhel/almalinux on el8 (default still prefers 8.10).
#   - Berkeley DB target validated with readelf -h, not just `file`.
#   - DB47 compat remains opt-in and OFF by default.
#
set -Eeuo pipefail
# ------------------------------------------------------------
# 0. Root check FIRST — before touching /var/log
# ------------------------------------------------------------
if [[ "${EUID}" -ne 0 ]]; then
    echo "[ERROR] Run as root: sudo $0"
    exit 1
fi
if [[ ! -r /etc/os-release ]]; then
    echo "[ERROR] /etc/os-release not found."
    exit 1
fi
# shellcheck disable=SC1091
source /etc/os-release
case "${ID:-}" in
    rocky|rhel|almalinux) ;;
    *)
        echo "[ERROR] Unsupported distribution ID='${ID:-}'."
        echo "[ERROR] Supported: rocky, rhel, almalinux (el8)."
        cat /etc/os-release
        exit 1
        ;;
esac
# Prefer exact 8.10; allow other 8.x with a warning (binary-compatible family).
if [[ "${VERSION_ID:-}" != "8.10" ]]; then
    if [[ "${VERSION_ID:-}" == 8.* ]] || [[ "${PLATFORM_ID:-}" == "platform:el8" ]]; then
        echo "[WARN] Target is ${PRETTY_NAME:-unknown} (VERSION_ID=${VERSION_ID:-})."
        echo "[WARN] Script is validated primarily on 8.10; continuing."
    else
        echo "[ERROR] This script targets el8 (preferably 8.10)."
        cat /etc/os-release
        exit 1
    fi
fi
if [[ "$(uname -m)" != "x86_64" ]]; then
    echo "[ERROR] Only x86_64 is supported."
    exit 1
fi
# ------------------------------------------------------------
# 1. Configuration (safe to set after root check)
# ------------------------------------------------------------
LOG_DIR="/var/log/eda-install"
TIMESTAMP="$(date +%Y%m%d_%H%M%S)"
LOG_FILE="${LOG_DIR}/eda_install_${TIMESTAMP}.log"
REPORT_FILE="${LOG_DIR}/eda_report_${TIMESTAMP}.txt"
EDA_DB47_COMPAT="${EDA_DB47_COMPAT:-0}"
EDA_CONTINUE_ON_REQUIRED_FAIL="${EDA_CONTINUE_ON_REQUIRED_FAIL:-1}"
FAILED_REQUIRED=()
FAILED_OPTIONAL=()
INSTALLED_OPTIONAL=()
CHECK_RESULTS=()
MISSING_REQUIRED_LIBS=()
mkdir -p "$LOG_DIR"
exec > >(tee -a "$LOG_FILE") 2>&1
on_error() {
    local rc=$?
    echo
    echo "[ERROR] Unexpected failure (exit=${rc}, line=${BASH_LINENO[0]:-unknown})."
    echo "[ERROR] See log: $LOG_FILE"
    exit "$rc"
}
trap on_error ERR
echo "============================================================"
echo " el8 EDA Base Environment Installation"
echo "============================================================"
echo "OS           : ${PRETTY_NAME:-el8}"
echo "Architecture : $(uname -m)"
echo "Hostname     : $(hostname)"
echo "Start        : $(date)"
echo "Log          : $LOG_FILE"
echo "DB47 compat  : ${EDA_DB47_COMPAT} (0=off, 1=opt-in)"
echo "Required fail: continue=${EDA_CONTINUE_ON_REQUIRED_FAIL} (0=fail-fast)"
# ------------------------------------------------------------
# Helper functions
# ------------------------------------------------------------
# True if rpm name or name.arch is installed.
rpm_is_installed() {
    local pkg="$1"
    rpm -q "$pkg" >/dev/null 2>&1
}
install_required() {
    local group="$1"
    shift
    echo
    echo ">>> REQUIRED: ${group}"
    if dnf install -y "$@"; then
        echo "[OK] ${group}"
    else
        echo "[ERROR] Failed group: ${group}"
        FAILED_REQUIRED+=("$group")
        if [[ "$EDA_CONTINUE_ON_REQUIRED_FAIL" == "0" ]]; then
            echo "[FATAL] Aborting on required group failure."
            exit 1
        fi
    fi
}
# el8 DNF 4.x: do NOT use `dnf install --skip-unavailable`
# (that flag belongs to history replay, not install).
# Install each package individually so one missing NVR cannot abort the rest.
install_optional_group() {
    local group="$1"
    shift
    echo
    echo ">>> OPTIONAL group: ${group}"
    local pkg rc
    for pkg in "$@"; do
        if rpm_is_installed "$pkg"; then
            INSTALLED_OPTIONAL+=("$pkg")
            echo "  [PRESENT] $pkg (already installed)"
            continue
        fi
        echo "  [TRY    ] $pkg"
        # With set -E, a failing command can still fire ERR even under set +e.
        # Temporarily clear the ERR trap around expected dnf failures.
        trap - ERR
        rc=0
        dnf install -y "$pkg" || rc=$?
        trap on_error ERR
        if [[ $rc -eq 0 ]] && rpm_is_installed "$pkg"; then
            INSTALLED_OPTIONAL+=("$pkg")
            echo "  [PRESENT] $pkg"
        else
            FAILED_OPTIONAL+=("$pkg")
            echo "  [ABSENT ] $pkg"
        fi
    done
}
# Prefer /lib64 file presence; fall back to ldconfig -p x86-64 entries.
# Plain `grep -F` on ldconfig alone has produced false negatives right after
# large multilib transactions on some el8 hosts.
library_found_x86_64() {
    local lib="$1"
    if [[ -e "/lib64/${lib}" || -e "/usr/lib64/${lib}" ]]; then
        return 0
    fi
    ldconfig -p 2>/dev/null | grep -F "${lib}" | grep -q 'x86-64'
}
check_required_library() {
    local lib="$1"
    if library_found_x86_64 "$lib"; then
        echo "[OK] ${lib}"
        CHECK_RESULTS+=("[OK] ${lib}")
    else
        echo "[MISSING] ${lib} (REQUIRED)"
        CHECK_RESULTS+=("[MISSING-REQUIRED] ${lib}")
        MISSING_REQUIRED_LIBS+=("$lib")
    fi
}
check_optional_library() {
    local lib="$1"
    if library_found_x86_64 "$lib"; then
        echo "[OK] ${lib}"
        CHECK_RESULTS+=("[OK] ${lib}")
    else
        echo "[OPTIONAL MISSING] ${lib}"
        CHECK_RESULTS+=("[OPTIONAL MISSING] ${lib}")
    fi
}
# ------------------------------------------------------------
# 2. DNF metadata — explicit error handling, do NOT abort
# ------------------------------------------------------------
echo
echo ">>> [1/10] Refreshing DNF metadata"
# PackageKit holding /var/lib/rpm causes: cannot open Packages database (-30969)
if command -v systemctl >/dev/null 2>&1; then
    if systemctl is-active --quiet packagekit 2>/dev/null; then
        echo "[INFO] Stopping PackageKit to avoid RPM DB lock contention."
        systemctl stop packagekit 2>/dev/null || true
    fi
fi
pkill -x packagekitd >/dev/null 2>&1 || true
rm -f /var/lib/rpm/__db.* 2>/dev/null || true
if ! dnf clean metadata; then
    echo "[WARN] Failed to clean DNF metadata; continuing with cached metadata."
    FAILED_REQUIRED+=("DNF metadata clean")
fi
if ! dnf makecache --refresh; then
    echo "[ERROR] Failed to refresh DNF metadata."
    FAILED_REQUIRED+=("DNF metadata refresh")
    if [[ "$EDA_CONTINUE_ON_REQUIRED_FAIL" == "0" ]]; then
        exit 1
    fi
fi
# ------------------------------------------------------------
# 3. Development environment — split
# ------------------------------------------------------------
echo
echo ">>> [2/10] Development environment"
if dnf group install -y "Development Tools"; then
    echo "[OK] Development Tools group"
else
    echo "[WARN] Development Tools group could not be fully installed."
    FAILED_OPTIONAL+=("Development Tools group")
fi
install_required "C/C++/Fortran compiler toolchain" \
    gcc gcc-c++ gcc-gfortran make cmake binutils
# csh is typically provided by tcsh on el8; listing both is fine.
install_required "Scripting and build utilities" \
    perl python3 ksh tcsh csh tcl tk environment-modules \
    which file tar gzip bzip2 xz patch diffutils hostname
install_required "Core development headers" \
    glibc-headers glibc-devel libstdc++ libstdc++-devel
# ------------------------------------------------------------
# 4. 64-bit runtime — split into logical groups
# ------------------------------------------------------------
echo
echo ">>> [3/10] 64-bit runtime libraries"
install_required "Base system runtime" \
    glibc libgcc libstdc++ zlib ncurses-libs
install_required "Network and security runtime" \
    libnsl libnsl2 libtirpc openssl-libs libcurl
# Use elfutils-libelf only — bare name `libelf` is not a reliable NVR on el8.
install_required "Compression, XML, and utility runtime" \
    elfutils-libelf libpng libjpeg-turbo \
    libuuid libxml2 expat libaio numactl-libs pcre libxslt libffi
install_required "Font and GUI runtime" \
    fontconfig freetype libdb gtk2 gtk3
install_required "Legacy image / media helpers" \
    libpng12 alsa-lib cups-libs
# redhat-lsb-core pulls many BaseOS tools; keep it optional so AppStream-only
# mirrors do not fail the whole required chain.
install_optional_group "LSB core compatibility" \
    redhat-lsb-core
install_optional_group "Additional 64-bit development headers" \
    zlib-devel ncurses-devel libnsl2-devel libtirpc-devel \
    libpng-devel libjpeg-turbo-devel openssl-devel libuuid-devel \
    libxml2-devel libcurl-devel libaio-devel pcre-devel libxslt-devel
# ------------------------------------------------------------
# 5. 32-bit compatibility — OPTIONAL by design
# ------------------------------------------------------------
echo
echo ">>> [4/10] 32-bit compatibility libraries (OPTIONAL)"
echo "[INFO] Verify actual ELF needs with: readelf -d <binary> | grep NEEDED"
echo "[INFO] and ldd <binary>; do not install i686 blindly."
install_optional_group "i686 core runtime" \
    glibc.i686 libgcc.i686 libstdc++.i686 zlib.i686 \
    ncurses-libs.i686 libnsl.i686 libnsl2.i686 libtirpc.i686 \
    libdb.i686
install_optional_group "i686 X11/OpenGL libraries" \
    libX11.i686 libXau.i686 libxcb.i686 libXext.i686 \
    libXt.i686 libXtst.i686 libXrender.i686 libXft.i686 \
    libXi.i686 libICE.i686 libSM.i686 libXpm.i686 \
    libXmu.i686 libXrandr.i686 libXcursor.i686 libXdamage.i686 \
    libXp.i686 libXv.i686 mesa-libGL.i686 mesa-libGLU.i686
# ------------------------------------------------------------
# 6. X11 / GUI / OpenGL
# ------------------------------------------------------------
echo
echo ">>> [5/10] X11, GUI and OpenGL"
install_required "Core X11 runtime" \
    libX11 libXau libxcb libXext libXt libXtst libXrender \
    libXft libXpm libXmu libXrandr libXcursor libXdamage libXi \
    libXcomposite libXfixes libXinerama libXxf86vm libICE libSM
install_required "OpenGL, font, and display utilities" \
    mesa-libGL mesa-libGLU mesa-dri-drivers fontconfig freetype \
    xorg-x11-xauth xorg-x11-server-Xvfb xterm
install_optional_group "Additional X11 compatibility libraries" \
    libXp libXv libXScrnSaver libXres libXxf86dga
# ------------------------------------------------------------
# 7. Legacy compatibility — Motif + OpenSSL 1.0 are REQUIRED
# ------------------------------------------------------------
echo
echo ">>> [6/10] Legacy EDA compatibility packages"
# motif obsoletes openmotif and provides openmotif; listing both is redundant.
install_required "Motif runtime (obsoletes openmotif)" \
    motif
install_required "OpenSSL 1.0 legacy compatibility (.so.10)" \
    compat-openssl10
install_optional_group "Motif / GUI development packages" \
    motif-devel libX11-devel libXext-devel libXt-devel libXpm-devel \
    libXmu-devel libXp-devel freetype-devel mesa-libGL-devel \
    elfutils-libelf-devel libstdc++-devel.i686
# ------------------------------------------------------------
# 8. Berkeley DB compatibility — opt-in, with readelf validation
# ------------------------------------------------------------
echo
echo ">>> [7/10] Berkeley DB compatibility"
ldconfig
if [[ "$EDA_DB47_COMPAT" == "1" ]]; then
    echo
    echo "############################################################"
    echo "# WARNING: EDA_DB47_COMPAT=1"
    echo "# libdb-4.7.so -> libdb-5.3.so is a linker-level workaround."
    echo "# It does NOT guarantee Berkeley DB 4.7 API/ABI compatibility."
    echo "# Use only when a specific tool fails with libdb-4.7.so missing."
    echo "############################################################"
    DB53_LIB=""
    for p in /usr/lib64/libdb-5.3.so /lib64/libdb-5.3.so; do
        if [[ -e "$p" ]]; then
            DB53_LIB="$p"
            break
        fi
    done
    if [[ -z "$DB53_LIB" ]]; then
        DB53_LIB="$(ldconfig -p 2>/dev/null |
            awk '$1 == "libdb-5.3.so" && /x86-64/ {print $NF; exit}')"
    fi
    if [[ -n "$DB53_LIB" && -e "$DB53_LIB" ]]; then
        DB53_REAL="$(readlink -f "$DB53_LIB")"
        DB47_LINK="/usr/lib64/libdb-4.7.so"
        DB47_IS_OURS=0
        # Stronger than `file`: verify ELF machine is x86-64.
        if ! readelf -h "$DB53_REAL" 2>/dev/null | grep -q "Advanced Micro Devices X86-64"; then
            echo "[ERROR] $DB53_REAL is not an x86-64 ELF object; refusing to link."
            exit 1
        fi
        echo "DB 5.3 target: $DB53_REAL"
        if [[ -L "$DB47_LINK" ]]; then
            EXISTING_TARGET="$(readlink -f "$DB47_LINK" || true)"
            if [[ "$EXISTING_TARGET" == "$DB53_REAL" ]]; then
                echo "[OK] Existing DB 4.7 link already points to DB 5.3."
                DB47_IS_OURS=1
            else
                echo "[WARN] Existing symlink points elsewhere; not overwritten:"
                ls -l "$DB47_LINK"
            fi
        elif [[ -e "$DB47_LINK" ]]; then
            echo "[WARN] Existing non-symlink DB 4.7 file; not overwritten:"
            ls -l "$DB47_LINK"
        else
            ln -s "$DB53_REAL" "$DB47_LINK"
            echo "[OK] Created $DB47_LINK -> $DB53_REAL"
            DB47_IS_OURS=1
        fi
        if [[ "$DB47_IS_OURS" == "1" && -r "$DB47_LINK" ]]; then
            if python3 -c 'import ctypes,sys; ctypes.CDLL(sys.argv[1])' "$DB47_LINK" 2>/dev/null; then
                echo "[OK] DB 4.7 -> 5.3 compat link loads (linker-level only)."
                CHECK_RESULTS+=("[OK] DB 4.7 compat link loads (ABI unverified)")
            else
                echo "[WARN] ctypes load test failed for the compat link."
                CHECK_RESULTS+=("[WARN] DB compat link load test failed")
            fi
        elif [[ -r "$DB47_LINK" ]]; then
            echo "[INFO] Existing libdb-4.7.so is not our link; load test skipped."
        fi
    else
        echo "[WARN] libdb-5.3.so not found; DB 4.7 link not created."
        FAILED_OPTIONAL+=("Berkeley DB 4.7 compat (target missing)")
    fi
else
    echo "[INFO] EDA_DB47_COMPAT=0 (default). libdb-4.7.so is NOT created."
    echo "[INFO] If a Cadence tool fails with libdb-4.7.so missing:"
    echo "[INFO]   a) rerun with EDA_DB47_COMPAT=1 (ABI risk), or"
    echo "[INFO]   b) place a genuine CentOS 7 libdb-4.7.so in LD_LIBRARY_PATH."
fi
# ------------------------------------------------------------
# 9. CAD infrastructure
# ------------------------------------------------------------
echo
echo ">>> [8/10] CAD infrastructure and network utilities"
install_required "Remote access and network clients" \
    openssh-clients openssh-server bind-utils net-tools iproute iputils
install_required "Filesystem and time services" \
    nfs-utils autofs chrony rsync
install_required "Debugging and inspection tools" \
    lsof strace gdb tcpdump procps-ng util-linux
# ------------------------------------------------------------
# 10. Runtime verification — REQUIRED libs affect final status
# ------------------------------------------------------------
echo
echo ">>> [9/10] Refresh linker cache and verify runtime"
ldconfig
# --- REQUIRED runtime libraries ---
check_required_library "libc.so.6"
check_required_library "libstdc++.so.6"
check_required_library "libgcc_s.so.1"
check_required_library "libnsl.so.1"
check_required_library "libssl.so.1.1"
check_required_library "libcrypto.so.1.1"
check_required_library "libssl.so.10"
check_required_library "libcrypto.so.10"
check_required_library "libXm.so.4"
check_required_library "libX11.so.6"
check_required_library "libGL.so.1"
# --- Optional / compatibility libraries ---
check_optional_library "libnsl.so.2"
check_optional_library "libdb-5.3.so"
check_optional_library "libtinfo.so.6"
check_optional_library "libXt.so.6"
check_optional_library "libpng12.so.0"
check_optional_library "libgtk-x11-2.0.so.0"
# ------------------------------------------------------------
# 11. Report
# ------------------------------------------------------------
echo
echo ">>> [10/10] Generate report"
{
    echo "============================================================"
    echo "el8 EDA Base Environment Report"
    echo "============================================================"
    echo "Date         : $(date)"
    echo "Hostname     : $(hostname)"
    echo "OS           : ${PRETTY_NAME:-el8}"
    echo "Architecture : $(uname -m)"
    echo "DB47 compat  : ${EDA_DB47_COMPAT} (0=off, 1=opt-in)"
    echo
    echo "Runtime checks:"
    printf '%s\n' "${CHECK_RESULTS[@]}"
    echo
    echo "Required failures:"
    if ((${#FAILED_REQUIRED[@]} == 0)); then
        echo "None"
    else
        printf '%s\n' "${FAILED_REQUIRED[@]}"
    fi
    echo
    echo "Missing REQUIRED libraries:"
    if ((${#MISSING_REQUIRED_LIBS[@]} == 0)); then
        echo "None"
    else
        printf '%s\n' "${MISSING_REQUIRED_LIBS[@]}"
    fi
    echo
    echo "Optional packages ABSENT (rpm -q verified):"
    if ((${#FAILED_OPTIONAL[@]} == 0)); then
        echo "None"
    else
        printf '%s\n' "${FAILED_OPTIONAL[@]}" | sort -u
    fi
    echo
    echo "Optional packages PRESENT (rpm -q verified):"
    if ((${#INSTALLED_OPTIONAL[@]} == 0)); then
        echo "None"
    else
        printf '%s\n' "${INSTALLED_OPTIONAL[@]}" | sort -u
    fi
    echo
    echo "Berkeley DB files:"
    ls -l /usr/lib64/libdb* 2>/dev/null || true
    echo
    echo "OpenSSL entries:"
    ldconfig -p 2>/dev/null | grep -E 'libssl|libcrypto' || true
    echo
    echo "Key RPMs:"
    rpm -q gcc gcc-c++ make cmake ksh tcsh tcl tk glibc \
        libstdc++ libnsl libnsl2 libdb openssl-libs compat-openssl10 \
        motif mesa-libGL xorg-x11-server-Xvfb gtk2 libpng12 \
        redhat-lsb-core 2>/dev/null || true
    echo
    echo "Log    : $LOG_FILE"
    echo "Report : $REPORT_FILE"
    echo "============================================================"
} | tee "$REPORT_FILE"
# ------------------------------------------------------------
# 12. Final status
# ------------------------------------------------------------
echo
echo "============================================================"
FINAL_FAIL=0
if ((${#FAILED_REQUIRED[@]} > 0)); then
    echo "[FAILED] Required package groups failed."
    FINAL_FAIL=1
fi
if ((${#MISSING_REQUIRED_LIBS[@]} > 0)); then
    echo "[FAILED] Missing REQUIRED runtime libraries:"
    printf '  - %s\n' "${MISSING_REQUIRED_LIBS[@]}"
    FINAL_FAIL=1
fi
if ((FINAL_FAIL == 0)); then
    echo "[SUCCESS] EDA base environment prepared."
else
    echo "[FAILED] One or more required checks did not pass."
fi
echo
echo "HINT: For Siemens Calibre on Rocky/RHEL 8, if it reports VCO mismatch, try:"
echo "      export USE_CALIBRE_VCO=aoi"
echo
echo "HINT: This script prepares OS runtime deps only. Install EDA tools,"
echo "      FlexLM/SCL, and vendor modulefiles separately."
echo
echo "Log    : $LOG_FILE"
echo "Report : $REPORT_FILE"
echo "============================================================"
exit "$FINAL_FAIL"


登录访问
本站用户 免费查看
登录账号
您未登录,请登录 或 注册后查看

相关推荐:

网友留言:

您需要 登录账户 后才能发表评论

我要评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。
验证码