diff --git a/CMakeLists.txt b/CMakeLists.txt index 044d868e978..446e030d5ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -614,3 +614,10 @@ if(WITH_SYSTEMD) endif() include(CTags) +option(CTAG_EXCLUDES "Exclude files/directories when running ctag.") +add_tags(ctags + SRC_DIR src + TAG_FILE tags + EXCLUDE_OPTS ${CTAG_EXCLUDES} + EXCLUDES "*.js") +add_custom_target(tags DEPENDS ctags) diff --git a/cmake/modules/CTags.cmake b/cmake/modules/CTags.cmake index 7b0d9d0a9ea..7d40984f749 100644 --- a/cmake/modules/CTags.cmake +++ b/cmake/modules/CTags.cmake @@ -1,27 +1,37 @@ find_program(CTAGS_EXECUTABLE ctags) -if(CTAGS_EXECUTABLE) - set(src_dir "src") - set(tag_file ${src_dir}/tags) - execute_process( - COMMAND git config --file .gitmodules --get-regexp path - COMMAND awk "/${src_dir}/ { print $2 }" - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - OUTPUT_VARIABLE submodules - OUTPUT_STRIP_TRAILING_WHITESPACE) - string(REPLACE "\n" " " submodules ${submodules}) - string(REPLACE "${src_dir}/" "--exclude=" excludes ${submodules}) - # cmake will quote any embedded spaces when expanding ${excludes} - # in the command below, so, turn ${excludes} into a cmake List (separated - # by semicolons) to let the expansion below simply replace them with spaces - # again. - separate_arguments(excludes UNIX_COMMAND ${excludes}) - add_custom_target(ctags - COMMAND ${CTAGS_EXECUTABLE} -R --c++-kinds=+p --fields=+iaS --extra=+q --exclude=*.js ${excludes} - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/${src_dir} - COMMENT "Building ctags file ${tag_file} (no submodules)" + +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} + OUTPUT_VARIABLE submodules + OUTPUT_STRIP_TRAILING_WHITESPACE) + 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() + 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 --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) - add_custom_target(tags - DEPENDS ctags) - set_source_files_properties(${CMAKE_SOURCE_DIR}/${tag_file} PROPERTIES + set_source_files_properties(${CMAKE_SOURCE_DIR}/${TAGS_TAG_FILE} PROPERTIES GENERATED true) -endif(CTAGS_EXECUTABLE) +endfunction()