如何处理使用 GCC 6.2.1 编译 GCC 4.7.0 时出现的错误

如何处理使用 GCC 6.2.1 编译 GCC 4.7.0 时出现的错误

我正在使用 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 下并不总是被认为有效

我读到了这里,这里, 和这里

所以我该怎么做才能解决这个问题

我认为两种可行的解决方案:

  1. 使用学校 Linux 计算机(也有 GCC 4.7.0,但它们是 32 位,而我有 64 位操作系统)为我的计算机交叉编译 GCC 4.7.0
  2. 首先在我的电脑上使用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

相关内容