Edited at

MSYS2小ネタ集

More than 3 years have passed since last update.

細かすぎて伝わらないMSYS2小ネタ集


シンボリックリンクの扱いについて

MSYS2における ln -s の振る舞いは環境変数 MSYS で変更することができる.

設定できる項目は以下の通り.



  • winsymlinks, winsymlinks:lnk


    • リンク先の情報が埋め込まれた読み込み専用のショートカット (.lnk) が作成される.
      そのため,Windowsネイティブのアプリケーションではシンボリックリンクとして認識されない.




  • winsymlinks:nativestrict, winsymlinks:native


    • Windowsネイティブのシンボリックリンクが作成される.
      管理者権限でシェルを実行していない場合エラーとなる




  • 指定なし


    • シンボリックリンクを作成せず,単にファイル・ディレクトリをコピーする




補足


  • 上記の設定は ln -s のみでなく,msys-2.0.dll を使用しているすべてのバイナリに影響する(/usr/bin/pythonなど).


  • ln -s で作成されたショートカットのコメント欄にはリンク先のパスが設定されるらしい.それ以外にもリンク内に属性を設定しているらしく,Windows側でショートカットを編集するとMSYS2側でシンボリックリンクとして認識されなくなることに注意.



参考URL


PATH の取り扱いについて

※ ここに記載されている内容は 2016年4月25日現在のものです

環境変数 MSYS2_PATH_TYPE を用いることで,$PATH にWindows側の設定を取り込む際の振る舞いを制御できる.設定できる項目は以下の通り.



  • MSYS2_PATH_TYPE=inherit


    • Windows側の環境変数(%PATH%)を継承する($PATHの末尾に追加される)




  • MSYS2_PATH_TYPE=strict


    • Windows側の環境変数を取り込まない




  • それ以外


    • Windows側の環境変数のうち,%SystemRoot%\System32, %SystemRoot%, %SystemRoot%\System32\Wbem%, %SystemRoot%\System32\WindowsPowerShell\v1.0 のみ読み込む.



参考: https://github.com/Alexpux/MSYS2-packages/pull/540


Windows ネイティブのバイナリ実行時におけるパス展開の防止

※ 2016/04/26 追記.@k-takata さん情報提供感謝します.

MSYS2 でWindowsネイティブなコマンドを実行する際,Unix 形式のパスが Windows 形式に自動的に変換される.しかし,使用するコマンドによってはWindows形式への展開を抑制したい場合がしばしば生じる.

例として公式のWiki にあるものを挙げると

# 3つめの引数が C:/msys64/sdcard/0/ に展開される(環境依存)

$ adb push readme.txt /sdcard/0/

このような場合,環境変数 MSYS2_ARG_CONV_EXCL を用いることで Windows 形式への変換を抑制することができる.具体的には,コマンドライン引数の接頭部とこの環境変数の値が一致したらWindows形式への変換を行わない.

上の例の場合は以下の通り:

# Windows形式に変換されずにコマンドが実行される

$ MSYS2_ARG_CONV_EXCL='/sdcard/0/' adb push readme.txt /sdcard/0/

変換を無視する候補が複数ある場合はセミコロン (;) で区切ることで指定できる.

/sdcard/0/;/hoge;/fuga/ など).


※動作確認

実験用にコマンドライン引数を表示するだけのプログラムを用意した.


test_path.cpp

#include <iostream>

using namespace std;

int main(int argc, char const* argv[])
{
for (int i=0; i<argc; ++i) {
cout << i << ": " << argv[i] << endl;
}
return 0;
}


これを MSYS2 版の g++ ,MinGW-w64 版の g++ それぞれでビルドすると次のような動作になる.


/usr/bin/g++

$ /usr/bin/g++ -o test_msys test_path.cpp

$ ./test_msys /hoge
0: ./test_msys
1: /hoge


/mingw64/bin/g++

$ /mingw64/bin/g++ -o test_mingw test_path.cpp

$ ./test_mingw /hoge
0: E:\work\test_mingw.exe
1: C:/msys64/hoge

$ ./test_mingw /hoge ./fuga --prefix=/fuga
0: E:\work\test_mingw.exe
1: C:/msys64/hoge
2: ./fuga
3: --prefix=C:/msys64/fuga


変換の対象となるのは / から始まる値のみらしい.

MSYS2_ARG_CONV_EXCL 有りで実行した場合は次の通り:


/mingw64/bin/g++

$ MSYS2_ARG_CONV_EXCL='/hoge;--prefix=' ./test_mingw /hoge --prefix=/fuga

0: E:\work\test_mingw.exe
1: /hoge
2: --prefix=/fuga

argv[0] がWindows形式なのが若干気持ち悪い...