2012-12-03 41 views
6

的良好做法我有我的项目目录结构如下:的Makefile

bin/ 
dist/ 
include/ 
├── module_a/ 
└── module_b/ 
Makefile 
src/ 
├── module_a/ 
└── module_b/ 

文件夹include/包含*.hpp的同时*.cpp的是src/。我想汇编所有来源到bin/,然后将它们连接在一起到dist/。对我来说似乎是一个相当合理的愿望。

我想知道这种情况下的Makefile的最佳做法。我能找到的所有目标都是%.o: %.cpp,但由于源文件和二进制文件夹不同,这并不实际。

我试图用这样的:

D_SRC = src 
D_BIN=bin 

F_CPP := $(shell find $(D_SRC) -iname '*.cpp' -type f) 
F_OBJ := $(shell echo $(F_CPP) | sed s:\ :\\n:g | sed s:$(D_SRC):$(D_BIN): | sed 's:^\(.*\)\.cpp$$:\1\.o:') 

$(F_OBJ): $(F_SRC)                 
    $(foreach file, $(F_SRC), \              
     $(GXX) $(CXXFLAGS) -c $(file)\            
    ) 

这个目标是不行的,因为$(F_OBJ)路径与bin/开始,而foreach编译来源,以当前的工作目录。我可以将它编译为bin/,但是这只会发生在几个sed表达式之后,并且它足够丑陋。

这对我来说可能是如此困难,因为我不知道make都很好,但我不能成为这个项目设置中唯一的一个。在我看来,它一定是相当普遍的。我知道我可以分别为每个模块编写一个Makefile,但这真的是最好的选择吗?

编辑︰我现在想知道我会用几个Makefiles实现什么。如果有人在src/module_a的根目录中,那么后者将如何知道bin/?如果你使用make -f src/module_a/Makefile执行它,它将与从根目录执行它相同,因为它的工作目录将是根目录。另一种方式,我想,将执行它之前改变目录,如下所示:make -C include/module_a,但在这种情况下,它将如何找到bin/?我不想在Makefile中有类似D_BIN = ../../bin的东西。

+0

更新了我的答案... –

回答

6

我通常做的是有在src目录下的Makefile文件(可从顶层Makefile文件,如果你喜欢被调用),然后使用规则是这样的:

D_BIN = ../bin 
$(D_BIN)/%.o: %.cpp 

你也可以只用实验在顶级目录生成文件和使用规则是这样的:

D_BIN = bin 
D_SRC = src 
$(D_BIN)/%.o: $(D_SRC)/%.cpp 

,但我没用过这样的规则,所以我不知道优点/缺点VS我通常做的方式。我通常做它工作得很好的方式,我甚至有一个建立取决于像这样的规则:

$(D_BIN)/%.d: %.cpp 

和链接规则是这样的:

../dist/outexe: $(F_OBJ) 

使用foreach通常是在,因为它皱起了眉头没有利用正常makefile规则中的所有功能(即,每个文件不存在依赖性检查,无论是建立一切还是不建立任何内容),并且这样的foreach只能作为最后的手段使用,但在此你可以在没有任何习惯的情况下使用它。

除此之外,还有更简单的方法来构建文件列表,您不需要使用shell或sed。

F_CPP = $(wildcard *.cpp) 
F_OBJ = $(F_CPP:.cpp=.o) 

更新:这是我常发出递归品牌:

SUBDIRS = src 
.PHONY: $(SUBDIRS) 
all: $(SUBDIRS) 

$(SUBDIRS): 
    @echo "Building [email protected]" 
    $(MAKE) -C [email protected] $(MFLAGS) 

然后确实是在你的submake,你将需要使用../bin例如。

但是与您​​的一样简单的项目,你可能会更好只是有在根一级makefile文件和使用的规则是这样的:

D_BIN = bin 
D_SRC = src 
$(D_BIN)/%.o: $(D_SRC)/%.cpp 

递归makefile文件都OK(确定,但不是很大)如果你有一个非常复杂的目录结构,随着时间的推移,你将添加/删除/修改新的目录树。但是对于一个简单的项目,你只想为代码和objs分开目录,这可能是矫枉过正的。

+0

这看起来像我一直在寻找的一切。我现在无法测试它,但据我所知,这将起作用。非常感谢你。 –