2017-10-19 70 views
0

如何在GNU Makefile中創建非依賴假目標?如何在GNU Makefile中創建非依賴假目標?

要求:

  1. 來檢查一個特定的設置的規則 - 可以比下面的例子更加複雜。
  2. 如果此規則失敗,則建立特定目標應失敗。
  3. 如果這個規則成功了,只有修改了它們的源代碼,才能建立特定的目標。
  4. 規則不可能是全球性的,因爲該規則甚至不應該對非特異性指標

如果規則是每一個具體目標的編譯規則之前插入這是可以實現的執行。 因爲它們可能有很多特定的目標,所以我更願意爲此規則創建一個假目標,並將此假目標指定爲所有這些特定目標的依賴項。 這有一個不需要的副作用,即當假目標成功時,即使它們的源未被修改,也會重建那些特定目標。

換句話說,我如何指定一個假目標來強制從屬目標被重建,如果它們的來源是最新的。

$ 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應該已經得到上面/最後的化妝編譯。

$ 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 
#------------------------------------------------------------ 
#... 

回答

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 
+0

感謝您的替代解決方案,但它確實沒有解決第四個要求(規則不應該針對非特定目標執行)。在你的答案中總是計算ARCH。只是fyi,我的實際問題有一個更復雜的檢查,我想避免爲其他(非特定)目標執行.. –

2

只需使用假目標作爲訂單唯一的先決條件。請如果在依賴關係圖中發現總會執行這個規則,但如果他們的正常先決條件是最近這取決於它的目標纔會被執行:

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 
+0

謝謝,手冊頁的make沒有這個。添加僅限訂單的先決條件的鏈接,以提供有關此主題的其他信息,以及可能遇到類似問題的其他人。 https://www.gnu.org/software/make/manual/make.html#Prerequisite-Types –