2012-03-22 13 views
14

Sto codificando un progetto C++ in vim.eseguire un comando shell (ctags) in cmake e make

Mi piacerebbe eseguire un comando ctags (ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .) per generare riferimenti quando eseguo make.

Penso che il modo per farlo sia utilizzare add_custom_command ma mi confondo su come integrarlo in CMakeLists.txt.

+0

Non sto testando più queste risposte. ctags richiede tempo sul mio i5 a potenza ultra bassa, così lo chiamo da vim una volta ogni tanto. –

risposta

15

Il modo più semplice per farlo è:

set_source_files_properties(tags PROPERTIES GENERATED true) 
add_custom_command (OUTPUT tags 
    COMMAND ctags -R --c++-kinds=+p --fields=+iaS --extra=+q . 
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) 
add_executable (MyProjectOutput tags) 

La prima riga dice che CMaketags verrà generato. Il add_custom_command è CMake genererà tags quando necessario e, infine, alcuni obiettivi devono dipendere da tags. La directory di lavoro predefinita si trova nell'albero di compilazione, pertanto WORKING_DIRECTORY deve essere impostato sulla struttura dei sorgenti. Ciò equivale una voce Makefile:

tags: 
    ctags -R --c++-kinds=+p --fields=+iaS --extra=+q . 

MyProjectOutput: tags 
    # Whatever here... 
+0

solo per essere sicuri, 'CMAKE_SOURCE_DIR' è specificato in base alle impostazioni predefinite. Non ho bisogno di specificarlo. destra? –

+1

Sì, 'CMAKE_SOURCE_DIR' viene automaticamente impostato sulla directory _current_ source (potrebbe essere una sottodirectory, se si aggiungono in modo ricorsivo i file di origine). 'CMAKE_SOURCE_DIR' è in genere la directory in cui si trova il file' CMakeLists.txt'. –

+0

CMAKE_SOURCE_DIR è il percorso fino al livello superiore dell'albero di origine. – camino

7

Nuova soluzione:

Penso CMake cambiato dal momento che la risposta precedente è stato dato.
Ecco le linee che ho aggiunto nella mia CMakeLists.txt (testato con la versione 2.8.12):

# Add "tags" target and make my_project depending on this target. 
set_source_files_properties(tags PROPERTIES GENERATED true) 
add_custom_target(tags 
    COMMAND ctags -R --c++-kinds=+p --fields=+iaS --extra=+q . 
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) 
add_dependencies(my_project tags) 

e funziona perfettamente ora!

+1

Ciao Creak, questo è stato contrassegnato come non una risposta. Questo ha risolto il tuo problema o stai facendo una domanda. Se risolvi un problema, puoi modificare il tuo post e chiarire in modo che altre persone non lo segnalino accidentalmente? Se fai una domanda, puoi rimuoverla e vedere [chiedere] per maggiori dettagli? Spero che questo aiuti, e buona fortuna! :) – jmort253

+1

@ jmort253: Scusa Creak, non ho letto correttamente il tuo post. Non ho idea di come annullare la segnalazione (hai fatto un errore e non vuoi più attirare l'attenzione di un moderatore ....). – user2284570

+1

@ jmort253: Ho cambiato il mio commento, è sicuramente una ** risposta ** e ** non una domanda **. – Creak

8

le risposte di Daniel e Creak di mi ha iniziato, ma ho finito con una soluzione più complessa che ho pensato di condividere:

# Add a top-level "tags" target which includes all files in both 
# the build and source versions of src/*. 
set_source_files_properties(tags PROPERTIES GENERATED true) 
add_custom_target(tags 
    COMMAND ctags -R --c++-kinds=+p --fields=+iaS --extra=+q 
     ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} 
    COMMAND ln -sf ${CMAKE_CURRENT_BINARY_DIR}/tags ${CMAKE_BINARY_DIR} 
    WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) 

# ...but only make it a dependency of the project if the ctags program 
# is available, else it will fail to build on Windows. 
find_program(CTAGS_PATH ctags) 
if(CTAGS_PATH) 
    message(STATUS "Found ctags: ${CTAGS_PATH}") 
    add_dependencies(MyProjecct tags) 
endif(CTAGS_PATH) 

Fa diverse cose che le soluzioni più semplici non lo fanno:

  1. Aggiunge solo "tag" come dipendenza del prodotto di generazione principale (MyProject) se sul sistema esiste effettivamente un programma ctags. Non vogliamo interrompere la compilazione solo perché si tratta di Windows o perché ctags non è stato ancora installato sul sistema di generazione.

  2. Estrae i simboli dai file di origine nelle directory di compilazione e di origine. Questo è importante in un paio di casi.

    In primo luogo, si potrebbero utilizzare configure_file() e venite da un background Autotools, così hai nominato i file di origine veri *.in, il che significa ctags -R non li scansione. Ne hai bisogno per analizzare le versioni generate nella directory di build. Ad esempio, potresti avere src/mainheader.h.in nell'albero dei sorgenti, con il numero di versione del progetto inserito automaticamente come build/src/mainheader.h.

    In secondo luogo, alcuni dei file "di origine" potrebbero essere generati da altri strumenti. Nel mio progetto attuale, ho un paio di file di intestazione C++ generati dagli script Perl. Voglio i simboli da entrambe le intestazioni generate e gli script Perl nel file di tag.

  3. Funziona in una sottodirectory.

    Nel progetto su cui sto lavorando in questo momento, il prodotto di costruzione principale è costituito da src/* relativo alla radice del progetto e desidero solo i simboli da quella sottostruttura nel file di tag. Non voglio che includa i simboli dei test delle unità, degli esempi o degli script di utilità.

    Poiché è progettato per essere eseguito in una sottodirectory, crea un collegamento simbolico al file src/tags nella parte superiore della directory di generazione, in modo che vi -t TagName funzioni. (Sto assumendo qui che se ctags esiste, ln fa, anche.)

Problemi correlati