2016-11-13 158 views
1

我有一個Makefile包含了建立一個小項目和清理它的規則。例如:如何在Makefile中創建'build'和'clean'的'重建'規則?

CC:=gcc 
LD:=gcc 
SOURCES:=$(wildcard src/*.c) 
OBJS:=$(SOURCES:src/%.c=build/%.o) 
TARGET:=bin/program 

all: $(TARGET) 

$(TARGET): $(OBJS) 
    @mkdir -p bin 
    $(LD) $+ -o [email protected] 

build/%.o: src/%.c 
    @mkdir -p build 
    $(CC) $+ -c -o [email protected] 

clean: 
    rm -rf $(OBJS) 
    rm -rf $(TARGET) 
    rmdir bin 
    rmdir build 

.PHONY: clean all 

我現在在創建規則rebuild這將依次執行cleanall感興趣。我沒有看到如何正確實現正確的順序。


我所看到的解決方案對我而言是錯誤的。

rebuild: clean all 
.PHONY: rebuild 

自然是錯誤的,因爲有依賴是在其出現的順序實際執行不能保證。 all可能在clean之前執行。

我已經看到答案,提示僅依賴訂單的依賴關係,例如

rebuild: | clean all 
.PHONY: rebuild 

據我所知,這並沒有解決問題。如果你說a: | b c這意味着a取決於bc,但如果採取bc,它不會強制執行a規則。它與訂購的依賴關係無關。

我現在看到的推出化妝的新實例,唯一的選擇具有

rebuild : clean 
    make build 

我真的想避免推出新作實例做一些簡單的那樣!


我做了所以有些reasearch。我看過類似的問題,但沒有正確答案。對我來說,制定目標.PHONY或使用僅依賴訂單的依賴關係不是解決方案。

回答

6

首先,這是不正確的,在一個規則:

rebuild: clean all 

all可以前clean連續運行時建(即,未啓用並行-j)。 Make始終按照它們在makefile中列出的順序構建先決條件(包含配方的規則有一個特殊情況,但這與此處不相關)。當使用並行構建時,仍然以相同的順序遍歷依賴樹,但由於規則是並行構建的,因此它們可能不會以相同的順序啓動。

但是,你說得對,這個規則不是其他原因的好主意(目錄緩存等)。)

我建議你使用遞歸建立調用做到這一點:

.PHONY: rebuild 
rebuild: 
     $(MAKE) clean 
     $(MAKE) all 
1

有一個辦法做到這一點不遞歸;價格是冗餘少量:

.PHONY: rebuild 
$(TARGET) rebuild: $(OBJS) 
    @mkdir -p bin 
    $(LD) $+ -o $(TARGET) # note that I have replaced [email protected] with $(TARGET) 

rebuild: | clean 
2

您可以使用MAKECMDGOALS有條件地添加cleanall之間的相關性時,我們的目標是rebuild。事情是這樣的:

ifeq (rebuild,$(findstring rebuild,${MAKECMDGOALS})) 
all: clean 
rebuild: all 
endif 

現在,我實在不明白在makefile執行此操作時還有其他的瑣碎和安全的方式做到這一點的好處(只是「make clean && make all」可能是一個更好的選擇)