запустите команду оболочки (ctags) в cmake и сделайте

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

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

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

3 ответов


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

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 будет сгенерирован. The add_custom_command is CMake будет генерировать tags при необходимости, и, наконец, некоторые цели должны зависеть от tags. Рабочий каталог по умолчанию находится в дереве сборки, поэтому WORKING_DIRECTORY должно быть установлено в исходное дерево. Это эквивалентно записи Makefile:

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

MyProjectOutput: tags
    # Whatever here...

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

Я думаю, что 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)

и теперь он отлично работает!


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

# 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() и исходят из фона Autotools, поэтому вы назвали свои истинные исходные файлы *.in, что означает ctags -R не сканировать их. Он нужен для сканирования сгенерированных версий в каталоге сборки. Например, у вас может быть src/mainheader.h.in в исходном дереве, с номером версии проекта, автоматически вложенным в него как build/src/mainheader.h.

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

  3. он работает в поддиректории.

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

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