我會參考你的this article深入討論兩種主要方法,但有幾種方法可以構建這樣的項目。
- 頂部一個CMakeLists.txt文件,它列出了所有不同子目錄中的所有源文件。您通常只會看到非常簡單的項目。
- 每個目錄中有一個CMakeLists.txt文件,每個文件由其父代使用
add_subdirectory()
引入。這種方法非常普遍。
- 頂層有一個CMakeLists.txt文件,每個子目錄都有自己的文件,列出自己的源文件和目標。頂級CMakeLists.txt文件將帶有
include()
的子目錄文件。不太常見,但可以比其他兩個有優勢。
各有其優缺點。只有一個頂級CMakeLists.txt文件只有在文件和子目錄很少時才被推薦。一旦項目增長,將所有內容保留在頂層可能會變得太多,導致CMakeLists.txt文件難以跟上。它還有一個缺點,即文件添加或刪除的更改不限於特定的目錄。這看起來可能不是什麼大不了的事情,但是如果有多個人正在從事項目工作,並且想要輕鬆看到其他人的更改會影響項目的哪部分內容(例如在git歷史記錄中),那就更困難了。如果您同時添加/刪除文件,則更是如此,因此都會更改頂級CMakeLists.txt文件並有可能發生衝突。
一旦項目大小變得不平凡,大多數人選擇在每個子目錄中添加一個CMakeLists.txt文件,並使用add_subdirectory()
將它們放在一起。 TheQuantumPhysicist的答案給出了一個很好的例子,說明這可能是有用的,所以我不會在這裏重複大部分細節。這個結構爲您提供了輕鬆打開/關閉構建樹的整個部分的能力,但更重要的是,它爲每個子目錄提供了自己的變量範圍。如果要在源樹的一部分中設置變量等,但在另一部分中不可見這些更改(請考慮只適用於複雜目錄結構的一部分的編譯器標誌),這一點很重要。
一個頂級CMakeLists.txt文件的第三個選項與每個提供include()
文件的子目錄不太一樣,但它與在每個子目錄中使用一個CMakeLists.txt文件相似。兩者都將目錄中文件的詳細信息本地化爲CMakeLists.txt或該目錄中的其他類似名稱的文件。因此,變更在版本控制歷史記錄等中變得更加容易合併和理解。第三種方法允許第二種方法不會在使用target_sources()
指定每個子目錄中的源文件時更自由地使用target_link_libraries()
。在這個答案的頂部鏈接的文章詳細說明了爲什麼target_sources()
可以是有利的,這是爲什麼這個第三種方法對許多項目來說可能是理想的核心。
最後,我建議你不要把你的構建樹放在你的源代碼樹中。相反,創建您的構建樹作爲源樹的兄弟。旨在保持源代碼樹不受構建影響。所需要的只是讓某人在源代碼樹中創建一個與您用於構建樹的任何名稱相同的名稱來爲出錯的目錄創建一個目錄(我已經多次看到這個目錄!)。您可能還想爲一個源代碼樹設置多個構建樹,例如一個用於調試構建,另一個用作發佈構建,因此將這些構建樹放在源代碼樹之外也有助於減少源樹的混亂。
我認爲CMakeLists.txt只是一個,在父目錄(PS)我不是cmake的專家 –
@DanishAlsayed我在這裏看到了一些例子,有些人建議多個CMakeLists.txt,但是他們有一個非常具體問題,我不知道這是否是我的問題的解決方案具體。 –
你看過文檔嗎? https://cmake.org/examples/ –