Windows 求生手冊:建置 C/C++ 編譯環境

到 msys2 官網,根據 CPU 的位元數下載相對應的 msys2 安裝程式,按照指示安裝即可。在 64 位元的系統,不需刻意選 32 位元的 msys2 安裝程式,在 64 位元的 msys2 中即同時包含 32 和 64 位元的套件。

使用 msys2 時,實際上我們有兩種終端機環境:

  • cmd:原生的 Windows 終端機環境,用於編譯 Windows 原生軟體和其他任務
  • msys:特殊的子系統,僅用於編譯和安裝套件

我們要安裝套件時,會使用 msys 環境,而要編譯 Windows 原生軟體時,就會回到 cmd 環境。

開啟一個 msys 視窗,更新系統的核心組件:

$ pacman -Syu

更新完成後,重開 msys 視窗,更新其他部分:

$ pacman -Sy

msys2 的套件有三種字首:

  • mingw-w64-i686:32 位元套件 (mingw32)
  • mingw-w64-x86_64:64 位元套件 (mingw64)
  • 無字首:僅用於 msys 環境中 (msys)

用以下指令搜尋套件:

$ pacman -Ss gcc

用以下指令安裝 C/C++ 編譯器和其他常見的開發工具:

$ pacman -S mingw-w64-x86_64-toolchain

安裝好開發工具後,將相對應的路徑加入 PATH 變數,以 64 位元工具來說,將 C:\msys64\mingw64\bin 加入即可。

開啟 cmd 終端機,檢查 GCC 版本:

C:\> gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=(省略部分內容)
Target: x86_64-w64-mingw32
Configured with: (省略部分內容)
Thread model: posix
gcc version 7.2.0 (Rev1, Built by MSYS2 project)

如果出現某個 GCC 版本,代表 C/C++ 編譯環境建置成功。

除了提供 C/C++ 編譯環境外,msys2 還將一些常見的 C/C++ 函式庫包裝成套件,簡化編譯套件的過程。在這裡,我們以 GTK+3 為例,說明如何使用 msys2 套件。

開啟 msys2 視窗,下載 64 位元版本的 GTK+3 套件:

$ pacman -S mingw-w64-x86_64-gtk3

在這裡,我們用 Go 社群的 gotk3 套件來展示使用套件的過程。請讀者先自行安裝 Go,再下載 gotk3 套件:

C:\> go get github.com/gotk3/gotk3/gtk

在這裡,以一個小型的視窗程式來試我們裝好的套件:

package main

import (
	"github.com/gotk3/gotk3/gtk"
	"log"
)

func main() {
	// Initialize GTK without parsing any command line arguments.
	gtk.Init(nil)

	// Create a new toplevel window, set its title, and connect it to the
	// "destroy" signal to exit the GTK main loop when it is destroyed.
	win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
	if err != nil {
		log.Fatal("Unable to create window:", err)
	}
	win.SetTitle("Simple Example")
	win.Connect("destroy", func() {
		gtk.MainQuit()
	})

	// Create a new label widget to show in the window.
	l, err := gtk.LabelNew("Hello, gotk3!")
	if err != nil {
		log.Fatal("Unable to create label:", err)
	}

	// Add the label to the window.
	win.Add(l)

	// Set the default window size.
	win.SetDefaultSize(800, 600)

	// Recursively show all widgets contained in this window.
	win.ShowAll()

	// Begin executing the GTK main loop.  This blocks until
	// gtk.MainQuit() is run. 
	gtk.Main()
}

編譯此程式後執行:

C:\> go build demo.go
C:\> .\demo.exe

要注意的是,如果在電腦上裝多套 C/C++ 編譯環境及一些函式庫,像是 Strawberry Perl 內附的 GCC,要把 msys2 所在的路徑向前移,才會正確呼叫到相對應的函式庫。