やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

cscスクリプト(実行ファイル名不定問題への妥協)

 cscのデフォルト挙動と異なってしまう。エントリポイントがある任意クラス名と同じ名前にはできない。手動で指定すればできる。-out:名前で指定した名前になるか、省略時はProgram.exeになる。

成果物

前回まで

コード

 コマンド。

csrun

Run() {
    . "$(cd $(dirname $0); pwd)/csrun.sh"
    BuildAndRun $@
}
Run $@

 ライブラリ。

csrun.sh

CallCsc() { csc -nologo -recurse:*.cs -out:"$(GetOut $@)" $@; }
GetOut() {
    while [ "$1" != "" ]; do
        [ "${1:0:5}" = '-out:' ] && { echo -n "${1:5}"; return; }
        shift
    done
    echo -n "Program.exe"
}
FindExe() { find . -name *.exe | xargs -I@ basename @; }
CallChmod() { chmod ${2:-755} "$1"; }
RunExe() { "./$1"; }
BuildAndRun() {
    local exe_name="$(GetOut $@)"
    CallCsc $@
    CallChmod "$exe_name"
    RunExe "$exe_name"
}

解決

 前回、エントリポイントがあるクラス名はProgramでなければ実行できなかった。これが解決した。

 ただし、以下のような妥協である。

  • もし-out:任意実行ファイル名なら、エントリポイントがあるクラス名が何であれ、指定した名前で生成し、実行する
  • もし-outを指定せず省略したら実行ファイル名はProgram.exeである。その名前で実行する

 本来ならデフォルト動作と同じにしたかった。つまり、エントリポイントがあるクラス名と同じ名前にしたかった。だが、その名前を取得する方法がない。自力でソースコードを解析するか、一旦自動生成した.exeファイル名を取得するしかない。

問題

実行ファイル名不定問題

 cscにおいてコンパイルすると実行ファイルが自動生成される。だが実行権限がないためchmodで付与せねばならない。このとき、実行ファイル名が必要である。

 実行ファイル名は不定である。デフォルトでは、ソースコードのうちエントリポイントstatic void Mainが存在するクラス名を実行ファイル名とする。もし-out引数があれば、その名前を実行ファイル名とする。つまり、これらを動的に取得することで実行ファイル名が判明する。

 さすがにコード解析するのは大変。そこで、-out引数により固定名を与えてしまうのが簡単だ。たとえばProgram.exeがデフォルトに近いだろう。エントリポイントがあるクラス名が何であれ固定名を与えることで、コード解析せず実行ファイル名を確定できる。

 もしコマンド引数に-outがあればその値を返す。無ければProgram.exe

所感

 自動生成した.exeファイル名を取得し、それを実行させればいいとも思う。なのでFindExe関数も作ってある。

対象環境

$ uname -a
Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux