制作:设置具有不同目标的目标特定变量

时间:2011-03-18 16:27:56

标签: makefile

我正在构建一个用于构建发布或调试目标库的makefile。我想将对象和自动生成的依赖文件放入调试或发布目录结构中,具体取决于请求的makefile目标。我不想指定一个可测试的make命令行参数(即DBG = 1),但是更喜欢分别运行make -f Makefile或make -f Makefiel dbg用于发布和调试目标目标。得到那个部分。我知道我不能分配一个特定于目标的变量,该变量包含可以在规则中用作Target规范的一部分的对象dir(发布或调试)的名称,就像我在下面显示的示例中所做的那样。在此示例中,OBJDIR是我想要根据构建目标设置的特定于目标的变量。因此,在此示例中,$(OBJDIR)在目标规则$(OBJDIR)/%。o中为空。有关如何很好地执行建议步骤的任何建议? (显示的示例只是复制/粘贴未经验证的示例...语法未经验证...实际上,我无法使标签正确显示...我希望得到一些实现方法)。 (另外,$(OBJDIR)没有设置在干净的目标中,如图所示......因为它不在dbg / all target dependancy heirarchy ......想法?)提前感谢。

Makefile:

OBJS    := a.o b.o c.o  
SRCS    := $(OBJS:.o=.c)  

-- Set up the release and the debug directory paths and object filenames  
RELEASE_DIR := ./release  
RELEASE_OBJ := $(OBJS:%=$(RELEASE_DIR)/%)  
DEBUG_DIR   := ./debug  
DEBUG_OBJ   := $(OBJS:%=$(DEBUG_DIR)/%)  

.PHONY : all dbg 

all: CFLAGS = -O3  
all: OBJDIR := RELEASE_DIR  
all: df     := $(RELEASE_DIR)/$(*F)  
all: init_release lib1.so  

dbg: CFLAGS = -g -O0  
dbg: OBJDIR := DEBUG_DIR  
dbg: df     := $(DEBUG_DIR)/$(*F)  
dbg: init_debug lib1.so  

Lib1.so: $(OBJ)  

init_release:  
    -@mkdir -p $(RELEASE_DIR)  

init_debug:  
    -@mkdir -p $(DEBUG_DIR)  

lib1.so: $(OBJ)  
    @echo '--------------------------------------------------------------'
    @echo linking $@  
    @gcc -shared -o lib1.so $(OBJ)  

-Compile including advance dependancy generation alg, per Tom Tromey:
    # http://make.paulandlesley.org/autodep.html  
$(OBJDIR)/%.o: %.c  
    echo $@    
    echo $(OBJDIR)  
    echo compiling $@  
    $(COMPILE.c) -MD -o $@ $<  
    cp $(df).d $(df).P; \  
    sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \  
             -e '/^$$/ d' -e 's/$$/ :/' < $(df).d >> $(df).P; \  
    rm -f $(df)/$*.d  

# If the goal is "clean", don't include these to avoid trying to build them
ifneq($(MAKECMDGOALS),clean)  
-include $(SRCS:%.c=$(OBJDIR)/%.P)
endif  

clean:  
    -@rm -f    $(OBJDIR)/*.[Pdo] lib1.so  

2 个答案:

答案 0 :(得分:4)

目标特定变量可能很棘手。改为使用间接。 Make有很多语法可以减少样板文本。 .SECONDEXPANSION通常很好。草图:

.SECONDEXPANSION:
${DEBUG_OBJ} ${RELEASE_OBJ}: $$(patsubst %.o,%.c,$${@F})
    gcc ${copts-${@D}} -c $< -o $@

我们告诉我./release/a.o取决于a.c。当make决定构建./release/a.o时,它会扩展shell行。在这样做时,${@D}自然是release,因此make会继续并扩展${copts-release},您将对其进行有用的定义。

同样,在制作./debug/a.o时,展开${copts-debug}

大量使用$(warning [blah])$(error [blah blah])和强制--warn-undefined-variables将有助于您做到这一点。

答案 1 :(得分:1)

您编写的Makefile无效,并且不会按预期生成目标。例如,您无法在目标定义CFLAGSall中设置dbg变量。

我能想到的唯一解决方案是使用相同的Makefile调用make,根据需要定义DBG变量。 E.g:

ifdef DBG
CFLAGS = -O0 -ggdb
OBJDIR = dbgdir
else
CFLAGS = -O2
OBJDIR = reldir
endif

all: $(OBJDIR)/target
    #Your commands here

dbg:
    $(MAKE) DBG=1

有了这个,如果你打电话给make,你就有了发布版本。如果你致电make dbg,你就有了发布版本。