如何将不同目录中的源代码编译成单个目录中的目标文件(Makefile)?
我有这样的布局:如何将不同目录中的源代码编译成单个目录中的目标文件(Makefile)?,makefile,compilation,shared-libraries,project,gnu-make,Makefile,Compilation,Shared Libraries,Project,Gnu Make,我有这样的布局: project/ Makefile core/ a.cpp a.hpp utl/ b.cpp b.hpp obj/ 我希望所有的.o文件都在obj文件夹中,这样我就可以从这些对象文件中创建一个共享库。但是,由于我的.cpp文件位于不同的目录中,我不知道如何实现自动化。有多个目录,不仅仅是这两个。任何暗示都将不胜感激 我的尝试失败了,因为我假设Make automatic rule for.o(我想使用)希望.cpp位于.o应该位
project/
Makefile
core/
a.cpp
a.hpp
utl/
b.cpp
b.hpp
obj/
我希望所有的.o文件都在obj文件夹中,这样我就可以从这些对象文件中创建一个共享库。但是,由于我的.cpp文件位于不同的目录中,我不知道如何实现自动化。有多个目录,不仅仅是这两个。任何暗示都将不胜感激
我的尝试失败了,因为我假设Make automatic rule for.o(我想使用)希望.cpp位于.o应该位于的同一目录中
# grab all cpp files with their path that are in some DIRS list
SRC = $(wildcard *.cpp) $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*.cpp))
# remove the path
SRC_WITHOUT_PATH = $(notdir $(SRC))
# stick the .obj/ directory before the .cpp file and change the extension
OBJ = $(SRC_WITHOUT_PATH:%.cpp=./obj/%.o)
# error is no rule to make target obj/a.o
您可以从对象文件创建一个分解库,即使它们位于不同的目录中。所以这并不是把它们放在别处的真正理由 然而,一个更好的理由是保持源目录整洁并简化清理(只需删除
obj
目录)
将不同目录中的源文件中的对象文件放在一个目录中是有问题的:如果有两个同名的源文件,它们将相互覆盖。解决这个问题的一种常见方法是保持源文件的目录结构,但将其放在新的顶级目录下;GNU使支持更容易:
# grab all cpp files with their path that are in some DIRS list
SRC = $(wildcard *.cpp) $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*.cpp))
# stick the .obj/ directory before the .cpp file and change the extension
OBJ = $(addprefix obj/,$(SRC:.cpp=.o))
obj/%.o : %.cpp
@mkdir -p $(@D)
$(COMPILE.cpp) -o $@ $<
#获取一些目录列表中的所有cpp文件及其路径
SRC=$(通配符*.cpp)$(foreach DIR,$(DIRS),$(通配符$(DIR)/*.cpp))
#将.obj/目录粘贴到.cpp文件之前并更改扩展名
OBJ=$(addprefix OBJ/,$(SRC:.cpp=.o))
obj/%.o:%.cpp
@mkdir-p$(@D)
$(COMPILE.cpp)-o$@$<
如果你真的,真的想让所有的对象文件都在同一个目录中,你就必须变得更有趣,因为make对目标使用简单的字符串匹配,所以你必须为每个目标和前提名称不同的关系编写一个新规则:基本上这意味着每个单独的源目录都有一个新规则
您可以通过使用GNU make来避免这种情况,如下所示:
# grab all cpp files with their path that are in some DIRS list
SRC = $(wildcard *.cpp) $(foreach DIR,$(DIRS),$(wildcard $(DIR)/*.cpp))
# remove the path
SRC_WITHOUT_PATH = $(notdir $(SRC))
# stick the .obj/ directory before the .cpp file and change the extension
OBJ = $(SRC_WITHOUT_PATH:%.cpp=obj/%.o)
# Give all the source directories to make
VPATH = $(sort $(dir $(SRC))
obj/%.o : %.cpp
$(COMPILE.cpp) -o $@ $<
#获取一些目录列表中的所有cpp文件及其路径
SRC=$(通配符*.cpp)$(foreach DIR,$(DIRS),$(通配符$(DIR)/*.cpp))
#移除路径
不带路径的SRC_=$(notdir$(SRC))
#将.obj/目录粘贴到.cpp文件之前并更改扩展名
OBJ=$(SRC_不带_路径:%.cpp=OBJ/%.o)
#提供所有要创建的源目录
VPATH=$(排序$(目录$(SRC))
obj/%.o:%.cpp
$(COMPILE.cpp)-o$@$<
感谢您的帮助!我在阅读了相关内容后也尝试过使用它,它的效果是:vpath%.cpp DIRS