2017-01-09 51 views
0

這裏是我的文件夾視圖:Autodependencies與GNU使

-> tree 
. 
├── Makefile 
└── src 
    ├── a10.c 
    ├── a11.c 
    ├── a12.c 
    ├── a13.c 
    ├── a14.c 
    ├── a15.c 
    ├── a16.c 
    ├── a1.c 
    ├── a2.c 
    ├── a3.c 
    ├── a4.c 
    ├── a5.c 
    ├── a6.c 
    ├── a7.c 
    ├── a8.c 
    ├── a9.c 
    ├── a.c 
    └── test.h 

a1.ca10.c都是空的,只是測試,只有a.ctest.h已代碼:

-> cat src/a.c 
#include "test.h" 

int main(void) 
{ 
    printf("VAR = %d\n", VAR); 
    printf("VAR1 = %d\n", VAR1); 

    return 0; 
} 

-> cat src/test.h 
#include <stdio.h> 

我有一個一個makefile功能:

-> cat Makefile 
ifeq '${INPUT}' '' 
     STR = LATEAST 
else 
     STR = ${INPUT} 
endif 

CC  := gcc 
LD  := gcc 

PROGRAM = Test 

MAKE_DIR  = $(PWD) 
MODULES   := src 
SRC_DIR   := $(addprefix $(MAKE_DIR)/,$(MODULES)) 
BUILD_DIR  := $(MAKE_DIR)/output 

SRC    := $(foreach sdir,$(SRC_DIR),$(wildcard $(sdir)/*.c)) 
OBJ    := $(patsubst %.c,%.o,$(SRC)) 

INCLUDES  := $(addprefix -I,$(SRC_DIR)) 
INCLUDES  += -I$(MAKE_DIR)/include 

#test 
F_VAR = 43 
F_VAR1 = 40+1+2 
$(warning F_VAR=$(F_VAR), F_VAR1=$(F_VAR1)) 

CFLAGS := 
CFLAGS = -DVAR=41+2 -DVAR1=40+1+2 


vpath %.c $(SRC_DIR) 

define make-goal 
$1/%.o: %.c 
     @$(CC) $(CFLAGS) $(INCLUDES) -c $$< -o [email protected] 
     @$(CC) -MM $(CFLAGS) $(INCLUDES) $$< > $1/$$*.d 
     @echo "Compile $$*.c" 
endef 

.PHONY: all checkdirs clean help flowchart 
all: checkdirs $(BUILD_DIR)/$(PROGRAM) 

$(BUILD_DIR)/$(PROGRAM): $(OBJ) 
     @echo "${STR}" 
     @$(LD) $^ -o [email protected] 
     @echo "Generate $(PROGRAM)" 


checkdirs: $(BUILD_DIR) 

$(BUILD_DIR): 
     mkdir -p [email protected] 

clean: 
     rm -f $(OBJ) $(BUILD_DIR)/$(PROGRAM) 
     rm -rf $(BUILD_DIR) 

help: 
     @echo "SRC DIR: $(SRC_DIR)" 
     @echo "Build DIR: $(BUILD_DIR)" 
     @echo "Source:  $(SRC)" 
     @echo "Obj:  $(OBJ)" 
     @echo "Includes: $(INCLUDES)" 

flowchart: 
     @cflow2dot pdf ${SRC} 

$(foreach sdir,$(SRC_DIR),$(eval $(call make-goal,$(sdir)))) 

我的quesa當我碰到一個頭文件時,它沒有觸發重新編譯,我的makefile中有任何問題?

-> make 
Makefile:28: F_VAR=43, F_VAR1=40+1+2 
mkdir -p /home/haochen/Work/test_code/test_make/output 
Compile a10.c 
Compile a11.c 
Compile a12.c 
Compile a13.c 
Compile a14.c 
Compile a15.c 
Compile a16.c 
Compile a1.c 
Compile a2.c 
Compile a3.c 
Compile a4.c 
Compile a5.c 
Compile a6.c 
Compile a7.c 
Compile a8.c 
Compile a9.c 
Compile a.c 
LATEAST 
Generate Test 

的Autodependenciescan產生:

-> cat src/a.d 
a.o: /home/haochen/Work/test_code/test_make/src/a.c \ 
/home/haochen/Work/test_code/test_make/src/test.h 

問題: 我改性test.h,添加一個錯誤:

-> vim src/test.h 
-> cat src/test.h 
#include <stdio.h> 
#error here 

無需重新編譯:

-> make 
Makefile:28: F_VAR=43, F_VAR1=40+1+2 
make: Nothing to be done for `all'. 

UPDATE:

我補充一下:

DEP := $(patsubst %.c,%.d,$(SRC)) 

同時,我在make文件的最後一行添加-include

-include $(DEP) 

我沒有看到任何改善

+0

至於我可以告訴你的Makefile中不使用* .d文件。 – melpomene

+0

@melpomene,所以你的意思是我需要在生成文件中使用(編寫一些代碼)生成的* .d場。 –

+0

如何讓應該知道如何處理* .d文件?您需要在Makefile中包含或包含* .d文件。 – Jens

回答

0

我發現這個問題,我應該:

  1. 寫DEPS

    DPES = ...

  2. 編譯C文件,-MMD選項:

    ... -MMD -c $< -o [email protected]

  3. ,然後補充:

    -include $(DPES)

0

.d文件是makefile,表示標題依賴關係。因此,您需要在生成文件中包含-include .d文件,例如

OBJ := $(patsubst %.c,%.o,$(SRC)) 
DEP := $(patsubst %.c,%.d,$(SRC)) 

... 

-include $(DEP) 
+0

我做了這些但仍然沒有改進 –

0

的依賴文件被正確生成,但你永遠不使用它們:用@$(CC) -MM $(CFLAGS) $(INCLUDES) $$< > $1/$$*.d,使發出命令生成依賴文件,但它不使用它。

依賴關係文件是自己的小Makefiles,註定要被make讀取。所以,你需要告訴make來讀取它們以及你的主Makefile。 爲此,您有include directive,它暫停讀取當前的makefile,並在恢復讀取當前makefile(我在此處引用該手冊...)之前將所有列出的文件讀爲makefiles。

由於依賴關係文件在第一個版本中不存在,因此您可能希望在其前面添加-以取消no such file的警告。

請注意,請確保在默認目標(或使用.DEFAULT_GOAL)之後包含依賴關係文件,因爲如果不這樣做,默認目標將成爲在包含文件中第一個找到的目標。 另外,您可能希望添加您的依賴關係文件作爲您的對象文件的先決條件,因爲缺失的依賴關係文件會使錯過一些先決條件。

所有這些都來自make維護者的博客here,您可以在其中找到其他信息。

編輯:

對不起,我上次錯過了它。如果我沒有錯,a.o$1/%.o不能匹配相同的目標。即使Makefile在子目錄中包含文件,它也不會自動知道,並且對他而言a.osrc/a.o並不相同(的確如此)。所以有兩個單獨的規則,一個是空的,沒有配方(依賴文件中的那個) 一種解決方案可能是使用-MT標誌來生成依賴關係(它將目標設置爲您指定的字符串,所以例如$ @。)

您可能想使用make的--debug選項來捕獲那種錯誤;到目前爲止,我發現跟蹤不正確的依賴關係非常有用。

+0

我在最後一行添加'-include',似乎沒有改進 –

+0

請參閱已編輯的答案。 – VannTen