起因
故事是从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语法报错,总的来说还是指的。