запустить команду оболочки (ctags) в cmake и сделать - PullRequest
14 голосов
/ 22 марта 2012

Я кодирую проект c ++ в vim.

Я хотел бы запустить команду ctags (ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .) для генерации ссылок при запуске make.

Iдумаю, что способ сделать это - использовать add_custom_command, но я запутался в том, как интегрировать его в CMakeLists.txt.

Ответы [ 3 ]

16 голосов
/ 23 марта 2012

Самый простой способ сделать это:

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 )

Первая строка сообщает CMake, что будет сгенерировано tags.add_custom_command is CMake будет генерировать tags при необходимости, и, наконец, некоторые цели должны зависеть от tags.Рабочий каталог по умолчанию находится в дереве сборки, поэтому WORKING_DIRECTORY должно быть установлено в исходное дерево.Это эквивалентно записи в Makefile:

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

MyProjectOutput: tags
    # Whatever here...
8 голосов
/ 23 сентября 2014

Ответы Даниэля и Крика заставили меня начать, но в итоге я нашел более сложное решение, которым, как я думал, я бы поделился:

# 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)

Он делает несколько вещей, которых нет в более простых решениях:

  1. Добавляет «теги» в качестве зависимости основного продукта сборки (MyProject), только если в системе действительно есть программа ctags. Мы не хотим прерывать сборку только потому, что это Windows или просто потому, что ctags еще не был установлен в системе сборки.

  2. Извлекает символы из исходных файлов как в сборочных, так и в исходных каталогах. Это имеет значение в нескольких случаях.

    Во-первых, вы можете использовать configure_file() и исходить из фона автоинструментов, поэтому вы назвали свои настоящие исходные файлы *.in, что означает, что ctags -R не будет их сканировать. Это нужно для сканирования сгенерированных версий в каталоге сборки. Например, в вашем исходном дереве может быть src/mainheader.h.in, а номер версии проекта автоматически вставляется в него как build/src/mainheader.h.

    Во-вторых, некоторые ваши "исходные" файлы могут быть сгенерированы другими инструментами. В моем текущем проекте у меня есть пара заголовочных файлов C ++, которые генерируются скриптами Perl. Я хочу символы из сгенерированных заголовков и скриптов Perl в файле тегов.

  3. Работает в подкаталоге.

    В проекте, над которым я сейчас работаю, основной продукт сборки сделан из src/* относительно корня проекта, и я хочу только символы из этого поддерева в файле тегов. Я не хочу, чтобы он включал символы из модульных тестов, примеров или служебных скриптов.

    Поскольку он предназначен для работы в подкаталоге, он создает символическую ссылку на файл src/tags в верхней части каталога сборки, поэтому vi -t TagName работает. (Я предполагаю, что если ctags существует, ln тоже существует.)

8 голосов
/ 06 ноября 2013

Новое решение:

Я думаю, что CMake изменился, так как был дан предыдущий ответ.
Вот строки, которые я добавил в свой CMakeLists.txt (протестирован с версией 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)

И теперь это прекрасно работает!

...