ソフトウェアとハードウェアの境界

ホビー開発に関する誰得情報満載☆

gvimでコンパイル時、error、warning箇所にジャンプできない

gvimのmakeとquickfix

gvimのmakeコマンドはquickfixと組み合わせると、errorやwarning箇所にすぐにジャンプすることができてとても便利だ。
コーディングがあらかた終わって、errorとwarningを取る作業をしている時など、なくてはならない存在だ。
現在僕は、KOZOSでsl811のドライバとUSBライブラリを作成(と言うか改修)しようとしているのだが、まぁwarningもerrorも多数出る。
いつもの如くquickfixを開き、エラー箇所にジャンプしようとするとこんなことになった。
f:id:tokixy56:20151222001607p:plain
ぶらんく(´・ω・`)
何やらパスの部分に「In file included from...」みたいなことが挟まれてる。h8300-elf-gccから出力されるパスがおかしいのか、gvimの解釈の仕方がおかしいのか、とぼんやり考えた。いろいろ考えた結果、コンパイラwindowsでのパスで表示するか、unix系のパスで表示するかちょっと変な感じになってて、ジャンプできないんじゃないかという結論に達した。そう思い違ったのが最大の失敗で、ここから地獄のGNU Toolchainコンパイル作業が始まった。

H8用gccコンパイラWindows上でソースから作成する(失敗)

前回の記事にも少し書いたのだが、これは非常にうまく行かなかった。まさか自分でgccbinutilsソースコードを修正する(実際には.texiなどのtexinfo系)とは思ってもいなかった。が、結果としてできなかったので、あえてその詳細は伏せておこう…。
いや、やっぱりちょっと書く。笑
コンパイルした環境としては、cygwinとmingw32の2つ。cygwinでは--hostと--buildを指定しないパターンと、--host=i686-w64-mingw32のパターンの2種類で実行したので、最終的には3パターンで作業した。結果としてはすべて惨敗。
最終的に頓挫した原因はnewlibであった。newlibのコンパイルで失敗する。「…ar: ../stdlib/lib.a: No such file or…」みたいなのが複数出る。なんでlib.aが作成されてないのかわからない。もう流石に開始から3週間ほど経っていたので諦めた…結果としてbinutilsとcコンパイラはできたので、それだけでよしとするか。KPITのインストーラでインストールしたものでh8300-elf-gcc -vして詳細を見たら、linuxmingwで作成した模様。windowsではそもそもできないのか??KPITはどうやってコンパイルしたんだろう。しかもzlib.dllやその他のdllも必要としない.exeである。この偉業に脱帽。
この作業をしていた時に参照させて頂いたのが以下のページだった。
イッチョカマーの徒然草: ARM用クロスコンパイラのビルド(Windows8+Cygwin)
OSDev.org • View topic - GCC for x86_64 + newlib problems
H8用コンパイラ GCC(Cygwin)
CygwinでH8のクロスコンパイル環境を作る » NezBlog
新たな挑戦者の登場と良い結果報告に期待する。

gvimの問題

こちらが本題だ。
結局、KPITのインストーラからインストールしたh8300-elfコンパイラを使用することにしたのだが、そもそも、ジャンプできない原因はコンパイラにあるのか?という疑問がふとよぎった、いや、1週間経ったあたりからその方向は見ないようにしてた。だって1週間が無駄になっちゃうじゃない。
そして3週間が過ぎて「この愚か者!!」と自分を罵った。
どうやら、コンパイラのバグではないようだ。gvimの問題と、なおかつmakefileの作りがまずいと起こるらしい。
そもそも僕は、過去記事にも書いたように、NERDTreeを使ってプロジェクトっぽくして使用してる。
tokixy56.hatenablog.com
プロジェクトパスとして設定しているディレクトリにcdして、そこのmakefileを実行する、という形をとっている。
ちなみに、現在の僕のKOZOSプロジェクトはGithubに登録してある。
github.com
また、ジャンプできなかった当時のmakefileは、ヘッダファイルの参照パスを指定するオプション-Iで、-I../commonのように、相対パスを指定していた。
加えて、以下の原因もあった。
stackoverflow.com
つまり、ジャンプできない原因は以下の2点である。

  • 相対パス指定のため、gvimのカレントディレクトリから見たパスにジャンプするため、必要なディレクトリが省かれ、ファイルが見つからない。
  • 「In file included ...」もファイル名であると解釈される。

ということであった。
上記を参考に、.vimrcとmakefileを修正しよう。

.vimrc
"makeコマンドのパスを指定
set makeprg=C:/Users/tokixy56/Work/cygwin/bin/make.exe
"バックスラッシュやめてっていう設定
set shellslash
"In file includeで区切る設定
set errorformat^=%-GIn\ file\ included\ from\ %f:%l:%c:,%-GIn\ file\ included\ from\ %f:%l:%c\\,,%-GIn\ file\ included\ from\ %f:%l:%c,%-GIn\ file\ included\ from\ %f:%l
makefile
...
###cygwinじゃない場合、$(realpath ..)だけでいい
HEADPATH = $(shell cygpath -m $(realpath ..))
########## コンパイルオプション(Compile Flags)
...
CFLAGS  += -I.#             ヘッダファイルの検索先を指定する
#CFLAGS    += -I../include     相対パスの指定をやめる
#CFLAGS    += -I../daemon      上に同じ
CFLAGS  += -I$(HEADPATH)/include
CFLAGS  += -I$(HEADPATH)/daemon

cygwinのmakeコマンドで普通にmakeすると、Unix形式のパスで表示されてしまい、これもまたgvimでジャンプすることができない。$(shell cygpath -m ...)で囲んであげることで、windows形式に変換することができる。cygpathの使い方はググろう。
絶対パスにしておけば、どこにエラーがあっても間違えることなくジャンプすることができる。
基本的にはgvimからコンパイルするより、シェルから実行する方が良いのだろうが、もしできる環境にあるのならば試してみてはいかがだろうか。
しかし、linuxwindowsの環境のことを考えてmakefileも書き換えないといけないなぁ…