在makefile中,目录名是伪目标还是"真实"目标?

Cha*_*nce 19 c++ linux 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;
Run Code Online (Sandbox Code Playgroud)

那么在这种情况下,是${OBJ_DIR},目录名称,虚假目标与否?

cam*_*amh 29

编辑:这仅适用于GNU make - 给出"linux"标签的公平假设.

你的目标是真正的目标,而不是PHONY目标.问题是当您在其中放置目标时输出目录会更新,以使其始终比您的目标更新.这意味着您的目标将始终构建,因为它的依赖项已过时.

您需要的是仅限订单的先决条件.这些先决条件允许您指定在不存在时需要构建它,但不要注意时间戳.也就是说,对于仅订单的先决条件,目标不会过时.

你这样指定:

$(EXEC_WITH_PATH): $(DPEND) $(OBJS) | ${OBJ_DIR}
...
Run Code Online (Sandbox Code Playgroud)

垂直条之后的任何内容都是仅限订单的先决条件.

您现在可以使OBJ_DIR目标更简单:

${OBJ_DIR} :
        mkdir -p ${OBJ_DIR}
Run Code Online (Sandbox Code Playgroud)

注意:我使用的是${OBJ_DIR}语法而不是$(OBJ_DIR)因为您使用的是语法.仅订单的先决条件不依赖于该语法.


Ale*_*own 7

这是一个真正的目标.

make系统不会自动检测到伪目标 - 必须由您使用.PHONY目标识别它们.

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

.PHONY: all clean install test
Run Code Online (Sandbox Code Playgroud)

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

mydir:
     mkdir mydir
Run Code Online (Sandbox Code Playgroud)

.PHONY目标当然是虚假的.

GNU文档可以在这里找到.