c++ 舊區重建例子 - 你如何強制makefile來重建目標




舊區重建英文 市區重建 (13)

我有一個生成文件,然後調用另一個生成文件。 由於這個makefile調用了更多的makefile,所以它並沒有真正改變。 因此它一直認為該項目是建立和最新的。

dnetdev11 ~ # make
make: `release' is up to date.

我如何強制makefile重建目標?

clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean


build = svn up ~/xxx                                                       \
        $(clean)                                                                \
        ~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace        \
        $(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1)                    \


release:
        $(build )

debug:
        $(build DEBUG=1)

clean:
        $(clean)

install:
        cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
        cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib

注:刪除名稱以保護無辜者

編輯:最終修正版本:

clean = $(MAKE) -f xxx_compile.workspace.mak clean;


build = svn up;                                         \
        $(clean)                                        \
        ./cbp2mak/cbp2mak -C . xxx_compile.workspace;   \
        $(MAKE) -f xxx_compile.workspace.mak    $(1);   \


.PHONY: release debug clean install

release:
        $(call build,)

debug:
        $(call build,DEBUG=1)

clean:
        $(clean)

install:
        cp ./source/xxx_utillity/release/xxx_util /usr/bin
        cp ./dlls/Release/xxxcore.so /usr/lib

Answers

其他人建議.PHONY這是絕對正確的。 .PHONY應該用於輸入和輸出之間的日期比較無效的任何規則。 由於你沒有任何形式output: input目標output: input你應該為它們使用.PHONY!

所有這些,你可能應該在你的makefile的頂部為各種文件名定義一些變量,並且定義具有輸入和輸出部分的真正的make規則,這樣你就可以使用make的好處,也就是說你只能實際編譯有必要的事情!

編輯:添加示例。 未經測試,但這是你如何做.PHONY

.PHONY: clean    
clean:
    $(clean)

我試過這個,它為我工作

將這些行添加到Makefile中

clean:
    rm *.o output

new: clean
    $(MAKE)     #use variable $(MAKE) instead of make to get recursive make calls

保存並現在打電話

make new 

它會重新編譯一切

發生了什麼?

'new'調用clean'clean'做'rm',它刪除所有擴展名為'.o''new'調用'make'的對象文件。 'make'看到沒有'.o'文件,所以它繼續並再次創建所有'.o'。 那麼鏈接器將所有.o文件鏈接到一個可執行輸出中

祝你好運


在我的Linux系統(Centos 6.2)上,當聲明目標.PHONY和在FORCE上創建一個偽依賴關係時,實際上創建一個匹配目標的文件時存在顯著差異。 當文件必須每次都重新生成時,它需要文件上的假依賴性FORCE和假依賴性的.PHONY。

錯誤:

date > [email protected]

對:

FORCE
    date > [email protected]
FORCE:
    .PHONY: FORCE

這種簡單的技術將允許makefile在不需要強制時正常運行。 在makefile結尾創建一個名為force的新目標。 強制目標將觸及默認目標所依賴的文件。 在下面的例子中,我添加了觸摸myprogram.cpp 。 我還添加了一個遞歸調用。 這會在每次輸入make force時導致默認目標被製作。

yourProgram: yourProgram.cpp
       g++ -o yourProgram yourProgram.cpp 

force:
       touch yourProgram.cpp
       make

它已經提到,但認為我可以添加到使用touch

如果您touch所有要編譯的源文件, touch命令會將文件的時間戳更改為系統執行touch命令時的時間戳。

源文件timstamp是用來“知道”一個文件已經改變,並且需要重新編譯的東西

例如:如果項目是一個c ++項目,那麼請touch *.cpp ,然後再次運行make ,並且應該重新編譯整個項目。


曾經在Sun手冊中記錄的一個技巧是使用(不存在的)目標'.FORCE'。 你可以通過創建一個包含以下內容的文件force.mk來實現:

.FORCE:
$(FORCE_DEPS): .FORCE

然後,假設你現有的makefile被稱為makefile ,你可以運行:

make FORCE_DEPS=release -f force.mk -f makefile release

由於.FORCE不存在,依賴於它的任何內容都將過期並重建。

所有這些都適用於任何版本的make ; 在Linux上,你有GNU Make,因此可以使用.PHONY目標。

同樣值得考慮的是為什麼認為發布是最新的。 這可能是因為你在執行的命令中有一個touch release命令; 這可能是因為有一個名為'release'的文件或目錄存在,並且沒有依賴關係,因此是最新的。 然後是真正的原因......


-B開關的長形式是--always-make ,告訴make忽略時間戳並製定指定的目標。 這可能會破壞使用make的目的,但它可能是您需要的。


你可以宣稱你的一個或多個目標是phony

虛假目標是一個並非真正的文件名稱; 相反,它只是一個名稱,用於在您提出明確請求時執行的配方。 使用虛假目標有兩個原因:避免與同名文件發生衝突,並提高性能。

...

虛假目標不應成為真實目標文件的先決條件; 如果是這樣,它的配方將在每次更新該文件時運行。 只要虛假目標永遠不是真正目標的先決條件,虛假目標配方將僅在虛假目標是特定目標時執行


它實際上取決於目標是什麼。 如果它是假目標(即目標與文件無關),則應將其聲明為.PHONY。

但是,如果目標不是虛假目標,但由於某種原因(例如當您使用__TIME__預處理宏),您只需要重新構建目標時,則應使用此處答案中所述的FORCE方案。


如果我沒有記錯,'make'使用時間戳(文件修改時間)來確定目標是否是最新的。 強制重新構建的常用方法是使用'touch'命令更新該時間戳。 您可以嘗試在makefile中調用'touch'來更新其中一個目標(可能是其中一個子目錄)的時間戳,這可能會強制Make執行該命令。


如果您不需要保留已經成功編譯的任何輸出

nmake /A 

重建所有


按照米勒的遞歸考慮有害,你應該避免調用$(MAKE) ! 在你展示的情況下,它是無害的,因為這不是一個真正的makefile,只是一個包裝腳本,這可能也是在Shell中編寫的。 但是你說你在更深的遞歸級別上繼續這樣做,所以你可能遇到了那篇大開眼界的文章中顯示的問題。

當然,對於GNU來說,避免是很麻煩的。 即使他們意識到這個問題,也是他們記錄的做事方式。

OTOH, makepp是為解決這個問題而創建的。 您可以在每個目錄級別編寫您的makefile,但它們都可以被整合到一個完整的項目視圖中。

但遺留的makefile是遞歸編寫的。 所以有一個解決方法,其中$(MAKE)什麼也不做,只是將子請求傳回主makepp進程。 只有在你的子部件之間做了冗餘或更差的矛盾事情時,你必須要求 - --traditional-recursive-make (這當然會打破makepp的這個優點)。 我不知道你的其他makefile,但如果它們是乾淨的書面的,makepp必須重新生成,而不需要別人在這裡提出的任何黑客攻擊。


使用PortAudio 。 它是一種便攜式跨平台音頻API。







c++ linux makefile