在cmake和make中运行shell命令(ctags)

时间:2012-03-22 17:16:30

标签: cmake ctags

我正在用vim编写一个c ++项目。

我想在运行make时运行ctags命令(ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .)来生成引用。

我认为这样做的方法是使用add_custom_command,但我对如何将其集成到CMakeLists.txt感到困惑。

3 个答案:

答案 0 :(得分:16)

最基本的方法是:

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将生成tagsadd_custom_command CMake会在需要时生成tags,最后,某些目标需要依赖tags。默认工作目录位于构建树中,因此必须将WORKING_DIRECTORY设置为源树。这相当于Makefile条目:

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

MyProjectOutput: tags
    # Whatever here...

答案 1 :(得分:8)

新解决方案:

我认为自从上一个答案发出以来,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)

现在它完美无缺!

答案 2 :(得分:8)

Daniel's和Creak的答案让我开始了,但我最终得到了一个更复杂的解决方案,我认为我会分享:

# 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加载到其中。

    其次,某些“源”文件可能由其他工具生成。在我当前的项目中,我有两个由Perl脚本生成的C ++头文件。我希望标记文件中生成的标题中的符号都是Perl脚本。

  3. 它适用于子目录。

    在我正在进行的项目中,主要构建产品是从src/*相对于项目根目录制作的,我只想在标记文件中使用该子树中的符号。我不希望它包含单元测试,示例或实用程序脚本中的符号。

    因为它被设计为在子目录中运行,所以它会在构建目录顶部的src/tags文件中创建一个符号链接,以便vi -t TagName起作用。 (我假设如果ctags存在,ln也会这样做。)