2017-03-05 106 views
1

我有兩個cmake項目。其中一個使用googletest,第二個也使用它。更重要的是,我在第二個項目中使用了第一個項目。如何刪除從屬項目中相同的依賴項源的重複

我在github上有第二個項目,googletest也在github上。所以,我想下載它們,當我用

ExternalProject_Add

命令建立我的第一個項目。


這simpified文件夾結構:

ProjectA 
| build/ 
| include/ 
| src/ 
| modules/ 
| | ProjectB/ 
| | | CMakeLists.txt 
| | googletest/ 
| | | CMakeLists.txt 
| CMakeLists.txt 

而對於ProjectB簡化結構:

ProjectB/ 
| build/ 
| include/ 
| src/ 
| modules/ 
| | googletest/ 
| | | CMakeLists.txt 
| CMakeLists.txt 

而且現在我有很重要的問題:它可以一次下載googletest代碼?現在我下載兩次,一次爲ProjectA,第二次爲ProjectB

我可以添加簡化的CMakeLists.txt代碼,但我認爲這不是必要的。

回答

1

您可以將googletest作爲第三個外部項目,然後將它的位置作爲CMake緩存變量傳遞到您的兩個項目中。這樣可以確保你只需要下載一次googletest,但是與直接將googletest作爲項目的一部分構建起來可能不太方便。您可以創建第四個頂級項目,將三個項目(googletest,projectA和projectB)中的每一個拉到一起,以便確保在您需要配置projectA或projectB之前構建googletest。 Externaltestject for googletest會將gtest和gmock目標安裝到其安裝區域。然後將該目錄傳遞給projectA的和projectB的ExternalProjects作爲查找Google測試的位置。您可以使用項目A和項目B中的FindGTest模塊進行此操作,讓頂級項目爲projectA和projectB設置GTEST_ROOT緩存變量。這可能是最簡單的選擇。

另一個選擇是下載並構建googletest作爲了projectA(見here的方法,我建議這樣做)的一部分,然後讓項目B重新使用googletest源或者更好的是,從內置目標了projectA。如果需要,您可以像上面的鏈接將googletest帶入projectA一樣將projectA引入projectB。我們在工作中使用這樣一種安排來彙集多個不同的項目,每個項目都可以獨立構建或作爲其他項目的一部分構建。這種方法的一個優點是,如果您使用Visual Studio,Xcode或Qt Creator之類的IDE,您可以查看源列表中所有項目的來源,並且IDE的問題檢測,重構工具等往往具有更全面地瞭解整體構建。它也傾向於最小化必須在項目之間手動傳遞的信息,因爲CMake在一個構建中看到了整套源和目標,因此不需要明確處理平臺特定的庫名稱,不同的構建輸出目錄結構等

如果你想保持projectA作爲projectB的ExternalProject,那麼你仍然可以重複使用ProjectA中的googletest源代碼,但你必須非常仔細地設置目標間依賴關係,以確保構建projectA在需要googletest資源的任何事情之前。你可能最終也不得不手動確定下載到projectA中的內容,如果你的項目建立在多個平臺上,這可能會很痛苦。這聽起來像是最接近你所要求的,但我可能會建議嘗試上述兩種方法之一。

還有其他選擇,例如使用像hunter這樣的軟件包管理器,但這可能會偏離問題的原始焦點太遠。

+0

謝謝你的回答!我今天會檢查一下。 – BartekPL

+0

感謝您的複雜答案。我檢查了你的博客文章和Git回購,並且我在我的問題中使用了這種方法。 – BartekPL

1

如果您不想兩次下載Google C++測試框架,只需使用適當的cmake查找模塊,並讓它從您的環境中找到所需。

請參閱FindGTest

實施例的使用從上面的鏈接:

enable_testing() 
find_package(GTest REQUIRED) 
add_executable(foo foo.cc) 
target_link_libraries(foo GTest::GTest GTest::Main) 
add_test(AllTestsInFoo foo) 

這就是說,它們與自己的模塊不同的項目。明確他們會更好。
您仍然可以在ProjectB中放置一個自定義cmake查找模塊,該模塊在ProjectA內查找gtest。無論如何,這是一個脆弱的解決方案,因爲只要ProjectA中的依賴關係發生變化,它就會中斷。


問題的意見:

這似乎是GTEST確實不錯,但我不知道如果我有不同的項目比GTEST(如項目C),那麼我該怎麼辦?我尋找更通用的解決方案。

如果我無法通過正確的查找模塊(以及需要的版本)在我的系統中查找依賴項,我通常更願意對它們進行明確的說明。因此,我將所需的依賴項添加到每個項目中,即使它意味着重新編譯它們兩次。
可以回答個爲什麼一個問題:如果ProjectA取決於標籤X給定模塊和ProjectB需要標籤Ÿ工作?如果兩個標籤破壞對方的API(不幸的是有時會發生),那麼除非您明確瞭解每個項目的依賴關係,否則您將遇到麻煩。

+0

那麼,如果您認爲擁有兩個獨立的Google測試資源副本會更好? – BartekPL

+0

@BartekPL不,我想你可以安全地使用FindGTest模塊。爲什麼不? – skypjack

+0

gtest似乎真的很好,但我不知道我是否有與gtest(例如ProjectC)不同的項目,那麼我該怎麼做?我尋找更多的解決方案:)你有什麼想法嗎? – BartekPL

相關問題