開発中のGtk3/Cによるベクターグラフィック・エディタであるvecterionの、Windowsx64ターゲット、Linuxホストでクロスビルド作業中。
とりあえず動作するところまでは行きました。
その時のトライアンドエラーというか問題と解決のざっとしたメモです。
Windowsターゲットビルドはvecterionにとってあくまでおまけなのだけれど、Linuxターゲットで開発していてコード中に甘かった箇所がいくつかあり(ex. フォーマット文字列中のsize_tの変換指定を%zuにしていなかったなど)、ついでに修正することができた。
原因を追い切ってはいません。Windows版の優先度はその程度です。
#### 解決方法をメモし忘れたエラー error: unknown type name ‘uid_t’
詳細を忘れてしまった。
確かMinGW64のWindowsターゲットクロスビルドであるにも関わらず、pkg-configがLinuxのライブラリをリンクして、起こっていたような気がする。
http://stackoverflow.com/questions/32282270/c99-error-unknown-type-name-pid-t
```
In file included from /usr/lib/x86_64-linux-gnu/glib-2.0/include/glibconfig.h:9:0,
from /usr/include/glib-2.0/glib/gtypes.h:32,
from /usr/include/glib-2.0/glib/galloca.h:32,
from /usr/include/glib-2.0/glib.h:30,
from /usr/include/gtk-3.0/gdk/gdkconfig.h:13,
from /usr/include/gtk-3.0/gdk/gdk.h:30,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from ./include/et_pointing_manager.h:4,
from source/et_pointing_manager.c:1:
/usr/include/glib-2.0/glib/gtypes.h: In function ‘_GLIB_CHECKED_ADD_U64’:
/usr/include/glib-2.0/glib/gmacros.h:232:53: error: size of array ‘_GStaticAssertCompileTimeAssertion_0’ is negative
#define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] G_GNUC_UNUSED
^
/usr/include/glib-2.0/glib/gmacros.h:229:47: note: in definition of macro ‘G_PASTE_ARGS’
#define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2
^
/usr/include/glib-2.0/glib/gmacros.h:232:44: note: in expansion of macro ‘G_PASTE’
#define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] G_GNUC_UNUSED
^
/usr/include/glib-2.0/glib/gtypes.h:422:3: note: in expansion of macro ‘G_STATIC_ASSERT’
G_STATIC_ASSERT(sizeof (unsigned long long) == sizeof (guint64));
^
In file included from /usr/include/glib-2.0/gio/gio.h:46:0,
from /usr/include/gtk-3.0/gdk/gdkapplaunchcontext.h:28,
from /usr/include/gtk-3.0/gdk/gdk.h:32,
from /usr/include/gtk-3.0/gtk/gtk.h:30,
from ./include/et_pointing_manager.h:4,
from source/et_pointing_manager.c:1:
/usr/include/glib-2.0/gio/gcredentials.h: At top level:
/usr/include/glib-2.0/gio/gcredentials.h:75:1: error: unknown type name ‘uid_t’
uid_t g_credentials_get_unix_user (GCredentials *credentials,
^
/usr/include/glib-2.0/gio/gcredentials.h:79:52: error: unknown type name ‘uid_t’
uid_t uid,
^
Makefile:60: ターゲット 'object/win/et_pointing_manager.o' のレシピで失敗しました```
```
58 export PKG_CONFIG_PATH=${GTK3LIBRARY_DIR}/lib/pkgconfig¬
59 make TARGET_ARCH=win CC=x86_64-w64-mingw32-gcc CFLAGS_APPEND=${CFLAGS_APPEND} INCLUDE_APPEND="-m windows"¬```
#### pkg-configで生成したビルドオプションの[-Werror=missing-include-dirs]
一時的にチェックフラグを解除して回避
最終的にビルドスクリプトを変更し、pkg-config(*.pc設定ファイル)が正しいパスを指すよう修正して解決
```
cc1: error: /srv/win32builder/fixed_3104/build/win64/include/freetype2: そのようなファイルやディレクトリはありません [-Werror=missing-include-dirs]
cc1: error: /srv/win32builder/fixed_3104/build/win64/include/libxml2: そのようなファイルやディレクトリはありません [-Werror=missing-include-dirs]
cc1: error: /srv/win32builder/fixed_3104/build/win64/include/freetype2: そのようなファイルやディレクトリはありません [-Werror=missing-include-dirs]
cc1: all warnings being treated as errors
Makefile:60: ターゲット 'object/win/et_pointing_manager.o' のレシピで失敗しました```
``` packaging_win64.sh
42 >-------pushd ${GTK3LIBRARY_DIR}¬
43 ¬
44 >-------unzip ${CACHE_DIR}/gtk+-bundle_3.10.4-20131202_win64.zip > /dev/null¬
45 >-------find -name '*.pc' | while read pc; do sed -e "s@^prefix=.*@prefix=$PWD@" -i "$pc"; done¬
46 >-------find -name '*.pc' | while read pc; do sed -e "s@/srv/win32builder/fixed_3104/build/win64 @$PWD@g" -i "$pc"; done¬
47 >-------sed -e "s@Z:/srv/win32builder/fixed_3104/build/win32/@@g" -i "lib/gdk-pixbuf-2.0/2.10.0/ loaders.cache"¬
48 ¬
49 >-------popd¬```
#### mingwがswitch defaultに置いたassert(false)を解釈してくれない
「到達しないソース行」の検出あたりが、linuxのgccとMinGWで違うようで(バージョンの違いかもしれない)、リターンエラーのメッセージが出る。
assert()のラッパを、新規作成したabort()のラッパ関数に置き換えて解決。
```
source/pv_type.c: In function ‘pv_rect_get_edge_point’:
source/pv_type.c:202:1: error: control reaches end of non-void function [-Werror=return-type]
}
^
cc1: all warnings being treated as errors```
```
195 >------->-------case PvRectEdgeKind_DownLeft:¬
196 >------->------->-------return (PvPoint){rect.x, (rect.y + rect.h)};¬
197 >------->-------case PvRectEdgeKind_DownRight:¬
198 >------->------->-------return (PvPoint){(rect.x + rect.w), (rect.y + rect.h)};¬
199 >------->-------default:¬
200 >------->------->-------pv_assertf(false, "%d", edgeKind);¬
201 >-------}¬
202 }¬```
```
200 >------->------->-------pv_abortf("%d", edgeKind);¬```
#### size_t型のリテラル間違い
size_tを"%lu"のままにしてしまうミス。
修正後、正しい指定の"%zu"を受け付けない。
一時的には、出力を潰して対処した。
最終的に、`-posix` 追加で"%zu"が使えるようになり解決。
```
- pv_debug("len:%lu '%s'", strlen(src), src);
+ pv_debug("len: '%s'", /*strlen(src),*/ src);```
#### sscanfの非C11標準(posix標準)リテラルの使用
sscanf()にて、リテラル記述に"%m"が存在しないとされて使えない。
-D_GNU_SOURCE=1 は効果なし。
gcc(MinGW)のバージョンが原因でもないように見えた。
最終的に、`-posix` 追加で解決。
```
source/pv_io.c: In function ‘_new_css_str_maps_from_str’:
source/pv_io.c:450:24: error: unknown conversion type character ‘m’ in format [-Werror=format=]
if(2 != sscanf(head, " %m[^:;] : %m[^;]", &skey, &svalue)){
^
source/pv_io.c:450:24: error: unknown conversion type character ‘m’ in format [-Werror=format=]```
http://linuxjm.osdn.jp/html/LDP_man-pages/man3/scanf.3.html
http://stackoverflow.com/questions/11926883/scanf-dynamic-allocation
`I don't see anything about m flag in my copy of C11 (which is, admittedly, a draft).`
http://grokbase.com/t/postgresql/pgsql-hackers/114vq5qrhn/unknown-conversion-m
`Hmm. The error disappears if I use -D__USE_MINGW_ANSI_STDIO=1 or -posix`
#### libxml2の引数型の間違い
関数の引数の型が合わないビルドエラー。
Web上のドキュメントではconst付きで記載されているが、実際にヘッダのソースコードを当たってみると、constなしになっている。
constを外して解決。
```
source/pv_io.c:450:24: error: too many arguments for format [-Werror=format-extra-args]
source/pv_io.c: In function ‘_overwrite_conf_read_svg_from_xmlnode’:
source/pv_io.c:534:32: error: passing argument 1 of ‘xmlGetProp’ discards ‘const’ qualifier from pointer target type [-Werror=discarded-qualifiers]
xmlChar *xc_fill = xmlGetProp(xmlnode, BAD_CAST "fill");```
http://xmlsoft.org/html/libxml-tree.html#xmlGetProp
#### libgtk3 for windowsの古いバージョンの未実装関数
gtk3-3.10.4がこの関数を未実装であるためエラー。
同名のラッパ関数を定義、またはターゲットにより関数呼び出しを取り除くマクロを定義して解決。
```
source/et_canvas_collection.c: In function ‘et_canvas_collection_delete_canvases_from_doc_id’:
source/et_canvas_collection.c:250:3: error: implicit declaration of function ‘gtk_notebook_detach_tab’ [-Werror=implicit-function-declaration]
gtk_notebook_detach_tab(GTK_NOTEBOOK(self->widget_tab), canvas_frame);```
https://mail.xfce.org/pipermail/xfce4-commits/2016-June/071144.html
```
source/et_layer_view.c:148:2: error: implicit declaration of function ‘gtk_text_view_set_monospace’ [-Werror=implicit-function-declaration]
gtk_text_view_set_monospace (GTK_TEXT_VIEW(self->text), TRUE);```
#### libgtkのsvgのローダ
svgが開かない
以前も見ていた不具合。
相対パスへの書き換えとライブラリの追加パッケージングで解決。
```
sed -e "s@Z:/srv/win32builder/fixed_3104/build/win32/@@g" -i "lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
${GTK3LIBRARY_DIR}/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.dll
${GTK3LIBRARY_DIR}/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache```
#### Windows環境でのマウスポインタ変更
windowへのポインタを取ろうとして、Windows環境で取れないため、マウスカーソル周りの処理でエラー。
マウスカーソル周りをWindowsターゲットのビルドで無効にして一時的に解決。
その後、あらためて確認したらビルドが通りました。ヘッダなどが必要だったのかもしれない。
```
(vecterion_vge.exe:4292): Gdk-CRITICAL **: gdk_screen_get_root_window: assertion 'GDK_IS_SCREEN screen)' failed
(vecterion_vge.exe:4292): Gdk-CRITICAL **: gdk_window_new: assertion 'GDK_IS_WINDOW (parent)' failed
(vecterion_vge.exe:4292): Gdk-WARNING **: gdk_input_wintab_init: gdk_window_new failed```
#### libgtkで一部のダイアログを出すのに必要なファイルの追加
Save操作時にエラーダイアログ。
パッケージにschemasファイルを追加して解決。
```
GLib-GIO-ERROR**: No GSettings schemas are installed on the system```
```
76 mkdir -p ${PACKAGE_DIR}/share/glib-2.0/¬
77 cp -r ${GTK3LIBRARY_DIR}/share/glib-2.0/schemas ${PACKAGE_DIR}/share/glib-2.0/¬```
http://stackoverflow.com/questions/28953925/glib-gio-error-no-gsettings-schemas-are-installed-on-the-system