2014-02-18 104 views
1

我在嘗試修改具有通用/特定模式特定規則的大型項目的gnu makefile。根據條件重建特定對象

該生成文件正在編譯和鏈接在單獨的規則。我有一個特定的需求,如果某個條件在鏈接時傳遞,那麼我想在再次鏈接之前再次調用編譯規則。從生成文件樣本問題如下,

$(obj_dir)/%.o: $(src_base)/%.cpp 
    @echo Compiling: $< 
    $(q)$(CXX) $(CXXFLAGS) $(REV) $(CXX_INCLUDE_PATH) -o [email protected] $< 

    $(link_files) : 
    @echo Linking [email protected] 
    $(q)$(CXX) $(LINKFLAGS) -o [email protected] %.o 
    ifeq (1,1) 
    #condition pass so I want to call generic above ompilation rule again 
     ????? 
    else 
     $(warning Do Nothing) 
    endif 

能有人幫我如何我可以遞歸或以其他方式再次調用通用的編譯規則。

幫助將不勝感激。提前致謝。

+0

難道你不想讓對象文件成爲鏈接規則的先決條件嗎?在這種情況下,再次調用編譯規則將不會執行任何操作,因爲對象文件已經是最新的。 – Beta

+0

謝謝。我可以添加目標文件作爲鏈接規則依賴項,或者我可以在再次調用編譯規則之前刪除生成的鏈接文件。你能幫我解決一下原來的問題:我怎樣才能在鏈接規則中再次調用編譯規則。 – Akamai

+0

我想你誤解了Make是如何工作的。如果您有所需的目標文件列表,重新編譯編譯規則很容易,但我沒有看到這樣做。你能告訴我們爲什麼你要重建目標文件嗎? – Beta

回答

0

我同意貝塔,這聽起來很瘋狂。

但是,如果你只是想要這樣做,這很簡單。但是,這裏的東西,你必須在配方中編寫測試,作爲shell測試。你不能使用製作測試(ifeq等)然後你可以調用一個遞歸make來建立文件,並使用-W標誌來強制它被重建。像(假設你要重建文件的東西是foo.cpp

$(obj_dir)/%.o: $(src_base)/%.cpp 
     @echo Compiling: $< 
     $(q)$(CXX) $(CXXFLAGS) $(REV) $(CXX_INCLUDE_PATH) -o [email protected] $< 

$(link_files) : 
     @echo Linking [email protected] 
     $(q)$(CXX) $(LINKFLAGS) -o [email protected] %.o 
     if [ 1 -eq 1 ]; then \ 
      $(MAKE) -W $(src_base)/foo.cpp $(obj_dir)/foo.o || exit 1; \ 
     else; \ 
      echo do nothing; \ 
     fi 
+0

謝謝..我還沒有測試過,但我有一個小混亂。我們明確指定源文件,其中一個對象可以由多個.cpp文件組成。有沒有辦法在遞歸make之前知道該對象由哪些源文件組成,或者只是在調用鏈接規則之前處理此對象的父編譯規則/ s。我問這個Makefile需要爲不同的對象自己執行。 – Akamai

+0

我不太清楚我是否理解這個問題,但總的來說,沒有內建的方法來確定造成某些其他規則的先決條件。如果這是你真正想要做的事情,你可以用'$(eval ...)'來做到這一點:在你的編譯規則中,你會添加類似'$(eval $ @ _ SRC:= $ <)'然後你可以使用變量$($(obj_dir)/foo.o_SRC)來檢索它。 – MadScientist

2

步驟1:得到基本的makefile工作也許你有這樣的了,但這裏有一個大綱:

OBJECTS := $(obj_dir)/foo.o $(obj_dir)/bar.o $(obj_dir)/baz.o 
# You MUST have a list like this somewhere, constructed somehow. 

$(obj_dir)/%.o: $(src_base)/%.cpp 
    @echo Compiling: $< 
    $(q)$(CXX) $(CXXFLAGS) $(REV) $(CXX_INCLUDE_PATH) -o [email protected] $< 

$(link_files) : $(OBJECTS) 
    @echo Linking [email protected] 
    $(q)$(CXX) $(LINKFLAGS) -o [email protected] $^ 

要確保在繼續之前,這個工作正常。特別是,確保您可以在命令行中通過爲值爲REV,如下所示:

make REV=123 

第2步:測試遞歸調用。一開始就是無條件的。

$(link_files) : $(OBJECTS) 
    @echo Linking [email protected] 
    $(q)$(CXX) $(LINKFLAGS) -o [email protected] $^ 
    $(MAKE) REV=$(NEWREV) $(OBJECTS) 

步驟3:測試條件。

$(link_files) : $(OBJECTS) 
    @echo Linking [email protected] 
    $(q)$(CXX) $(LINKFLAGS) -o [email protected] $^ 
    $(MAKE) REV=$(NEWREV) $(OBJECTS) 
    if [ 1 -eq 2 ];\ 
     then echo Do Something; \ 
    else \ 
     echo Do Nothing; \ 
    fi 

注意,這是在一個輸出語句有條件的,不是輸出語句在使條件。 (Make語句傾向於在任何規則運行之前進行評估。)在if前有一個TAB,但條件中其他行前的空格僅爲空格。

第4步:把它放在一起。

$(link_files) : $(OBJECTS) 
    @echo Linking [email protected] 
    $(q)$(CXX) $(LINKFLAGS) -o [email protected] $^ 
    $(MAKE) REV=$(NEWREV) $(OBJECTS) 
    if [ 1 -eq 2 ];\ 
     then $(MAKE) REV=$(NEWREV) $(OBJECTS); \ 
    else \ 
     echo Do Nothing; \ 
    fi 
+0

謝謝測試版。我沒有測試過你的解決方案,但是我能夠創建一個類似的Makefile,它遵循或多或少相同的方法,但我引入了一些更多的自定義規則,以便我可以基於該特定對象的新修訂版遞歸調用這些特定規則。 – Akamai