4

上周左右我一直在尝试编译任何 GCC 4 系列编译器以在 GCC 版本 3.4.5 附带的 MinGW 5.1.6 / MSYS 1.0.11(来自 Sourceforge.org 的自动安装程序)中运行. 最终目标是安装 GCC 4.5,但我无法构建任何 4.xx 编译器。

我已将其范围缩小为导致某些异常行为的构建指令序列。编译器执行:

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 机器上执行此操作。

谢谢。

更新:我已将两个可疑文件的压缩副本上传到此位置。 事实证明 min-insn-modes.c 也比它应该的大。这两个文件(总共超过 3GB)压缩到 121KB。

4

3 回答 3

3

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

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

于 2010-07-24T21:12:12.430 回答
2

insn-modes.c 不应很大或充满空格;genmodes 出现故障。我不知道为什么它会那样失败,但我很想看看 insn-modes.c (如果你把它放在一个 .zip 文件中,它应该把它缩小到你可以合理地将其上传到某处并将URL编辑到您的问题中)。

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

编辑:我查看了您上传的 min-insn-modes.c,我认为 Bryan 是对的,其中有一个错误tagged_printf:每次调用它时,它都会发出大约 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也会充满大量空间。

于 2010-07-24T05:55:31.840 回答
2

MSDN 文档是这样说的:

安全说明 %n 格式本质上是不安全的,默认情况下是禁用的;如果在格式字符串中遇到 %n,则调用无效的参数处理程序,如参数验证中所述。要启用 %n 支持,请参阅_set_printf_count_output

所以 _set_printf_count_output(1) 应该可以解决这个问题。是的,这很糟糕。

于 2010-08-09T10:28:08.997 回答