こんにちは!開発環境アーキテクトの先輩です。
普段、WindowsでC/C++の開発をしていると、「どうしてもあのオープンソースのライブラリを使いたいのに、MSYS2の公式リポジトリ(pacman)に存在しない……!」という壁にぶぶつかったことはありませんか?
そんなとき、ソースコードから手動で `cmake` を叩いてビルドし、ヘッダファイルやライブラリを `C:\` の適当な場所にコピーして回る……なんて泥臭い管理をしていませんか? それだと、後からバージョンのアップデートがあった時や、別の環境へ移行する時に地獄を見ることになります。
今回は、MSYS2のパッケージマネージャー(pacman)の心臓部である `PKGBUILD` をマスターし、自作のライブラリを完全自動でビルド&パッケージング、さらにはローカルリポジトリでスマートに管理する手法を伝授します。
これをマスターすれば、DLL地獄やインクルードパスの迷子から永遠に解放されますよ。さあ、一緒にモダンなパッケージ管理の世界へ踏み出しましょう!
—
なぜMSYS2の「Pacman自作(PKGBUILD)」が必要なのか?
まず、なぜ手動ビルドではなく `pacman` の管理下に置くべきなのか、そのアーキテクチャ上のメリットを理解しておきましょう。
MSYS2は、Arch Linuxのパッケージ管理システムである `pacman` およびビルドシステム `makepkg` をWindows上に移植したものです。
すべてのライブラリを `pacman` 管理下に置くことで、以下の圧倒的な恩恵を受けられます。
1. 依存関係の自動解決: ライブラリAが依存しているライブラリBのバージョン競合を防ぎます。
2. クリーンなアンインストール: 手動インストールだとファイルがシステム中に散らばりますが、`pacman -R` 一発で綺麗に消し去ることができます。
3. アップデートの追従: ソースコード側がアップデートされた際、スクリプトのバージョンを書き換えて再ビルドするだけで、環境全体を最新に保てます。
それでは、実際に手を動かしながら、最小限のサンプルをpacmanパッケージ化するフローを見ていきましょう。
—
1. 開発環境のウォーミングアップ(事前準備)
まずは、MSYS2環境でパッケージをビルドするために必要なツールチェーン(コンパイラやビルドツール)が揃っているか確認し、導入します。
MSYS2のターミナル(通常は MSYS2 MinGW x64)を開き、以下のコマンドを実行してください。
パッケージデータベースを同期し、コアシステムをアップデート
pacman -Syu
(※ウィンドウが閉じたら、再度ターミナルを開いて `pacman -Su` を実行してシステムを最新化してください)
続いて、ビルドに必要な基本ツール群(Git, Make, 圧縮ツールなど)と、パッケージ作成の必須コマンドである `base-devel` グループをインストールします。
ビルドに必要な開発ツールのインストール
pacman -S –needed base-devel git mingw-w64-x86_64-toolchain
これで、いつでもパッケージをビルドする準備が整いました。
—
2. Hello World的なターゲット:独自ライブラリの用意
今回は解説用に、非常にシンプルなC言語のライブラリ「`myprint`」を想定します。
ホームディレクトリ(`~`)の下に作業用フォルダを作成しましょう。
作業用ディレクトリの作成と移動
mkdir -p ~/pkg-workspace/myprint
cd ~/pkg-workspace/myprint
ここに、簡単なソースコード `myprint.c` とヘッダーファイル `myprint.h` を作成します。
myprint.h
ifndef MYPRINT_H
define MYPRINT_H
// 挨拶を出力するだけのシンプルな関数
void print_hello(const char name);
endif
myprint.c
include
include “myprint.h”
void print_hello(const char name) {
printf(“Hello, %s! Welcome to custom pacman world.\n”, name);
}
さらに、これをビルドするための `CMakeLists.txt` も用意します。
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(myprint C)
ライブラリのターゲット作成(共有ライブラリ)
add_library(myprint SHARED myprint.c)
インストールルールの定義(どこに何を配置するか)
include(GNUInstallDirs)
install(TARGETS myprint
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
install(FILES myprint.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
—
3. 魂の核心:`PKGBUILD` の書き方
ここからが本番です。`makepkg` が参照するレシピファイルである `PKGBUILD` を作成します。
同じフォルダ内に `PKGBUILD` という名前でファイルを作成し、以下のように記述してください。
PKGBUILD
Maintainer: Your Name
pkgname=mingw-w64-x86_64-myprint # MSYS2の命名規約に従い、プレフィックスを付与
pkgver=1.0.0 # パッケージのバージョン
pkgrel=1 # リカバリや改訂を示すリビジョン番号
pkgdesc=”A custom Hello World library for demonstration” # パッケージの説明
arch=(‘any’) # アーキテクチャ(今回はソースからビルドするのでanyまたはx86_64)
license=(‘MIT’) # ライセンス
depends=(‘mingw-w64-x86_64-crt’) # 依存するパッケージ(必要に応じて追加)
makedepends=(‘cmake’ ‘mingw-w64-x86_64-toolchain’) # ビルド時にのみ必要なツール
ソースコードのありか(今回はローカルディレクトリを指定)
source=(“.”)
sha256sums=(‘SKIP’) # ローカルビルドのためチェックサムはスキップ
ビルド前に実行される関数(CMakeによる設定)
build() {
# MSYS2のビルド環境(MinGW 64bit)に合わせてCMakeを設定
# ${srcdir} はソースが展開される一時ディレクトリ
cmake -B build -S “${srcdir}” \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/mingw64 # インストール先をMinGW64のルートに指定
# 実際のコンパイル実行
cmake –build build
}
ビルドした成果物をパッケージング用ディレクトリ($pkgdir)にコピーする関数
package() {
# CMakeのインストール機能を利用して、$pkgdir配下にファイルを綺麗に配置
DESTDIR=”${pkgdir}” cmake –install build
}
💡 先輩エンジニアのワンポイント解説:MSYS2命名規則の罠
MSYS2/MinGW環境でパッケージを作る際、パッケージ名(`pkgname`)は必ず `mingw-w64-x86_64-`(またはi64など)のプレフィックスを付けるのが鉄則です。これによって、どのランタイム向けのパッケージなのかをpacmanが正しく識別できるようになります。
—
4. ビルドとパッケージの生成 (`makepkg`)
レシピが書けたら、いよいよビルドの魔術を実行します。
ターミナルで以下のコマンドを叩いてください。
パッケージ作成コマンドの実行 (-s は依存関係の自動解決、-f は既存パッケージの上書き)
makepkg-mingw -sf
実行ログのイメージ:
==> 依存関係のチェック中…
==> ソースの取得中…
==> 正在解凍 …
==> build() を実行中…
— The C compiler identification is GNU 13.2.0
…
[100%] Built target myprint
==> package() を実行中…
==> パッケージを作成中…
-> 圧縮パッケージを作成中…
-> 完了
ビルドが成功すると、同じディレクトリに `mingw-w64-x86_64-myprint-1.0.0-1-any.pkg.tar.zst` という拡張子 `.pkg.tar.zst` のファイルが生成されます。これが、あなた専用のカスタムバイナリパッケージです!
—
5. ローカルリポジトリの構築とpacman管理下のインストール
せっかく作ったパッケージを、ただの「野良ファイル」ではなく、`pacman` の管理下に置きましょう。
自分専用の「ローカルリポジトリ」をPC上に作成し、そこにこのパッケージを登録します。
ステップ1: リポジトリ用フォルダの作成
適当な場所にリポジトリ用のディレクトリを作ります(例:`C:\my-local-repo`)。MSYS2内からは `/c/my-local-repo` としてアクセスできます。
ローカルリポジトリ用ディレクトリの作成
mkdir -p /c/my-local-repo
先ほど作成したzstパッケージをそのディレクトリに移動
cp mingw-w64-x86_64-myprint-1.0.0-1-any.pkg.tar.zst /c/my-local-repo/
ステップ2: データベースの作成 (`repo-add`)
pacmanに「このフォルダはリポジトリだよ」と教えるために、索引データベース(db)を生成します。
cd /c/my-local-repo
repo-add myrepo.db.tar.zst mingw-w64-x86_64-myprint-1.0.0-1-any.pkg.tar.zst
ステップ3: pacmanの設定ファイルにローカルリポジトリを追加
MSYS2に「このローカルリポジトリを参照しなさい」と設定します。
`/etc/pacman.conf` をテキストエディタ(nanoなど)で開きます。
nano /etc/pacman.conf
ファイルの一番最後に、以下のブロックを追加してください。
[myrepo]
SigLevel = Never
Server = file:///c/myrepo
(※ `Ctrl + O` で保存、`Enter`、`Ctrl + X` でnanoを終了します)
ステップ4: データベースの同期とパッケージのインストール!
ついに、自作パッケージをpacman経由でインストールします。
リポジトリ情報を最新化
pacman -Sy
自作パッケージのインストール!
pacman -S mingw-w64-x86_64-myprint
おめでとうございます!これで `myprint` ライブラリがあなたのMSYS2/MinGW64環境の完全な管理下に置かれました。
—
動作確認:自作パッケージの恩恵を確かめる
本当に正しくインストールされ、どこからでもインポートできるか簡単なテストプログラムを作って確認してみましょう。
作業ディレクトリに戻り、テスト用の `test.c` を書きます。
test.c
include
int main() {
print_hello(“MSYS2 Developer”);
return 0;
}
コンパイルして実行してみます。
GCCでコンパイル(インクルードパスやライブラリパスを指定しなくても、MinGW64標準パスに入っているためそのまま通ります)
gcc test.c -lmyprint -o test
実行
./test.exe
出力結果:
Hello, MSYS2 Developer! Welcome to custom pacman world.
どうでしょうか?
`/mingw64/include` と `/mingw64/lib` に美しく配置され、`pacman -Q` を叩けばちゃんと管理リストに `mingw-w64-x86_64-myprint` が表示されます。
pacman -Q | grep myprint
出力: mingw-w64-x86_64-myprint 1.0.0-1
—
まとめ:これをマスターすれば毎日の開発が劇的に楽になる
今回は、MSYS2における `PKGBUILD` の書き方から、ローカルリポジトリの作成、そして `pacman` によるクリーンなインストールまでの全工程を解説しました。
- 手動ビルドの煩雑さ から解放され、
- 依存関係やアンインストール の管理がスマートになり、
- チーム開発や個人環境の再構築時にも、リポジトリフォルダをポンと置くだけで同じ環境を再現できるようになります。
最初は少し難しく感じるかもしれませんが、一度この型(PKGBUILD)を覚えてしまえば、世の中に存在しないマイナーなライブラリや社内共通ライブラリであっても、すべてpacmanエコシステムの中で統一管理できるようになります。
ぜひ、あなたの手元のプロジェクトでも試してみてください。快適な低レイヤ・コンパイルライフを!