2012-10-28 50 views
7

下我的C的目錄結構++項目
編譯,利用makefile所有CPP文件MinGW的

/.. 
    makefile  <- the makefile is in root 
    /include  <- subdirectory that has to be included while compiling 
    /obj   <- target place for all *.o and final executable 
    /src   <- sources 

而且我目前的Makefile:

CC=g++ 
CFLAGS=-c -Wall -std=c++11 

INC=-Iinclude 
SRC=src 
TGT=obj 

all: myapp 

myapp: myapp.o 
    $(CC) $(TGT)/myapp.o -o $(TGT)/myapp 

myapp.o: 
    $(CC) $(CFLAGS) $(INC) $(SRC)/myapp.cpp -o $(TGT)/myapp.o 

clean: 
    rm -rf $(TGT) 
    mkdir $(TGT) 

這個工作對我的第一個文件。我是一個總的makefile新手 - 請幫我編譯/src目錄下的所有文件,並將它們鏈接到/obj目錄中的可執行文件。

的Makefile有Windows下工作,我使用MinGW和MSYS

回答

5

添加源文件的列表:

SOURCES = $(wildcard $(SRC)/*.cpp) 

和相應的目標文件的列表:

OBJS = $(addprefix $(TGT)/, $(notdir $(SOURCES:.cpp=.o))) 

和目標可執行:

$(TGT)/myapp: $(OBJS) 
    $(CXX) $(LDFLAGS) $(OBJS) -o [email protected] 

的建築物的規則:

$(TGT)/%.o: $(SRC)/%.cpp 
    $(CXX) $(CXXFLAGS) -c $< -o [email protected] 

現在必須指定是G ++的選項:

INCLUDES = -Iinclude 
CXXFLAGS = -Wall -std=c++11 $(INCLUDES) 

而且都在一起:

SRC=src 
TGT=obj 
INCLUDES = -Iinclude 
CXXFLAGS = -Wall -std=c++11 $(INCLUDES) 
SOURCES = $(wildcard $(SRC)/*.cpp) 
OBJS = $(addprefix $(TGT)/, $(notdir $(SOURCES:.cpp=.o))) 

$(TGT)/%.o: $(SRC)/%.cpp 
    $(CXX) $(CXXFLAGS) -c $< -o [email protected] 

$(TGT)/myapp: $(OBJS) 
    $(CXX) $(LDFLAGS) $(OBJS) -o [email protected] 

是很重要的,即在$(CXX) ...前必須有一個「標籤「字符,而不是空格。

+0

'-Idir'部分可以參數化嗎?你的解決方案看起來簡潔。有兩件事要改變:make-script應該將'* .o'和最終的可執行文件都放在TGT目錄中...... – emesx

+0

你對參數化有什麼意義?當然,你可以把它放在一個單獨的變量中,並把這個變量加到'CXXFLAGS'中。查看修改後的答案 –

+1

@elmes請嘗試修改後的'Makefile',我調整了單獨的目標目錄。 –

1

您可以使用VPATH for separating source and object files

src/myapp.c 
obj/Makefile 

把你現有的Makefile,將其移動到obj/,省略引用$(TGT)$(SRC)並添加以下內容:

VPATH=../src 

請注意,如果你ar e試圖做multi-architecture builds, VPATH is not ideal


順便說一句,你沒有資本builtin rules。當你有

CC=g++ 
CFLAGS=-c -Wall -std=c++11 
myapp: myapp.o 
    $(CC) $(TGT)/myapp.o -o $(TGT)/myapp 

myapp.o: 
    $(CC) $(CFLAGS) $(INC) $(SRC)/myapp.cpp -o $(TGT)/myapp.o 

你也可以使用:

CXXFLAGS=-Wall -std=c++11 
CXXFLAGS+=$(INC) 
LDLIBS+=-lstdc++ 

myapp: myapp.o 

所以,總括起來,你的新obj/Makefile應該是這樣的:

VPATH=../src 
INC=-I../include 
CXXFLAGS=-Wall -std=c++11 
CXXFLAGS+=$(INC) 
LDLIBS+=-lstdc++ 

myapp: myapp.o 

你可以如果有必要,從obj/開始創建另一個Makefile以緩存到這個新的:

all: obj/myapp 

obj/myapp: 
    mklink obj/Makefile ../Makefile 
    $(MAKE) --directory=obj/ 
+0

正如我所說,我是makefile的新手。你能否創建一個適合問題中描述的場景的工作示例? – emesx

+0

好的,這個例子中唯一缺少的就是VPATH。所以你去了。 –

+0

但是爲什麼makefile必須駐留在'obj'目錄中。它不是一個好的保存目錄,因爲我想輕鬆地清除那個目錄 – emesx