简明的Makefile

waf*_*man 5 makefile gnu-make

我正在做一些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)

...
Run Code Online (Sandbox Code Playgroud)

我想为每个.o编译消除对$(CREATE_OBJ_DIR)的调用.有人知道怎么做吗?我尝试添加这个,但它不会构建目标文件:

$(OBJS): | $(OBJ_DIR)

$(OBJ_DIR):
    $(CREATE_OBJ_DIR)
Run Code Online (Sandbox Code Playgroud)

dee*_*146 3

您似乎已经解决了您的第一点:将它们全部放在一个变量中(我不认为您实际上需要像您一样将它们分成 TEMP1 和 TEMP2,只是有不同的构建规则)

对于第二点,您可以告诉编译器在哪里输出目标文件(对于 g++ 来说是这样的:

g++ -c MySourceFile.cpp -o obj/MySourceFile.o
Run Code Online (Sandbox Code Playgroud)

其 make 规则如下所示:

obj/%.o: %.cpp
    g++ -c $*.cpp -o obj/$*.o
Run Code Online (Sandbox Code Playgroud)

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

obj:
    mkdir obj
Run Code Online (Sandbox Code Playgroud)

编辑:或按照您的代码示例:

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

$(BIN_DIR):
    $(CREATE_OUT_DIR) 
Run Code Online (Sandbox Code Playgroud)