使用macOS自带的c编译器(clang)编译c程序
- macOS自带的c编译器工具链是LLVM/Clang并非gcc,如果对
/usr/bin/gcc
和/usr/bin/clang
进行ls -l
会发现两者大小是一样的,其实是因为gcc在最新的macOS(13+)下只是clang的别名而已。 - 使用系统自带的
clang
需要先装sdk,说白了就是装xcode,并且xcode-select --install
c/cpp头文件在哪?
- 如果在官网上下载特定的llvm/clang源码版本自行编译使用,编译出来的clang是编译不了正常的c程序的,会出现
fatal error: 'stdio.h' file not found
之类的问题。 - 一般来说看到这样的报错意识到头文件找不到,那头文件在哪呢?是不是和普通的Linux发行版一样在
/usr/include
下呢? - 通过自带的clang可以查看这个能正常编译的编译器在编译和链接时在哪寻找头文件(diff testing的思想),通过命令行
clang -x c -E - -v < /dev/null
查看-x c
, 将输入看成c语言文件,举一反三-x c++
则把输入看成c++对待-E
, 只运行预处理(什么是预处理?直观来说把头文件、宏展开)-
, 单一横线表示把内容输出到stdout(标准输出)</dev/null
, unix的特殊文件,表示无底洞,在这里作为一个输入
- 通过查看系统的clang和自己编译的特定版本的clang会发现差异
- 留意
ignoring nonexistent directory
的信息 - 结论就是c/cpp库的标准头文件并不在
/usr/include
- 有人说在
/usr/local/include
下,也不对,因为ls /usr/local/include | grep stdio
会发现根本没有想要的文件
- 留意
- 实际上头文件在sdk中,这就是为什么需要先
xcode-select --install
- 留意刚才
#include <...> search starts here:
下的信息
- 留意刚才
或者正常情况下,常见的Linux发行版和macOS在装gcc/clang的时候会装上一个名为cpp(The C Preprocessor)
那么这个命令也可以查看:cpp -v /dev/null -o /dev/null
-v
, 显示编译器调用的程序/dev/null
, 特殊的unix文件,可以理解成空文件、黑洞文件
所以如果使用源码编译出来的clang去编译c程序,应该怎么解决头文件问题?
- 加上选项:
-isysroot `xcrun --show-sdk-path`
- 如:
/path/to/your/clang -isysroot `xcrun --show-sdk-path` hello.c -o hello
- 单独运行
xcrun --show-sdk-path
会发现输出一条路径,而且一看就能猜出是sdk的路径(前提是你用xcode-select --install
装了)
- 如:
c++同理,在此不赘述
灵感来源: http://lists.llvm.org/pipermail/llvm-dev/2016-July/102044.html
部分来源: https://blog.csdn.net/BjarneCpp/article/details/76135980