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

kir*_*gum 14 cmake ctags

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

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

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

Dan*_*zek 15

最基本的方法是:

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 )
Run Code Online (Sandbox Code Playgroud)

第一行告诉CMake我们tags将生成.该add_custom_commandIS CMake将产生tags需要的时候,终于,一些目标需要靠tags.默认工作目录位于构建树中,因此WORKING_DIRECTORY必须设置为源树.这相当于Makefile条目:

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

MyProjectOutput: tags
    # Whatever here...
Run Code Online (Sandbox Code Playgroud)


Cre*_*eak 9

新解决方案:

我认为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)
Run Code Online (Sandbox Code Playgroud)

它现在完美运作!


War*_*ung 8

丹尼尔和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)
Run Code Online (Sandbox Code Playgroud)

它做了一些简单的解决方案没有的事情:

  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,那也是.)