0

私は次の構造を持っています

home
|-- Makefile
|-- H1
|   |-- Makefile
|   `-- h1.c
|-- H2
|   |-- Makefile
|   `-- h2.c
|-- main.c

H1/メイクファイル

h1.o:h1.c
        gcc -c h1.c

H2/メイクファイル

h2.o:h2.c
        gcc -c h2.c

ホーム/メイクファイル

DIR = h1 h2
main.out:main.o
        for i in $(DIR);\
        do (cd $$i; make);\ //1.why () used here to encolose 2 commands and $$ before the i
        done
        gcc -o main.out main.o ./h1/h1.o ./h1/h1.o

main.o:main.c
        gcc -c main.c

上記は正常に機能し、出力ファイルを提供しますが、これがこのコンパイルを行う効率的な方法であるか、またはこれを行う他の方法であるかは疑問です。

私の質問はコードのコメントに記載されており、以下にも続きます

I have tried like 
do(cd $i;make;)//this showing error
also do(cd $$i;)make;//this also sowing error

、親切にアイデアを教えてください。ここで何が起こっているのですか。私はいくつかの本を調べましたが、$$ は現在のプロセス Id を意味することがわかりましたが、ここで i の前にこれを使用することは何ですか。

()また、2 つのコマンド [cdmake]を囲むために ,を使用する意味は何ですか。

私の疑問に答えてください。

4

2 に答える 2

1

1: @BasileStarynkevitchが言うように、Makeはこれを拡張します:

for i in $(DIR); do (cd $$i; make); done

これに:

for i in h1 h2; do (cd $i; make); done

そしてそれをシェルに渡します。

2:括弧は必要ありません。これも同様に機能します。

for i in $(DIR); do cd $$i; make; done

[Virgileが指摘したように、私はこの点について間違っていました。]

3: @BasileStarynkevitchが言うように、$(MAKE) -C $$iよりも優れていcd $$i; makeます。

4:ループなしで実行できます(したがって、依存関係を正しく処理できます)。

h1/h1.o: h1/h1.c
    $(MAKE) -C h1

h2/h2.o: h2/h2.c
    $(MAKE) -C h2

main.out:main.o h1/h2.o h1/h2.o
    gcc -o main.out main.o ./h1/h1.o ./h2/h2.o

5:再帰なしで完全に行うことができます:

h1/h1.o: h1/h1.c
    gcc -c h1/h1.c -o h1/h1.o

h2/h2.o: h2/h2.c
    gcc -c h2/h2.c -o h2/h2.o

5:自動変数を使用して、ルールをより明確にすることができます。

h1/h1.o: h1/h1.c
    gcc -c $< -o $@

h2/h2.o: h2/h2.c
    gcc -c $< -o $@

main.out:main.o h1/h2.o h1/h2.o
    gcc -o $@ $^

さらに単純化することもできますが、そのような単純なmakefileの場合は価値がありません。

于 2012-10-21T17:00:26.873 に答える
1

makeルールのアクションですべてのmake-variables ($(CFLAGS)または など) を展開し、シェルを使用してそれを実行します。$@として$$展開され$ます。したがって、シェルは$iそのforループ内を認識します。$iルールのみを記述した場合は、シェルを呼び出す前$(i)に空に展開されます ( make にはバインドされたmake-variableがないため)。makei

何が起こっているのかを理解するために、GNU remakeを使用してくださいremake -x

ところで、私はあなたMakefileが間違っていると信じています:(cd $$i; make)そうあるべきです$(MAKE) -C $$i (GNU makeプロセスは非常に特別な$(MAKE)ので、たとえば、を開始するときmake -j 2

于 2012-10-21T16:14:58.947 に答える