deep
1
我最近在使用cquery作为C++语法解析后端时, 发现cquery解析boost的一些语法会报错,但这些语法的写法都是比较基本的官网例子,比如:
{
...
boost::thread t(function);
..
}
会报错no matching constructor for initialization of 'boost::thread'
,或者
class A {
...
boost::asio::io_context io;
boost::asio::steady_timer timer;
};
A::A() : timer(io, boost::asio::chrono::seconds(1)) {}
会报错excess elements in scalar initializer
编译环境为Ubuntu16.04, boost版本为1.58, 使用CMake生成的compile_commands.json
作为索引.
请问有人遇到类似的情况吗?我的配置或用法是否有问题?
deep
5
由于个人编程习惯不好。。。所以现在不具备make的条件。。。bear make编译不了。。。我甚至连makefile都还没有。。。
沒有compile_commands.json
.cquery或.ccls
,很容易不帶開關編譯(像這樣:clang++ a.cc
),對於boost檢索不了很正常
bear make -k
,不一定需要編譯通過,能運行編譯命令就好。
deep
7
现在使用了CMake管理工程, 并通过CMake的CMAKE_EXPORT_COMPILE_COMMANDS
生成了compile_commands.json
文件. 工程可以正确编译, 并且没有warning, 但是在emacs里依然存在上述问题…
会不会跟 compile_commands.json 文件应该放在哪里有关?
比如工程是这样编译的:
$ mkdir build && cd build
$ cmake ../src
......
$ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ../src
生成的 compile_commands.json 文件也在 build/
,不在项目根目录,所以其实没有起作用?
deep
9
应该不是找不到compile_commands.json文件的原因:
- 我的compile_commands.json文件确实是在build目录下, 但是我再根目录建立了连接, 我看其他有些项目也是这样做的.
- 并不是所有语法解析都不正确, 很多其他的语法解析和自动补全都还是正常的. 其实总结一下问题, 目前我发现的主要是两个, 一个是boost类里面有些构造函数解析不太正常, 如主题中的例子; 另一个是有些类找不到合适的定义, 比如最近又遇到了
boost::asio::serial_port
和boost::unordered_map
被认为是int型的问题. 其他一些东西, 比如boost::shared_ptr
和boost::container::deque
是可以正常解析的.
PS: 我的boost是安装在系统里的, 路径在/usr/local
下面. 不知道语法解析会需要对这个做特殊配置, 但是自动补全是没有问题的.
deep
12
这里 是我临时写的一个可以编译运行的工程. 会出现前面我提到的问题. 工程下面的compile_commands.json
是一个指向 build 文件夹中内容的一个软连接, 可能需要根据实际情况调整.
再次说明一下: 我的这个工程需要环境安装了 boost 库, 我自己是用的默认的安装方式, 再路径/usr/local
下面. 个人感觉 cquery 还是找到了这个位置, 因为很多 boost 库里定义的补全都是可以自动找到的.
这个是在我的机器上的效果, 双显示器不太会处理截图…
Debian libboost-all-dev
boost::asio::io_device <point>io
boost::<point>bind
等位置都能跳轉。
可能是因爲你的boost path components裏有幾個..
的。在Arch Linux還能觀察到#include <string>
等都無法檢索,可以觀察到clang++ -xc++ /dev/null -E -v
返回的include path 中..
太多了。
我很久以前給libclang加了clang_File_tryGetRealPathName
,ccls
用了。
deep
14
不好意思, 由于我对细节不太了解, 有点没太看懂您的解释. 我可以简单理解为:
- 这个问题我在不触碰cquery源码的情况下不能自己解决了吗?
- ccls可以正确解析不会有这个问题是吗?
你添加-isystem/usr/include
到.cquery
試試。或其他包含boost的目錄名。
ccls只有用clang>7才有clang_File_tryGetRealPathName
。這也只是我的一個猜測。
deep
16
是否.cquery
文件存在后, compile_commands.json
就不起做用了? 还是两个同时能起作用, .cquery
优先级高些?
试了你给的测试代码,发现我之前 #11 楼贴的图是有问题的:
- 没开启 cquery/ccls。
-
补全是 company-clang 提供的。
如果不开启 cquery/ccls,我打开 BoostTester.hpp 也会看到 2 处错误(数字可能跟 company-clang 版本有关),错误信息应该也是 comany-clang 给 flycheck 的:
company-clang 提供的信息可能有点过时。开启 cquery/ccls 之后,flyckeck 就收到正确的信息了,没有错误(注意 mode-line 颜色,红色表示有错误),光标下的函数信息都有提示(底部 minibuffer 和 右侧 tooltip 浮动窗口):
我看你的图,也只有 flycheck 下划波浪线提示。检查你打开 hpp 文件的时候是否自动启动了 cquery/ccls:
⋊> pgrep -fl cquery
71685 /usr/local/bin/cquery
@MaskRay
发现一个真正的 cqueyr/ccls 两者都有的问题,总是提示找不到当前正在编辑的文件 BoostTester.hpp:
步骤:
- 克隆 #12 楼的代码
cd boost_test && mkdir build && cd build
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 ..
- Emacs 打开 BoostTester.hpp 文件
- 观察 Minibuffer /
*Messages*
deep
18
我觉得我的情况和您不一样, 其实你仔细看我的图片, 会发现flycheck的错误提示前面都有cquery:***
, 这让我觉得我这里的错误确实是cquery报出来的. 至于版本, 由于我是不升级不舒服司机, 所以不敢说最新, 但是cquery, spacemacs和其他的melpa包都应该是比较新的, 而且这个问题出现有比较长的时间了, 几次更新都没有什么改善, 所幸没有遇到新的问题…
发现一个真正的 cqueyr/ccls 两者都有的问题,总是提示找不到当前正在编辑的文件 BoostTester.hpp:
hover(textDocument/hover
)在io.run()
上不能顯示:
std::size_t boost::asio::io_service::run()
?我這裏是好的。Unable to find file
通常是因爲一個檔案解析失敗了,--log-file
裏往往會有libclang
crash的字樣。
我發現一個真正的ccls的問題,.h
裏沒有diagnostics信息,可能在最新的commit Display diagnostics from header files
修復了。這裏的改動在於ccls不會直接索引.h
,而cquery會(如果.h
和.cc
不在同一目錄,clang command line推導錯誤會導致.h
中的索引信息丟失)
deep
20
确实使用.cquery
文件是可以解决问题的, 我还是没太体会
的意思, 因为在我的boost装在/usr/local/include
, 而我的环境这个是系统路径, 不论是.cquery
还是compile_commands.json
文件中都没有与这个路径相关的信息.