2016-04-27 14 views
5

Ilekroć chciałam dołączyć do katalogu, który był poza moim projektem z Clion, użyłbym flagi -I somedir. Tym razem jednak, co chcę zrobić, to mieć hierarchię tak:W tym katalogi w Clion

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

chcę mojego kodu w katalogu /src. I nie tylko to, ale także, na przykład, w pliku Dijkstra.h Chcę dołączyć Graph.h w ten sposób: #include "Graph/Graph.h, a nie w ten sposób: #include "../Graph/Graph.h.

Gdybym tylko dodać -I src flagę, a następnie, jeśli jestem wewnątrz pliku Dijkstra.h i chciałem to Graph.h, chciałbym napisać #include "../Graph/Graph.h, który nie jest to, co chcę.

Więc starałem się również dodać INCLUDE_DIRECTORIES(src). To naprawiło powyższy problem, jednak gdy próbowałem go skompilować, otrzymałem błąd linkera undefined reference to....

Więc próbowałem dodawanie plików jeden po drugim tak:

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

i przywrócił poprzednią problem, gdzie musiałem dołączyć pliki w ten sposób: #include "../Graph/Graph.h".

Jak zrobić to poprawnie, aby uzyskać pożądane zachowanie?

+0

i sugeruje, aby korzystać strukturę katalogów jak ten wykres/src/* CPP, Graph/include/* .h, Dijkstra/src/*. cpp i Dijkstra/include/*. h .. Następnie spróbuj SET (GRAPH_INCLUDE_DIR Graph/include /), SET (DIJKSTRA_INCLUDE_DIR Dijkstra/include /) INCLUDE_DIRECTORIES ($ {GRAPH_INCLUDE_DIR} $ {DIJKSTRA_INCLUDE_DIR}) – Varun

+0

Brak jasnego pytania. Jeśli używasz ostatniego wariantu i dodajesz 'include_directories (src/Graph src/Dijkstra)' co się dzieje? – fghj

+0

Sposób, w jaki zasugerowałem, jest lepszym sposobem tworzenia struktury katalogów. .cpp w jednym katalogu i .h w innym katalogu. Dlaczego mieszać te pliki w jednym katalogu. – Varun

Odpowiedz

5

poleceń INCLUDE_DIRECTORIESnie dodaje dowolny plik źródło dla kompilacji!

Zamiast tego, to polecenie definiuje katalogi dla plików nagłówkowych wyszukiwania ..

Trzeba wymienić wszystkie source pliki add_executable() zaproszenia w każdym przypadku.

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

AKTUALIZACJA: @ Odpowiedź Tsyvareva jest poprawna. Zmieniłem tę odpowiedź, aby usunąć niepoprawną część i zachować komentarze dotyczące target_include_directories(), ale powinno to być postrzegane jako dodatkowe w odpowiedzi Tsyvareva.

INCLUDE_DIRECTORIES(src) spowoduje, że katalog src zostanie dodany jako ścieżka wyszukiwania do wszystkich obiektów docelowych zdefiniowanych od tego punktu. Nie dodaje źródeł do żadnych celów. Ścieżka wyszukiwania będzie odnosić się do bieżącego katalogu źródłowego, a CMake dostosuje ją odpowiednio podczas zstępowania do podkatalogów poprzez add_subdirectory(). Chociaż wszystko jest w porządku, jeśli tego chcesz, ponieważ projekt staje się większy i bardziej skomplikowany, może się okazać, że wolisz zastosować ustawienia ścieżki dołączania tylko do niektórych celów. W tym celu należy użyć target_include_directories() zamiast:

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

ten będzie miał ten sam efekt, ale to ogranicza stosowanie dodanego zawierać ścieżkę do właśnie cel someprojectname. Jeśli później zdefiniujesz inny cel, który nie potrzebuje ścieżki dołączania, nie zostanie on dodany. Może to pomóc w zapobieganiu sytuacji, takich jak nieoczekiwane pliki, które zostały pobrane, jeśli masz głębokie hierarchie katalogów i na przykład ponownie używasz nazw katalogów w różnych miejscach.

Polecenie ma dodatkowe zalety w przypadku zastosowania do obiektów bibliotecznych, ponieważ program CMake może przenosić ścieżkę dołączania do wszystkich elementów połączonych z tą biblioteką. Nie brzmi jak dużo, ale dla dużych projektów, które definiują i łączą wiele bibliotek, może być ogromną pomocą. Istnieją również inne polecenia specyficzne dla celu, które również mają podobne zalety. This article może dać ci odrobinę wyczucia tego, co jest możliwe (zrzeczenie się: napisałem artykuł). Jest on bardziej skoncentrowany na target_sources(), ale może być przydatna dyskusja na temat przenoszenia zależności do innych celów.

+0

'include_directories()' ** automatycznie ** przekształca wszystkie ścieżki względne na bezwzględne. Więcej informacji można znaleźć w [documentation] (https://cmake.org/cmake/help/v3.0/command/include_directories.html). – Tsyvarev

+0

Rzeczywiście masz rację! I źle zrozumiałem pytanie (pominięto, gdy użyto katalogu include_directories()). Zostawię tu swoją odpowiedź na chwilę, aby umożliwić tym, którzy już ją przeczytali, zobaczyć moją korektę, wtedy usunę odpowiedź. Dziękuję za poprawienie mnie! –