简明的Makefile

时间:2011-03-16 13:19:27

标签: makefile gnu-make

我正在做一些Makefile重构,并试图找出实现Makefile的最简洁方法,它执行以下操作:

  1. 有一个变量列出了所有源文件(可以是C和C ++文件)
  2. 所有目标文件均在OBJ_DIR
  3. 中生成
  4. 如果对象目录不存在,则创建该对象目录
  5. 这是我到目前为止所做的:

    ...
    
    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)
    

3 个答案:

答案 0 :(得分: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) 

答案 1 :(得分:1)

关于你的第3点:这个问题有been asked here before。不幸的是,对此没有真正好的答案,你需要从答案中找到最难看的黑客。就个人而言,我投票支持标记文件解决方案。

答案 2 :(得分:0)

这就是我的所作所为:

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

但是,我非常感兴趣地看着这些其他答案。