2010-11-22 116 views
18

根据我读过的有关makefile的信息,虚假目标是任何不符合实际文件名的目标。我的直觉表明,作为目标的目录将被视为与文件相同。在makefile中,目录名称是伪目标还是“真实”目标?

为什么这很重要?我有一个目录作为我的makefile中的目标。当我将它作为我的主要可执行文件的先决条件时,该可执行文件总是会生成,无论是否最新。如果我把它作为先决条件,我的makefile足够聪明,可以知道什么时候需要构建,但是我不知道是否需要创建目录。根据我读过的有关make的信息,任何虚假目标都不是先决条件,因为make并不知道它们是否是最新的,所以它们总是会重建相关的目标。这里是我的makefile的摘录。

$(EXEC_WITH_PATH): ${OBJ_DIR} $(DPEND) $(OBJS) 
    @echo "--------------------------------------------"; 
    @echo "$(THIS_DIR) $(MACHINE)"; 
    @echo "Linking Shared Library"; 
    @echo "ar -rc $(EXEC_WITH_PATH) INSERT::{OBJS}"; 
    ar -rc $(EXEC_WITH_PATH) $(OBJS); 
    @echo "--------------------------------------------"; 


# Make dirs for object code and links 
${OBJ_DIR} : 
     @if [ ! -d ${OBJ_DIR} ]; then \ 
       mkdir ${OBJ_DIR}; \ 
     fi; 
在这种情况下

那么,是${OBJ_DIR},目录名,假目标或没有?

+1

无论如何,为了解决你的问题,你可以有一个mkdir命令前加一个“ - ”,这样就可以忽略返回值。 – siukurnin 2010-11-22 17:34:13

+4

@siukurnin:不,你应该使用`mkdir -p`,这样,如果目录已经存在,它就会成功,但如果无法创建目录,则会失败。 – Cascabel 2010-11-22 18:01:40

回答

27

编辑:这只适用于GNU make - 假定给出“linux”标签的公平假设。

你的目标是真正的目标,而不是PHONY。问题在于,当您将目标放在目标中时,输出目录会更新,以便它总是比目标更新。这意味着你的目标总是会被建立,因为它的依赖关系已经过时了。

你需要的是一个order-only prerequisite。这些先决条件允许您指定如果它不存在但需要注意时间戳,则需要构建它。也就是说,一个目标不会在订单唯一的先决条件方面过时。

你喜欢这个指定:竖线后

$(EXEC_WITH_PATH): $(DPEND) $(OBJS) | ${OBJ_DIR} 
... 

什么就是命令,唯一的先决条件。

现在,您可以让您的OBJ_DIR目标简单:

${OBJ_DIR} : 
     mkdir -p ${OBJ_DIR} 

注:我用的${OBJ_DIR}语法而不是$(OBJ_DIR),因为这是你用什么。仅限订单的先决条件不依赖于该语法。

7

这是一个真正的目标。

制造系统不会自动检测到虚假目标 - 它们必须由您使用.PHONY目标进行标识。

明智的假目标包括allclean - 这些不符合实际的文件,而是要行动要让Makefile做。以下说明如何解释:

.PHONY: all clean install test 

目录是makefile规则的合法目标。你不应该做这些假。

mydir: 
    mkdir mydir 

的.PHONY目标是当然的,假。

GNU文档可以找到here