最近写代码想Makefile同时支持交叉编译器和主机编译器,所以要把不同编译器生成的目标文件放到不同的目录中。首先想到的是目录里要保留原来的源文件目录结构,这样就可以用隐式规则或静态规则推导出源文件,否则根本无法得到依赖关系。最后用了
隐式规则扣出源文件路径才勉强可用,照这个思路花了点时间写了个测试例子,准备把现有需要交叉编译的程序都转到这种模式:
ifdef HOST
    objdir:=obj_$(word 1, $(subst -, ,$(HOST)))
else
    objdir:=obj
endif
SRC_DIR:=. src
CFILES:=$(shell find $(SRC_DIR) -maxdepth 1 -name "*.c")
OBJS:=$(addprefix $(objdir)/,$(CFILES:%.c=%.o))
OBJDIRS:=$(addprefix $(objdir)/, $(SRC_DIR))
TARGET=main
all:$(OBJDIRS) $(TARGET)
$(TARGET):$(OBJS)
    gcc -o $@ $(OBJS)
$(objdir)/%.o:%.c
    gcc -c $< -o $@
$(OBJDIRS):
    @mkdir -p $@
clean:
    -rm -r -f $(objdir) $(TARGET)
.PHONY: clean all
还有就是查资料时发现了这个东东(order-only prerequisites),可惜没法用在我这里,因为用隐式规则我没法弄出目录依赖-_-!!!,下一步是把所有*.d文件也搞进目录中去。
gnu make的两种依赖关系(Prerequisites):
- 
正常依赖(normal prerequisites)
1)检查和重建依赖
2)如果依赖更新,则要重建目标
 - 
顺序依赖(order-only prerequisites)
1)检查和重建依赖
 
顺序依赖不会影响最终的目标的重建,这个适合与在makefile里建目录,因为目录作为目标有一个特性是目录里的文件改了,目录就更新了,导致一系列不必要的重建,用顺序依赖方式的话,就不回影响最终的目标了
Gnu make手册上给了个例子:
 OBJDIR := objdir
 OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
 $(OBJDIR)/%.o : %.c
         $(COMPILE.c) $(OUTPUT_OPTION) $<
 all: $(OBJS)
 $(OBJS): | $(OBJDIR)
 $(OBJDIR):
         mkdir $(OBJDIR)
http://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html http://cm.techwell.com/articles/weekly/making-directories-gnu-make