0

私は今日この問題に頭を悩ませてきました。

多くのディレクトリに多くのcファイルがあります。それらはすべてコンパイルしてライブラリにリンクする必要があります。

ファイルの架空のレイアウトは次のとおりです。

main_dir/
  thing1/
    thing1.c
  thing2/
    thing2.c
  thing3/
    thing3.c
MakeFile

これらのファイルを「検索」して必要なオブジェクトを生成するmakefileがありますが、常に同じcファイルが入力として使用されます。

Makefileは次のようになります(各ファイルの内容は、それぞれがputs()を使用する関数です)。

C=gcc
CFLAGS=-Wall -g
OBJDIR=obj
SRC=$(shell find src/ -type f -name "*.c")
SRC_DIRS=$(shell find src/ -type f -name "*.c" -exec dirname {} \; | uniq)
OBJS=$(SRC:%.c=${OBJDIR}/%.o)    

$(OBJS) : $(SRC)
    @echo Compiling : $<
    $(C) -c $(CFLAGS) -o $@ $<

clean:
    rm -fv $(OBJS) thingy.a

folders:
    $(call build_dirs)

all: folders $(OBJS)
    ar -r -o thingy.a $(OBJS)

define build_dirs
    for dir in $(SRC_DIRS); do \
        mkdir -pv $(OBJDIR)/$$dir; \
    done
endef

作成からの出力:

for dir in src/thing1 src/thing2 src/thing3; do mkdir -pv obj/$dir; done
Compiling : src/thing1/thing1.c
gcc -c -Wall -g -o obj/src/thing1/thing1.o src/thing1/thing1.c
Compiling : src/thing1/thing1.c
gcc -c -Wall -g -o obj/src/thing2/thing2.o src/thing1/thing1.c
Compiling : src/thing1/thing1.c
gcc -c -Wall -g -o obj/src/thing3/thing3.o src/thing1/thing1.c
ar -r -o thingy.a obj/src/thing1/thing1.o obj/src/thing2/thing2.o obj/src/thing3/thing3.o
ar: creating thingy.a

問題は$(OBJS)での$(SRC)の使用にあると確信しています:$(SRC)しかし、どうしたらよいかわかりません。

助けてくれるMakeFuを持っている人はいますか?

4

2 に答える 2

1

$(OBJS)は正しく設定されているようです。したがって、($(OBJ):$(SRC)ターゲットの代わりに)次のように機能するはずです。

$(OBJDIR)/%.o : %.c
    @echo Compiling : $<
    $(C) -c $(CFLAGS) -o $@ $<
于 2012-09-27T19:11:45.603 に答える
1

あなたは$(OBJS)ルールが問題であるということについて正しいです。

変数を見てください:(SRC)src/thing1/thing1.c src/thing2/thing2.c src/thing3/thing3.c、、$(OBJS)はですobj/src/thing1/thing1.o obj/src/thing2/thing2.o obj/src/thing3/thing3.o。(srcディレクトリが必要ですか?)ここで、次のルールを使用しobj/てビルドするとします。obj/src/thing2/thing2.o

$(OBJS) : $(SRC)
    @echo Compiling : $<
    $(C) -c $(CFLAGS) -o $@ $<

前提条件フィールド($(SRC))は「src /thing1 /thing1.csrc/thing2/thing2.csrc/thing3/thing3.c」に展開されるため$<、「src/thing1/thing1.c」に展開されます。明らかに、この場合に必要なのは「src / things2 / things2.c」なので、これが前提条件フィールドである必要があります。必要なのは、パターンルール静的パターンルールのようなものです。秘訣は、事前にパスがわからず、Makeがパターンをうまく処理できないため、巧妙である必要があるということです。

$(OBJS) : $(OBJDIR)/%.o : %.c
    @echo Compiling : $<
    $(C) -c $(CFLAGS) -o $@ $<
于 2012-09-27T23:53:03.780 に答える