2017-06-20 49 views
2

有誰知道在CMake文件中應用「包含一次」模式的簡單方法嗎?在C/C++中,它曾經在頭文件的開始和結尾需要一個#ifdef/#endif對,直到#pragma一度變得很普遍。當然,也可以在CMake中做同樣的事情,但是我認爲如果它不需要明確的條件語句會更好。是否有包含一次cmake文件的命令?

重編:看起來,return()命令應該這樣做。我會定義一個這樣的宏:

macro(include_once) 
    if (INCLUDED_${CMAKE_CURRENT_LIST_FILE}) 
    return() 
    endif() 
    set(INCLUDED_${CMAKE_CURRENT_LIST_FILE} true) 
endmacro() 

在文件的開頭使用宏,沒有任何參數。因爲它是一個宏,所以返回來自文件的include命令,而不是來自宏本身。

請注意,創建的變量有一個奇怪的名稱,但CMake似乎接受這一點。

+1

什麼是在CMake的文件你包括,你的設置是什麼,你*會*要求防止多重包含?就個人而言,我通常擁有「main」CMakeLists.txt(它不包含「包含」)和帶有輔助函數的模塊(不會抱怨首先包含多個包含)。在這裏,我不太清楚用例是什麼。 – DevSolar

+0

有各種各樣的情況可能是必要的。具體來說,我有一個包含子目錄的頂級項目,我想讓每個子目錄成爲一個獨立項目。所以頂級項目和所有的子級都包含一個共享的定義文件。如果定義文件打印的東西,它打印得比我想要的多得多。這是一個處理開銷。等等。所以,我認爲有充足的理由要求這樣做。 –

+0

如果子目錄是作爲獨立項目構建的 - 每個項目的輸出應該是獨立完成的 - 或者處理開銷的影響(即使對於大多數涉及的項目我都認爲是微不足道的,我不相信印刷信息的冗餘)用CMake處理,儘管我總是從一個單獨的CMakeLists.txt構建(包含)。但我願意讓這個休息一下,指出Tsyvarev在「如何」和「爲什麼」這兩個方面的出色答案。 – DevSolar

回答

0

它明確規定 Refer Here更多信息here

include(<file|module> [OPTIONAL] [RESULT_VARIABLE <VAR>] 
        [NO_POLICY_SCOPE]) 
+4

問題是關於「包含**一次**」。這並沒有回答這個問題。 – DevSolar

3

對多個模塊包括最簡單的保護圖案會

if(<something-which-is-defined-in-your-module>) 
    return() 
endif() 

例如,如果你的CMake的模塊定義的函數foo_func,你可以使用這個後衛:

if(COMMAND foo_func) 
    return() 
endif() 

你真的需要警衛嗎?

依賴於模塊中定義的事情,模塊可能需要保護多次包含或不包含。

在許多簡單的情況下,警衛不需要:即使包含多次,模塊的代碼也可以工作。

但是在其他一些情況下,錯誤的保護可能會破壞被檢測模塊的使用。

  1. 甲模塊定義了一個函數:保護被不需要

    CMake允許多次定義函數和宏。

  2. 甲模塊定義了一個恆定變量:保護被不需要

    與功能一樣,CMake允許多次定義變量。

    但是,如果你在這種情況下,使用保護,它應該檢查參數,而不是一個函數:

    if(foo_var) 
        return() 
    endif() 
    

    這是因爲函數有全球知名度,但變量有當地的知名度。也就是說,如果你的模塊將被包含到其他子樹中,該函數將在該子樹中已經可見,但該變量不是。

  3. 模塊經由set(CACHE)限定全局變量:後衛是如果變量被定義爲set(CACHE INTERNAL)只需要

    通過例如set(CACHE STRING)find_library定義的變量不需要警衛。

  4. 模塊定義全球房地產:是需要後衛。

請注意,如果您的模塊使用簡單(沒有CACHE)變量作爲全球性的,它不能在多個子樹工作,所以後衛應該是

if(foo_var) 
     message(SEND_ERROR "Module <...> cannot be included twice") 
    endif() 
相關問題