run a shell command (ctags) in cmake and make

前端 未结 3 507
我在风中等你
我在风中等你 2020-12-29 07:55

I\'m coding a c++ project in vim.

I\'d like to run a ctags command (ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .) to generate referen

相关标签:
3条回答
  • 2020-12-29 08:34

    The most basic way to do this is:

    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 )
    

    The first line tells CMake that tags will be generated. The add_custom_command is CMake will generate tags when needed, and finally, some target needs to depend on tags. The default working directory is in the build tree, so WORKING_DIRECTORY must be set to your source tree. This is equivalent a Makefile entry:

    tags:
        ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .
    
    MyProjectOutput: tags
        # Whatever here...
    
    0 讨论(0)
  • 2020-12-29 08:40

    New solution:

    I think CMake changed since the previous answer was given.
    Here is the lines I added in my CMakeLists.txt (tested with version 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)
    

    And it works perfectly now!

    0 讨论(0)
  • 2020-12-29 08:42

    Daniel's and Creak's answers got me started, but I ended up with a more complex solution that I thought I'd share:

    # 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)
    

    It does several things that the simpler solutions do not:

    1. It only adds "tags" as a dependency of the primary build product (MyProject) if there is actually a ctags program on the system. We don't want to break the build just because this is Windows, or because ctags simply hasn't been installed yet on the build system.

    2. It extracts symbols from source files in both the build and source directories. This matters in a couple of cases.

      First, you might be using configure_file() and come from an Autotools background, so you've named your true source files *.in, which means ctags -R won't scan them. You need it to scan the generated versions in the build directory. For example, you might have src/mainheader.h.in in your source tree, with the project version number automatically subbed into it as build/src/mainheader.h.

      Second, some of your "source" files might be generated by other tools. In my current project, I have a couple of C++ header files that are generated by Perl scripts. I want symbols from both the generated headers and the Perl scripts in the tags file.

    3. It works in a subdirectory.

      In the project I'm working on right now, the primary build product is made from src/* relative to the project root, and I only want symbols from that subtree in the tags file. I don't want it to include symbols from the unit tests, the examples, or the utility scripts.

      Because it is designed to run in a subdirectory, it creates a symlink to the src/tags file in the top of the build directory, so that vi -t TagName works. (I'm assuming here that if ctags exists, ln does, too.)

    0 讨论(0)
提交回复
热议问题