1

bin、inc、obj、srcなどの複数のフォルダーを持つプログラム用の「適切な」makefileを作成する必要があります。これが私のmakeファイルです。makeと入力すると、プログラムはまったくコンパイルされていませんが、何もできないとだけ表示されます。どこかにエラーがあると思いますが、本当に見つかりません。(ps私は作るのがまったく新しいです)。あなたの助けをどうもありがとう!

binフォルダー内のmakefile:

vpath %.o ../obj/
$(prog): $(objs)
$(cc) $(ccflags) -o $@ $^ $(ldflags)

objフォルダー内のmakefile:

vpath %.c ../src
vpath %.h ../inc
all: $(objs)
%.o: %.c %.h
$(cc) $(ccflags) -c $<
-include *.d    

一般的なmakefile:

export prog := inv_svn
export objs := $(patsubst %.c, %.o, $(wildcard src/*.c)))
export src_dir := src
export inc_dir := inc
export obj_dir := obj
export bin_dir := bin
export cc := gcc
export ccflags := -I $(PWD)/$(inc_dir) -MMD -g -Wall
export ldflags := -lcurses -lgdbm

test := ./$(prog)

all: $(prog)
$(prog): $(bin_dir)
$(bin_dir): $(obj_dir)
$(bin_dir):
make -C $@
$(obj_dir):
make -C $@

.PHONY: clean 

clean: 
rm -f $(obj_dir)/*.[od]$(prog)
4

1 に答える 1

0

ここには問題が多すぎて、一度に修正することはできません。小さくてシンプルなものから始めて、積み上げていきましょう。

まず、本当に必要がないときにMakeを再帰的に使用しています。後で、この設計を再検討する必要があります。今のところ、私たちが働くことができるかどうか見てみましょうobj/makefile

objs第2に、サブmakefileは、呼び出し元のmakefileから渡された変数(など)に依存します。これらの変数は、自分で作成することもできます。これは悪いデザインです。割り当てを入れますobj/makefile

objs := $(patsubst %.c, %.o, $(wildcard ../src/*.c))

)(私は物事を台無しにしていた余分なものを削除したことに注意してください。)

第三に、これをテストすると、が得られますが../src/foo.o ../src/bar.o、これはおそらく私たちが望んでいることではありません。オブジェクトをビルドしたいのですがobj/、ではありませんsrc/(メインのmakefileの割り当てにも同じ問題がありました)。だから私たちはそれを変更します:

objs := $(patsubst ../src/%.c, %.o, $(wildcard ../src/*.c))

(もっと優雅な方法がありますが、今のところ気にしないでください。)

第四に、私はあなたがに同様の変更を加えることができると信じていますbin/makefile

第5に、メインのMakefileでは、サブディレクトリが実際にはターゲットではない場合に、サブディレクトリをターゲットとして扱います。これらのルールのポイントは、サブディレクトリを作成することではなく、サブディレクトリでMakeを実行することです。それらがすでに存在する場合(それらは存在します)、Makeは満足しており、それを結論付け、$(prog)all構築する必要はありません。これは、いくつかのPHONYターゲットで解決できます。

.PHONY: RUN_IN_$(obj_dir) RUN_IN_$(bin_dir)

$(prog):  RUN_IN_$(bin_dir)
RUN_IN_$(bin_dir): RUN_IN_$(obj_dir)
RUN_IN_$(bin_dir):
    make -C $(bin_dir)
RUN_IN_$(obj_dir):
    make -C $(obj_dir)

粗野だが効果的。

それはあなたを地面から離すのに十分なはずです。

于 2012-10-24T19:21:12.687 に答える