前回まで、「MSYS2」をインストールした後は特に何の説明もせずに、Windows TerminalでMSYS2のコマンドを使ってきた。しかし、通常はMSYS2をインストールするとメニューに次のような項目が追加されるので、これを起動して使うのが「想定されている使い方」なのではないかと思う。
このアプリケーションメニューは、実際には次のようなショートカットになっており、ショートカット先は「C:\msys64\msys2_shell.cmd」というコマンドだ。
どのショートカットもこのコマンドを呼び出すものであり、オプションだけが異なる(少なくとも執筆時点ではこのような仕組みになっている。将来のバージョンでは変わっている可能性もあるので、その場合は読み替えていただきたい)。まとめると次のようになる。
アプリケーション | 本体 |
---|---|
MSYS2 MinGW 32-bit | C:\msys64\msys2_shell.cmd -mingw32 |
MSYS2 MinGW 64-bit | C:\msys64\msys2_shell.cmd -mingw64 |
MSYS2 MinGW UCRT 64-bit | C:\msys64\msys2_shell.cmd -ucrt64 |
MSYS2 MSYS2 | C:\msys64\msys2_shell.cmd -msys |
C:\msys64\msys2_shell.cmdは、次のように「環境変数を設定してターミナルを起動する」という内容のバッチファイルになっている。
本連載では、インストールしたMSYS2を使用するために次の環境変数を設定したわけだが、こういった設定を行わずに起動するための仕組みがC:\msys64\msys2_shell.cmdということになるわけだ。
環境変数 | 内容 |
---|---|
HOME | C:\Users\ユーザー名 |
LC_CTYPE | ja_JP.UTF-8 |
Path | C:\msys64\usr\bin |
C:\msys64\mingw64\bin |
なぜこのような仕組みになっているかというと、実はMSYS2は内部に特定のアーキテクチャやプラットフォーム向けの領域を持っており、そのプラットフォームのなかに入るためだ。目的は開発であり、そのためにこうした仕組みが用意されている。
デプロイは開発環境別に分離されている
MSYS2は「C:\msys64\」にインストールされるわけだが、このディレクトリにどんなファイルやディレクトリがインストールされているか見てみよう。
PS C:\msys64> ls -l
total 31473
-rw-r--r-- 1 daichi daichi 5236 Aug 30 17:56 InstallationLog.txt
-rw-r--r-- 1 daichi daichi 82 May 19 15:51 autorebase.bat
drwxr-xr-x 1 daichi daichi 0 Sep 2 16:55 bin
drwxr-xr-x 1 daichi daichi 0 Aug 30 17:55 clang32
drwxr-xr-x 1 daichi daichi 0 Aug 30 17:55 clang64
-rwxr-xr-x 1 daichi daichi 79095 Apr 27 16:45 clang64.exe
-rw-r--r-- 1 daichi daichi 30450 Jun 6 14:20 clang64.ico
-rw-r--r-- 1 daichi daichi 154 Apr 27 16:45 clang64.ini
drwxr-xr-x 1 daichi daichi 0 Aug 30 17:55 clangarm64
-rw-r--r-- 1 daichi daichi 915 Aug 30 17:56 components.xml
drwxr-xr-x 1 daichi daichi 0 Aug 30 17:55 dev
-rw-r--r-- 1 daichi daichi 541 Jul 26 01:37 dir
drwxr-xr-x 1 daichi daichi 0 Aug 31 16:40 etc
drwxr-xr-x 1 daichi daichi 0 Aug 30 17:55 home
-rw-r--r-- 1 daichi daichi 48 Aug 30 17:56 installer.dat
drwxr-xr-x 1 daichi daichi 0 Aug 30 17:55 installerResources
drwxr-xr-x 1 daichi daichi 0 Aug 30 17:55 mingw32
-rwxr-xr-x 1 daichi daichi 79095 Apr 27 16:45 mingw32.exe
-rw-r--r-- 1 daichi daichi 30309 Jun 6 14:20 mingw32.ico
-rw-r--r-- 1 daichi daichi 154 Apr 27 16:45 mingw32.ini
drwxr-xr-x 1 daichi daichi 0 Sep 2 16:52 mingw64
-rwxr-xr-x 1 daichi daichi 79095 Apr 27 16:45 mingw64.exe
-rw-r--r-- 1 daichi daichi 30532 Jun 6 14:20 mingw64.ico
-rw-r--r-- 1 daichi daichi 154 Apr 27 16:45 mingw64.ini
-rwxr-xr-x 1 daichi daichi 87287 Apr 27 16:45 msys2.exe
-rw-r--r-- 1 daichi daichi 38434 Jun 6 14:20 msys2.ico
-rw-r--r-- 1 daichi daichi 151 Apr 27 16:45 msys2.ini
-rw-r--r-- 1 daichi daichi 8390 Jun 6 14:20 msys2_shell.cmd
-rw-r--r-- 1 daichi daichi 362 Aug 30 17:56 network.xml
drwxr-xr-x 1 daichi daichi 0 Aug 30 17:55 opt
dr-xr-xr-x 7 daichi daichi 0 Sep 7 17:33 proc
drwxr-xr-x 1 daichi daichi 0 Sep 7 13:31 tmp
drwxr-xr-x 1 daichi daichi 0 Aug 30 17:55 ucrt64
-rwxr-xr-x 1 daichi daichi 79095 Apr 27 16:45 ucrt64.exe
-rw-r--r-- 1 daichi daichi 30459 Jun 6 14:20 ucrt64.ico
-rw-r--r-- 1 daichi daichi 153 Apr 27 16:45 ucrt64.ini
-rw-r--r-- 1 daichi daichi 47414 Aug 30 17:56 uninstall.dat
-rwxr-xr-x 1 daichi daichi 31329792 Aug 30 17:56 uninstall.exe
-rw-r--r-- 1 daichi daichi 4872 Aug 30 17:56 uninstall.ini
drwxr-xr-x 1 daichi daichi 0 Sep 2 16:47 usr
drwxr-xr-x 1 daichi daichi 0 Aug 30 17:55 var
PS C:\msys64>
ご覧の通り、UNIX系プラットフォームに見られるbin、dev、etc、home、proc、tmp、usr、varなどが確認できる。MSYS2のルートディレクトリがC:\msys64\であり、ここにUNIX系プラットフォームでおなじみのディレクトリやファイルがデプロイされているのだ。
これに加えて、mingw64やmingw32、ucrt64やclang64といったディレクトリもある。これはMSYS2に特有のディレクトリで、開発環境専用のルートディレクトリのようなものになっている。例えば、「C:\msys64\mingw64」はUNIX系ソフトウエアを64ビットWindows向けのソフトウエアとして開発するための環境のルートディレクトリということになる。
プラットフォームという視点で簡単にまとめると次のようになる。
ルートディレクトリ | プラットフォーム |
---|---|
C:\msys64\ | MSYS2 |
C:\msys64\mingw32\ | MinGW 32-bit |
C:\msys64\mingw64\ | MinGW 64-bit |
C:\msys64\ucrt64\ | MinGW UCRT 64-bit |
C:\msys64\clang32\ | Clang 32-bit |
C:\msys64\clang64\ | Clang 64-bit |
C:\msys64\clangarm64\ | Clang 64-bit (ARM) |
MSYS2 (C:\msys64)はUNIX互換環境という側面が強い。UNIX互換プラットフォームとしての利用や、UNIX寄りのソフトウエアを開発する場合には、MSYS2を使うことになる。一方、MinGW 64-bit (C:\msys64\mingw64)はもっとWindowsネイティブ寄りだ。UNIX系ソフトウエアを活用しつつもWindowsネイティブなソフトウエアを開発する場合にはこちらを使うことになる。
プラットフォームごとに依存関係が分離している
「プラットフォームが異なる」というのが具体的に何を意味しているかだが、ライブラリなどの依存関係がそのプラットフォーム(ルートディレクトリ以下)で閉じているかどうか、といった辺りでよくわかる。例えば、C:\msys64\usr\bin\には、MSYS2本体で使われるコマンドがデプロイされているわけだが、依存関係を調べると次のようにWindowsとMSYS2のライブラリに依存しており、ほかのプラットフォームにインストールされるライブラリには依存していないことを確認できる。
PS C:\msys64\usr\bin> ldd .\zip.exe
ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffd81710000)
KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffd80d40000)
KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffd7f110000)
msys-bz2-1.dll => /usr/bin/msys-bz2-1.dll (0x461220000)
msys-2.0.dll => /usr/bin/msys-2.0.dll (0x180040000)
PS C:\msys64\usr\bin> ldd .\vim.exe
ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffd81710000)
KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffd80d40000)
KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffd7f110000)
USER32.dll => /c/WINDOWS/System32/USER32.dll (0x7ffd809c0000)
win32u.dll => /c/WINDOWS/System32/win32u.dll (0x7ffd7f030000)
msys-intl-8.dll => /usr/bin/msys-intl-8.dll (0x430b30000)
msys-iconv-2.dll => /usr/bin/msys-iconv-2.dll (0x5603f0000)
msys-2.0.dll => /usr/bin/msys-2.0.dll (0x180040000)
GDI32.dll => /c/WINDOWS/System32/GDI32.dll (0x7ffd80d10000)
gdi32full.dll => /c/WINDOWS/System32/gdi32full.dll (0x7ffd7ee40000)
msvcp_win.dll => /c/WINDOWS/System32/msvcp_win.dll (0x7ffd7f540000)
msys-ncursesw6.dll => /usr/bin/msys-ncursesw6.dll (0x5fcb10000)
ucrtbase.dll => /c/WINDOWS/System32/ucrtbase.dll (0x7ffd7f610000)
PS C:\msys64\usr\bin>
MinGW 64-bitにインストールされるライブラリに依存していないかどうかを調べてみると、次のように依存していないことを確認できる。分離されているのだ。
PS C:\msys64\usr\bin> ldd *.exe | grep /c/mingw64
PS C:\msys64\usr\bin>
逆に、MinGW 64-bitにインストールされたコマンドの依存関係を調べてみると、次のようにWindowsとMinGE 64-bitにインストールされているライブラリに依存しており、MSYS2本体のライブラリには依存していないことを確認できる。
◆C:\msys64\mingw64\bin\以下のコマンドの依存関係
PS C:\msys64\mingw64\bin> ldd .\bzip2.exe
ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffd81710000)
KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffd80d40000)
KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffd7f110000)
msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ffd80620000)
libbz2-1.dll => /mingw64/bin/libbz2-1.dll (0x7ffd73c50000)
PS C:\msys64\mingw64\bin> ldd .\gm.exe
ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ffd81710000)
KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ffd80d40000)
KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ffd7f110000)
msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ffd80620000)
libGraphicsMagick-3.dll => /mingw64/bin/libGraphicsMagick-3.dll (0x7ffd169a0000)
ADVAPI32.dll => /c/WINDOWS/System32/ADVAPI32.dll (0x7ffd807f0000)
sechost.dll => /c/WINDOWS/System32/sechost.dll (0x7ffd7f920000)
RPCRT4.dll => /c/WINDOWS/System32/RPCRT4.dll (0x7ffd806c0000)
GDI32.dll => /c/WINDOWS/System32/GDI32.dll (0x7ffd80d10000)
win32u.dll => /c/WINDOWS/System32/win32u.dll (0x7ffd7f030000)
gdi32full.dll => /c/WINDOWS/System32/gdi32full.dll (0x7ffd7ee40000)
msvcp_win.dll => /c/WINDOWS/System32/msvcp_win.dll (0x7ffd7f540000)
ucrtbase.dll => /c/WINDOWS/System32/ucrtbase.dll (0x7ffd7f610000)
USER32.dll => /c/WINDOWS/System32/USER32.dll (0x7ffd809c0000)
libbz2-1.dll => /mingw64/bin/libbz2-1.dll (0x7ffd73c50000)
libwinpthread-1.dll => /mingw64/bin/libwinpthread-1.dll (0x7ffd59fa0000)
libgomp-1.dll => /mingw64/bin/libgomp-1.dll (0x7ffd58f20000)
liblcms2-2.dll => /mingw64/bin/liblcms2-2.dll (0x7ffd3c7b0000)
libltdl-7.dll => /mingw64/bin/libltdl-7.dll (0x7ffd4f600000)
libfreetype-6.dll => /mingw64/bin/libfreetype-6.dll (0x7ffd20420000)
zlib1.dll => /mingw64/bin/zlib1.dll (0x7ffd45500000)
libgcc_s_seh-1.dll => /mingw64/bin/libgcc_s_seh-1.dll (0x7ffd4f5e0000)
libbrotlidec.dll => /mingw64/bin/libbrotlidec.dll (0x7ffd4c6c0000)
libharfbuzz-0.dll => /mingw64/bin/libharfbuzz-0.dll (0x7ffd168a0000)
libpng16-16.dll => /mingw64/bin/libpng16-16.dll (0x7ffd34cb0000)
libbrotlicommon.dll => /mingw64/bin/libbrotlicommon.dll (0x7ffd2db50000)
DWrite.dll => /c/WINDOWS/SYSTEM32/DWrite.dll (0x7ffd4dd40000)
USP10.dll => /c/WINDOWS/SYSTEM32/USP10.dll (0x7ffd454e0000)
libglib-2.0-0.dll => /mingw64/bin/libglib-2.0-0.dll (0x7ffd0e390000)
libstdc++-6.dll => /mingw64/bin/libstdc++-6.dll (0x7ffd16580000)
libgraphite2.dll => /mingw64/bin/libgraphite2.dll (0x7ffd2db20000)
ole32.dll => /c/WINDOWS/System32/ole32.dll (0x7ffd7fb40000)
combase.dll => /c/WINDOWS/System32/combase.dll (0x7ffd80ef0000)
SHELL32.dll => /c/WINDOWS/System32/SHELL32.dll (0x7ffd7fe10000)
WS2_32.dll => /c/WINDOWS/System32/WS2_32.dll (0x7ffd7fda0000)
libintl-8.dll => /mingw64/bin/libintl-8.dll (0x7ffd2d840000)
libiconv-2.dll => /mingw64/bin/libiconv-2.dll (0x7ffd161a0000)
libpcre-1.dll => /mingw64/bin/libpcre-1.dll (0x7ffd20260000)
PS C:\msys64\mingw64\bin>
◆C:\msys64\mingw64\bin\以下のコマンドはMSYS2本体には依存していない
PS C:\msys64\mingw64\bin> ldd *.exe | grep /c/usr/
PS C:\msys64\mingw64\bin>
MSYS2を使ってWindows向けのソフトウエアを開発する場合、この辺りを理解していないと、うまくビルドができずに困ることになる。開発目的のためにこのような構造になっている、ということを覚えておいてもらえればと思う。
コマンドを使うだけならプラットフォームの違いは気にしない
ただし、UNIX系のコマンドを使いたいだけ(開発はしない)という場合は、この限りではない。例えば、画像を変換/加工する際に便利な「GraphicsMagick」というソフトウエアがあるのだが、MSYS2でそのパッケージを検索すると、次のような検索結果が得られる。
PS C:\msys64> pacman -Ss graphicsmagick
mingw32/mingw-w64-i686-graphicsmagick 1.3.36-5
An image viewing/manipulation program (mingw-w64)
mingw64/mingw-w64-x86_64-graphicsmagick 1.3.36-5 [installed]
An image viewing/manipulation program (mingw-w64)
ucrt64/mingw-w64-ucrt-x86_64-graphicsmagick 1.3.36-5
An image viewing/manipulation program (mingw-w64)
clang64/mingw-w64-clang-x86_64-graphicsmagick 1.3.36-5
An image viewing/manipulation program (mingw-w64)
PS C:\msys64>
パッケージ名から推測できるように、GraphicsMagickのパッケージはMinGW 64-bit、MinGW 32-bit、MinGW UCRT 64-bit、Clang 64-bitプラットフォーム向けのものが用意されている。MinGW 64-bit向けのGraphicsMagickパッケージは、「mingw-w64-x86_64-graphicsmagick」ということになるのだが、このパッケージでインストールされるファイル一覧を確認すると次のように表示される。
PS C:\msys64> pacman -Fl mingw-w64-x86_64-graphicsmagick
mingw-w64-x86_64-graphicsmagick mingw64/
mingw-w64-x86_64-graphicsmagick mingw64/bin/
mingw-w64-x86_64-graphicsmagick mingw64/bin/gm.exe
mingw-w64-x86_64-graphicsmagick mingw64/bin/GraphicsMagick++-config
mingw-w64-x86_64-graphicsmagick mingw64/bin/GraphicsMagick-config
mingw-w64-x86_64-graphicsmagick mingw64/bin/GraphicsMagickWand-config
mingw-w64-x86_64-graphicsmagick mingw64/bin/libGraphicsMagick++-12.dll
mingw-w64-x86_64-graphicsmagick mingw64/bin/libGraphicsMagick-3.dll
mingw-w64-x86_64-graphicsmagick mingw64/bin/libGraphicsMagickWand-2.dll
mingw-w64-x86_64-graphicsmagick mingw64/include/
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/Blob.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/CoderInfo.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/Color.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/Drawable.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/Exception.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/Geometry.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/Image.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/Include.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/Montage.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/Pixels.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/STL.h
mingw-w64-x86_64-graphicsmagick mingw64/include/GraphicsMagick/Magick++/TypeMetric.h
...略...
mingw-w64-x86_64-graphicsmagick mingw64/share/man/
mingw-w64-x86_64-graphicsmagick mingw64/share/man/man1/
mingw-w64-x86_64-graphicsmagick mingw64/share/man/man1/gm.1.gz
mingw-w64-x86_64-graphicsmagick mingw64/share/man/man1/GraphicsMagick++-config.1.gz
mingw-w64-x86_64-graphicsmagick mingw64/share/man/man1/GraphicsMagick-config.1.gz
mingw-w64-x86_64-graphicsmagick mingw64/share/man/man1/GraphicsMagickWand-config.1.gz
mingw-w64-x86_64-graphicsmagick mingw64/share/man/man4/
mingw-w64-x86_64-graphicsmagick mingw64/share/man/man4/miff.4.gz
mingw-w64-x86_64-graphicsmagick mingw64/share/man/man5/
mingw-w64-x86_64-graphicsmagick mingw64/share/man/man5/quantize.5.gz
PS C:\msys64>
これらは全て、C:\msys64\mingw64\以下にインストールされている。つまり、このコマンドを使おうと思ったらC:\msys64\mingw64\bin\にインストールされるコマンドを実行する必要があるわけだ。環境変数PathにC:\msys64\mingw64\binを追加したのはそのためである。
開発目的で完全に分離されたインストールが行われるのだが、コマンドを使うという観点だけから言えば、C:\msys64\usr\binにインストールされるコマンドもC:\msys64\mingw64\binにインストールされるコマンドも同じだ。パッケージを検索する場合には、MSYS2またはMinGW 64-bitを対象としたものは使えると考えておいてよいと思う。ほかのプラットフォームのパッケージをインストールして使えるようにしてもよいのだが、とりあえずMSYS2、またはMinGW 64-bitを対象としたものを使うと考えておけば問題ない。これで「pacman」で検索して表示されるパッケージが複数存在していることの理由がわかったのではないだろうか。
さまざまなパッケージが用意されているので、普段Linuxで使っているコマンドをMSYS2でインストールし、Windowsで使ってみよう。WindowsでネイティブにLinux系コマンドが使えると実に便利だ。
付録: MSYS2インストール方法など
環境変数 | 内容 |
---|---|
HOME | C:\Users\ユーザー名 |
LC_CTYPE | ja_JP.UTF-8 |
Path | C:\msys64\usr\bin |
C:\msys64\mingw64\bin |
MSYS2のインストール方法
winget install MSYS2
pacman -Syu
コマンド | 内容 |
---|---|
pacman -S | パッケージインストール |
pacman -Ss | パッケージ検索 |
pacman -R | パッケージアンインストール |
pacman -Rs | パッケージおよびそのパッケージのみが必要としているパッケージをアンインストール |
pacman -Rns | パッケージおよびそのパッケージのみが必要としているパッケージおよびバックアップファイルをアンインストール |
pacman -Fx | 指定したファイルが含まれているパッケージを一覧表示 |
pacman -Fl | 指定したパッケージがインストールするファイルを一覧表示 |
pacman -Q | インストール済みパッケージ一覧表示 |
pacman -Syu | メタデータアップデートとパッケージアップグレード |