2012-03-22 1066 views
14

我在vim中编写了一个C++项目。在cmake中运行shell命令(ctags)并使

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

我认为这样做的方式是使用add_custom_command,但我很困惑如何将它集成到CMakeLists.txt中。

+0

我不再测试这些答案。 ctags在我的超低功耗i5上需要时间,所以我偶尔从vim中调用它。 – 2013-11-06 17:05:32

回答

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) 

第一行告诉CMaketags将会产生。 add_custom_commandCMake将在需要时生成tags,最后,某些目标需要依赖tags。默认工作目录位于构建树中,因此WORKING_DIRECTORY必须设置为源树。这相当于Makefile项:

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

MyProjectOutput: tags 
    # Whatever here... 
+0

只是为了确保默认情况下指定'CMAKE_SOURCE_DIR'。我不需要指定它。对? – 2012-03-23 16:15:10

+1

是的,'CMAKE_SOURCE_DIR'自动设置为_current_源目录(如果递归添加源文件,可能是一个子目录)。 'CMAKE_SOURCE_DIR'通常是'CMakeLists.txt'文件所在的目录。 – 2012-04-05 12:40:02

+0

CMAKE_SOURCE_DIR是源树顶层的路径。 – camino 2016-05-26 01:19:03

7

新的解决方案:

我想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) 

而且它现在完美的作品!

+1

嗨Creak,这被标记为不是答案。这是解决你的问题还是你问一个问题?如果解决问题,您是否可以编辑您的帖子并澄清,以便其他人不会意外标记它?如果问一个问题,你可以删除它,并看到[问]的更多细节?希望这会有所帮助,祝你好运! :) – jmort253 2013-11-06 02:33:04

+1

@ jmort253:对不起,Creak,我没有正确阅读你的文章。我不知道如何撤销标记(你犯了一个错误,你不想再吸引主持人的注意力......)。 – user2284570 2013-11-06 23:44:29

+1

@ jmort253:我改变了我的评论,这绝对是**答案**和**不是问题**。 – Creak 2013-11-13 18:13:31

8

丹尼尔和吱吱的回答让我开始,但我结束了一个更复杂的解决方案,我想我会分享:

# 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. 如果在系统上实际存在ctags程序,它只会将“标签”添加为主版本产品(MyProject)的依赖项。我们不想因为这是Windows而打破构建,或者因为构建系统上尚未安装ctags

  2. 它从build目录和源目录中的源文件中提取符号。这在很多情况下都很重要。

    首先,您可能使用的是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也是。)