首页 文章

如何在GNU Makefile中创建非依赖的虚假目标?

提问于
浏览
0

如何在GNU Makefile中创建非依赖的虚假目标?

要求:

  • 检查特定设置的规则 - 可能比下面的示例更复杂 .

  • 如果此规则失败,则构建特定目标应该失败 .

  • 如果此规则成功,则只有在修改其来源时才应构建特定目标 .

  • 规则不能是全局规则,因为甚至不应对非特定目标执行该规则

如果在每个特定目标的编译规则之前插入规则,则可以实现这一点 . 由于它们可能是许多特定目标,我更喜欢为此规则创建虚假目标,并将此虚假目标指定为所有这些特定目标的依赖项 . 这会产生不必要的副作用,当虚假目标成功时,即使未修改其来源,也会重建这些特定目标 .

换句话说,如果其源是最新的,如何指定虚假目标以强制重建依赖目标 .

$ make --version | grep Make
GNU Make 3.82

$ make -f try.mk clean setup
rm -f try.out?
touch try.c #Dummy create source

$ make -f try.mk
touch try.out1 #Dummy compile
touch try.out2 #Dummy compile
touch try.out3 #Dummy compile

$ make -f try.mk
touch try.out3 #Dummy compile

try.out3应该 NOT 已经编译在上面/最后一个make中 .

$ cat try.mk
#try.mk
base=try

all: $(base).out1 $(base).out2 $(base).out3 #...

clean:
    rm -f $(base).out?

setup:
    touch $(base).c #Dummy create source

.PHONY: all clean platform_ok

#------------------------------------------------------------
#Specific targets
#------------------------------------------------------------

#Attempt 1: works, but platform check is a rule, and hence needs to be inserted wherever it is needed.
$(base).out1: $(base.c)
    @if [ $(shell uname -i) == x86_64 ]; then exit 0; else exit 1; fi
    touch $(base).out1 #Dummy compile

#Attempt 2: works, but platform check is global, which gets executed even when building Non-OS specific targets
$(eval platform_check:=$(shell (if [ $(shell uname -i) == x86_64 ]; then echo 0; else echo 1; fi)))
$(base).out2:  $(base).c
    @exit $(platform_check)
    touch $(base).out2 #Dummy compile

#Attempt 3: works partially when platform check is a phony target, but target gets rebuilt even if source is uptodate.
$(base).out3:  $(base).c platform_ok
    touch $(base).out3 #Dummy compile
platform_ok:
    @if [ $(shell uname -i) == x86_64 ]; then exit 0; else exit 1; fi

#------------------------------------------------------------
#Non-Specific targets
#------------------------------------------------------------
#...

2 回答

  • 0

    我会对此略有不同:

    base=try
    ARCH := $(shell test `uname -i` = "x86_64"; echo $$? )
    
    ifeq ($(ARCH),0)
    define PLATFORM_64 =
    out3
    endef
    endif
    
    define ALL =
    out1
    out2
    $(PLATFORM_64)
    endef
    
    all: $(addprefix $(base)., $(ALL))
    

    我会松散 platform_ok

    $(base).out3: $(base).c
        touch $(base).out3 #Dummy compile
    
  • 2

    只需使用虚假目标作为仅限订单的先决条件 . 如果在依赖关系图中找到,则Make将始终执行此规则,但只有在正常先决条件更新的情况下才会执行依赖于它的目标:

    base=try
    
    all: $(base).out1 $(base).out2 $(base).out3 #...
    
    clean:
        rm -f $(base).out?
    
    setup:
        touch $(base).c #Dummy create source
    
    .PHONY: all clean platform_ok
    
    #------------------------------------------------------------
    #Specific targets
    #------------------------------------------------------------
    
    $(base).out1: $(base).c | platform_ok
        touch $(base).out1 #Dummy compile
    
    $(base).out2:  $(base).c | platform_ok
        touch $(base).out2 #Dummy compile
    
    $(base).out3:  $(base).c | platform_ok
        touch $(base).out3 #Dummy compile
    
    platform_ok:
        @if [ $(shell uname -i) == x86_64 ]; then exit 0; else exit 1; fi
    

相关问题