2010-07-24 62 views
2

在编写一个精心设计的Makefile时,如果文件已被更改,那么只需最小程度的保留,似乎install:目标往往被忽略。更多的时候则不能安装目标看起来像:仅当文件发生更改时才进行安装

TRG := /trg 
BIN_TRG := $(TRG)/bin 
ETC_TRG := $(TRG)/etc 
BIN_FILES := b1 b2 b3 
ETC_FILES := e1 e2 e3 

install: 
    install $(BIN_FILES) $(BIN_TRG) 
    install $(ETC_FILES) $(ETC_TRG) 

.PHONY: install 

也就是说,没有依赖假目标检查都没有。

如果不是简单安装,而是需要填充临时区域来准备诸如RPM包等二进制包,或者下一阶段构建依赖于该临时区域,则此类问题会变得更加严重。在这种情况下,在安装阶段之后,依赖关系树就会崩溃。

问题是:安装规则跟踪依赖关系的最佳方法是什么?

回答

2

我不熟悉你的“安装”功能,您的两种解决方案使用不同的方法,但这个怎么样:

TRG := /trg 
BIN_TRG := $(TRG)/bin 
ETC_TRG := $(TRG)/etc 
BIN_FILES := b1 b2 b3 
ETC_FILES := e1 e2 e3 
INSTALLS := $(addprefix $(BIN_TRG)/,$(BIN_FILES)) \ 
     $(addprefix $(ETC_TRG)/,$(ETC_FILES)) 

install: $(INSTALLS) 

$(BIN_TRG)/% $(ETC_TRG)/%: % 
    install $< [email protected] 

.PHONY: install 

编辑:附:如果您想要install步骤填充暂存区域或其他任何地方,请使暂存区域成为具有自己规则的单独目标。

+0

谢谢,这是非常有帮助的。 – theosp 2011-03-11 09:45:22

0

我发现的一种方法是专门描述安装规则的依赖关系。对于每一个文件,我们需要构建一个规则,如:

trg_dir/my_file: my_file 
    install $< [email protected] 

要做到这一点,但是需要一些使用gmake法宝:

TRG := /trg 
BIN_TRG := $(TRG)/bin 
ETC_TRG := $(TRG)/etc 
BIN_FILES := b1 b2 b3 
ETC_FILES := e1 e2 e3 
INSTALLS := $(addprefix $(BIN_TRG)/,$(BIN_FILES)) \ 
      $(addprefix $(ETC_TRG)/,$(ETC_FILES)) 

install: $(INSTALLS) 

define install_rule 
$(1)/$(2): $(2) 
    install $(2) $(1)/$(2) 
endef 

$(foreach file,$(BIN_FILES),$(eval $(call install_rule,$(BIN_DIR),$(file)))) 
$(foreach file,$(ETC_FILES),$(eval $(call install_rule,$(ETC_DIR),$(file)))) 

.PHONY: install 

我觉得这个代码需要一些解释,这也是我的主要抱着它 - 它是更复杂,然后这样一个看似普通的任务应该是:

目标保持虚假,但它现在将只用于检查单个安装规则,是最新的。

通过评估调用单个规则的宏定义的结果来生成规则。我们使用​​函数遍历每个文件,并在$(call ...)install_rule时给出正确的参数。


我把问题和答案在这里,我虽然看似解决了它已经,因为我不满意这个解决方案。任何更优雅的将被热切接受。

0

由于make不支持伪目标的先决条件,因此您必须在磁盘上创建实际的虚拟文件,并在安装目标触发器时触摸该文件。

.PHONY: install 

install: dummy 

dummy: $(FILES_THAT_WERE_CHANGED) 
     install $(BIN_FILES) $(BIN_TRG) 
     install $(ETC_FILES) $(ETC_TRG) 
     touch dummy 
相关问题