Haskell/GHCスクリプティング時の実行ファイルパス取得、あるいはGHCが公開するC言語APIは何処にあるか?
問題
runhaskell/runghcを用いることにより、Haskell/GHCではshebangを書き込んだスクリプティングが可能である。 特にStackの登場以降、依存性の解決も容易となり非常に気軽に扱えるようになった。
個人的にシェルスクリプトは避けていきたいため、これは渡りに船だ。しかし基準となる実行ファイルのパスが取得できないという問題があった。 System.EnvironmentのgetExecutablePath関数だとビルドツールの作業ディレクトリを見に行ってしまうのである。
解決策
FindBinパッケージのgetProgPath関数はスクリプティング時に実行ファイルのパスを取得し、コンパイルするプログラムであれば実行するバイナリのパスを取得する。一見その古さに驚くがlts-8.21(GHC 8.0.2)にて動作を確認した。
FindBin: Locate directory of original program
この実装が以下となる。
さて、ここでヘッダファイルの読み込み無しにforeign import ccallされているgetProgArgv関数らは一体何者だろうか? (なおgetProgArgvはSystem.Environmentでも使われている)
これらの正体はGHCがghc/includes/RtsAPI.h
にて公開している関数である。詳細は以下が詳しい。
この疑問はHaskell-jpのSlackにて@hiratara氏に答えをいただいた。
Commentary/SourceTree/Includes – GHC
実際のコードはgithubの方が見やすい。
そろそろ象牙の塔の外側が見えてきたようだ。