2017-04-05 46 views
1

我已經閱讀了其他問題提出類似的事情,唉,我仍然困惑。如何使用Makefiles編譯包含多個目錄的C++項目?

這是我目前的Makefile:

CC = g++ 

EXEFILE = template 

IFLAGS= -I/usr/include/freetype2 -I../Camera 
LFLAGS= -L/usr/lib/nvidia-375 -L/usr/local/lib -L/usr/include/GL -L/usr/local/include/freetype2 -L/usr/local/lib/ 
LIBS = -lglfw -lGL -lGLU -lOpenGL -lGLEW -pthread -lfreetype 

SRC=*.cpp 
DEPS=*.h 

$(EXEFILE): 
    $(CC) -std=c++11 -o $(EXEFILE) -Wall -Wno-comment $(SRC) $(IFLAGS) $(LFLAGS) $(LIBS) 

all: run clean 

run: $(EXEFILE) 
    ./$(EXEFILE) 
clean: 
    rm $(EXEFILE) 

現在我所有的.h文件和.cpp文件上的工作目錄,一切編譯和運行就好了。我的問題是我已經有大量的文件,並且變得相當混亂。我想創建多個目錄(甚至可能在這些目錄內的目錄)來組織我的文件。但只要我將一個頭文件和相應的cpp文件移動到當前目錄中的某個目錄,編譯器就不知道如何鏈接它們了。

如何告訴我的make文件編譯並鏈接當前根目錄下的所有內容?

另外,是否有一個ELI5指南makefile語法?

+0

可能的重複[來自源文件中的子目錄](http://stackoverflow.com/questions/4036191/sources-from-subdirectories-in-makefile) – flyx

+0

如果你更換你的構建過程會更好'$(EXEFILE):'帶'$(EXEFILE):$(SRC)' - 不需要刪除可執行文件來重建它。雖然你真的想在最後一個階段使用'$(OBJ)',所以你不想每次都重新編譯每個源文件。 –

+0

爲了更容易編譯 - 查看Cmake。 – SHG

回答

0

我發現了一個解決方案,即,對我的口味似乎優雅,或至少易於使用通配符追查。這是我當前的makefile:

EXEFILE := $(shell basename $(CURDIR)) 


DIRECTORIES = $(filter-out ./ ./.%, $(shell find ./ -maxdepth 10 -type d)) 
IFLAGS= -I/usr/include/freetype2 
LOCAL_I_DIRS =$(addprefix -I./, $(DIRECTORIES)) 
LFLAGS= -L/usr/lib/nvidia-375 -L/usr/local/lib -L/usr/include/GL -L/usr/local/include/freetype2 -L/usr/local/lib/ 
LIBS = -lglfw -lGL -lGLU -lOpenGL -lGLEW -pthread -lfreetype 

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

$(EXEFILE): $(EXEFILE).cpp 
    g++ -std=c++11 -o $(EXEFILE) -Wall -Wno-comment $(SRC) $(IFLAGS) $(LOCAL_I_DIRS) $(LFLAGS) $(LIBS) 

all: run clean 

run: $(EXEFILE) 
    ./$(EXEFILE) 

clean: 
    rm $(EXEFILE) 

print-%: ; @echo $* = $($*) 

所以我得到的所有目錄多達10深度然後我去了當前的根(./)和任何隱藏的目錄(./。)讓我下存儲的標準子目錄「DIRECTORIES」然後,我將-I添加到每個目錄中,使其成爲一個包含目錄,並將它們存儲在LOCAL_I_DIRS中 因此,我現在可以根據需要創建任意數量的子目錄(最多10個級別),編譯器會很高興。

0

爲您解決問題最快的辦法是增加SRC和DEPS文件包含了所有的子目錄,這樣的:

SRC=*.cpp src/*.cpp 
DEPS=*.h inc/*.h 

現在你可能會考慮寫一個規則,首先編譯中的每個文件一個單獨的目錄:

# Group compilation option 
CXXFLAGS := -std=c++11 -Wall -Wno-comment $(IFLAGS) 

# A directory to store object files (.o) 
ODIR := ./objects 

# Read this ugly line from the end: 
# - grep all the .cpp files in SRC with wildcard 
# - add the prefix $(ODIR) to all the file names with addprefix 
# - replace .cpp in .o with patsubst 
OBJS := $(patsubst %.cpp,%.o,$(addprefix $(ODIR)/,$(wildcard $(SRC)/*.cpp))) 

# Compile all the files in object files 
# [email protected] refers to the rule name, here $(ODIR)/the_current_file.o 
# $< refers to first prerequisite, here $(SRC)/the_current_file.cpp 
$(ODIR)/%.o:$(SRC)/%.cpp $(DEPS)/%.h 
    $(CXX) $(CXXFLAGS) -c -o [email protected] $< 

# Finally link everything in the executable 
# $^ refers to ALL the prerequisites 
$(EXEFILE): $(OBJS) 
    $(CXX) $(CXXFLAGS) -o [email protected] $^ $(LFLAGS) $(LIBS)