2011-03-16 115 views
5

我做一些Makefile的重构,并试图找出最简洁的方式来实现一个Makefile执行以下操作:简明的Makefile

  1. 有具有列出的所有源文件中的一个变量(既可以是C和C++文件)
  2. 所有对象文件都在OBJ_DIR
  3. 如果不存在

这对象目录中创建生成是我到目前为止有:

... 

OBJ_DIR = obj/ 
BIN_DIR = bin/ 
PROGRAM = program 

SRCS = test1.cpp test2.c 

OBJS = $(addprefix $(OBJ_DIR), \ 
     $(patsubst %.cpp, %.o, \ 
     $(patsubst %.c, %.o, $(SRCS)))) 

$(BIN_DIR)$(PROGRAM) : $(OBJS) 
    $(CREATE_OUT_DIR) 
    $(LINK) 

$(OBJ_DIR)%.o : %.c 
    $(CREATE_OBJ_DIR) 
    $(CCOMPILE) 

$(OBJ_DIR)%.o : %.cpp 
    $(CREATE_OBJ_DIR) 
    $(CPPCOMPILE) 

... 

我想消除每个.o编译对$(CREATE_OBJ_DIR)的调用。有人知道怎么做吗?我尝试添加这一点,但那就不是建立目标文件:

$(OBJS): | $(OBJ_DIR) 

$(OBJ_DIR): 
    $(CREATE_OBJ_DIR) 
+0

我看到这个设计的问题。你如何解释标题依赖关系?我通常使用'src = $(shell find ./ --name“* .cpp”)来编写makefile,并使用GCC'-M'开关为我处理依赖关系。这样,我为我的所有项目都有一个简短的可重用makefile。至于你的实际问题,为什么不事先创建'obj'目录? – 2011-03-16 13:29:04

+0

不完全是答案,但您是否已经查看了'Makefile'的替代方案? 'SConstruct'出现在我的脑海里(很棒),但还有很多其他工具可以很好地处理这些问题。 – ereOn 2011-03-16 13:35:53

+0

@Alexandre:我也正在研究头文件依赖关系。你有一个很好的例子来说明如何做到这一点? – waffleman 2011-03-17 13:50:04

回答

3

您似乎已经解决了你的第一个观点:让他们都在同一个变量(我不应该觉得你真的需要将它们分成TEMP1和TEMP2喜欢你,只是有不同的生成规则)

对于第二点,你可以告诉编译器输出目标文件(G ++它是这样的:

g++ -c MySourceFile.cpp -o obj/MySourceFile.o 

这种情况的生成规则将如下所示:

obj/%.o: %.cpp 
    g++ -c $*.cpp -o obj/$*.o 

而你的第三点也很容易解决,因为你可以有一个构建规则(在列出所有对象之前,只需将目录名称放入目标的依赖项列表中),构建规则将如下所示

obj: 
    mkdir obj 

编辑:或以下的代码示例:

$(BIN_DIR)$(PROGRAM) : $(BIN_DIR) $(OBJS) 
$(LINK) 

$(BIN_DIR): 
    $(CREATE_OUT_DIR) 
+0

目录依赖关系应该仅限于顺序依赖关系。 – 2011-03-16 14:31:40

+0

我将目标文件列表生成压缩成一个命令。谢谢你的提示。 – waffleman 2011-03-17 13:55:42

1

至于你的第三个问题:这个问题有been asked here before。不幸的是,没有真正的好的答案,你需要从答案中找到最不可思议的答案。就我个人而言,我投票选择了标记文件解决方案。

0

这是我做的:

$(OBJ_LOC)/%.o: $(SRC_LOC)/%.c 
    @[ -d $(OBJ_LOC) ] || mkdir -p $(OBJ_LOC) 
    g++ ... 

但是,我在看非常INTE这些其他的答案休息。