【问题标题】:Make: Setting Target Specific Variables With Different GoalsMake:设置具有不同目标的特定目标变量
【发布时间】:2011-07-18 07:39:10
【问题描述】:

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

生成文件:

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  

【问题讨论】:

    标签: makefile


    【解决方案1】:

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

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

    这里我们告诉 make ./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 将帮助您做到这一点。

    【讨论】:

    • 不错。那么,要添加到组合中,有没有一种方法可以参数化设置 OBJDIR 以反映以下原始示例中的类似扩展(发布或调试子目录)? (我有点惊讶这在 makefile 领域不是更常见的实现......不同的构建配置和将对象/依赖项放在他们自己的子目录中以减少大型项目的构建时间) ifneq($(MAKECMDGOALS),clean ) - 包括 $(SRCS:%.c=$(OBJDIR)/%.P) endif
    • @user654077:很难阅读您的评论。我只想无条件地说include所有的部门。它不会受伤。不要先检查MAKECMDGOALS——这似乎有点脆弱。 (-include $(patsubst %.o,%.P,${DEBUG_OBJ} ${RELEASE_OBJ}).)
    • 非常感谢...到目前为止效果很好。还有一个扩展问题,我想我会解决这个问题的。也许,与其简单地将构建配置放入 .debug 或 .release,不如将所需的对象目录更像“./LibName/.debug”和“./LibName/.release”。使用您的 .SECONDEPANSION 解决方案,我想将 ${copts-${@D}} 解析为简单的 .debug 或 .release,而不是 LibName/.debug 等。找不到仅提取“last subdir”部分的 OBJDIR。想法?
    • @user654077:几个想法。 $(notdir $(patsubst %/,%,$(dir ${var})));或者$(lastword $(subst /, ,$(dir ${var})));然后再$(patsubst ./LibName/%,%,${var})。您可能会发现 Static Pattern Rules 非常有用,因为您可以获得 $* 来匹配您需要的位。就像 perl 人可能会说的那样,TMTOWDI。
    • 太棒了...使用了您第二个建议的变体。像冠军一样工作!非常感谢(也感谢提示和建议阅读)。
    【解决方案2】:

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

    我能想到的唯一解决方案是使用定义 DBG 变量的相同 Makefile 调用 make,如您所愿。例如:

    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,您将获得发布版本。

    【讨论】:

    • 是的,在我的“真实”实现中,CFLAGS += 那些标志......我只是为了示例目的而剪切和粘贴和编辑)。我确实想到了递归 make 解决方案,但希望有另一种更优雅的方法。我在另一个线程中发现了一些接近的东西:
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    • 2014-04-11
    • 2012-12-13
    • 2012-03-07
    相关资源
    最近更新 更多