わいえむねっと

Contents
Categories
Calendar
2007/09
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30
Monthly Archives
~2000/01
Recent Entries
RSS1.0
Templates
Information
Processed: 0.053 sec
Chashed: -
2007/09/10 Mon
道路に出た瞬間に土砂降られる。 なぜなぜQ&Q!(懐かしすぎる)

Q:カレント以外に置いてあるファイルをカレント内の同名ファイルより優先的にインクルードするには?
Q:そもそも、なんでそんな配置なの?

コンパイル前後でリネームするとか。
gccなら-I-、Visual C++なら/Xで検索パスをどうにかするとか。
ただし、/Xは-I-と違って全てのパスが消えるので、$(VCInstallDir)\includeとかの追加が必要になって鬱陶しい。

http://www.linux.​or.jp/JM/html/GNU_gcc/man1/gcc.1.html​
これに加えて `-I-' オプションは、カレントディレクトリ (現在の入力ファイルが存在するディレクトリ) が `#include "file"' に対する最初の検索対象となることを抑制します。`-I-' によるこの効果を上書きする方法はありません。`-I.' を指定することによって、コンパイラが起動されたディレクトリが検索されることを指定することは可能です。これはプリプロセッサが行なうデフォルトの動作とは異なりますが、たいていはこれで十分です。

http://msdn2.micr​osoft.com/ja-jp/library/93t31bx4(VS.80).aspx
環境変数 PATH と INCLUDE で指定されたディレクトリ内でインクルード ファイルが検索されなくなります。
Q:-MMで依存関係を出力しているのに依存ファイルを更新してもMakefileと別ディレクトリにあるソースが再コンパイルされないのですが?
Q:だから、なんでそんな配置なの?

-MMとか使わず自前で依存関係を記述するとか。
そもそも、

$ cat Makefile
TARGET      =   foo
SRCS        =   foo.cc \
                bar/bar.cc
OBJS        =   $(SRCS:%.cc=%.o)
DEPEND      =   $(TARGET).d
CXXFLAGS    =   -Ibar
 
all: $(TARGET)
 
$(TARGET): $(OBJS)
 
$(DEPEND): $(SRCS)
    $(CXX) $(CXXFLAGS) -MM $^ >$@
 
include $(DEPEND)

とかなっていた時、dependファイルには

$ cat foo.d
foo.o: foo.cc foo.h bar/bar.h
bar.o: bar/bar.cc bar/bar.h

のようにbar/bar.oではなくbar.oの依存関係として出力されており、bar/bar.oには結局暗黙ルールが使われてしまう。
ので、

$(DEPEND): $(SRCS)
    $(CXX) $(CXXFLAGS) -MM $^|perl -e '\
    do{\
        do{\
            /([^\/]+)$$/ and $$IN =~ s/$$1/$$_/\
        } foreach split(/\s/, qq{$(OBJS)});\
        print $$IN\
    } while($$IN = <>)' >$@

とかして-MMの出力結果を加工してみる。

$(DEPEND): $(SRCS)
    $(CXX) $(CXXFLAGS) -MM $^|perl -e '\
    do{\
        sub{\
            do{\
                /([^\/]+)$$/ and $$_[0] =~ s/$$1/$$_/\
            } foreach split(/\s/, qq{$(OBJS)})\
        }->($$_);\
        print\
    } while(<>)' >$@

無名サブルーチンで一時変数を除去。

$(DEPEND): $(SRCS)
    $(CXX) $(CXXFLAGS) -MM $^|perl -pe '\
    sub{\
        do{\
            /([^\/]+)$$/ and $$_[0] =~ s/$$1/$$_/\
        } foreach split(/\s/, qq{$(OBJS)})\
    }->($$_)' >$@

-pでwhileとprintを省略。

$(DEPEND): $(SRCS)
    $(CXX) $(CXXFLAGS) -MM $^|perl -0pe 'sub{do{/([^\/]+)$$/ and $$_[0]=~s/$$1/$$_/}foreach split(/\s/,qq{$(OBJS)})}->($$_)' >$@

ワンライナー。
ついでに繰り返しが無駄なので-0。
デミタス。
舌打ち。
デミタス。
舌打ち。
デミタス。
舌打ち。 玉音を聴いた。