在MinGW/MSYS上编译GCC 4.x.x失败了。

4
我已经尝试了最近一周左右,编译GCC 4系列编译器以在MinGW 5.1.6 / MSYS 1.0.11(均来自Sourceforge.org的自动安装程序)中运行,该版本附带GCC版本3.4.5。最终目标是安装GCC 4.5,但我无法构建任何4.x.x编译器。
我将其缩小为一系列构建说明,导致一些不寻常的行为。编译器执行以下操作:
build/genmodes.exe > tmp-modes.c
/bin/sh ../../gcc-4.2.4/gcc/../move-if-change tmp-modes.c insn-modes.c
echo timestamp > s-modes
gcc -c   -g -fkeep-inline-functions -DIN_GCC   -W -Wall -Wwrite-strings
-Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -Wmissing-format-attribute
-fno-common   -DHAVE_CONFIG_H -I. -I. -I../../gcc-4.2.4/gcc -I../../gcc-4.2.4/gcc/.
-I../../gcc-4.2.4/gcc/../include -I./../intl -I../../gcc-4.2.4/gcc/../libcpp/include
-I../../gcc-4.2.4/gcc/../libdecnumber -I../libdecnumber    insn-modes.c -o insn-modes.o

cc1.exe: out of memory allocating 2239725803 bytes
make[3]: *** [insn-modes.o] Error 1
make[3]: Leaving directory `/home/root/gcc-4.2.4-build/gcc'
make[2]: *** [all-stage1-gcc] Error 2
make[2]: Leaving directory `/home/root/gcc-4.2.4-build'
make[1]: *** [stage1-bubble] Error 2
make[1]: Leaving directory `/home/root/gcc-4.2.4-build'
make: *** [all] Error 2

主要问题似乎是对genmodes.exe的调用。它会生成一个约2GB大小的C文件(insn-modes.c),据我所知,该文件主要由空格填充(尽管偶尔有一些C代码行)。GCC 3.4.5在此处出现故障,并以此结束构建。我尝试过所有版本,都出现了类似的情况,除了4.5版本,但其失败原因希望通过使用编译器的中间版本来解决。

所以,三个问题:

  1. 还有其他人遇到过这个问题吗?
  2. 是什么导致了这个问题?
  3. 如果有的话,是否存在任何解决方法?

我正在尝试在64位Windows 7机器上完成这个操作。

谢谢。

更新:我已将两个可疑文件的压缩副本上传到this location.。结果发现min-insn-modes.c也比它应该的大小要大。这两个文件(总计超过3GB)压缩后为121KB。

3个回答

3

我有同样的问题;我已经将它缩小到genmodes.c中的tagged_printf。我仍然不知道为什么它失败了,但是用以下内容替换tagged_printf的定义(从do到包括while)解决了这个问题:

#define tagged_printf(FMT, ARG, TAG) printf(" " FMT ",\n", ARG)


2

insn-modes.c不应该过于庞大或充满空白;genmodes出现了故障。我不知道为什么会出现这种故障,但如果您将其放入.zip文件中(这样可以将它缩小到您可以合理地上传到某个地方并将URL编辑到您的问题中),我会非常好奇地查看insn-modes.c。

手动剥离文件中所有额外的空白(tr -s' \r\n\t\v\f'' ')可能会得到一些可编译的东西。

编辑:我查看了您上传的min-insn-modes.c,并且我认为Bryan是对的,在中存在一个错误:每次调用它时,它都会发出大约700万个空格字符。 Bryan的更改应该可以让您跨越这个障碍,或者您可以通过将定义更改为以下内容来帮助进一步调查:

#define tagged_printf(FMT, ARG, TAG) do { \
    int count_ = printf (" " FMT ",", ARG); \
    printf ("\t/* %s [%d], */\n", TAG, count_); \
} while (0)

这应该可以让您的构建成功,我希望看到min-insn-modes.c做出这个改变。(insn-modes.c也没有必要)

补充: 请查看emit_insn_modes_h()函数。它还包含了带有%n格式说明符的printf语句,需要类似上面的修改:

int count_ = printf ("  %smode,", m->name);

如果不进行这个更改,insn-modes.h 也会被填满大量的空格。


我更新了问题并发布了两个可疑文件(min-insn-modes.c和insn-modes.c)的zip链接。 - andand
andand:我更新了我的答案,有一个新的东西让你尝试,如果你不介意的话。 - zwol
这两个代码都编译通过了。我很喜欢这个建议,因为它更接近原始的genmodes.c源代码。 - andand
我认为你可能误解了我的建议 - 它避免了错误,但它也会对代码进行仪器化,以便我们可以找出错误并让GCC开发人员修复它。我想再次看到min-insn-modes.c,并使用我的更改生成。 - zwol

2

MSDN文档中提到:

安全提示: %n格式本质上是不安全的,因此默认情况下已被禁用。如果在格式字符串中遇到%n,则会调用无效参数处理程序,具体请参见参数验证。要启用%n支持,请参阅_set_printf_count_output

因此,使用_set_printf_count_output(1)可以解决这个问题。 是的,这很糟糕。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接