summaryrefslogtreecommitdiffstats
path: root/cmake/modules/CTags.cmake
blob: c3e1b3799b02451e07ac8198c56808d442bb2814 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
find_program(CTAGS_EXECUTABLE ctags)

function(add_tags name)
  cmake_parse_arguments(TAGS "" "SRC_DIR;TAG_FILE" "EXCLUDE_OPTS;EXCLUDES" ${ARGN})
  set(excludes ${TAGS_EXCLUDES})
  if(TAGS_EXCLUDE_OPTS)
    # always respect EXCLUDES_OPTS
    list(APPEND excludes ${TAGS_EXCLUDE_OPTS})
  else()
    # exclude the submodules under SRC_DIR by default
    execute_process(
      COMMAND git config --file .gitmodules --get-regexp path
      COMMAND awk "/${TAGS_SRC_DIR}/ { print $2 }"
      WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
      RESULT_VARIABLE result_code
      OUTPUT_VARIABLE submodules
      OUTPUT_STRIP_TRAILING_WHITESPACE)
    if(${result_code} EQUAL 0)
      string(REPLACE "${TAGS_SRC_DIR}/" "" submodules ${submodules})
      # cmake list uses ";" as the delimiter, so split the string manually
      # before iterating in it.
      string(REPLACE "\n" ";" submodules ${submodules})
      list(APPEND excludes ${submodules})
    endif()
  endif()
  message(STATUS "exclude following files under ${TAGS_SRC_DIR}: ${excludes}")
  # add_custom_target() accepts a list after "COMMAND" keyword, so we should
  # make exclude_arg a list, otherwise cmake will quote it. and ctags will
  # take it as as a single argument.
  foreach(exclude ${excludes})
    list(APPEND exclude_args --exclude=${exclude})
  endforeach()
  add_custom_target(${name}
    COMMAND ${CTAGS_EXECUTABLE} -R --python-kinds=-i --c++-kinds=+p --fields=+iaS --extra=+q ${exclude_args}
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/${TAGS_SRC_DIR}
    COMMENT "Building ctags file ${TAGS_TAG_FILE}"
    VERBATIM)
  set_source_files_properties(${CMAKE_SOURCE_DIR}/${TAGS_TAG_FILE} PROPERTIES
    GENERATED true)
endfunction()