Let's start Scheme

2018-02-24

MSYS2サポート 2

前回の続きと僕なりの回答。

前回MSYS2上でのシンボリックリンクの話とSagittarius上でどうするかというのを書いた。書いた後に助言やMSYSがどのようにシンボリックリンクを扱っているかというののヒント(調べた結果Qiitaの記事が古いのか現状の挙動と違った)をもらったのでそれを踏まえて実装してみた、という話。

【MSYS2上でのシンボリックリンク】

 MSYS2上ではシンボリックリンクはデフォルトでは作られず、ファイルのコピーとなる。この挙動を制御するためには環境変数MSYSを適切に設定する必要がある。2018年現在では以下の表のようになる。
挙動
  • winsymlinks
  • winsymlinks:lnk
ショートカットを作成する。
MSYS2上からはシンボリックリンクとして見える、かつWindows上ではショートカットになる。
  • winsymlinks:native
  • winsymlinks:nativestrict
シンボリックリンクを作成する。
Windows上でもシンボリックリンクになるが、管理者権限またはWindows 10かつDeveloper modeである必要がある。
失敗した場合は単にコピーになるか、作成されない。
  • 上記以外
  • 未設定(デフォルト)
ファイルをコピーする。
ソースも確認したのでこれであっているはず。ちなみに上記はsymlink(2)の挙動なので、ln -sは多少違うかもしれない(たぶんあってると思うけど)。

【Sagittarius上ではどうしたか】 

シンボリックリンクの作成を失敗したくないというのが大前提としてあったので、最低でもショートカットにフォールバックするようにしたかった。ということで、Sagittarius上では以下のフローでシンボリックリンクの作成をする。
  1.  環境変数のチェック
    1. コピー以外のいずれかならばsymlink(2)を使用する
    2. コピーならばWindows上のシンボリックリンクを試す
  2. ファイルが作成されているかチェック
    1. 作成されているなら終了
    2. 作成されていないなら、環境変数MSYSwinsymlinks:lnkを設定し#1へ 
(Windows上のシンボリックリンクを試す必要ないかもしれないなぁとこれ書いてて思ったので、ファイルチェック→環境変数セット→リトライのフローだけにするか。)

とりあえずこれで、create-symbolic-link手続きがMSYS上では何かしらシンボリックリンクっぽいものを作成することになる。いつも思うがサポートする環境を増やすときはこうい環境特有の workaround が必要になるの辛い。

6 comments:

Kaz said...

keiさん、このプロジェクトを御覧ください。

http://www.kylheku.com/cygnal/

kei said...

Kazさん

情報ありがとうございます。Sagittariusは既にCygwinをサポートしているのですが、このプロジェクトとCygwinの違いはなんでしょうか?(例えば、このプロジェクトを使うことで現在Cygwinが持っている問題の回避ができる等あるのでしょうか?)

Kaz said...

CygwinのアプリのユーザーはUNIXの規則や慣用が分からなければならないです。
例えば、パス名は、C:\Users\fooの代わりに、/cygdrive/c/Users/foo使わなければなりません。

CygnalのCYGWIN1.DLLは、普通の「C:\Users\foo」のアスが分かります。

ユーザーに対して、Cygnalは、Windowsの規則を従っています。

kei said...

なるほど。いくつか追加で質問ですが、

− 現在ビルドプロセスにCMakeを使っているのですが、CygnalはCMakeに対応していますか?
− Cygwin固有のforkが失敗する問題は解決されているのでしょうか?
− Shellはありますか?(DLLだけだと設定が大変なので)

Kaz said...

keiさんの質問に対して、

Cygnalは、Cygwinみたいな環境ではありません。ライブラリーだけです。

まずは、CygnalのアプリをCygwinの環境に、Cygwinのアプリとしてビルドして。

そして、Cygnalの「cygwin1.dll」と合わせます。

他の必要な「.DLL」は、Cygwinの取らなければいけなりません。

同じ「.EXE」がCygwinのアプリとしてCygnalの「ネイチィブ」アプリとして稼働出来ます。

Kaz said...

Cygnalは、Shellはないです。

system("dir /w")やpopen("command ..")は、わざと、/bin/shの代わりにCMD.EXEを使えます!

forkは、Cygwinのforkだから、大丈夫。

Post a Comment