- 追加された行はこの色です。
- 削除された行はこの色です。
*コンパイラ構成論ソース読み会 〜ghc〜 [#i886aa16]
**ghcインストール前に入れる [#h44f1f9a]
$ git clone --recursive git://git.haskell.org/ghc.git
-/usr/local/以下にインストールしても構わない場合はcloneしてきたディレクトリ上に移動して作業する
-install先を指定する場合は以下の処理を行ってから作業する
--ディレクトリ作成、移動
$ mkdir ghc_build
$ cd ghc_build
--
--cabalをインストールする
$ brew install cabal-install
--happyとAlexをインストールする
$ cabal install happy
$ cabal install Alex
--happyとAlexにシンボリックリンクを貼る
$ cd /usr/local/bin
$ ln -s ~/.cabal/bin/happy happy
$ ln -s ~/.cabal/bin/alex alex
**インストール [#w4862c51]
-公式ホームページ(https://ghc.haskell.org/trac/ghc/wiki/Building/Using)を参考に
-git で落としてくる
$ git clone --recursive git://git.haskell.org/ghc.git
-/usr/local/以下にインストールしても構わない場合はcloneしてきたディレクトリ上に移動して作業する
$ cd ghc
-install先を指定する場合は以下の処理を行ってから作業する
--install先ディレクトリ作成、移動
$ mkdir ghc_build
$ cd ghc_build
--ソースへのリンク作成
$ lndir ../ghc
$ ln -s ../ghc/.git
-bootスクリプトの実行
$ perl boot
-configureの実行
$ ./configure
--install先をしてする場合は以下のようにprefixを指定する
$ ./configure --prefix=$PWD
-build.mk の作成
--mk以下にbuild.mk.sampleというファイルがあるのでそれをコピーして編集
$ cp mk/build.mk.sample mk/build.mk
$ vim mk/build.mk
12行目辺りの以下の部分を#を消して有効に
#BuildFlavour = perf
80行目付近の以下の部分を
ifeq "$(BuildFlavour)" "perf"
# perf matches the default settings, repeated here for comparison:
SRC_HC_OPTS = -O -H64m
GhcStage1HcOpts = -O -fasm
GhcStage2HcOpts = -O2 -fasm
このように編集する
ifeq "$(BuildFlavour)" "perf"
# perf matches the default settings, repeated here for comparison:
SRC_HC_OPTS = -O -H64m
GhcStage1HcOpts = -O -fasm -DDEBUG
GhcStage2HcOpts = -O2 -fasm -DDEBUG
-makeとmake installする
--top levelのmakeが下のmakeを呼ぶときに -j が引き継がれるようにする。
$ make MAKE="make -j" -j
$ make install
prefixを指定した場所に、ghcができている。指定してなければ/usr/local/bin/。
-エラーと対処法
--Bad interface file: ***.hi-boot
--Bad interface file: ***.hi
---異なるバージョンのghcでコンパイルされたバイナリが残っているのが原因なのでいちど.hi-boot,.hiファイルを消す。
$ rm **/*.hi-boot
--ghc-pkg: ghc no longer supports single-file style package databases
---ghc-pkg 7.9ではファイル形式のデータベースはサポートしていないのでinitし直す必要がある。
---古いghcを消した時に発生した。
$ rm libraries/botstrapping.conf
$ ghc-pkg init libraries/bootstrapping.conf
* 1日目 [#f8353671]
** どこのghcが呼ばれているのかを調べる [#fbf44b30]
-新しくインストールしたghcを、適当なディレクトリに移動する
$ vim ghc
-最後の行のexecをechoに変更する
$ ./ghc ../append.hs
これで、ghcを実行する時、どのファイルが呼ばれるかがわかる
** lldbで追っかけようとした [#g08dd524]
$ lldb -- /Users/one/workspace... append.hs
これでは、mainがないというエラーが出る話が
** アセンブラを生成する [#s7837b80]
-append.hsを編集し、先頭にModuleを追加する。
--.oを生成
$ ghc_build/bin/ghc -c append.hs
--.s(アセンブラコード)を生成
$ ghc_build/bin/ghc -S append.hs
** ghc_build/compiler/main/HscMain.hsをghciで動かす [#m31d55a7]
-ghcがあるディレクトリへ移動
$ cd ghc_build/compiler
-Hscmain.hsを、ghciで動かすために様々なオプションを追加する
-cpp : Cのプリプロセッサを通す
-I : #includeファイルを探すディレクトリを、通常のCでの方法で指定する
-S : .s(アセンブラコード)を生成
-i : 必要なモジュールのディレクトリを指定する
-D : 値を定義する
- オプションを探す場合
$ ghc --help
$ man ghc
**Main.hsを動かす [#g400a981]
-FingerPrint.hsが重複していて、エラーが出た
--FingerPrint.hsを読み込まないように、
--__GLASGOW_HASKELL__ < 707なif文にかかる処理を取った
---これをとるとmakeが通らなくなったので必要な処理だったようだ
---buildされるghcのバージョンではなくbuildに使用したghcのバージョン?
$ ghci -fno-code -cpp -DSTAGE=2 -I. -I../ghc -I./stage2 -I./stage2/build -iutils:main:prelude:hsSyn:types:typecheck:deSugar:stage2/build:parser:iface:basicTypes:profiling:specialise:coreSyn:cmm:simplCore:codeGen:nativeGen:StgSyn:cbits:rename:simplStg:specialise:stranal:types:vectorise:llvmGen ../ghc/Main.hs
-この方法でghciは通った
-次は、ghc_build/compiler/main/HscMain.hsを動かしたい
- HscEnv とCompileFileを呼び出せばいい
- InitSysToolsをつかってSettingsを作る
let s = SysTools.initSysTools ( Just "/Users/one/workspace/ghc_build/lib/ghc-7.9.20141204" )
ss <- s
- SettingsからDynFlagsが作れる (defaultDynFlags.Settings DynFlag.hs)
let df = DynFlags.defaultDynFlags s
- DynFlagsからHscEnvが作れる (newHscEnv HscMain.hs)
HscMain.newHscEnv df
--ライブラリが見つからないと怒られる
* 2日目 [#f8353671]
** Haskell Compilerについて勉強する [#l845347c]
スライド(http://www.scs.stanford.edu/11au-cs240h/notes/ghc-slides.html#%281%29)を
読んで、Haskell Compilerについて勉強する。
** GCについて勉強 [#yfce9ca2]
スライド(http://www.slideshare.net/dec9ue/rts-gc)を読んで、
Gerbage Collectionについて勉強する。
** Main.hsを動かす(2) [#p12e0d6c]
- .hiと.oがあると、ghciのbreak pointがかけられない。
$ -fno-code を適用すると .o が作成されなくなる
- 動かない。Makeをやりなおし。
** デバッグオプションがついてない?(問題編) [#q6bd9eea]
- config.mk.inの作成
GhcDebugged=YES
- configureを実行すると、GhcDebuggedがNOになる。
GhcDebugged=NO
* 3日目 [#c6233ecd]
** デバッグオプションがついてない?(解決編) [#k66b060e]
- 設定を書き換えたい分だけは、新しいファイル(build.mk)に書き込む。
- build.mkの作成
GhcDebugged=YES
** lldbで読もう [#da52547a]
- lldbでcプログラムを読むように、ghcの実行ファイルを読む。
- nmコマンドを使って、symboltableから、調査対象の関数名とプログラムアドレスを抜き出す。
- プログラムアドレスにbreak pointをあてて、そこからstep実行をして、動作を細かく調査しようとした。
- lldbで読んだ結果
-- ライブラリの読み込みやインダイレクトジャンプばかりをやっていて、追いにくそう..
** parser/Lexer.x を読む。 [#ke163cab]
定義を確認し、alexにかけることで**.hsに変換
alex Parser.x
変換したParser.hsを読む。
** Lexer.hsをghciにいれてみる。 [#n3117e98]
$ ../../build/bin/ghci -fno-code -cpp -DSTAGE=2 -I. -I../ghc -I./stage2 -I./stage2/build -iutils:main:prelude:hsSyn:types:typecheck:deSugar:stage2/build:parser:iface:basicTypes:profiling:specialise:coreSyn:cmm:simplCore:codeGen:nativeGen:StgSyn:cbits:rename:simplStg:specialise:stranal:types:vectorise:llvmGen ./parser/Lexer.hs
- Libraryが読み込めないからソースコードから読むことに。
- Lexer.hsには字句解析について書かれている。
- AlexInputが怪しいのでは?
-- AlexInputが書かれているコードを探す -> Parser.yに書かれているらしい
** parser/Parser.hsを読む [#eeef9a03]
Parser.y を happyで *.hsに変換
happy Parser.y
- Parser.hsで予約語の確認など(tokenとかも)
- 数字の定義をするのが大変らしい
- happyThenとは? -> ammsの定義を確認
-- aaって何? -> aa = annotation
-- amms = リストに対してannotationをマップして付けるもの
** ParseResultとは? [#t918af22]
-- parser/Lexer.hsにあるらしい
-- runParser発見!
** parser を実行したい [#l9ca87cd]
- parser/Parser.y
- happy parser/Parser.y
-- で parser/Parser.hs が手に入る
- parser は runParser で実行できそう? ソースにコメントで書かれてた
runParser :: DynFlags -> String -> P a -> ParseResult a
runParser flags str parser = unP parser parseState
where
filename = "\<interactive\>"
location = mkRealSrcLoc (mkFastString filename) 1 1
buffer = stringToStringBuffer str
parseState = mkPState flags buffer location in
** PState とは? [#ob6d27a9]
- parser/HscMain.hsにcaseで使われてる。
** Desugar を追う。 [#r6319f58]
Hskellからcoreにするときにdesugarするので、Desugarを追う。
-> desugar/Desugar.hsに書かれてる。
** dsLExprとは [#f8ac644c]
- deSugar/DsExpr.hsに書いてある。
- coreExpr を発見
-- coreの計算を行うところらしい。
--- oreSyn/CoreSyn.hsに書いてある。
- coreSyn/CoreSyn.hsでcoreの定義がされている。
** 他に読むものは? [#s1848bf0]
- typechaek/TcUnify.hsを見たら推論木がわかりそう。
- typecheck/TcType.hsを流し読み。