openEuler24.03安装vmwareworkstation启动时 gcc找不到 报错处理

openEuler24.03的/proc/version中,使用了gcc_old (GCC)这样的格式,而不是vmware能识别的格式。在启动vmwareworkstation时提示gcc找不到。

临时处理方法一

临时替换/proc/version,然后利用vmware自带工具vmware-modconfig处理。经AI生成的脚本如下:

注:需要管理员权限执行

#!/bin/bash
set -euo pipefail

# 前置依赖检查(核心必做)
if [ ! -d "/lib/modules/$(uname -r)/build" ]; then
    echo "❌ 请先执行:sudo dnf install -y kernel-devel-$(uname -r)"
    exit 1
fi

# 核心:替换/proc/version中的gcc_old,解决识别失败
PROC_BAK=$(mktemp /tmp/proc_version_bak.XXXXXX)
cat /proc/version > "$PROC_BAK"
sed 's/gcc_old (GCC)/gcc version/' "$PROC_BAK" > /tmp/proc_version_fixed
# 临时挂载修改后的文件
while mount | grep -q "/proc/version"; do umount /proc/version; done
mount --bind /tmp/proc_version_fixed /proc/version

# 仅使用官方工具编译VMware模块(移除手动编译兜底)
echo "✅ 使用官方工具编译VMware模块"
vmware-modconfig --console --install-all

# 恢复原生/proc/version,清理临时文件
umount /proc/version && rm -f "$PROC_BAK" /tmp/proc_version_fixed
# 重启VMware服务
sudo pkill -f vmware-authdlauncher || true
sudo systemctl restart vmware

# 验证结果
echo -e "\n===== 修复完成验证 ====="
sudo lsmod | grep -E "vmmon|vmnet" && echo "✅ 模块加载成功" || echo "⚠️  模块加载失败,可尝试重新执行脚本"
sudo systemctl status vmware --no-pager | grep Active

临时处理方法二

手动编译受影响的模块vmmon和vmnet.经AI生成的脚本如下:

#!/bin/bash
set -euo pipefail

KERNEL_VERSION=$(uname -r)
MODULE_SRC="/usr/lib/vmware/modules/source"
MODULE_DEST="/lib/modules/${KERNEL_VERSION}/misc"

# 检查模块是否已存在且版本匹配
check_module() {
    local mod_path="$1"
    if [ ! -f "$mod_path" ]; then
        return 1
    fi
    # 获取模块 vermagic
    local vermagic
    vermagic=$(modinfo -F vermagic "$mod_path" 2>/dev/null | head -1)
    if [ -z "$vermagic" ]; then
        return 1
    fi
    # 比较 vermagic 是否包含当前内核版本
    if [[ "$vermagic" == *"$KERNEL_VERSION"* ]]; then
        return 0
    else
        return 1
    fi
}

if check_module "${MODULE_DEST}/vmmon.ko" && check_module "${MODULE_DEST}/vmnet.ko"; then
    echo "当前内核的 VMware 模块已存在且版本匹配,跳过编译。"
    exit 0
fi

# 检查内核头文件
if [ ! -d "/lib/modules/${KERNEL_VERSION}/build" ]; then
    echo "❌ 未找到内核头文件,请执行:sudo dnf install kernel-devel-${KERNEL_VERSION}"
    exit 1
fi

# 进入源码目录
cd "${MODULE_SRC}"

# 清理可能存在的旧解压目录
rm -rf vmmon-only vmnet-only

# 解压并编译 vmmon
echo "🔨 编译 vmmon..."
tar xf vmmon.tar
cd vmmon-only
make
cd ..

# 解压并编译 vmnet
echo "🔨 编译 vmnet..."
tar xf vmnet.tar
cd vmnet-only
make
cd ..

# 创建目标目录
mkdir -p "${MODULE_DEST}"

# 复制模块
cp vmmon-only/vmmon.ko "${MODULE_DEST}/vmmon.ko"
cp vmnet-only/vmnet.ko "${MODULE_DEST}/vmnet.ko"

# 更新模块依赖
depmod -a

# 清理临时解压目录
rm -rf vmmon-only vmnet-only

echo "✅ 编译完成,模块已安装至 ${MODULE_DEST}"

开机自动处理

建立systemd服务,开机自动启动手动编译脚本。由AI生成的一键安装测试脚本如下:

#!/bin/bash
# VMware 模块自动编译部署脚本(手动编译 + systemd)
# 适用于 openEuler / RHEL / CentOS 等使用 dnf 的发行版
set -euo pipefail

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}   VMware 模块自动编译部署脚本           ${NC}"
echo -e "${GREEN}========================================${NC}"

# 检查是否 root 权限
if [ "$EUID" -ne 0 ]; then
    echo -e "${RED}请以 root 权限运行此脚本(使用 sudo)。${NC}"
    exit 1
fi

# 检查 VMware 是否已安装(通过检测模块源码)
VMWARE_SRC="/usr/lib/vmware/modules/source"
if [ ! -f "$VMWARE_SRC/vmmon.tar" ] || [ ! -f "$VMWARE_SRC/vmnet.tar" ]; then
    echo -e "${RED}错误:未找到 VMware 模块源码,请先安装 VMware Workstation。${NC}"
    exit 1
fi
echo -e "${GREEN}✅ 检测到 VMware 模块源码。${NC}"

# 安装依赖
echo -e "${YELLOW}正在安装依赖(kernel-devel, make, gcc, elfutils-libelf-devel)...${NC}"
dnf install -y kernel-devel-$(uname -r) make gcc elfutils-libelf-devel
echo -e "${GREEN}✅ 依赖安装完成。${NC}"

# 创建手动编译脚本
echo -e "${YELLOW}创建编译脚本 /usr/local/bin/vmware-manual-build.sh ...${NC}"
cat > /usr/local/bin/vmware-manual-build.sh << 'EOF'
#!/bin/bash
set -euo pipefail

KERNEL_VERSION=$(uname -r)
MODULE_SRC="/usr/lib/vmware/modules/source"
MODULE_DEST="/lib/modules/${KERNEL_VERSION}/misc"

# 检查模块是否已存在且版本匹配
check_module() {
    local mod_path="$1"
    if [ ! -f "$mod_path" ]; then
        return 1
    fi
    # 获取模块 vermagic
    local vermagic
    vermagic=$(modinfo -F vermagic "$mod_path" 2>/dev/null | head -1)
    if [ -z "$vermagic" ]; then
        return 1
    fi
    # 比较 vermagic 是否包含当前内核版本
    if [[ "$vermagic" == *"$KERNEL_VERSION"* ]]; then
        return 0
    else
        return 1
    fi
}

if check_module "${MODULE_DEST}/vmmon.ko" && check_module "${MODULE_DEST}/vmnet.ko"; then
    echo "当前内核的 VMware 模块已存在且版本匹配,跳过编译。"
    exit 0
fi

# 检查内核头文件
if [ ! -d "/lib/modules/${KERNEL_VERSION}/build" ]; then
    echo "❌ 未找到内核头文件,请执行:sudo dnf install kernel-devel-${KERNEL_VERSION}"
    exit 1
fi

# 进入源码目录
cd "${MODULE_SRC}"

# 清理可能存在的旧解压目录
rm -rf vmmon-only vmnet-only

# 解压并编译 vmmon
echo "🔨 编译 vmmon..."
tar xf vmmon.tar
cd vmmon-only
make
cd ..

# 解压并编译 vmnet
echo "🔨 编译 vmnet..."
tar xf vmnet.tar
cd vmnet-only
make
cd ..

# 创建目标目录
mkdir -p "${MODULE_DEST}"

# 复制模块
cp vmmon-only/vmmon.ko "${MODULE_DEST}/vmmon.ko"
cp vmnet-only/vmnet.ko "${MODULE_DEST}/vmnet.ko"

# 更新模块依赖
depmod -a

# 清理临时解压目录
rm -rf vmmon-only vmnet-only

echo "✅ 编译完成,模块已安装至 ${MODULE_DEST}"
EOF

chmod +x /usr/local/bin/vmware-manual-build.sh
echo -e "${GREEN}✅ 编译脚本创建成功。${NC}"

# 创建 systemd 服务单元
echo -e "${YELLOW}创建 systemd 服务 /etc/systemd/system/vmware-manual-build.service ...${NC}"
cat > /etc/systemd/system/vmware-manual-build.service << 'EOF'
[Unit]
Description=VMware Manual Module Build
After=local-fs.target
Before=vmware.service
ConditionPathExists=/lib/modules/%v/build
ConditionPathExists=/usr/lib/vmware/modules/source/vmmon.tar
ConditionPathExists=/usr/lib/vmware/modules/source/vmnet.tar

[Service]
Type=oneshot
ExecStart=/usr/local/bin/vmware-manual-build.sh
RemainAfterExit=no
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
EOF

# 重新加载 systemd
systemctl daemon-reload

# 启用服务(开机自启)
systemctl enable vmware-manual-build.service
echo -e "${GREEN}✅ systemd 服务已启用。${NC}"

# 立即执行一次(测试)
echo -e "${YELLOW}立即执行编译脚本以测试...${NC}"
systemctl start vmware-manual-build.service

# 检查服务状态(使用 ExecMainStatus 判断)
EXIT_CODE=$(systemctl show -p ExecMainStatus --value vmware-manual-build.service)
if [ "$EXIT_CODE" = "0" ]; then
    echo -e "${GREEN}✅ 编译服务执行成功。${NC}"
else
    echo -e "${RED}⚠️ 编译服务执行可能失败,请查看日志:journalctl -u vmware-manual-build.service${NC}"
fi

# 重启 VMware 服务(如果已安装)
if systemctl list-unit-files | grep -q vmware.service; then
    echo -e "${YELLOW}重启 VMware 服务...${NC}"
    systemctl restart vmware.service || true
fi

# 最终提示
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}部署完成!${NC}"
echo -e "编译脚本位置:${YELLOW}/usr/local/bin/vmware-manual-build.sh${NC}"
echo -e "systemd 服务:${YELLOW}vmware-manual-build.service${NC}"
echo -e ""
echo -e "每次系统启动时会自动检查并编译当前内核的 VMware 模块。"
echo -e "手动运行:${YELLOW}sudo systemctl start vmware-manual-build.service${NC}"
echo -e "查看日志:${YELLOW}sudo journalctl -u vmware-manual-build.service${NC}"
echo -e "${GREEN}========================================${NC}"

测试开机自动处理

开机自动处理脚本中有一次自启动完成编译。通过删除编译后的vmmon和vmnet,然后打开vmware报gcc找不到,然后重启后vmware能正常打开即可。
删除vmmon和vmnet模块脚本:

#!/bin/bash
# 查找所有内核版本下的 vmmon/vmnet 模块文件
sudo find /lib/modules -name "vmmon.ko*" -o -name "vmnet.ko*" 2>/dev/null

# 删除所有找到的文件(谨慎操作,确保不误删重要文件)
sudo find /lib/modules -name "vmmon.ko*" -o -name "vmnet.ko*" -exec rm -f {} \;

# 重新生成所有内核版本的模块依赖(可选,但建议执行)
sudo depmod -a

清除开机自动处理脚本留下的文件,进行还原

#!/bin/bash
# VMware 模块自动编译方案清理脚本
set -euo pipefail

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color

echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}   VMware 自动编译方案清理脚本           ${NC}"
echo -e "${GREEN}========================================${NC}"

# 检查是否 root 权限
if [ "$EUID" -ne 0 ]; then
    echo -e "${RED}请以 root 权限运行此脚本(使用 sudo)。${NC}"
    exit 1
fi

# 定义服务名和脚本路径
SERVICE_NAME="vmware-manual-build.service"
SCRIPT_PATH="/usr/local/bin/vmware-manual-build.sh"

# 1. 停止并禁用服务(如果存在)
if systemctl list-unit-files | grep -q "$SERVICE_NAME"; then
    echo -e "${YELLOW}正在停止并禁用 $SERVICE_NAME ...${NC}"
    systemctl stop "$SERVICE_NAME" 2>/dev/null || true
    systemctl disable "$SERVICE_NAME" 2>/dev/null || true
    echo -e "${GREEN}✅ 服务已停止并禁用。${NC}"
else
    echo -e "${YELLOW}服务 $SERVICE_NAME 不存在,跳过。${NC}"
fi

# 2. 删除服务单元文件
if [ -f "/etc/systemd/system/$SERVICE_NAME" ]; then
    echo -e "${YELLOW}正在删除服务单元文件...${NC}"
    rm -f "/etc/systemd/system/$SERVICE_NAME"
    echo -e "${GREEN}✅ 服务单元文件已删除。${NC}"
else
    echo -e "${YELLOW}服务单元文件不存在,跳过。${NC}"
fi

# 3. 重新加载 systemd
systemctl daemon-reload
echo -e "${GREEN}✅ systemd 已重新加载。${NC}"

# 4. 删除编译脚本
if [ -f "$SCRIPT_PATH" ]; then
    echo -e "${YELLOW}正在删除编译脚本 $SCRIPT_PATH ...${NC}"
    rm -f "$SCRIPT_PATH"
    echo -e "${GREEN}✅ 编译脚本已删除。${NC}"
else
    echo -e "${YELLOW}编译脚本不存在,跳过。${NC}"
fi

# 5. 询问是否删除已安装的模块文件
echo -e "${YELLOW}是否要删除已安装的 VMware 模块文件(位于 /lib/modules/$(uname -r)/misc/ 下)?${NC}"
echo -e "${YELLOW}注意:删除后 VMware 将无法启动,除非重新编译模块。${NC}"
read -p "请输入 y/N: " -r choice
if [[ "$choice" =~ ^[Yy]$ ]]; then
    MODULE_DEST="/lib/modules/$(uname -r)/misc"
    if [ -d "$MODULE_DEST" ]; then
        echo -e "${YELLOW}正在删除模块文件...${NC}"
        rm -f "$MODULE_DEST"/vmmon.ko "$MODULE_DEST"/vmnet.ko
        echo -e "${GREEN}✅ 模块文件已删除。${NC}"
        # 更新模块依赖
        depmod -a
        echo -e "${GREEN}✅ 模块依赖已更新。${NC}"
    else
        echo -e "${YELLOW}模块目录不存在,跳过。${NC}"
    fi
else
    echo -e "${YELLOW}保留已安装的模块文件。${NC}"
fi


# 6. 提示完成
echo -e "${GREEN}========================================${NC}"
echo -e "${GREEN}清理完成!${NC}"
echo -e "如需重新部署,请再次运行安装脚本。"
echo -e "${GREEN}========================================${NC}"