2

非再帰的なメイクファイルを使用して単純なプロジェクトを完成させるために、いくつかの例を検索して試してみました。以前は、単純な単一ディレクトリのコードベースを使用していましたが、現在は複数のエンジニア用の環境をまとめています :-)

+--app
|  +-- obj/
|  +-- Makefile
|  +-- first.c
|  +-- second.c
|
+--lib1
|  +-- obj/
|  +-- Makefile
|  +-- foo.c
|  +-- bar.c
|
+--lib2
|  +-- obj/
|  +-- Makefile
|  +-- sample.c

ライブラリコードと複数のアプリケーションがすべて「app」ディレクトリにある2つのディレクトリ(おそらく3番目以降)だけです。きれいにするために、.o ファイルと .d ファイルを別の obj/ ディレクトリに保持したいと考えています。

  1. ライブラリを検証するために、lib1 や lib2 などの各サブディレクトリで「make」を実行できるようにしたいと考えています。それぞれ libabc.a と libxyz.a が生成されます。
  2. 簡単な Makefile を書きましたが、ルールが機能せず、GNU の make マニュアルを理解しようとしましたが、道に迷っています。

lib1/メイクファイル:

lib_src = foo.c bar.c
lib_obj = $(patsubst %.c,obj/%.o,$(lib_src))
libabc.a: $(lib_obj)
    @echo [Archive... $(@F)]
    @$(AR) -cr libabc.a $^
obj/%.c : %.c 
    $(CC) $(CFLAGS) -c -o $@ $<

アプリ/メイクファイル:

ALL_APP = first second
% : %.c libabc.a libxyz.a
     $(CC) $(CLFAGS) $^ -o $@
include ../lib1/Makefile
include ../lib2/Makefile

ここで、各 Makefile で同じターゲットを定義するのに問題があります (明らかに)。lib1 が含まれているため、lib1/Makefile と app/Makefile でクリーンを定義できなかったように。lib1だけでmake cleanを実行できることを望んでいましたが、理にかなっています。

「app」でmakeを行うと、obj/foo.oを作成するルールがなくなりました。パスがすべて偽物だからだと思います。「obj/」は lib1/obj/ を参照しますが、Makefile が含まれているため、すべて失われます。

上記のような本当に単純な Makefile を使用してプロジェクトをビルドできますか。オンラインのほとんどの例は、より多くのことを達成しようとしているため、かなり複雑です (私は信じています)。

事前に感謝します(何度も議論されたトピックについて申し訳ありません). automake と cmake は、できれば今すぐに学習したくありません。私のプロジェクトが、これらの強力なツールの使用を保証しないほど単純であることを願っています。

よろしくお願いします、

4

1 に答える 1

3

から始めましょうlib1/Makefile

lib_src = foo.c bar.c
lib_obj = $(patsubst %.c,obj/%.o,$(lib_src))

libabc.a: $(lib_obj)
    @echo [Archive... $(@F)]
    @$(AR) -cr libabc.a $^

obj/%.c : %.c 
    $(CC) $(CFLAGS) -c -o $@ $<

変数を導入しHERE、いくつかの小さな変更を加えます。

HERE := ../lib1

lib_src := foo.c bar.c
lib_obj := $(patsubst %.c,$(HERE)/obj/%.o,$(lib_src))

$(HERE)/libabc.a: $(lib_obj)
    @echo [Archive... $(@F)]
    @$(AR) -cr $@ $^

$(HERE)/obj/%.c : $(HERE)/%.c 
    $(CC) $(CFLAGS) -c -o $@ $<

この makefile は、 内から呼び出されたときと同様に機能しますlib1/。しかし、対応する変更を に加えたら、次のように変更lib2/Makefileできますapp/Makefile

ALL_APP = first second
% : %.c ../lib1/libabc.a ../lib2/libxyz.a
     $(CC) $(CLFAGS) $^ -o $@

include ../lib1/Makefile
include ../lib2/Makefile

さて、cleanルールです。lib1/Makefile=>lib1/lib1.maklib2/Makefile=>の名前を変更lib2/lib2.makし、新しい を書きますlib1/Makefile:

include lib1.mak

clean:
    @rm -f lib*.a obj/*

で同じことを行い、次のlib2/ように変更しapp/Makefileます。

...

include ../lib1/lib1.mak
include ../lib1/lib1.mak

clean:
    @rm -f $(ALL_APP)
    @$(MAKE) -C ../lib1 clean
    @$(MAKE) -C ../lib2 clean

(再帰なしでそれを行うこともできますが、それはより複雑になります。このように再帰的な Make を使用しても、実際には何も問題はありません。)

いくつかのさらなる改良が可能です。たとえば、パスlib1/lib1.maklib2/lib2.makこのようにハードコーディングするのは良くありませんが、これは修正できます。でもこれで1日は十分です。

于 2014-10-28T22:54:20.237 に答える