源文件在不同目录中的Makefile
我有一个项目的目录结构是这样的:
$projectroot | +---------------+----------------+ | | | part1/ part2/ part3/ | | | +------+-----+ +---+----+ +---+-----+ | | | | | | | data/ src/ inc/ src/ inc/ src/ inc/
我应该如何编写一个部分在/ src(或真正在哪里)可以在/ c ++源文件/ / src中完成/链接的makefile?
我可以做一些像-I $ projectroot / part1 / src -I $ projectroot / part1 / inc -I $ projectroot / part2 / src …
如果这样做,有没有一个更简单的方法来做到这一点。 我见过每个相应部分都有makefile的项目吗? 文件夹。 [在这篇文章中,我用了bash语法中的问号]
传统的方法是在每个子目录( part1 , part2等)中都有一个Makefile ,允许您独立构build它们。 此外,在构build一切的项目的根目录中有一个Makefile 。 “根” Makefile将如下所示:
all: +$(MAKE) -C part1 +$(MAKE) -C part2 +$(MAKE) -C part3
由于make目标中的每一行都在其自己的shell中运行,所以不必担心遍历目录树或其他目录。
我build议看看GNU make手册第5.7节 ; 这是非常有帮助的。
如果你有一个子目录中的代码依赖于另一个子目录中的代码,那么最好在顶层使用一个makefile。
请参阅“ recursion制作”有害于完整的基本原理,但基本上,您希望获得所需的全部信息来决定是否需要重新构build文件,如果仅告诉其中的三分之一你的项目。
上面的链接似乎无法访问。 同一个文件可以在这里find:
- aegis.sourceforge.net
- lcgapp.cern.ch
您可以将规则添加到您的根Makefile以编译其他目录中的必要cpp文件。 下面的Makefile例子应该是一个很好的开始,让你到你想要的地方。
CC =克++
TARGET = cppTest
OTHERDIR = .. / .. / someotherpath /中/项目/ src目录
SOURCE = cppTest.cpp
SOURCE = $(OTHERDIR)/file.cpp
##结束来源定义
INCLUDE = -I./ $(AN_INCLUDE_DIR)
INCLUDE = -I。$(OTHERDIR)/../ inc
##结束更多包括
VPATH = $(OTHERDIR)
OBJ = $(join $(addsuffix ../obj/,$(dir $(SOURCE))),$(notdir $(SOURCE:.cpp = .o)))
##修正依赖关系目标是相对于src目录的../.dep
DEPENDS = $(join $(addsuffix ../.dep/,$(dir $(SOURCE))),$(notdir $(SOURCE:.cpp = .d)))
##默认规则执行
全部:$(TARGET)
@真正
##清理规则
清洁:
@ -rm -f $(TARGET)$(OBJ)$(DEPENDS)
##制定实际目标的规则
$(TARGET):$(OBJ)
@echo“=============”
@echo“链接目标$ @”
@echo“=============”
@ $(CC)$(CFLAGS)-o $ @ $ ^ $(LIBS)
@echo - 链接完成 -
##通用编译规则
%.o:%.cpp
@mkdir -p $(dir $ @)
@echo“=============”
@echo“编译$ <”
@ $(CC)$(CFLAGS)-c $ <-o $ @
##来自cpp文件的对象文件的规则
##每个文件的对象文件放在obj目录中
##从实际的源代码目录上升一级。
../obj/%.o:%.cpp
@mkdir -p $(dir $ @)
@echo“=============”
@echo“编译$ <”
@ $(CC)$(CFLAGS)-c $ <-o $ @
#规则为“其他目录”你将需要一个“其他”目录
$(OTHERDIR)/../ obj /%。o:%.cpp
@mkdir -p $(dir $ @)
@echo“=============”
@echo“编译$ <”
@ $(CC)$(CFLAGS)-c $ <-o $ @
##制定依赖性规则
../.dep/%.d:%.cpp
@mkdir -p $(dir $ @)
@echo“=============”
@echo构build$ *。o的依赖关系文件
@ $(SHELL)-ec'$(CC)-M $(CFLAGS)$ <| sed“s ^ $ *。o ^ .. / obj / $ *。o ^”> $ @'
##“其他”目录的依赖规则
$(OTHERDIR)/../。dep /%。d:%.cpp
@mkdir -p $(dir $ @)
@echo“=============”
@echo构build$ *。o的依赖关系文件
@ $(SHELL)-ec'$(CC)-M $(CFLAGS)$ <| sed“s ^ $ *。o ^ $(OTHERDIR)/../ obj / $ *。o ^”> $ @'
##包含依赖文件
-include $(DEPENDS)
VPATH选项可能会派上用场,它告诉做什么目录来查找源代码。 不过,您仍然需要为每个包含path指定-I选项。 一个例子:
CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc VPATH=part1/src:part2/src:part3/src OutputExecutable: part1api.o part2api.o part3api.o
这将自动在任何VPATH指定的目录中find匹配的partXapi.cpp文件并进行编译。 然而,当你的src目录被分解成子目录时,这会更有用。 正如其他人所说的,对于你所描述的内容,你可能最好用每个部分的makefile,特别是如果每个部分都可以独立的话。
如果源文件被分散在多个文件夹中,那么就像之前build议的那样使用单独的Makefiles是合理的,recursionmake是一个好方法,但是对于较小的项目,我发现将Makefile中的所有源文件与它们的相对path到这样的Makefile :
# common sources COMMON_SRC := ./main.cpp \ ../src1/somefile.cpp \ ../src1/somefile2.cpp \ ../src2/somefile3.cpp \
然后我可以这样设置VPATH :
VPATH := ../src1:../src2
然后我build立对象:
COMMON_OBJS := $(patsubst %.cpp, $(ObjDir)/%$(ARCH)$(DEBUG).o, $(notdir $(COMMON_SRC)))
现在这个规则很简单:
# the "common" object files $(ObjDir)/%$(ARCH)$(DEBUG).o : %.cpp Makefile @echo creating $@ ... $(CXX) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
build立输出甚至更容易:
# This will make the cbsdk shared library $(BinDir)/$(OUTPUTBIN): $(COMMON_OBJS) @echo building output ... $(CXX) -o $(BinDir)/$(OUTPUTBIN) $(COMMON_OBJS) $(LFLAGS)
甚至可以通过以下方式使VPATH生成自动化:
VPATH := $(dir $(COMMON_SRC))
或者使用sort删除重复的事实(尽pipe这不重要):
VPATH := $(sort $(dir $(COMMON_SRC)))
我认为最好指出,使用Make(recursion或不是)通常是你可能想要避免的,因为与现在的工具相比,很难学习,维护和扩展。
这是一个非常棒的工具,但直接使用应该在2010年被认为是过时的。
当然,除非你正在一个特殊的环境中工作,比如一个传统的项目等等。
使用IDE, CMake,或者,如果你辛苦的话, Autotools 。
(由于downvotes编辑,ty洪扎指出)
RC的职位是超级有用的。 我从来没有想过使用$(dir $ @)函数,但它正是我所需要做的。
在parentDir中,有一堆包含源文件的目录:dirA,dirB,dirC。 各种文件依赖于其他目录中的目标文件,所以我希望能够从一个目录中创build一个文件,并通过调用与该依赖关联的makefile来创build依赖关系。
本质上,我在parentDir中创build了一个Makefile(其中包含许多其他内容)的类似于RC的通用规则:
%.o : %.cpp @mkdir -p $(dir $@) @echo "=============" @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o $@
每个子目录都包含这个高级makefile,以便inheritance这个通用规则。 在每个子目录的Makefile中,我为每个文件写了一个自定义规则,以便跟踪每个单独文件所依赖的所有内容。
无论何时我需要创build一个文件,我都(基本上)使用这个规则recursion地创build任何/所有的依赖关系。 完善!
注意:有一个名为“makepp”的工具,它似乎更直观地完成了这个任务,但为了便于携带而不依赖于其他工具,我select这样做。
希望这可以帮助!
recursion使用Make
all: +$(MAKE) -C part1 +$(MAKE) -C part2 +$(MAKE) -C part3
这允许make分成作业并使用多个核心
我build议使用autotools :
//##将生成的目标文件(.o)放在与源文件相同的目录中,以避免使用非recursionmake时的冲突。
AUTOMAKE_OPTIONS = subdir-objects
只要将其包含在Makefile.am与其他非常简单的东西。
这里是教程 。