2016-10-06 17 views
0

私は以下のディレクトリ構造を持っています。サブフォルダを使ったMakefileの使用

Project/ 
    ├── bin/ 
    ├── src/ 
    │ ├── main.c 
    │ ├── util/ 
    │   ├── util.c 
    │   ├── util.h 
    ├── obj/ 
    ├── .depend/ 

すべてのソースコードはsrcフォルダにあります。 srcルートには、私のmain.cファイルがあります。 (または同じレベルのフォルダ内にある)同じレベルにある他のファイルも含まれます。下のMakefileは、同じレベルのmain.cのすべてのファイルでうまく動作しますが、src内のサブフォルダ内のファイルでは動作しません。

srcフォルダ内のサブフォルダを許可するようにMakefileを変更するにはどうすればよいですか?

CC := gcc 
CFLAGS := -Wall -Wextra 
BINDIR := bin 
OBJDIR := obj 
SRCDIR := src 
DEPDIR := .depend 
SOURCES := $(wildcard $(SRCDIR)/*.c) 
OBJECTS := $(patsubst $(SRCDIR)/%.c, $(OBJDIR)/%.o, $(SOURCES)) 
DEPENDS := $(patsubst $(SRCDIR)/%.c, $(DEPDIR)/%.d, $(SOURCES)) 

$(BINDIR)/app: $(OBJECTS) | $(BINDIR) 
    @$(CC) -o [email protected] $^ 

-include $(DEPENDS) 

$(OBJDIR)/%.o: $(SRCDIR)/%.c | $(OBJDIR) 
    @$(CC) $(CFLAGS) -c -o [email protected] $< 

$(DEPDIR)/%.d: $(SRCDIR)/%.c | $(DEPDIR) 
    @$(CC) -MM -MG $< | sed 's!^\(.\+\).o:!$(DEPDIR)/\1.d $(OBJDIR)/\1.o:!' > [email protected] 

$(DEPDIR) $(BINDIR) $(OBJDIR): 
    @mkdir [email protected] 

clean: 
    @rm -rf $(BINDIR)/* 
    @rm -rf $(OBJDIR)/* 

.PHONY: clean 

EDIT.o.dファイルは、構造のオリジナルデザインを尊重する必要はありません。そして、私は、Windows(MinGWの)

+0

詳細を指定する必要があります。サブディレクトリにソースファイル用の '.o'と' .d'ファイルを作成する場所はどこですか?それらはすべて同じフラットディレクトリまたは同等のサブディレクトリに作成されるかどうかなどです。使用できるプラットフォーム固有のツールがある可能性があるため、プラットフォームも指定する必要があります。 –

+0

申し訳ありませんが、.oファイルと.dファイルは構造の元のデザインを尊重する必要はありません。そして私はWindows(MinGW)を使っています –

+1

オブジェクトファイルの同形ディレクトリ構造を生成する必要があります。純粋なmakeを使用することは可能ですが、最初のボイラープレートコードは少し長めです。私はそのためのギター・レポを作ることを考えています。 –

答えて

0

を使用しています。このようなあなたのソースを設定しよう:それは右のように動作しない場合は、ちょうどあなたのコマンドラインで実行してデバッグしよう

SOURCES := $(shell find $(SRCDIR) -type f -name "*.c")

find src -type f -name "*.c"

と、それはファイルの正しいリストを出力し、正しい相対パスで、それに応じて調整するかどうかを確認します。

このアプローチはUNIX系の環境でしか動作しません.MSYSやCygwin環境からMinGWを使用している場合は、動作するはずです。

2

まず、ソースを再帰的に見つけるようにSOURCESを変更する必要があります。これは純粋なmakeで行うことができます。

subdirs = $(filter-out $1,$(sort $(dir $(wildcard $1*/)))) 
rfind = $(wildcard $1$2) $(foreach d,$(call subdirs,$1),$(call rfind,$d,$2)) 

SOURCES := $(call rfind,$(SRCDIR)/,*.c) 

ディレクトリの作成を除いて他のすべてが機能します。まず、二次拡張で$(@D)を使用するように前提条件を変更:

.SECONDEXPANSION: 

$(OBJDIR)/%.o: $(SRCDIR)/%.c | $$(@D) 
    ... 
$(DEPDIR)/%.d: $(SRCDIR)/%.c | $$(@D) 
    ... 

その後、すべてのディレクトリ含まれるように、ディレクトリの作成ルールを変更します。

$(BINDIR) $(patsubst %/,%,$(sort $(dir $(OBJECTS) $(DEPENDS)))): 
    @mkdir -p [email protected] 

再帰的な検索と同様に、それは重複排除するsortを使用しています(そうでなければmakeは警告を出します)、スラッシュを取り除きます($(@D)にはスラッシュが付きません)。順序の問題を避けるために、他のディレクトリーとソースが含まれていないディレクトリーのみを避けるためには、-pが必要であることに注意してください。