在 Cygwin 跨平台编译 GTK+ 程序

Cygwin 是一套在 Windows 平台上运行的类 Unix 模拟环境。通过 Cygwin 可以将一些开源程序编译到 Windows 中运行。与 Cygwin 类似还有一套工具叫做 MinGW,不过现在 Cygwin 已经可以包含 MinGW 了。

由于 Cygwin 是模拟类 Unix 环境。所以在其中编译的程序依然无法脱离 Cygwin 环境而运行,也就是说你不能直接从 Windows 中通过双击来运行。但是 MinGW 可以生成原生 Windows 程序而不需要第三运行时,即你可以从 Windows 的资源管理器中直接双击运行。

对于拥有 GUI 的跨平台程序在 Cygwin 中编译运行需要安装 Cygwin/X 。但在这里要介绍的主要是在 Cygwin 中通过 MinGW 编译程序,故 Cygwin/X 的使用不做说明。

一、安装 MinGW 环境

MinGW-x86_64 通过 MSYS2 也可以安装并且 MSYS2 支持 pacman 包管理程序。但是这里主要介绍的是在 Cygwin 中安装。确保已经安装里基本的 Cygwin 环境,当然你也可以一次安装。打开 Cygwin 管理器,并勾选以下程序包:1.1

  • mingw64-x86_64-gcc-core

  • mingw64-x86_64-gcc-g++

  • mingw64-x86_64-glib2.0

  • mingw64-x86_64-gtk3

  • mingw64-x86_64-pkg-config

  • mingw64-x86_64-adwaita-icon-theme

勾选这6个包安装时会自动安装所有依赖包。安装好之后 MinGW64 的编译环境就安装好了。

二、编译GTK程序

通过以下命令编译 GTK+ 程序即可,务必使用 x86_64-w64-mingw32-gcc 和 x86_64-w64-mingw32-pkg-config 而不要使用 gcc 和 pkg-config 程序,这两个程序是 cygwin 的。

1
$ x86_64-w64-mingw32-gcc <source files> `x86_64-w64-mingw32-pkg-config --cflags --libs gtk+-3.0`
1.2

三、运行环境

1. 添加系统环境变量

将 \\usr\x86_64-w64-mingw32\sys-root\mingw\bin 添加的系统环境变量中就可以直接从 Windows 中双击运行了。

2. 独立抽取dll

运行所需的 DLL 都在上述添加到系统环境的路径中,只需将所需 DLL 复制出来放到和应用程序同一目录下即可不用修改系统环境变量运行 GTK 程序。GTK 所需 DLL 如下所示:
etc、libcairo-gobject-2.dll、libgdk_pixbuf-2.0-0.dll、libharfbuzz-0.dll、libpixman-1-0.dll、libepoxy-0.dll、libgdk-3-0.dll、libintl-8.dll、libpng16-16.dll、iconv.dll、libexpat-1.dll、libgio-2.0-0.dll、libpango-1.0-0.dll、libwinpthread-1.dll、lib、libffi-6.dll、libglib-2.0-0.dll、libpangocairo-1.0-0.dll、share、libatk-1.0-0.dll、libfontconfig-1.dll、libgmodule-2.0-0.dll、libpangoft2-1.0-0.dll、zlib1.dll、libbz2-1.dll、libfreetype-6.dll、libgobject-2.0-0.dll、libpangowin32-1.0-0.dll、libcairo-2.dll、libgcc_s_seh-1.dll、libgtk-3-0.dll、libpcre-1.dll

其中 etc 、lib、share为目录文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
➜  FuncPlotter find etc                                          # settings 配置文件
etc
etc/gtk-3.0
etc/gtk-3.0/settings.ini
➜ FuncPlotter find lib
lib # pixbuf cache 文件
lib/gdk-pixbuf-2.0
lib/gdk-pixbuf-2.0/2.10.0
lib/gdk-pixbuf-2.0/2.10.0/loaders.cache
➜ FuncPlotter find share # 图标
share
share/icons
share/icons/Adwaita
share/icons/Adwaita/16x16
share/icons/Adwaita/16x16/actions
share/icons/Adwaita/16x16/actions/action-unavailable-symbolic.symbolic.png
......

没有这三个目录也可以运行程序,问题不大。

1.3

四、注意

zlib1.dll 是被 libpng.dll 所依赖,故 gtk 程序在没有zlib1.dll 文件时不会提示缺少 zlib1.dll。而会提示 "无法定位程序输入点 inflateReset2 于动态链接库 libpng16-16.dll"错误。(google了好久才发现T_T)