Entries

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

大文字のファイル名とインクルード

タグ: C++ gcc

Linux用に作られたソース群をMacでビルドする作業中。
「特に何のエラーも出ないな」とか言った矢先に、ずらずらと姿を現す「未定義」エラーたち。

/usr/include/c++/4.0.0/bits/localefwd.h:124: error: ‘mbstate_t’ was not declared in this scope
/usr/include/c++/4.0.0/bits/localefwd.h:124: error: template argument 3 is invalid
/usr/include/c++/4.0.0/bits/localefwd.h:126: error: ‘mbstate_t’ was not declared in this scope
/usr/include/c++/4.0.0/bits/localefwd.h:126: error: template argument 3 is invalid
/usr/include/c++/4.0.0/bits/localefwd.h:132: error: expected type-specifier before ‘istreambuf_iterator’
/usr/include/c++/4.0.0/bits/localefwd.h:132: error: expected `>' before ‘istreambuf_iterator’
……

こんな(標準ヘッダファイルがインクルードしている)ファイルでエラーが出るとは、嫌な感じだ。
mbstate_t はよく知らないが、 istreambuf_iterator くらいは必要なら自分でインクルードするのではないか? 標準ヘッダなら。

これは何かおかしい。
もしかしたら誰か読み込むヘッダを間違っているのかもしれない。
とりあえず、コンパイルエラーを起こしているファイルの中身を

#include <iostream>

だけにしてコンパイルしてみる。

../util/time.h:29: error: expected constructor, destructor, or type conversion before ‘&’ token
/usr/include/c++/4.0.0/ctime:68: error: ‘::tm’ has not been declared
/usr/include/c++/4.0.0/ctime:70: error: ‘::clock’ has not been declared
/usr/include/c++/4.0.0/ctime:71: error: ‘::difftime’ has not been declared
……

( ゚д゚)ポカーン
標準ヘッダしかインクルードしていないのに、最初の行の相対パスは一体……って、あ、いや、そうか。

../util は -I../util によってインクルードパスに指定されている。
そしてその中には「time.h」は存在しないが、頭文字が大文字の「Time.h」が存在する。
「大文字小文字を区別する」ファイルシステム(元の環境のような)であれば、この2つは別物として扱われる。
だがMacの現在一般的なファイルシステムは「大文字小文字を区別しない」。
そのため、標準ヘッダが標準ヘッダの「time.h」をインクルードしようとして、パス優先度が上位にきている ../util の「Time.h」をインクルードすることになってしまったのだ。
このことは g++ -Mg++ -M -I../util の出力を見比べてみるとよく分かる。

  • g++ -M コンパイルエラーを起こしているファイル | grep time.h

      /usr/include/time.h /usr/include/_structs.h /usr/include/sys/_structs.h \
  • g++ -M -I../util コンパイルエラーを起こしているファイル | grep time.h

      ../util/time.h /usr/include/ctype.h /usr/include/runetype.h \

この状態を解決するには、問題のパスをメインインクルードパスに追加(-I../util)するのではなく、第2インクルードパスに追加(-idirafter ../util)すれば良い。

もっとも、そもそもこんなことにならないよう、予め「大文字小文字を区別しないファイルシステムでも重複しない名前を付ける」とか、「インクルード対象が曖昧にならないよう構成(例えばBoostなどのように)しておく」ことの方が大切なのだが。

スポンサーサイト

コメント

コメントの投稿

コメントの投稿
管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://idlysphere.blog66.fc2.com/tb.php/124-049573d3
この記事にトラックバックする(FC2ブログユーザー)

Appendix

タグ

Blog内検索

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。