首页 文章

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

提问于
浏览
3

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

  • 1

    目标特定变量可能很棘手 . 改为使用间接 . 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 时make会扩展 ${copts-debug} .

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

  • 4

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

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

    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 ,你就有了发布版本 .

相关问题