2014-09-24 57 views
2

我目前正在編寫一個更大的makefile,它將處理源文件的遞歸結構,並將它放入目標目錄中的同一個遞歸結構中。基本上,你可以假設這樣的Makefile:GNU Make - 如何處理目標文件中的路徑

DESTINATION_DIR = out 
SOURCE_DIR = src 
OBJECTS = out/abc.o out/subdir/test.o out/subdir/subdir/xyz.o 

.PHONY: all 
all: $(OBJECTS) 

$(DESTINATION_DIR)/%.o: $(SOURCE_DIR)/%.c 
    @echo "[email protected] --- $<" 

正如你看到的,我想用$(SOURCE_DIR)的依賴,以取代$(DESTINATION_DIR),但這並不工作。我該如何解決這個問題?我甚至試圖用這種方式替換腳本:

%.o: $(shell myreplacementscript.py "%.c" "$(DESTINATION_DIR)" "$(SOURCE_DIR)") 
    @echo "[email protected] --- $<" 

但百分比符號將被傳遞到我的腳本沒有更換。那麼我怎麼能告訴它輸出依賴於源文件動態?我需要將子目錄保存在OBJECTS變量中,我不能將結構展平。而子目錄是動態的,而不是預定義的。

我已經搜索了其他人有相同的問題,但他們要麼有平的OBJECTS或遞歸的製造,在我的情況是不適合的,因爲根據依賴目錄之間的互連。

摘要/錯誤消息:

它不會取代輸出/輸入與Src /對象。所以錯誤信息是「Keine Regel vorhanden,um das Target»out/abc.o«,benötigtvon»all«,zu erstellen。Schluss。」這是典型的錯誤「沒有制定目標的規則......」。

完整的makefile可以在這裏看到: Full Makefile

每當我離開%的.html結腸的右手邊在左側它的工作原理,但我需要有源文件作爲依賴以獲得工作增量構建(希望沒有創建依賴文件)。

親切的問候,

丹尼爾

+0

你使用什麼版本的Make? (如果您不確定,請嘗試使用'make -v'。) – Beta 2014-09-24 22:55:30

+2

如果您確切地說明了_but這不起作用_實際上意味着(錯誤消息?錯誤行爲?缺少行爲?),那麼幫助會簡單得多您。 – MadScientist 2014-09-24 23:34:47

+0

@Beta:GNU Make 3.81 – DanielB 2014-09-25 07:12:07

回答

0

隨着邁克爾·格魯內瓦爾德答案,並MadScientist的網站上,我決定去VPATH方式。但是,因此我必須先切換到輸出目錄並刪除OBJECTS的輸出/前綴(通過對makefile的遞歸調用)。上述簡短的例子將被修改如下:

ROOTDIR = $(abspath ./) 

DESTINATION_DIR = out 
SOURCE_DIR = src 

DESTINATION_DIRABS = $(abspath $(shell cd $(ROOTDIR); cd $(DESTINATION_DIR); pwd)) 
SOURCE_DIRABS = $(abspath $(shell cd $(ROOTDIR); cd $(SOURCE_DIR); pwd)) 

ifneq ($(abspath ./),$(DESTINATION_DIRABS)) 
# we are not in the destination directory, so we first need to change to it 
OBJECTS  = 
else 
# without out/ prefix! 
OBJECTS  = abc.o subdir/test.o subdir/subdir/xyz.o 
# set the VPATH for the source files 
VPATH  = $(SOURCE_DIRABS) 
endif 

.PHONY: all 
all: $(OBJECTS) 
ifneq ($(abspath ./),$(DESTINATION_DIRABS)) 
    # call make inside the destination directory 
    $(MAKE) -C $(DESTINATION_DIRABS) -f $(ROOTDIR)/Makefile ROOTDIR='$(ROOTDIR)' 
endif 

%.o: %.c 
    @echo "[email protected] --- $<" 

(在這個小例子未經檢驗的,但在我的大的Makefile作品)

所以最後它現在按預期工作。非常感謝您的評論MichaelGrünewald,MadScientist和Beta。

更新:

最後我重試$(DESTINATION_DIR)/%○:$(SOURCE_DIR)/%C的做法和錯誤只是簡單地認爲$(DESTINATION_DIR)已經包含在斜線。我的完整makefile。

對不起,並再次感謝。對於任何人,因爲有類似的問題而閱讀本文:請檢查斜槓兩次!

1

使用GNU make擴展的解決方案不是一個好方法。我建議不要使用任何GNU Make特定功能。首先它不是便攜式的。其次,它的語法是可怕的。使用有史以來發明的標準工具和技術。你的解決方案是 - 殼牌。您可以將Makefile包裝到shell腳本中,並使用通用shell語言進行所有計算和字符串操作。以下面的示例爲例:

src_files="file1.c file2.c file3.c" 

cat > Makefile <<EOF 
- 
- 
YOUR MAKEFILE STATIC STUFF GOES HERE 
- 

all: $(OBJECTS) 

EOF 

for file in $src_files; do 
    src="src/$file" 
    obj=`echo $file | sed 's/\.c$/\.o/'` 
    sources="$sources $src" 
    objects="$objects out/$obj" 

    cat >>Makefile <<EOF 
$obj: $src 
    YOUR CODE HERE 
EOF 
done 

cat >>Makefile <<EOF 
SOURCES = $sources 
OBJECTS = $objects 

EOF 

命名您的腳本'mkmf'並運行./mkmf。它會生成Makefile。您可以參數化並使其非常強大和智能。沒有必要使用稀少和骯髒的GNU做擴展。

+0

這可能是真的,但可移植性對我來說不是真的需要。你的意思是什麼?我終於把它用在標準模式out /%。o:in /%。o。 – DanielB 2014-10-01 17:45:08

+1

所有那些甜美的東西'$(shell ..)'都是GNU特有的功能。它在其他make實現中不起作用。 – 2014-10-01 18:40:49

+0

謝謝你提供的信息,但正如我所說,我可以忍受這一點。我不關注GNU make的其他make實現。 – DanielB 2014-10-02 08:27:55