ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

openSUSE 12.3 下 GCC 32位与64位安装配置全指南

openSUSE 12.3 下 GCC 32位与64位安装配置全指南 简介这份资源面向需要在 openSUSE 12.3 系统上安装 GCC 编译器的开发者与运维人员尤其适合仍维护老旧 SUSE 环境、受限于官方源失效而无法直接安装编译工具链的用户。资源包内共 86 个文件以 gz 压缩包、asc 签名文件、key 密钥文件为主另含 patterns、media、content 及 xml 等仓库元数据整体约 22.53MBrar 打包便于一次性获取。其核心价值在于完整保留了 openSUSE 12.3 的 zypp 仓库缓存目录结构涵盖 openSUSE-12.3-1.7、repo-oss、repo-non-oss、repo-update 及 repo-update-non-oss 等模块并附带对应的签名与密钥文件可直接拷贝至 /var/cache/zypp/raw 下供 zypper 识别使用省去逐一下载与配置源的繁琐过程。目前已有 911 人学习下载适合需要离线部署或修复旧版 SUSE 编译环境的读者参考使用。1. openSUSE 12.3 上装 GCC为什么 32 位和 64 位要分开处理openSUSE 12.3 是个 2013 年发布的老版本默认自带的 GCC 版本停留在 4.7.x 附近。如果你手头有台老机器、老工控机或者某个只认这个系统的编译环境想在上面装一套能同时编 32 位和 64 位程序的 GCC会发现事情没那么简单——不是zypper install gcc一条命令就能收工的。32 位和 64 位在 openSUSE 里走的是两套不同的库路径和包名混着装很容易出现头文件找不到、链接器报skipping incompatible这类问题。这份资源就是针对这个场景整理的openSUSE 12.3 下 GCC 的安装包与配置参考覆盖 32 位和 64 位两条线。适合两类人一是维护老 openSUSE 环境的运维二是需要在 32 位目标上做交叉编译或本地编译的嵌入式开发者。下面从包的选择、安装、验证到踩坑一步步拆开讲。2. 先搞清楚 openSUSE 12.3 的 GCC 包结构32 位和 64 位到底差在哪2.1 包名与架构后缀的对应关系openSUSE 的包管理用 zypper架构后缀决定了你装的是哪一套。64 位系统上默认的gcc包指向 64 位版本而 32 位支持需要额外装gcc-32bit和对应的glibc-devel-32bit。很多人第一次装完发现gcc -m32报错就是因为只装了 64 位的开发库。常见做法是先确认系统架构uname -m # x86_64 表示 64 位系统i686 表示 32 位系统如果是 x86_64你要同时准备两套用途包名说明64 位编译gcc, gcc-c, glibc-devel默认安装32 位编译gcc-32bit, gcc-c-32bit, glibc-devel-32bit需手动补装头文件kernel-devel, make编译内核模块时必需这里的关键点是gcc-32bit并不是一个独立的编译器而是让 64 位 gcc 能生成 32 位代码所需的运行时库和头文件。真正干活的还是同一个 gcc 二进制只是通过-m32参数切换目标。2.2 为什么不能只装一个架构的包有人会想我只要编 32 位程序那装个 32 位的 gcc 不就行了在 openSUSE 12.3 上这条路走不通因为系统本身是 64 位的话zypper 的默认仓库只提供 64 位主包32 位包是以补充形式存在的。你没法把整个系统的 gcc 换成 32 位版本只能让 64 位 gcc 具备生成 32 位代码的能力。另一个误区是直接去下源码编译。GCC 源码编译一次动辄半小时到几小时在 12.3 这种老系统上依赖还容易缺。除非你有特殊需求比如要特定版本的 GCC否则优先用包管理装。提示openSUSE 12.3 的官方仓库已经停止维护如果 zypper 源失效需要先确认本地是否有安装介质或内网镜像源。这一步不在本文展开但装包前务必确认源可用。3. 动手装从 zypper 命令到 32 位库补全3.1 基础安装步骤先刷新源再装 64 位基础套件# 刷新软件源元数据 sudo zypper refresh # 安装 64 位 GCC 及常用工具 sudo zypper install gcc gcc-c make # 验证 64 位编译 echo int main(){return 0;} test64.c gcc -m64 test64.c -o test64 file test64 # 输出应包含 ELF 64-bitzypper refresh会拉取仓库最新的包索引如果源不可用这里就会报错先解决源的问题再往下走。gcc-c是 C 编译前端即使你只写 C很多构建系统也会依赖它。make不用多说老项目基本都靠 Makefile。3.2 补装 32 位支持这一步是重点也是最多人翻车的地方# 安装 32 位运行时和开发库 sudo zypper install gcc-32bit gcc-c-32bit glibc-devel-32bit # 验证 32 位编译 gcc -m32 test64.c -o test32 file test32 # 输出应包含 ELF 32-bit如果gcc -m32报cannot find -lgcc或gnu/stubs-32.h找不到说明 32 位开发库没装全。glibc-devel-32bit提供的就是 32 位的头文件和静态库链接缺了它编译器找不到 32 位的crt1.o和libc.so。参数说明-m32和-m64是 GCC 的目标架构开关不是所有平台都支持。在 openSUSE 12.3 的 x86_64 上这两个开关都可用前提是两套库都齐。3.3 用 spec 文件或环境变量固定架构如果你经常需要切换可以在 Makefile 里用变量控制# Makefile 片段 CC gcc CFLAGS -O2 -Wall ARCH ? 64 ifeq ($(ARCH),32) CFLAGS -m32 LDFLAGS -m32 else CFLAGS -m64 LDFLAGS -m64 endif hello: hello.c $(CC) $(CFLAGS) $ -o $ $(LDFLAGS)这样make ARCH32就编 32 位make默认编 64 位。逻辑说明?表示如果命令行没传 ARCH 就用 64ifeq做条件判断把-m32同时加到编译和链接阶段。注意链接阶段也要加-m32只加编译不加链接会出现目标文件格式不匹配。4. 验证与排查怎么确认两套 GCC 都真的能用4.1 用 file 和 readelf 做双重确认file命令看的是 ELF 头readelf能看更细的架构信息# 查看 ELF 头 readelf -h test32 | grep Machine # 应输出 Intel 80386 readelf -h test64 | grep Machine # 应输出 Advanced Micro Devices X86-64如果file显示对了但运行报Exec format error可能是内核不支持该架构或者你编出来的其实是错的架构。用readelf交叉验证最稳。4.2 检查 gcc 的默认目标gcc -v 21 | grep Target # 输出类似 x86_64-suse-linux这个 Target 是 gcc 的默认目标不影响-m32的使用但能帮你确认装的是哪个版本。如果这里显示的是 i686 而你系统是 x86_64说明装错了包。4.3 常见报错与对应检查点报错信息可能原因检查动作cannot find -lgcc32 位 libgcc 缺失确认 gcc-32bit 已装gnu/stubs-32.h: No such fileglibc-devel-32bit 缺失zypper se glibc-devel-32bitskipping incompatible链接时混用了 32/64 位 .o检查 LDFLAGS 是否带 -m32unrecognized command line option -m32gcc 不支持多架构确认装的是 x86_64 版 gcc5. 避坑openSUSE 12.3 装 GCC 的五个血泪教训5.1 现象zypper install gcc-32bit 提示找不到包原因openSUSE 12.3 的仓库已经归档默认源可能指向了失效地址或者你用的是 32 位系统但想装 32 位包——32 位系统上不需要gcc-32bit因为默认就是 32 位。解决先zypper lr看源列表确认有可用的 12.3 仓库。如果是 32 位系统直接装gcc即可不要装-32bit后缀的包。5.2 现象编译通过但链接报 undefined reference to__stack_chk_fail原因32 位和 64 位的栈保护库路径不同混用时会找不到符号。解决确保编译和链接用同一套-m32或-m64不要一个文件用 32 位编、另一个用 64 位编再链在一起。用make clean清掉旧的目标文件重新编。5.3 现象gcc -m32 能编但生成的程序跑不起来原因系统缺少 32 位运行时库或者内核没开 32 位兼容。解决装glibc-32bit运行时包用ldd test32看依赖是否都能解析。如果ldd报not a dynamic executable说明静态链接了检查是否误加了-static。5.4 现象装了新 GCC 但 gcc --version 还是旧的原因PATH 里有多个 gcc或者用了update-alternatives但没切换。解决which -a gcc看所有 gcc 路径echo $PATH确认优先级。openSUSE 上可以用update-alternatives --config gcc切换但 12.3 的 alternatives 配置可能不完整手动改 PATH 更直接。5.5 现象编 32 位程序时头文件找到 64 位的原因-I路径里混入了 64 位头文件目录或者CFLAGS里有多余的-I/usr/include导致搜索顺序错乱。解决用gcc -m32 -E -v - /dev/null看实际的头文件搜索路径确认 32 位路径在 64 位之前。必要时用-nostdinc加手动-isystem指定。6. 进阶用 GCC 的 -print-search-dirs 摸清库路径与多版本共存装完只是第一步真正要稳得知道 GCC 到底从哪儿找库。gcc -print-search-dirs会输出三个关键路径install、programs、libraries。在 openSUSE 12.3 上跑一下gcc -print-search-dirs # 输出示例 # install: /usr/lib64/gcc/x86_64-suse-linux/4.7/ # programs: /usr/lib64/gcc/x86_64-suse-linux/4.7/:/usr/lib64/gcc/x86_64-suse-linux/4.7/ # libraries: /usr/lib64/gcc/x86_64-suse-linux/4.7/:/usr/lib64/gcc/x86_64-suse-linux/4.7/../../../../x86_64-suse-linux/lib/...注意 libraries 那一行默认全是 64 位路径。当你加-m32时GCC 会自动把路径里的lib64换成lib但前提是这些 32 位目录真实存在。如果gcc-32bit没装好这里就不会有 32 位路径链接自然失败。我一般会做一件事把 32 位和 64 位的库路径都打印出来对比。# 64 位库搜索路径 gcc -m64 -print-search-dirs | grep libraries # 32 位库搜索路径 gcc -m32 -print-search-dirs | grep libraries两条输出的差异就是你需要补的目录。如果 32 位那条里缺少/usr/lib/gcc/x86_64-suse-linux/4.7/32/这类路径说明gcc-32bit的运行时没装全回去补zypper install gcc-32bit。另一个实用技巧是用-Wl,--verbose让链接器把搜索过程全打出来gcc -m32 test64.c -o test32 -Wl,--verbose 21 | grep succeeded这会列出链接器实际找到的每一个库文件。如果某个库显示not found但编译还是过了说明它走了默认路径或静态链接。这个输出对排查skipping incompatible特别有用——你能看到链接器在哪个目录找到了 64 位的库然后跳过了。多版本共存方面openSUSE 12.3 允许你同时装 gcc 4.7 和 gcc 4.8如果源里有。用update-alternatives管理sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 47 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 48 sudo update-alternatives --config gcc但注意-32bit包通常只对应默认版本。如果你切到 4.8 但 32 位库还是 4.7 的-m32可能出问题。所以我的习惯是老系统上不折腾多版本锁定一个能同时支持 32/64 的版本用到底。从那以后我每次在新机器上配 GCC都强制走一遍gcc -m32和gcc -m64各编一个 hello world 并readelf确认架构不看到两个 ELF 头都对上不算完。希望帮到你。本文还有配套的精品资源点击获取
返回列表