2016-04-27 103 views
5

每當我想包含一個位於我的項目之外的目錄與Clion時,我將使用-I somedir標誌。而這一次,我想要做的就是有這樣的層次結構:在Clion中包含目錄

/project 
    CMakeLists.txt 
    /src 
     /Graph 
     Graph.h 
     Graph.cpp 
     /Dijkstra 
     Dijkstra.h 
     Dijstra.cpp 

我想我在/src目錄代碼。不僅如此,而且,例如,在文件Dijkstra.h中,我想包含Graph.h,如下所示:#include "Graph/Graph.h而不是像這樣:#include "../Graph/Graph.h

如果我只添加一個-I src標誌,那麼如果我是Dijkstra.h文件裏面,我想包括Graph.h,我會寫#include "../Graph/Graph.h,這不是我想要的。

所以我試着還加了INCLUDE_DIRECTORIES(src)。這解決了上面的問題,但是當試圖編譯時,我得到了一個鏈接器錯誤undefined reference to...

所以我嘗試添加的文件一個個像這樣的:

set(SOURCE_FILES 
     src/Dijkstra/Dijkstra.h 
     src/Dijkstra/Dijkstra.cpp 
     src/Graph/Graph.h 
     src/Graph/Graph.cpp) 
add_executable(someprojectname ${SOURCE_FILES}) 

,並勾起以前的問題,在這裏我必須包括像這樣的文件:#include "../Graph/Graph.h"

我該怎麼做才能得到我想要的行爲?

+0

我建議,您使用的目錄結構類似這樣的圖形/ src目錄/ * CPP,圖形/包括/ * .h,Dijkstra/src/*。cpp和Dijkstra/include/*。h ..然後嘗試SET(GRAPH_INCLUDE_DIR Graph/include /),SET(DIJKSTRA_INCLUDE_DIR Dijkstra/include /)INCLUDE_DIRECTORIES($ {GRAPH_INCLUDE_DIR} $ {DIJKSTRA_INCLUDE_DIR}) – Varun

+0

根本不清楚問題。如果使用最後一個變體並添加'include_directories(src/Graph src/Dijkstra)'會發生什麼? – fghj

+0

我建議的方式是製作目錄結構的更好方法。 .cpp放在一個目錄中,而.h文件放在另一個目錄中。爲什麼要在單個目錄中混合這些文件。 – Varun

回答

5

命令INCLUDE_DIRECTORIES不添加用於編譯任何源文件

取而代之的是,該命令爲搜索頭文件定義了目錄。

你需要列出所有add_executable()通話文件在任何情況下:

include_directories(src) 
set(SOURCE_FILES 
    src/Dijkstra/Dijkstra.cpp 
    src/Graph/Graph.cpp) 
add_executable(someprojectname ${SOURCE_FILES}) 
2

更新: @ Tsyvarev的答案是正確的。我編輯了這個答案以刪除不正確的部分,並保留與target_include_directories()有關的評論,但它應該被視爲Tsyvarev的答案的補充。

INCLUDE_DIRECTORIES(src)將使src目錄作爲搜索路徑被添加到從該點開始定義的所有目標。它不會爲任何目標添加源。搜索路徑將相對於當前的源目錄,當通過add_subdirectory()下載到子目錄時,CMake將根據需要進行調整。雖然這很好,如果這是你想要的,隨着項目變得越來越複雜,你可能會發現你更喜歡將包含路徑設置應用到一些目標。爲此,使用target_include_directories()代替:

target_include_directories(someprojectname "${CMAKE_CURRENT_SOURCE_DIR}/src") 

這將有同樣的效果,但它限制使用的附加包括路徑,只是someprojectname目標。如果稍後定義了一些不需要包含路徑的其他目標,則不會添加它。例如,如果您有較深的目錄層次結構,並且您在不同的地方重新使用目錄名稱,這可以幫助防止發生意外文件等情況。

當應用於庫目標時,target_include_directories()命令具有額外的優勢,因爲CMake能夠將包含路徑傳遞給您與該庫鏈接的任何內容。聽起來並不多,但對於定義和鏈接許多圖書館的大型項目來說,這可能是一個巨大的幫助。還有其他特定於目標的命令也具有類似的優點。 This article可能會給你一點感覺,可能是什麼(免責聲明:我寫了文章)。它更專注於target_sources(),但圍繞其他目標進行依賴關係的討論可能會有用。

+0

'include_directories()** **自動**將所有相對路徑轉換爲絕對路徑。有關更多詳細信息,請參見[文檔](https://cmake.org/cmake/help/v3.0/command/include_directories.html)。 – Tsyvarev

+0

確實你是對的!我誤解了這個問題(錯過了include_directories()被使用的地方)。我會在這裏留下我的答案一段時間,讓已經閱讀過它的人看到我的更正,然後我會刪除我的答案。感謝您的更正! –