ここは俺の備忘録だ

少なくとも日本語での言及が少ない話をするつもりです

Haskell/GHCスクリプティング時の実行ファイルパス取得、あるいはGHCが公開するC言語APIは何処にあるか?

問題

runhaskell/runghcを用いることにより、Haskell/GHCではshebangを書き込んだスクリプティングが可能である。 特にStackの登場以降、依存性の解決も容易となり非常に気軽に扱えるようになった。

github.com

個人的にシェルスクリプトは避けていきたいため、これは渡りに船だ。しかし基準となる実行ファイルのパスが取得できないという問題があった。 System.EnvironmentのgetExecutablePath関数だとビルドツールの作業ディレクトリを見に行ってしまうのである。

解決策

FindBinパッケージのgetProgPath関数はスクリプティング時に実行ファイルのパスを取得し、コンパイルするプログラムであれば実行するバイナリのパスを取得する。一見その古さに驚くがlts-8.21(GHC 8.0.2)にて動作を確認した。

FindBin: Locate directory of original program

この実装が以下となる。

github.com

さて、ここでヘッダファイルの読み込み無しにforeign import ccallされているgetProgArgv関数らは一体何者だろうか? (なおgetProgArgvはSystem.Environmentでも使われている)

これらの正体はGHCghc/includes/RtsAPI.hにて公開している関数である。詳細は以下が詳しい。 この疑問はHaskell-jpのSlackにて@hiratara氏に答えをいただいた。

Commentary/SourceTree/Includes – GHC

実際のコードはgithubの方が見やすい。

github.com

そろそろ象牙の塔の外側が見えてきたようだ。