如何解决ycm-generator未传递-I标志引发的YouCompleteMe插件错误?
场景说明
我在Vim里用YouCompleteMe和ycm-generator插件,项目情况如下:
- CMakeLists.txt里写了:
configure_file(src/config.hpp.in config.hpp) target_include_directories(target BEFORE PRIVATE "${PROJECT_BINARY_DIR}") - 项目目录结构:
. ├── CMakeLists.txt └── src ├── config.hpp.in └── main.cpp - src/main.cpp里引入了生成的头文件:
#include "config.hpp"
代码能正常编译,但用:YcmGenerateConfig生成.ycm_extra_conf.py后,YouCompleteMe报错找不到config.hpp——因为ycm-generator没把生成文件所在的build目录加到flags的-I列表里。手动加-Ibuild能解决,但发现列表里有个莫名其妙的-I/tmp/tmp36Q3_Q,怀疑是ycm-generator找build目录失败,想知道怎么让它自动把生成文件的路径加入包含目录。
解决办法
1. 让CMake生成编译数据库
ycm-generator靠CMake的compile_commands.json提取编译参数,构建时要显式开启这个选项:
如果用单独的build目录,执行:
cd build cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
如果直接在根目录构建,执行:
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .
2. 指定build目录生成配置
在Vim里执行:YcmGenerateConfig时,手动指定build目录路径,让插件读取该目录下的编译数据库:
:YcmGenerateConfig build/
这样插件就能自动提取到正确的包含目录(包括PROJECT_BINARY_DIR对应的build路径)。
3. 调整CMake的包含目录配置
把target_include_directories里的路径改成更明确的写法,确保CMake生成编译数据库时能正确记录:
target_include_directories(target BEFORE PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
如果是多模块项目,用PROJECT_BINARY_DIR也没问题,只要编译数据库里能正确输出这个路径就行。
4. 给ycm-generator加本地配置
在项目根目录创建.ycm_generator.conf文件,指定build目录路径:
[general] build_dir = build
之后再执行:YcmGenerateConfig,插件会自动读取这个配置,找到正确的build目录和编译数据库,自动把生成文件的包含目录加到.ycm_extra_conf.py的flags里。
内容的提问来源于stack exchange,提问作者Christopher Weronski

