![如何处理使用 GCC 6.2.1 编译 GCC 4.7.0 时出现的错误](https://linux22.com/image/102614/%E5%A6%82%E4%BD%95%E5%A4%84%E7%90%86%E4%BD%BF%E7%94%A8%20GCC%206.2.1%20%E7%BC%96%E8%AF%91%20GCC%204.7.0%20%E6%97%B6%E5%87%BA%E7%8E%B0%E7%9A%84%E9%94%99%E8%AF%AF.png)
我正在使用 Arch linux,并且我需要 GCC 4.7.0 来上课。
目前我的系统上只安装了 GCC 6.2.1。
我正确遵循了所有安装说明,但在运行初始make
.
$ make
.
.
In file included from /home/flounder/src/gcc-4.7.0/gcc-4.7.0/gcc/cp/except.c:987:0:
cfns.gperf: At top level:
cfns.gperf:101:1: error: ‘gnu_inline’ attribute present on ‘libc_name_p’
cfns.gperf:26:14: error: but not here
.
.
make[3]: *** [Makefile:1055: cp/except.o] Error 1
make[3]: Leaving directory '/home/flounder/src/gcc_compile/gcc'
make[2]: *** [Makefile:4101: all-stage1-gcc] Error 2
make[2]: Leaving directory '/home/flounder/src/gcc_compile'
make[1]: *** [Makefile:19342: stage1-bubble] Error 2
make[1]: Leaving directory '/home/flounder/src/gcc_compile'
make: *** [Makefile:898: all] Error 2
我读到,尝试使用现代版本构建旧版本的 GCC 时可能会发生这种情况,因为:
随着版本的继续,GCC 会添加新的错误,因此旧版本的 GCC 源代码在新版本的 GCC 下并不总是被认为有效
所以我该怎么做才能解决这个问题?
我认为两种可行的解决方案:
- 使用学校 Linux 计算机(也有 GCC 4.7.0,但它们是 32 位,而我有 64 位操作系统)为我的计算机交叉编译 GCC 4.7.0
- 首先在我的电脑上使用GCC 6.2.1编译GCC 5.4.x,然后使用GCC 5.4.x编译GCC 4.7.0
第一个选项似乎更安全。他们俩都能工作吗?这个比那个好吗?
编辑:
正如 @Kenneth B. Jensen 下面提到的,我尝试使用设置的标志运行配置,并尝试使用设置的标志--disable-werror
运行初始配置,但我仍然遇到了麻烦。以下是错误输出:make
-k
$ make -k
.
.
.
if [ xinfo = xinfo ]; then \
makeinfo --split-size=5000000 --split-size=5000000 --split-size=5000000 --no-split -I . -I /home/flounder/src/gcc-4.7.0/gcc/doc \
-I /home/flounder/src/gcc-4.7.0/gcc/doc/include -o doc/cppinternals.info /home/flounder/src/gcc-4.7.0/gcc/doc/cppinternals.texi; \
fi
echo timestamp > gcc.pod
perl /home/flounder/src/gcc-4.7.0/gcc/../contrib/texi2pod.pl /home/flounder/src/gcc-4.7.0/gcc/doc/invoke.texi > gcc.pod
Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/^\@strong{ <-- HERE (.*)}$/ at /home/flounder/src/gcc-4.7.0/gcc/../contrib/texi2pod.pl line 319.
echo timestamp > doc/gcc.1
(pod2man --center="GNU" --release="gcc-4.7.0" --date=2012-03-22 --section=1 gcc.pod > doc/gcc.1.T$$ && \
mv -f doc/gcc.1.T$$ doc/gcc.1) || \
(rm -f doc/gcc.1.T$$ && exit 1)
echo timestamp > gpl.pod
perl /home/flounder/src/gcc-4.7.0/gcc/../contrib/texi2pod.pl /home/flounder/src/gcc-4.7.0/gcc/doc/include/gpl_v3.texi > gpl.pod
Unescaped left brace in regex is deprecated, passed through in regex; marked by <-- HERE in m/^\@strong{ <-- HERE (.*)}$/ at /home/flounder/src/gcc-4.7.0/gcc/../contrib/texi2pod.pl line 319.
echo timestamp > doc/gpl.7
(pod2man --center="GNU" --release="gcc-4.7.0" --date=2012-03-22 --section=7 gpl.pod > doc/gpl.7.T$$ && \
mv -f doc/gpl.7.T$$ doc/gpl.7) || \
(rm -f doc/gpl.7.T$$ && exit 1)
cp doc/gcc.1 doc/g++.1
make[3]: Target 'all' not remade because of errors.
rm gcc.pod
make[3]: Leaving directory '/home/flounder/src/gcc_compile/gcc'
make[2]: *** [Makefile:4101: all-stage1-gcc] Error 2
make[2]: Target 'all-stage1' not remade because of errors.
make[2]: Leaving directory '/home/flounder/src/gcc_compile'
make[1]: *** [Makefile:19342: stage1-bubble] Error 2
make[1]: Target 'stage3-bubble' not remade because of errors.
make[1]: Leaving directory '/home/flounder/src/gcc_compile'
make: *** [Makefile:898: all] Error 2
答案1
我同意使用较新的 gcc 通常不是一个好的选择。我必须为运行 Pengutronix 的嵌入式 ARM v4 系统编写一个新程序,该系统卡在 2.6 内核和旧的 glibc 上。因此我必须在我的系统上编译旧的工具链。
通常较新的 GCC 版本会在源代码中发现错误,这些错误已经存在相当长一段时间了。我建议不要关闭错误检查,而是修复源代码。
根据错误日志,函数声明和函数头不匹配
const char * libc_name_p (const char *, unsigned int);
在 except.c 中包含的文件 cfns.h 中
编辑 cfns.h 并更改函数声明
#ifdef __GNUC__
__inline
#endif
const char * libc_name_p (const char *, unsigned int);
到
#ifdef __GNUC__
__inline
#ifdef __GNUC_STDC_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
const char * libc_name_p (const char *, unsigned int);
然后编译应该可以工作。
答案2
要扩展 @AxelBe 答案:使用较新的 GCC,您可能需要在 cfns.h 中更改函数声明和定义:
#ifdef __GNUC__
__inline
#endif
const char * libc_name_p (const char *, unsigned int);
或者
#ifdef __GNUC__
__inline
#ifdef __GNUC_STDC_INLINE__
__attribute__ ((__gnu_inline__))
#endif
#endif
const char * libc_name_p (const char *, unsigned int);
到
#ifdef __GNUC__
#ifdef __GNUC_STDC_INLINE__
__attribute__ ((__gnu_inline__))
#else
__inline
#endif
#endif
const char * libc_name_p (const char *, unsigned int);
以避免同时具有__inline
和属性(导致错误)。当我用 GCC 9.2 编译 GCC 5.3 时,这对我有用。__gnu_inline__
redeclared inline with 'gnu_inline' attribute
答案3
您可能最终会花费大量时间在当前系统上构建 GCC 4.7,并且最终您仍然不确定结果:您学校计算机的 GCC 版本可能包含分发补丁甚至本地补丁您的版本不会有的更改。
我建议您在虚拟机中运行学校正在使用的发行版。您的学校正在使用 RHEL,您也可以:您可以从以下网站获得免费的开发人员订阅:红帽开发人员;订阅后,您可以下载任何仍受支持的 RHEL 版本的 ISO,因此您应该能够安装与学校计算机上使用的版本相同的版本。
无论如何,由于这是出于评分目的,因此您应该在提交之前在学校计算机上检查您的代码!
答案4
这只是为了“修复”错误。修复后,出现另一个错误。
要解决这个问题 -
在文件./gcc/cp/cfns.gperf第23--26行
#ifdef __GNUC__
__inline
#endif
const char * libc_name_p (const char *, unsigned int);
只需注释掉该ifdef
语句即可。
一个新错误 -
cp/except.o: In function `nothrow_libfn_p':
/home/user/Documents/build/gcc464objdir/gcc/../../gcc-4.6.4/gcc/cp/except.c:932: undefined reference to `libc_name_p'
collect2: error: ld returned 1 exit status