Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何编译c++;使用Makefiles使用多个目录的项目?_C++_Linux - Fatal编程技术网

C++ 如何编译c++;使用Makefiles使用多个目录的项目?

C++ 如何编译c++;使用Makefiles使用多个目录的项目?,c++,linux,C++,Linux,我读过其他问类似问题的文章,唉,我还是很困惑 这是我当前的生成文件: 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 -

我读过其他问类似问题的文章,唉,我还是很困惑

这是我当前的生成文件:

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指南?

解决问题的最快方法是在所有子目录中添加文件包含的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
# $@ 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 $@ $<

# Finally link everything in the executable
# $^ refers to ALL the prerequisites
$(EXEFILE): $(OBJS)
    $(CXX) $(CXXFLAGS) -o $@  $^ $(LFLAGS) $(LIBS)
#组编译选项
CXXFLAGS:=-std=c++11-Wall-Wno注释$(IFLAGS)
#存储对象文件(.o)的目录
ODIR:=/对象
#从结尾读这句难看的话:
#-使用通配符grep SRC中的所有.cpp文件
#-将前缀$(ODIR)添加到具有addprefix的所有文件名中
#-将.cpp in.o替换为patsubst
OBJS:=$(patsubst%.cpp,%.o,$(addprefix$(ODIR)/,$(通配符$(SRC)/*.cpp)))
#编译对象文件中的所有文件
#$@指规则名称,此处为$(ODIR)/当前文件
#$<指的是第一个先决条件,这里是$(SRC)/the\u current\u file.cpp
$(ODIR)/%.o:$(SRC)/%.cpp$(DEPS)/%.h
$(CXX)$(CXXFLAGS)-c-o$@$<
#最后链接可执行文件中的所有内容
#$^引用所有先决条件
$(EXEFILE):$(OBJS)
$(CXX)$(CXXFLAGS)-o$@$^$(LFLAGS)$(LIBS)

解决问题的最快方法是在所有子目录中添加文件所包含的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
# $@ 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 $@ $<

# Finally link everything in the executable
# $^ refers to ALL the prerequisites
$(EXEFILE): $(OBJS)
    $(CXX) $(CXXFLAGS) -o $@  $^ $(LFLAGS) $(LIBS)
#组编译选项
CXXFLAGS:=-std=c++11-Wall-Wno注释$(IFLAGS)
#存储对象文件(.o)的目录
ODIR:=/对象
#从结尾读这句难看的话:
#-使用通配符grep SRC中的所有.cpp文件
#-将前缀$(ODIR)添加到具有addprefix的所有文件名中
#-将.cpp in.o替换为patsubst
OBJS:=$(patsubst%.cpp,%.o,$(addprefix$(ODIR)/,$(通配符$(SRC)/*.cpp)))
#编译对象文件中的所有文件
#$@指规则名称,此处为$(ODIR)/当前文件
#$<指的是第一个先决条件,这里是$(SRC)/the\u current\u file.cpp
$(ODIR)/%.o:$(SRC)/%.cpp$(DEPS)/%.h
$(CXX)$(CXXFLAGS)-c-o$@$<
#最后链接可执行文件中的所有内容
#$^引用所有先决条件
$(EXEFILE):$(OBJS)
$(CXX)$(CXXFLAGS)-o$@$^$(LFLAGS)$(LIBS)

我找到了一个解决方案,按照我的口味,它看起来很优雅,或者至少很容易使用通配符进行跟踪。这是我当前的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的目录。然后,我取出当前根目录(./)和任何隐藏目录(./),留下存储在“目录”下的标准子目录,然后向每个目录添加-I,使其成为包含目录,并将它们存储在本地目录中
因此,我现在可以根据需要创建任意多的子目录(最多10个级别),编译器会很高兴的。

我找到了一个解决方案,在我看来,这个解决方案很优雅,或者至少很容易使用通配符符进行跟踪。这是我当前的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的目录。然后,我取出当前根目录(./)和任何隐藏目录(./),留下存储在“目录”下的标准子目录,然后向每个目录添加-I,使其成为包含目录,并将它们存储在本地目录中
因此,我现在可以根据需要创建任意多个子目录(最多10个级别),编译器会很高兴。

如果您将
$(EXEFILE):
替换为
$(EXEFILE):$(SRC)
,则无需删除可执行文件来重建它,您会发现构建过程工作得更好。虽然您确实希望在最后一个阶段使用
$(OBJ)
,因为您不想每次都重新编译每个源文件。为了更容易编译,请查看Cmake。如果您将
$(EXEFILE):
替换为
$(EXEFILE):$(SRC),您可能会发现构建过程工作得更好
-无需删除可执行文件来重建它。虽然您确实希望在最后一个阶段使用
$(OBJ)
,因为您不想每次都重新编译每个源文件。为了更容易编译,请查看Cmake。