代码之家  ›  专栏  ›  技术社区  ›  Chance

在makefile中,目录名是虚假目标还是“真实”目标?

  •  18
  • Chance  · 技术社区  · 15 年前

    根据我读到的关于makefiles的内容,假目标是与实际文件名不对应的任何目标。我的直觉是,作为目标的目录将被视为一个文件。

    为什么这很重要?我的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} 目录名,假目标?

    2 回复  |  直到 10 年前
        1
  •  28
  •   James Ko    10 年前

    编辑:这只适用于GNU制造——考虑到“linux”标签,这是一个公平的假设。

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

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

    您可以这样指定它:

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

    垂直条之后的任何内容都是仅订购的先决条件。

    现在可以简化obj_dir目标:

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

    注:我用过 ${OBJ_DIR} 语法而不是 $(OBJ_DIR) 因为那是你用过的。仅顺序先决条件不依赖于该语法。

        2
  •  7
  •   Alex Brown    15 年前

    这是一个真正的目标。

    make系统不会自动检测假目标-必须由您使用 .PHONY 目标。

    明智的虚假目标包括 all 和 clean -这些不符合真实的文件,而是 行动 您希望生成文件执行此操作。以下是如何解释这一点:

    .PHONY: all clean install test
    

    目录是makefile规则的合法目标。你不应该把这些弄虚作假。

    mydir:
         mkdir mydir
    

    假目标当然是假的。

    可以找到GNU文档 here .