2016-04-27 33 views
5

Ogni volta che volevo includere una directory che si trovava al di fuori del mio progetto con Clion, avrei usato il flag -I somedir. Questa volta, però, quello che voglio fare è di avere una gerarchia simile a questo:Includere le directory in Clion

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

voglio che il mio codice in una directory /src. E non solo, ma anche, per esempio, all'interno del file Dijkstra.h Voglio includere Graph.h come questo: #include "Graph/Graph.h e non così: #include "../Graph/Graph.h.

Se solo aggiungo una bandiera -I src, quindi se io sono all'interno del file Dijkstra.h e ho voluto includere Graph.h, avrei dovuto scrivere #include "../Graph/Graph.h, che non è quello che voglio.

Quindi ho provato ad aggiungere anche INCLUDE_DIRECTORIES(src). Ciò risolve il problema sopra, tuttavia quando ho provato a compilare, ho ricevuto un errore del linker undefined reference to....

Così ho provato ad aggiungere i file uno per uno come questo:

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

e che ha riportato il problema precedente, in cui ho dovuto includere i file di questo tipo: #include "../Graph/Graph.h".

Come posso farlo correttamente per ottenere il comportamento che voglio?

+0

vorrei suggerire, l'utilizzo di struttura di directory come questo grafico/src/* cpp, Grafico/include/* .h, Dijkstra/src/*. cpp e Dijkstra/include/*. h .. Quindi prova SET (GRAPH_INCLUDE_DIR Graph/include /), SET (DIJKSTRA_INCLUDE_DIR Dijkstra/include /) INCLUDE_DIRECTORIES ($ {GRAPH_INCLUDE_DIR} $ {DIJKSTRA_INCLUDE_DIR}) – Varun

+0

Domanda non chiara. Se usi l'ultima variante e aggiungi 'include_directories (src/Graph src/Dijkstra)' cosa succede? – fghj

+0

Il modo in cui ho suggerito è un modo migliore di strutturare le directory. .cpp in una directory e un file .h in un'altra directory. Perché mescolare questi file in un'unica directory. – Varun

risposta

5

Comando INCLUDE_DIRECTORIESnon aggiunge qualsiasi file di fonte per la compilazione!

Invece, questo comando definisce le directory per i file di intestazione di ricerca .

È necessario elencare tutti fonte file in add_executable() chiamata in ogni caso:.

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

UPDATE: @ La risposta di Tsyvarev è corretta. Ho modificato questa risposta per rimuovere la parte errata e mantenere i commenti relativi a target_include_directories(), ma dovrebbe essere vista come aggiuntiva alla risposta di Tsyvarev.

INCLUDE_DIRECTORIES(src) farà aggiungere la directory src come percorso di ricerca a tutti i target definiti da quel punto in poi. Non aggiunge fonti a nessun obiettivo. Il percorso di ricerca sarà relativo alla directory sorgente corrente e CMake lo regolerà come appropriato quando discenderanno in sottodirectory tramite add_subdirectory(). Mentre questo va bene se è quello che vuoi, poiché il progetto diventa più grande e più complicato, potresti scoprire che preferiresti applicare le impostazioni del percorso di inclusione ad alcuni target. Per questo, utilizzare target_include_directories() invece:

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

questo avrà lo stesso effetto, ma limita l'uso del percorso aggiunto includere al proprio someprojectname bersaglio. Se in seguito si definisce un altro target che non ha bisogno del percorso di inclusione, non verrà aggiunto. Questo può aiutare a prevenire situazioni come file inaspettati che vengono captati se si hanno gerarchie di directory profonde e si riutilizzano i nomi di directory in posti diversi, ad esempio).

Il comando target_include_directories() ha vantaggi aggiuntivi quando viene applicato alle destinazioni della libreria poiché CMake ha la capacità di trasportare il percorso di inclusione in tutto ciò che si collega anche a quella libreria. Non sembra molto, ma per grandi progetti che definiscono e collegano molte librerie, può essere di grande aiuto. Esistono altri comandi specifici per il target che hanno anche vantaggi simili. This article potrebbe darti un'idea di ciò che è possibile (disclaimer: ho scritto l'articolo). È più focalizzato su target_sources(), ma la discussione su come portare le dipendenze attraverso altri obiettivi può essere utile.

+0

'include_directories()' ** automaticamente ** trasforma tutti i percorsi relativi in ​​assoluti. Vedi [documentazione] (https://cmake.org/cmake/help/v3.0/command/include_directories.html) per maggiori dettagli. – Tsyvarev

+0

In effetti hai ragione! E ho frainteso la domanda (mancava dove era stato usato include_directories()). Lascerò qui la mia risposta per un po 'per permettere a quelli che già lo leggono di vedere la mia correzione, quindi cancellerò la mia risposta. Grazie per la correzione! –

Problemi correlati