Mac上Clion编译报错找不到_ctermid.h头文件,Mac上Clion调试无法查看STL容器的元素值
使用CLion在对程序进行调试的时候,无法显示STL容器中的元素值,fatal error: _ctermid.h: No such file or directory,MacOS安装GDB,安装GCC,安装Xcode CommandLineTools,设置CLion中CMAKE_OSX_SYSROOT:PATH,MacOS上Xcode的SDK选择与使用更新。
目录
问题描述
问题一
MacOS上的Clion在编译项目的时候编译不成功,出现
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/wchar.h:90,
from /usr/local/Cellar/gcc/11.2.0_3/include/c++/11/cwchar:44,
from /usr/local/Cellar/gcc/11.2.0_3/include/c++/11/bits/postypes.h:40,
from /usr/local/Cellar/gcc/11.2.0_3/include/c++/11/iosfwd:40,
from /usr/local/Cellar/gcc/11.2.0_3/include/c++/11/ios:38,
from /usr/local/Cellar/gcc/11.2.0_3/include/c++/11/ostream:38,
from /usr/local/Cellar/gcc/11.2.0_3/include/c++/11/iostream:39,
from /Users/macbookpro/Documents/CLion/Test/main.cpp:2:
/usr/local/Cellar/gcc/11.2.0_3/lib/gcc/11/gcc/x86_64-apple-darwin19/11/include-fixed/stdio.h:219:10: fatal error: _ctermid.h: No such file or directory
219 | #include <_ctermid.h>
| ^~~~~~~~~~~~
compilation terminated.
ninja: build stopped: subcommand failed.
这样的报错,简单来讲是在编译的时候无法找到_ctermid.h
这个文件。
问题二
使用CLion在对程序进行调试的时候,无法显示STL容器中的元素值,只能显示开始指针、结束指针等一些内存地址值,甚至有时候通过输入变量来查看的时候,表达式会莫名其妙显示expr failed
,从而无法查看很影响调试的过程(由于问题暂时解决无法演示,寻找网图来解释,侵删)
我想要的结果:
在调试的时候可以显示出STL的值。
由于问题一是由问题二引出的,接下来我将按照时间顺序讲述问题解决的过程,解决问题的最终方法(暂时不是正面解决)放在最后部分。
软件平台版本
- Xcode 10.1
- Clion 2021.3.4 专业版
- MacOS 10.15.7 Catalina (前段时间由10.13一路升上来)
- GCC9、GCC11
- LLDB 13.0
问题二的研究过程
如果要解决问题二,目前有如下几种方案:
方案一:设置里面禁用GNU C++ 库渲染器
知乎上有人回答说通过在设置里面禁用GNU C++ 库渲染器,如下图所示,把圈住的勾去掉,然后重新打开项目,再次调试就没有问题了。
不知道这种方法在Windows上用处如何,但是在MacOS上是完全没有作用的。
方案二:通过写一个函数来传参打印
通过手写一个函数,就像打印的时候一样,调用函数表达式来打印出来想要的元素值。这种方法确实万能,但是当我一个容器内很多元素想要查看的时候,一个一个传参查看非常麻烦。
方案三:通过使用LLDB指令来打印
在调试的时候在终端中使用LLDB输入相应的调试指令来打印出来,这种方式也是万能的,但是需要一定的学习成本,要对调试器的指令比较熟悉才行,而且方法仍然不够便捷,每次运行都需要输入指令来查看内容。
方案四:安装GDB
看到有人说在Mac上CLion使用GDB的话可以查看STL元素的值,而LLDB是不可以的,由于我自己的Window上的Clion使用的MinGW带的GDB就可以查看STL元素的值,翻阅了很多文献发现从2017年开始,一直到现在都有人反映LLDB无法查看STL元素的问题,并且暂时没有看到完美解决的便于操作的方法,故决定采用GDB进行尝试。
CLion自己带了一个10.2版本的GDB,但是不知道是升级版本的问题还是怎么,当时用这个GDB的时候总会报出警告,然后把CLion卡死
BFD: /usr/lib/dyld(i386:x86-64): unknown load command 0x34
BFD: /usr/lib/dyld(i386:x86-64): unknown load command 0x34
BFD: /usr/lib/dyld(i386:x86-64): unknown load command 0x34
最终显示connect time out error
,无法进行调试,并且设置断点的时候也无法停留命中,故尝试额外安装GDB。这部分参考网上的教程对GDB进行安装,主要参考
2020 年在 macOS 上设置 gdb
在macOS10.14上使用GDB的教程
这两篇文章,使用homebrew
安装GDB,并设置签名证书使得电脑对其信任。
安装完成之后在CLion里面可以成功的在下图方框位置处看到有一个新的gdb被识别出来(由于我后面把他卸了,所以在截图上没明确显示),选中之后Clion会进行检测版本,但是很不幸的是:选中以后发现我的CLion最高只支持到11.1的GDB版本,而brew安装的是最新版本11.2,我直接当场气昏。
此外还有一个不幸的消息:安装GDB之后直接把我原来的gcc9替换成了最新的gcc11,将编译器都指向被替换的gcc11路径,并使用原有的LLDB调试器后,我测试了是否可以用其来进行编译,结果当然也很不幸,这时候出现了问题一。
问题一的引出及研究历程
这个时候我以为是最新的gcc11与gcc9不兼容,于是又把gcc11全部卸载,重新装上了gcc9,但是错误似乎不可逆,并没有消失,这意味着我Mac上的gcc环境完全不能使用,但是并没有详细准确的教程来解决这个问题,在网络上关于这个问题的资料几乎为0,我只在Stack Overflow上找到一篇帖子反映这个情况
在 macOS Mojave 10.14.6 上找不到 _ctermid.h
根据解答中所说进行了尝试,现将已尝试方法列在下面
方法一:重新安装brew和gcc
无效,这个在刚才已经尝试过,错误是不可逆转的。
方法二:安装macOS_SDK_headers_for_macOS_10.14
根据描述,我需要
open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg
来进行安装,但是我是10.15系统,系统中这个目录已经没有了。
方法三:删除CommandLineTools并重装
使用
(sudo) rm -rf /Library/Developer/CommandLineTools
把CommandLineTools删除掉,使用
xcode-select --install
进行重装。没有效果。
方法四:安装系统版本支持的最新的CommandLineTools
支持此说法的原因是,使用
xcode-select --install
安装的CommandLineTools不会安装版本最新的工具,总是安装Xcode10的版本,现在需要安装版本最高支持的工具来解决这个问题。由于无法从App store直接更新,于是我从
Xcode历代版本下载
下载了目前MacOS10.15可以支持的最新版本12.4,(需要登录app store账户)
需要查看相应系统支持的Xcode版本的可以在这个页面查到:
Xcode系统及相应版本支持
在下载安装好之后,在终端输入指令
xcrun --show-sdk-path
就可以查看当前使用的SDK了。
但是很遗憾的是,尽管这种方法看起来很靠谱,但是仍然没有在我的Mac上起作用。
方法五:设置CLion中CMAKE_OSX_SYSROOT:PATH
在方法四行不通之后,就没有可供查阅的根据这个问题的教程了,我只能翻阅大量资料,由于我是在一段时间前从10.13版本升级到10.15的,所以有没有可能是因为使用了较新的gcc版本导致出问题呢?于是我查阅了一些资料,主要汇集在下面这个帖子中:
升级到 Catalina 10.15 后无法在 Mac 上编译 C 程序
大多数回答的观点是,由于更新到10.15系统之后,头文件的文件夹发生了变化,但是寻找的路径没有发生改变,所以会出现找不到的情况,通过对他们进行连接到相应文件夹就可以了。
但是我查看了那些文件夹,发现自己的问题与他们其实并不相同。就在这个时候我重新查看了报错信息,发现了这样一个消息
在编译的时候cmake其实是寻找Xcode中安装的SDK的,但是他使用的SDK并不是方法四中我们选择的SDK,而是XCode中的老SDK,于是我进入了这个文件夹里面进行了查看
cd /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/
发现在这个SDK的头文件里面果然没有_ctermid.h
头文件。
在此之后我查看了方法四中我们更新后的CommandLineTools里面的SDK
cd /Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/include/
发现在这里面是含有_ctermid.h
头文件的
这时候我大概明白了原因:由于我之前使用的一直是从10.13遗留下来的老版本gcc9,在10.14版本以前都是没有_ctermid.h
头文件的,而在当我把gcc更新到11版本之后,由于使用brew
进行安装,其默认会寻找适配于当前系统下的gcc版本,而在10.15版本中,无论是gcc11还是gcc9,他们都需要这个头文件,这就是就算把版本回退到了9版本编译仍然失败的原因。
所以可以看出,CLion使用的还是旧的SDK,是否可以通过更改CLion所指定的SDK路径来让他用上我新安装的SDK呢?经过一番查找,我发现在项目里面的CMakeCatch.txt
文件里面可以更改指定的SDK路径。
我将上图中的PATH更改为安装的CommandLineTools里面的SDK路径,结果却出现了这样的报错
unsupported tapi file type '!tapi-tbd' in YAML file '/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/usr/lib/libSystem.tbd' for architecture x86_64
好家伙旧坑没填上又开一个新坑,简单查找了一番资料,该问题的出现不太好确定是哪里的问题,但是我个人感觉可能跟我Mac上混乱的C++版本有关,由于时间成本的关系,暂时没有在这个问题上进行深究,该方法失效。
结论
在试过上面方法之后,事情一度陷入了僵局,似乎并没有找到什么方法来直面解决这个问题。于是我抱着最后的希望查看了Xcode是否还能够成功编译,惊喜发现Xcode中还能够正常编译C++文件,可以看出Xcode是自己包含了一套内置的C++环境,且与外界隔绝的。
那么有没有一种方法能够将CLion使用上Xcode的这一套内在的编译系统呢?我在设置里面找到了这个。
生成器这个选项中最开始默认的是Ninja,而其中存在Xcode的选项,当选中Xcode的时候程序已经可以正常编译运行,如图所示,调试的时候STL容器也能够直接看到值,问题一和问题二从某种奇怪的角度上得以解决。
相关猜想
综上,通过在CLion的CMake生成器选项中选择Xcode,就可以使用Xcode的一套编译体制,并且尽管是通过LLDB调试器,仍然可以显示出STL容器的元素值。但是此方式并没有从正面解决该问题,目前整个Mac的C++版本仍然相对混乱,由于时间成本关系,我没有继续深入正面探索解决问题所在。但是根据目前试过的方法,对可能正面解决问题的方式作出如下猜想:
在解决问题一的方法四中,尽管将CommandLineTools更新至12.4版本,但是Xcode仍然是10.13时候的上古版本10.1,目前针对MacOS 10.15.7的最高Xcode支持版本为12.4,由于更新了CommandLineTools后仍然会进行报错是因为CLion使用的SDK与CommandLineTools的SDK并不是一个,但是是否会通过Xcode的升级,让其与CommandLineTools的版本进行匹配,进而更新CLion所使用的默认SDK使其可以在当前系统下执行的情况呢?这方面应该值得进一步探索。
更多推荐
所有评论(0)