$ git clone --recursive git://git.haskell.org/ghc.git
$ mkdir ghc_build $ cd ghc_build
$ brew install cabal-install
$ cabal install happy $ cabal install Alex
$ cd /usr/local/bin $ ln -s ~/.cabal/bin/happy happy $ ln -s ~/.cabal/bin/alex alex
https://ghc.haskell.org/trac/ghc/wiki/Building/GettingTheSources % git clone --recursive git://git.haskell.org/ghc.git
% brew install m4 % brew install autoconf % brew install automake
$ git clone --recursive git://git.haskell.org/ghc.git
$ cd ghc
$ mkdir ghc_build $ cd ghc_build
$ lndir ../ghc $ ln -s ../ghc/.git
$ ./ boot 以前はPerlだったらしいがPythonに変わってた
$ ./configure
$ ./configure --prefix=$PWD
configureにときにhappyが無いと言われるケースが存在する. happyはhaskellのパーサジェネレータで,Haskellのstack(The Haskell Tool Stack)かcabalで導入する.
stackの場合 ghcも入る
$ brew install stack $ stack install happy
cabal
$ brew install cabal-install $ cabal update $ cabal install happy
$ cp mk/build.mk.sample mk/build.mk $ vim mk/build.mk12行目辺りの以下の部分を#を消して有効に
#BuildFlavour = perf80行目付近の以下の部分を
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
今はこうする?
GhcStage1HcOpts? = -O0 $(GhcFAsm) -fprof-auto -DDEBUG GhcStage2HcOpts? = -O0 $(GhcFAsm) -fprof-auto -DDEBUG
$ make MAKE="make -j" -j $ make installprefixを指定した場所に、ghcができている。指定してなければ/usr/local/bin/。
$ rm **/*.hi-boot
$ rm libraries/botstrapping.conf $ ghc-pkg init libraries/bootstrapping.conf
$ vim ghc
$ ./ghc ../append.hs
これで、ghcを実行する時、どのファイルが呼ばれるかがわかる
$ lldb -- /Users/one/workspace... append.hs
これでは、mainがないというエラーが出る話が
$ ghc_build/bin/ghc -c append.hs
$ ghc_build/bin/ghc -S append.hs
$ cd ghc_build/compiler
-cpp : Cのプリプロセッサを通す -I : #includeファイルを探すディレクトリを、通常のCでの方法で指定する -S : .s(アセンブラコード)を生成 -i : 必要なモジュールのディレクトリを指定する -D : 値を定義する
$ ghc --help $ man 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
let s = SysTools.initSysTools ( Just "/Users/one/workspace/ghc_build/lib/ghc-7.9.20141204" ) ss <- s
let df = DynFlags.defaultDynFlags s
HscMain.newHscEnv df
スライド(http://www.scs.stanford.edu/11au-cs240h/notes/ghc-slides.html#%281%29)を 読んで、Haskell Compilerについて勉強する。
スライド(http://www.slideshare.net/dec9ue/rts-gc)を読んで、 Gerbage Collectionについて勉強する。
$ -fno-code を適用すると .o が作成されなくなる
GhcDebugged=YES
GhcDebugged=NO
GhcDebugged=YES
定義を確認し、alexにかけることで**.hsに変換 alex Parser.x 変換したParser.hsを読む。
$ ../../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
Parser.y を happyで *.hsに変換
happy Parser.y
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
Hskellからcoreにするときにdesugarするので、Desugarを追う。 -> desugar/Desugar.hsに書かれてる。
data Tree a v = Node a v (Tree a v) (Tree a v) | Leaf deriving (Show) insert :: (Ord a ) => Tree a v -> a -> v -> Tree a v insert Leaf k v = Node k v Leaf Leaf insert (Node k v left right) k1 v1 | k == k1 = Node k v1 left right | k > k1 = Node k v (insert left k1 v1 ) right | k < k1 = Node k v left ( insert right k1 v1) test1 = Node 1 0 Leaf Leaf test2 = insert test1 2 1
data Tree a v = Node a v (Tree a v) (Tree a v) | Leaf deriving (Show) insert :: (Ord a ) => Tree a v -> a -> v -> Tree a v insert Leaf k v = Node k v Leaf Leaf insert (Node k v left right) k1 v1 | k == k1 = Node k v1 left right | k > k1 = Node k v (insert left k1 v1 ) right | k < k1 = Node k v left ( insert right k1 v1) test1 = Node 1 0 Leaf Leaf test2 = insert test1 2 1
main = do
return test2