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
関数も作ってある。
対象環境
- Raspbierry pi 3 Model B+
- Raspbian stretch 9.0 2018-11-13 ※
- bash 4.4.12(1)-release ※
- SQLite 3.29.0 ※
- C# dotnet 3.0.100 ※
$ uname -a Linux raspberrypi 4.19.42-v7+ #1218 SMP Tue May 14 00:48:17 BST 2019 armv7l GNU/Linux