簡體   English   中英

不同輸出目錄的GCC依賴關系生成

[英]GCC dependency generation for a different output directory

我正在使用GCC生成依賴文件,但我的構建規則將輸出放入子目錄中。 有沒有辦法告訴GCC將我的子目錄前綴放在它為我生成的依賴文件中?

gcc $(INCLUDES) -E -MM $(CFLAGS) $(SRC) >>$(DEP)

我假設你正在使用GNU Make和GCC。 首先添加一個變量來保存依賴項文件列表。 假設您已經有一個列出我們所有來源的:

SRCS = \
        main.c \
        foo.c \
        stuff/bar.c

DEPS = $(SRCS:.c=.d)

然后在makefile中包含生成的依賴項:

include $(DEPS)

然后添加此模式規則:

# automatically generate dependency rules

%.d : %.c
        $(CC) $(CCFLAGS) -MF"$@" -MG -MM -MP -MT"$@" -MT"$(<:.c=.o)" "$<"

# -MF  write the generated dependency rule to a file
# -MG  assume missing headers will be generated and don't stop with an error
# -MM  generate dependency rule for prerequisite, skipping system headers
# -MP  add phony target for each header to prevent errors when header is missing
# -MT  add a target to the generated dependency

“$ @”是目標(在左側的東西:),“$ <”是先決條件(在右側的東西:)。 表達式“$(<:。c = .o)”用.o替換.c擴展名。

這里的技巧是通過添加-MT兩次來生成具有兩個目標的規則; 這使得.o文件和.d文件都依賴於源文件及其頭文件; 這樣,只要更改了任何相應的.c或.h文件,依賴文件就會自動重新生成。

如果缺少頭文件,-MG和-MP選項會使make嚇壞。

答案在GCC手冊中 :使用-MT標志。

-MT target

更改依賴關系生成所發出的規則的目標。 默認情況下,CPP獲取主輸入文件的名稱,刪除任何目錄組件和任何文件后綴(如.c ,並附加平台的常用對象后綴。 結果是目標。

-MT選項將目標設置為您指定的字符串。 如果需要多個目標,可以將它們指定為-MT的單個參數,或使用多個-MT選項。

例如, -MT '$(objpfx)foo.o'可能會給出

 $(objpfx)foo.o: foo.c 

你可能會喜歡Don McCaughey這個簡短版本的答案

SRCS = \
    main.c \
    foo.c \
    stuff/bar.c

DEPS = $(SRCS:.c=.d)

添加-include $(DEPS)注意-前綴,如果.d文件尚不存在,則會使錯誤無效。

生成依賴項文件不需要單獨的模式規則。 只需將-MD-MMD添加到正常編譯行,並在編譯源文件的同時生成.d文件。 例如:

%.o: %.c
     gcc $(INCLUDE) -MMD -c $< -o $@

# -MD can be used to generate a dependency output file as a side-effect of the compilation process.

詳細介紹了DGentry的答案 ,這對我來說效果很好:

.depend: $(SOURCES)
    $(CC) $(CFLAGS) -MM $(SOURCES) | sed 's|[a-zA-Z0-9_-]*\.o|$(OBJDIR)/&|' > ./.depend

這也適用於只有一個依賴項文件包含所有源文件的依賴項規則的情況。

好的,只是為了確保我的問題是正確的:我假設你有test.c ,其中包括test.h ,你想生成subdir/test.d而不生成subdir/test.osubdir/test.d包含

subdir/test.o: test.c test.h

而不是

test.o: test.c test.h

這就是你現在得到的。 那正確嗎?

我無法想出一個簡單的方法來完成你所要求的。 但是,查看依賴關系生成改進 ,如果要在生成.o文件時創建.d文件,可以使用:

gcc $(INCLUDES) -MMD $(CFLAGS) $(SRC) -o $(SUBDIR)/$(OBJ)

(給定SRC=test.cSUBDIR=subdirOBJ=test.o )這將創建subdir / test.o和subdir / test.d,其中subdir/test.d包含如上所需的輸出。

如果GCC有這樣的爭論,我不知道它是什么。 我們最終通過sed管道依賴輸出,將所有出現的<blah>.o重寫為${OBJDIR}/<blah>.o

  1. 如果不將輸出放在當前目錄中,[GNU] make會生氣。 您應該從構建目錄中運行make,並使用VPATH make變量來查找源代碼。 如果你撒謊到編譯器,它遲早會報復。

  2. 如果您堅持在其他目錄中生成對象和依賴項,則需要使用-o參數,如Emile所述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM