win64アプリケーションクロスビルドでアイコン・プロパティ・リソースを付ける

Gtk3/Cで書いたベクターグラフィック・エディタのvecterionを、Ubuntu16.04ホストでwin64ターゲットにクロスビルド中。でアイコン・プロパティ・リソースを付けた作業のメモです。


以下のようなコードで実現できます。

# .rcほか、リソースファイルを用意する 

実際に必要なのは```IDI_ICON ICON ~```行だけです。
そのICONこれも実は文字列"ICON"とファイルパス以外は大した意味はないとか、他にもオプションが付けられるとかあるようです。
Win32アプリケーションプログラミングをマスターしたいわけではないので.rcファイルの記述はスルー。
.icoファイルですが、GIMPでいい加減に縮小するだけならいい加減に作れます。PNG透過の正方形画像を、512px, 64px,32px,16pxの順にレイヤ複製->レイヤ縮小を繰り返して、最後に.icoで保存しようとすると、アイコン形式画像を保存するウィザードが出てきてGIMPが良いようにしてくれます。
(64pxは48pxのほうがいいかもしれないけれどしていません。512pxもMacOSX対応にしては中途半端。)


Ubuntu16.04環境ではnautilusもeogもこの.icoを正しく描画できませんでしたが、Windowsではとしてはきちんとアプリケーションアイコンとして表示されたので問題ありません。

```
diff --git a/deploy/win/vecterion.rc b/deploy/win/vecterion.rc
new file mode 100644
index 0000000..ed229c3
--- /dev/null
+++ b/deploy/win/vecterion.rc
@@ -0,0 +1,24 @@
+#include <windows.h>
+
+//ICON
+IDI_ICON1 ICON DISCARDABLE "deploy/win/vecterion_icon.ico"
+
+1 VERSIONINFO
+FILEVERSION     0,0,0,1
+PRODUCTVERSION  0,0,0,1
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "080904E4"
+        BEGIN
+            VALUE "InternalName",        "vecterion_vge"
+            VALUE "OriginalFilename",     "vecterion_vge.exe"
+            VALUE "ProductName",        "vecterion_vge"
+            VALUE "ProductVersion",        "0.0.0.1"
+            VALUE "FileVersion",        "0.0.0.1"
+            VALUE "CompanyName",        "project daisy bell"
+            VALUE "LegalCopyright",        "Michinari.Nukazawa"
+            VALUE "FileDescription", "Vecterion, the true vector graphics editor for linux (and other)."
+        END
+    END
+END
diff --git a/deploy/win/vecterion_icon.ico b/deploy/win/vecterion_icon.ico
new file mode 100644
index 0000000..bf8ade4
Binary files /dev/null and b/deploy/win/vecterion_icon.ico differ
diff --git a/deploy/win/vecterion_icon.xcf b/deploy/win/vecterion_icon.xcf
new file mode 100644
index 0000000..7ba9088
Binary files /dev/null and b/deploy/win/vecterion_icon.xcf differ

```

# Windowsリソースのオブジェクト作成します。

クロスビルドはbashスクリプトにしています。

ここでリソース(.rc テキストのソース)をwindresでオブジェクトに変換します。
Makefileに入れるより楽そうで、やってみると、ビルド時間にほぼ影響がなかったので。
```
+# make resource(icon and other)
+TARGET_ARCH_WIN_RESOURCE=${OBJECT_DIR}/vecterion.res
+x86_64-w64-mingw32-windres ${ROOT_DIR}/deploy/win/vecterion.rc -O coff -o ${TARGET_ARCH_WIN_RESOURCE}
+


 # build app source
 CFLAGS_APPEND=-Wno-missing-include-dirs

 [ -d ${GTK3LIBRARY_DIR}/lib/pkgconfig ]
 export PKG_CONFIG_PATH=${GTK3LIBRARY_DIR}/lib/pkgconfig
-make TARGET_ARCH=win CC=x86_64-w64-mingw32-gcc CFLAGS_APPEND=${CFLAGS_APPEND} INCLUDE_APPEND="-mwindows"
+make TARGET_ARCH=win CC=x86_64-w64-mingw32-gcc CFLAGS_APPEND=${CFLAGS_APPEND} INCLUDE_APPEND="-mwindows" TARGET_ARCH_WIN_RESOURCE=${TARGET_ARCH_WIN_RESOURCE}

```



# リソースのオブジェクトをリンクします。

Windowsクロスビルド以外ではリソースのオブジェクトのパスを空文字にします。```
diff --git a/Makefile b/Makefile
index 4f859f1..0aa22f9 100644
--- a/Makefile
+++ b/Makefile
@@ -71,6 +71,7 @@ $(APP_FILE) : $(OBJECTS)
     $(CC) \
         $^ \
         $(OBJECT_DIR)/version.c \
+        $(TARGET_ARCH_WIN_RESOURCE) \
         $(CFLAGS) \
         $(INCLUDE) \
         -o $(APP_FILE)


```



gtk3アプリケーションのクロスビルド(Windowsターゲット、Linuxホスト)した際のメモ

開発中の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




TIGORA(ティゴラ)のトレッキング シューズ

 TIGORA(ティゴラ)の トレッキング シューズを買いました。 メインの靴がアシックスウォーキングで街歩き用なのですが、これまではこれで高尾山などの軽い山も登っていました。 今回、靴底があまりに摩耗したこともあってアシックスウォーキングを買い替えたのですが、ついでに消耗が激...