Linux下多Clang工具链的踩坑


起因

故事是从C++ 17标准说起,在写线程池异步执行的时候发现居然没法使用move移动,然后怀疑到了clang头上,因为发现当我使用C++17标准下的std::invoke_result时直接报错是没有这个函数实现,说明clang版本有点旧了(加上我需要C++20的实现),然后就开始研究起来clang的更新。

第一个坑

首先,因为需要做cmu15445 2023spring的project,在我的环境下安装了全套clang-14的tool-chain,那么问题来了,首先,你直接apt install只能安装到14的版本,其次,如果能安装了,但我需要使用最新的C++标准,但我又想保留老的tool chain怎么办?(可以试一试,如果直接安装的话会把老的版本卸载了)

首先是安装:我先找到了llvm官网的安装脚本,但又存在一个问题,通过这个安装脚本下载的话速度太慢(是的挂梯子也不行),后来翻找发现果然国内有对应的镜像源。那么怎么做,长话短说,直接通过脚本安装的话会卸载,这里是手动启用了一部分,即首先信任来自 llvm 的 PGP 公钥。然后先手动安装clang-17以及clang++-17(或许还有别的,但这两个是肯定有的),在手动安装的情况下因为指定了版本号,所以是不会冲突的(clang-14与clang-17),最重要的部分安装好后通过先前的脚本将完整的tool-chain下载下来(即clang-tidy-17等等)。

到目前为止没结束,因为还需管理多版本clang,需要通过update-alternatives选择对应版本号,具体怎么用直接搜索该命令就好,最后应该把这3个软件版本设成最新的:clang、clang++、clangd。那么目前多版本算是好了。

第二个坑

那么怎么使用多版本呢?如果你不是命令行档(即干啥都坚持在命令行cmake),想要自己多个选择的话,那么此时你打开vscode对应的项目会出现下面的问题

原因很显然,因为我们将对应的默认clang版本更改了,但是理论上说,在vscode上选择对应工具链会切换成对应的版本号,那么为什么?我花了大量时间在.vscode和插件的配置上,但实际上这些都是没用的。上图是我已经正常配置过了的版本,如果你之前使用的话,那么你会发现clang 14和clang17这两个地方的编译器的链接是完全相同的。

出现这个情况的原因在上文中已经说了,因为我们使用的update-alternatives,做的实际上是帮助我们创建对应的软链接,即:对于clang ,如果我在update-alternatives中把clang版本中的14设为高优先级那么clang链接的就是14,设置的是17就是17。我们需要做的是更改tool chain对应找的工具,也就是不再要之前的软链接(曾经是对的,但不会自动更改)。

当时思路是正确了,那么怎么更改?在扫描tool chain的时候我注意到他会去一个目录下加载,于是去那个目录:

把对应的clang14和clang17的tool-chain加上版本号即可,这时候vscode的cmake tool chain也设置好了。以后如果是多环境也是这样即可。

别的坑

其实实际上踩的坑不止这些,包括但不限于把公钥全删了导致apt报错等等,但最后终于把vscode下c++的clangd更新,不再给我那些C++17语法报错,总的来说还是指的。


文章作者: JoyTsing
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 JoyTsing !
评论
 上一篇
贵安,元旦快乐 贵安,元旦快乐
元旦快乐2024年伊始,很久没有更新新的博文了,先给大家祝贺一下。在这里顺便说一下本站接下来的计划吧: 因为这个blog是我大二时候一时兴起搭的,大部分插件什么的也是那会弄的,现在发现已经有很多不能用了,可能之后会有一次大的迭代或者重构吧。
2024-01-02
下一篇 
内存分配函数malloc的原理及实现 内存分配函数malloc的原理及实现
1 什么是malloc在实现malloc之前,先要相对正式地对malloc做一个定义。 根据标准C库函数的定义,malloc具有如下原型: void* malloc(size_t size); 这个函数要实现的功能是在系统中分配一段连续的可
2023-12-19
  目录