2020/08/09

Winelib使用時にd3d9_main.cのFIXME()でコンパイラの警告が出る件

Wine 5.0.2が出たが、これを書いている時点では公式サイトのUbuntu用バイナリパッケージが公開されていなかったので、Ubuntuのバージョン5.0のソースパッケージを基にして実験的にPPAにアップロードしてみたところ、ソースパッケージ内の既存のパッチは問題なく適用されることが確認できたのだが、以下のようなビルドエラーが出てパッケージ作成に失敗した。

gcc -c -o d3d9_main.o d3d9_main.c -I. -I../../include -I../../include/msvcrt -D__WINESRC__ -D_REENTRANT -fno-PIC -fno-builtin -fshort-wchar -Wall -pipe -fcf-protection=none -fno-stack-protector -fno-strict-aliasing -Wdeclaration-after-statement -Wempty-body -Wignored-qualifiers -Wno-packed-not-aligned -Wshift-overflow=2 -Wstrict-prototypes -Wtype-limits -Wunused-but-set-parameter -Wvla -Wwrite-strings -Wpointer-arith -Wlogical-op -gdwarf-2 -gstrict-dwarf -fno-omit-frame-pointer -Werror -Wdate-time -g -O2 -fdebug-prefix-map=/<>=. -fstack-protector-strong -Wformat -Werror=format-security -fcommon -Wno-shift-overflow -Wno-unused-function -Wno-deprecated-declarations -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0
In file included from d3d9_private.h:36,
                 from d3d9_main.c:25:
d3d9_main.c: In function ‘shader_validator_Begin’:
d3d9_main.c:154:11: error: 'I' flag used with ‘%x’ gnu_printf format [-Werror=format=]
  154 |     FIXME("iface %p, callback %p, context %p, arg3 %#Ix, stub!\n", iface, callback, context, arg3);
      |           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../include/wine/debug.h:89:49: note: in definition of macro ‘__WINE_DBG_LOG’
   89 |     wine_dbg_log( __dbcl, __dbch, __FUNCTION__, args); } } while(0)
      |                                                 ^~~~
../../include/wine/debug.h:480:36: note: in expansion of macro ‘__WINE_DPRINTF’
  480 | #define WINE_FIXME                 __WINE_DPRINTF(_FIXME,__wine_dbch___default)
      |                                    ^~~~~~~~~~~~~~
../../include/wine/debug.h:519:36: note: in expansion of macro ‘WINE_FIXME’
  519 | #define FIXME                      WINE_FIXME
      |                                    ^~~~~~~~~~
d3d9_main.c:154:5: note: in expansion of macro ‘FIXME’
  154 |     FIXME("iface %p, callback %p, context %p, arg3 %#Ix, stub!\n", iface, callback, context, arg3);
      |     ^~~~~
d3d9_main.c:154:55: note: format string is defined here
  154 |     FIXME("iface %p, callback %p, context %p, arg3 %#Ix, stub!\n", iface, callback, context, arg3);
      |                                                       ^
In file included from d3d9_private.h:36,
                 from d3d9_main.c:25:
d3d9_main.c:154:11: error: format ‘%x’ expects argument of type ‘unsigned int’, but argument 8 has type ‘DWORD_PTR’ {aka ‘long unsigned int’} [-Werror=format=]
  154 |     FIXME("iface %p, callback %p, context %p, arg3 %#Ix, stub!\n", iface, callback, context, arg3);
      |           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                            ~~~~
      |                                                                                              |
      |                                                                                              DWORD_PTR {aka long unsigned int}
../../include/wine/debug.h:89:49: note: in definition of macro ‘__WINE_DBG_LOG’
   89 |     wine_dbg_log( __dbcl, __dbch, __FUNCTION__, args); } } while(0)
      |                                                 ^~~~
../../include/wine/debug.h:480:36: note: in expansion of macro ‘__WINE_DPRINTF’
  480 | #define WINE_FIXME                 __WINE_DPRINTF(_FIXME,__wine_dbch___default)
      |                                    ^~~~~~~~~~~~~~
../../include/wine/debug.h:519:36: note: in expansion of macro ‘WINE_FIXME’
  519 | #define FIXME                      WINE_FIXME
      |                                    ^~~~~~~~~~
d3d9_main.c:154:5: note: in expansion of macro ‘FIXME’
  154 |     FIXME("iface %p, callback %p, context %p, arg3 %#Ix, stub!\n", iface, callback, context, arg3);
      |     ^~~~~
d3d9_main.c:154:55: note: format string is defined here
  154 |     FIXME("iface %p, callback %p, context %p, arg3 %#Ix, stub!\n", iface, callback, context, arg3);
      |                                                    ~~~^
      |                                                       |
      |                                                       unsigned int
      |                                                    %#Ilx

...

cc1: all warnings being treated as errors
make[2]: *** [Makefile:196: d3d9_main.o] Error 1

試行錯誤の末に

(This patch is Public Domain)
--- a/dlls/d3d9/d3d9_main.c
+++ b/dlls/d3d9/d3d9_main.c
@@ -151,7 +151,7 @@ static ULONG WINAPI shader_validator_Release(IDirect3DShaderValidator9 *iface)
 static HRESULT WINAPI shader_validator_Begin(IDirect3DShaderValidator9 *iface,
         shader_validator_cb callback, void *context, DWORD_PTR arg3)
 {
-    FIXME("iface %p, callback %p, context %p, arg3 %#Ix, stub!\n", iface, callback, context, arg3);
+    FIXME("iface %p, callback %p, context %p, arg3 %#x, stub!\n", iface, callback, context, (unsigned int)arg3);
 
     return S_OK;
 }

という修正でビルドには成功したが、mingw-w64では

#include <stdio.h>
#include <windows.h>

int
main()
{
    DWORD_PTR a = 1;
    printf("%#Ix\n", a);
    return 0;
}

上のコードのようなフォーマット指定を普通に受け付けており、コンパイラの警告やエラーは出ないため、Wineのライブラリ部分(include/basetsd.hあたり?)に互換性の怪しい部分があるような気もする。

使用したバージョン:
  • Wine 5.0.2
  • GCC 9.3.0-10ubuntu2 (ネイティブ), 9.3-win32 20200320 (mingw-w64のクロスコンパイラ)