我正在用vim编写一个c ++项目。
我想在运行make时运行ctags
命令(ctags -R --c++-kinds=+p --fields=+iaS --extra=+q .
)来生成引用。
我认为这样做的方法是使用add_custom_command
,但我对如何将其集成到CMakeLists.txt感到困惑。
答案 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
将生成tags
。 add_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)
它做了一些简单的解决方案没有的事情:
如果系统上实际存在MyProject
程序,它只会将“标记”添加为主要构建产品(ctags
)的依赖项。我们不想因为这是Windows而破坏构建,或者因为ctags
尚未在构建系统上安装。
它从构建目录和源目录中的源文件中提取符号。这在几个案例中很重要。
首先,您可能正在使用configure_file()
来自Autotools背景,因此您已命名真正的源文件*.in
,这意味着ctags -R
将无法扫描它们。您需要它来扫描构建目录中生成的版本。例如,您的源树中可能有src/mainheader.h.in
,项目版本号会自动作为build/src/mainheader.h
加载到其中。
其次,某些“源”文件可能由其他工具生成。在我当前的项目中,我有两个由Perl脚本生成的C ++头文件。我希望标记文件中生成的标题和中的符号都是Perl脚本。
它适用于子目录。
在我正在进行的项目中,主要构建产品是从src/*
相对于项目根目录制作的,我只想在标记文件中使用该子树中的符号。我不希望它包含单元测试,示例或实用程序脚本中的符号。
因为它被设计为在子目录中运行,所以它会在构建目录顶部的src/tags
文件中创建一个符号链接,以便vi -t TagName
起作用。 (我假设如果ctags
存在,ln
也会这样做。)