使用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