Configuring qemu build results in an "Error: configure test passed without -Werror but failed with -Werror."

Configuring qemu build results in an "Error: configure test passed without -Werror but failed with -Werror."

我正在尝试从源代码构建 qemu,我使用 ./configure --enable-capstone --enable-tcg-plugin --target-list=x86_64-linux-user 在使用 make 构建之前对其进行配置。

这会导致以下错误:

ERROR: configure test passed without -Werror but failed with -Werror.
       This is probably a bug in the configure script. The failing command
       will be at the bottom of config.log.
       You can run configure with --disable-werror to bypass this check.

这是 config.log 文件的底部:

config-temp/qemu-conf.c: In function ‘main’:
config-temp/qemu-conf.c:2:25: warning: null argument where non-null required (argument 1) [-Wnonnull]
    2 | int main(void) { return sem_timedwait(0, 0); }
      |                         ^~~~~~~~~~~~~
config-temp/qemu-conf.c:2:25: warning: null argument where non-null required (argument 2) [-Wnonnull]
cc -Werror -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -fPIE -DPIE -m64 -mcx16 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv -Wno-error=address-of-packed-member -Wexpansion-to-defined -Wendif-labels -Wno-shift-negative-value -Wno-missing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-strong -I/usr/include/capstone -o config-temp/qemu-conf.exe config-temp/qemu-conf.c -Wl,-z,relro -Wl,-z,now -pie -m64 -g
config-temp/qemu-conf.c: In function ‘main’:
config-temp/qemu-conf.c:2:25: error: null argument where non-null required (argument 1) [-Werror=nonnull]
    2 | int main(void) { return sem_timedwait(0, 0); }
      |                         ^~~~~~~~~~~~~
config-temp/qemu-conf.c:2:25: error: null argument where non-null required (argument 2) [-Werror=nonnull]
cc1: all warnings being treated as errors
~                                                                                                                                                                                                                  
~                                      

我也试过--disable-werror,这个configure很好,但是建不起来。构建时出现以下错误:

/home/p/Desktop/qemu-plugins-tutorial/qemu/linux-user/syscall.c:256:16: error: static declaration of ‘gettid’ follows non-static declaration
  256 | _syscall0(int, gettid)
      |                ^~~~~~
/home/p/Desktop/qemu-plugins-tutorial/qemu/linux-user/syscall.c:187:13: note: in definition of macro ‘_syscall0’
  187 | static type name (void)   \
      |             ^~~~
In file included from /usr/include/unistd.h:1170,
                 from /home/p/Desktop/qemu-plugins-tutorial/qemu/include/qemu/osdep.h:90,
                 from /home/p/Desktop/qemu-plugins-tutorial/qemu/linux-user/syscall.c:20:
/usr/include/x86_64-linux-gnu/bits/unistd_ext.h:34:16: note: previous declaration of ‘gettid’ was here
   34 | extern __pid_t gettid (void) __THROW;
      |                ^~~~~~
/home/p/Desktop/qemu-plugins-tutorial/qemu/linux-user/ioctls.h:224:9: error: ‘SIOCGSTAMP’ undeclared here (not in a function); did you mean ‘SIOCSRARP’?
  224 |   IOCTL(SIOCGSTAMP, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timeval)))
      |         ^~~~~~~~~~
/home/p/Desktop/qemu-plugins-tutorial/qemu/linux-user/syscall.c:4756:23: note: in definition of macro ‘IOCTL’
 4756 |     { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
      |                       ^~~
/home/p/Desktop/qemu-plugins-tutorial/qemu/linux-user/ioctls.h:225:9: error: ‘SIOCGSTAMPNS’ undeclared here (not in a function); did you mean ‘SIOCGSTAMP_OLD’?
  225 |   IOCTL(SIOCGSTAMPNS, IOC_R, MK_PTR(MK_STRUCT(STRUCT_timespec)))
      |         ^~~~~~~~~~~~
/home/p/Desktop/qemu-plugins-tutorial/qemu/linux-user/syscall.c:4756:23: note: in definition of macro ‘IOCTL’
 4756 |     { TARGET_ ## cmd, cmd, #cmd, access, 0, {  __VA_ARGS__ } },
      |                       ^~~
  CC      x86_64-linux-user/linux-user/strace.o
make[1]: *** [/home/p/Desktop/qemu-plugins-tutorial/qemu/rules.mak:69: linux-user/syscall.o] Error 1
make[1]: *** Waiting for unfinished jobs....
  LINK    qemu-img
make: *** [Makefile:484: subdir-x86_64-linux-user] Error 2

可能的解决方法是什么?

这是因为您正在尝试针对较新的 glibc 构建相当旧的 QEMU 版本。有时 glibc 头文件的更改会导致用于编译的 QEMU 代码出错,因此更改 QEMU 以避免该问题。在这种特定情况下,当 glibc 2.29(或类似版本)添加一个 gettid() 函数时,这破坏了 QEMU 代码中定义其自己的同名函数的部分。 QEMU commit 71ba74f67eaca21b,从 2019 年 3 月开始,是针对该问题的上游修复。

虽然简单的解决方法是:不要尝试构建非常旧的 QEMU:构建最新版本。

如果您出于某种原因确实需要在较新的发行版上构建旧的 QEMU,您应该准备好修复或解决这种形式的一些构建错误。一些使这更容易的技巧:

  • 如果您可以选择主机发行版,请避免使用最前沿的发行版(例如,较旧的 Ubuntu LTS 比最新的 Fedora 问题更少)
  • 如果您不关心正在崩溃的代码位中的功能,请使用配置选项禁用它(在这种情况下,除非您需要用户模式模拟器,否则您可以使用合适的 - -目标列表设置)
  • 搜索上游 QEMU git 提交日志和 qemu-devel 邮件列表存档以查找您看到的错误消息:通常您会找到修复程序,然后您可以挑选或调整它以适应您必须构建的版本