2013-10-27 27 views
6

我正在重組使用CMake構建的許多第三方依賴關係的large cross-platform C++ project的物理(磁盤)佈局。大型跨平臺C++項目的磁盤上的物理佈局,具有許多第三方依賴關係

由於我們需要支持Windows,一個沒有完善的軟件包管理器的平臺,我們很早以前決定在源碼樹中包含我們依賴的第三方庫。但是,在我們支持的其他平臺(如Linux和Mac OS X)上,許多這些第三方庫可作爲軟件包提供,或者已經存在於系統中,並且很容易通過CMake找到。

目前的項目佈局如下:

root/ 
    src/ 
     3rd-party-lib1/  (build system modified to output to build/) 
     3rd-party-lib2/  (build system modified to output to build/) 
     project-module1/  (our own code) 
     project-module2/  (our own code) 
    build/     (CMake is invoked from here) 
     3rd-party-lib1-bin/ 
     3rd-party-lib2-bin/ 

第三方庫已經調整,這樣建,他們輸出的二進制文件root/build/<lib>/時。

用這個佈局的問題是多方面的:

  • 第三方庫不再是100%原裝。這使得它們更新比要求更難。
  • src/目錄包含我們自己的代碼和第三方代碼的混合物,這很混亂。
  • src/目錄非常大。因爲src/包含第三方庫,所以它與原始源代碼的實際數量相比非常大,使得我們自己的代碼的備份比需要的稍微複雜(我們不能僅存檔整個src/目錄)。
  • 由於包含第三方庫(可能包含大量非源文件,如文檔,測試數據等),因此項目存儲庫(Git)非常大,因此它會變大我們更新它們的時間爲。不幸的是,除非我們決定重新啓動一個新的存儲庫(不幸的是丟失了整個提交歷史記錄),否則沒有辦法回到這裏。
  • 許多那些包含第三方庫(例如zlib,libpng)的用戶在Linux或Mac OS X上構建項目時完全不需要,儘管它們極大地簡化了Windows用戶的操作。

另一種佈局將是如下:

root/ 
    3rdparty/ 
     3rd-party-lib1/  (100% original, contains built artifacts) 
     3rd-party-lib2/  (100% original, contains built artifacts) 
    src/ 
     project-module1/  (our own code) 
     project-module2/  (our own code) 
    build/     (CMake is invoked from here) 

我們CMake的文件需要進行修改,以尋找第三方頭文件和庫中每個庫的正確的地方。

有關在本地跨平臺項目中處理第三方庫的最佳做法是什麼?哪種佈局會爲我們的開發人員在各自的平臺上帶來最令人吃驚的構建體驗?來自現有項目的成功布局的具體例子也很受歡迎。

+1

也許Windows的數據包管理器可以解決這個問題。我試圖自己創建一個:http://vertexwahn.de/bluego.html - 現在只支持Qt。在我自己的項目中,我使用了一種混合方法 - Boost,Qt,OptiX,Cuda,Windows SDK被假定爲由用戶安裝 - 其他庫如gtest,OpenEXR,zlib,freetype,glews等都隨源代碼提供。 – Vertexwahn

+0

感謝您的輸入。我們也希望用戶可以在他們的機器上安裝Qt和Boost。我關心的是其他較小但較少知名的庫,如ILMBase,OpenEXR,Alembic,zlib,libpng等。 –

+0

剛發現NuGet for C++:http://blogs.msdn.com/b/vcblog/archive/2013 /04/26/nuget-for-c.aspx。一些庫已經被支持:http://www.nuget.org/profiles/coapp/但是我沒有實際的經驗。 – Vertexwahn

回答

7

我的經驗表明,以下爲最佳實踐:

  • 當一個第三方的開源庫用來完全原來的樣子,提交主要git倉庫內下載的壓縮tar文件的本地副本,以避免阻止軟件構建的網絡連接問題。

  • 當第三方開源庫幾乎按原樣使用但需要調整(在交叉編譯時,這種情況很常見:許多軟件包需要對其配置步驟進行輕微調整),請將壓縮tarball和主要git倉庫中的「統一差異」補丁文件,並將補丁應用到ExternalProject_Add的PATCH_COMMAND步驟中。

  • 當你的組織需要大量修改或擴展第三方開源庫時,請使用單獨的git存儲庫來存放指向上游存儲庫的指針(當它也使用git時最簡單,但上游svn也可以管理)。將組織的更改提交給用於鏡像上游的分支的不同分支。如果你願意,你可以在主要的git倉庫和這個倉庫之間引入一個子模塊關係,不過因爲DOWNLOAD_COMMAND可以直接從任意的倉庫倉庫中獲取,所以在技術上並不需要這樣做。

  • 對於單個目標平臺,通過將它們歸檔到主git倉庫中來處理小型,不太常見的第三方專有二進制文件是合理的。但是,可用於各種平臺的第三方二進制文件很大或經常發展,應該存儲在其自己的git倉庫中,並通過DOWNLOAD_COMMAND提取,如上所述。

+0

+1,但恕我直言,沒有必要提交tarball /二進制文件到主git回購。爲什麼不簡單地使用'ExternalProject_Add'將發佈快照從自定義位置下載? – 2013-11-02 05:08:12

+0

根據具體情況,這可能是一個合理的選擇 - 甚至只使用ExternalProject_Add_Step就足夠了。但是,存在一個嚴重的風險,即構建快照的知識會隨着時間流逝而丟失。爲了防止這種情況發生,重要的是快照製作過程必須以一致的可重複形式進行捕捉。但是,除非這個過程是真正耗時的,否則將產生它的算法與產生主構建的算法分離是沒有價值的。 – newbrific

+0

謝謝@newbrific爲優秀的答案!爲了不阻止其他貢獻者分享他們的想法和經驗,我會繼續保持這個問題的時間。 –

相關問題