clang可以編譯匯編嗎
❶ 如何讓clang編譯C代碼的時候,錯誤提示有顏色
1. 無選項編譯鏈接
> 用法: gcc test.c
> 作用:將test.c預處理、匯編、編譯並鏈接形成可執行文件。這里未指定輸出文件,默認輸出為a.out。
2. 選項 -o 第四步 鏈接(Linking)
> 用法: gcc test.c -o test
> 作用:將test.c預處理、匯編、編譯並鏈接形成可執行文件test。-o選項用來指定輸出文件的文件名。
3. 選項 -E 第一步 預處理(Pre-Processing)
> 用法: gcc -E test.c -o test.i
> 作用:將test.c預處理輸出test.i文件。
4. 選項 -S 第二步 編譯(Compiling)
> 用法: gcc -S test.i
> 作用:將預處理輸出文件test.i匯編成test.s文件。
5. 選項 -c 第三步 匯編(Assembling)
> 用法: gcc -c test.s
> 作用:將匯編輸出文件test.s編譯輸出test.o文件。
6. 無選項鏈接
> 用法: gcc test.o -o test
> 作用:將編譯輸出文件test.o鏈接成最終可執行文件test。
7. 選項 -O
> 用法: gcc -O1 test.c -o test
> 作用:使用編譯優化級別1編譯程序。級別為1~3,級別越大優化效果越好,但編譯時間越長。
二. 多源文件的編譯方法
1. 多個文件一起編譯
> 用法:#gcc testfun.c test.c -o test
> 作用:將testfun.c和test.c分別編譯後鏈接成test可執行文件。
2. 分別編譯各個源文件,之後對編譯後輸出的目標文件鏈接。
> 用法:
> gcc -c testfun.c //將testfun.c編譯成testfun.o
> gcc -c test.c //將test.c編譯成test.o
> gcc -o testfun.o test.o -o test //將testfun.o和test.o鏈接成test
❷ LLVM - 工具
LLVM工具通過調用LLVM的一部分庫,實現庫的功能,通常使用編譯器或者開發編譯器的人會用到這些工具。
這是一個在LLVM IR級別做程序優化的工具,輸入和輸出都是LLVM IR。編譯器,或者基於LLVM做優化的開發者通常會使用這一標准工具來查看優化的效果。它也提供了很多option, 可以執行某一特定的pass。
這是微觀意義上的LLVM編譯器,不同於gcc的編譯器,它的輸入是LLVM IR,輸出是匯編文件或者是目標文件。通過-filetype=asm或者-filetype=obj來指定輸出是匯編文件還是目標文件,若生成是目標文件,llc會調用LLVM中的匯編輸出的代碼庫來工作(注意這個匯編器和gcc的匯編器也不同,它輸入的是MI,是一種後端的中間表示)。除此之外,還可以用-On來指定優化級別(llc默認優化級別是-O2),或者其他一些參數。
(.bc文件換成.ll文件也可以)
這是LLVM匯編器,它輸入匯編文件,輸出目標文件, 類似於gnu中的as命令。同時,它也可以反匯編,指定特殊參數(–disassemble)就行。可以發現,llc和llvm-mc都會調用到輸出目標文件的庫,也就是MCObjectStreamer。
這個工具是LLVM IR的解釋器,也是一個JIT編譯器。LLVM可以把C語言翻譯成LLVM IR,然後解釋執行,與Java的那一套類似,這也是最初LLVM編寫時的實現(一個虛擬機運行IR)。
最早看到這個工具,以為是鏈接器,其實它是IR級別的鏈接器,鏈接的是IR文件。談到這里,可以說一下LLVM針對多個源文件編譯時的兩種目標碼輸出方式。
第一種是LLVM先通過前端把每個源文件單獨翻譯成IR級別,然後用llvm-link鏈接成一個IR,然後再經過優化、後端等步驟生成目標文件,使用llvm-link的同時,可以使用鏈接時優化。不過需要注意,這種方式同樣需要最終調用鏈接器,將這個目標文件鏈接成可執行文件。
第二種是LLVM通過前端把每個源文件單獨翻譯後,再單獨經過優化、後端等工作,將每個源文件生成目標文件,之後再調用鏈接器,將所有目標文件鏈接成可執行文件。
這是針對LLVM IR的匯編器,其實名字里帶as,實際上不是gcc那個as,它的功能是將.ll文件翻譯為.bc文件,LLVM項目里,.ll稱為LLVM匯編碼,所以llvm-as也就是IR的匯編器了。
與llvm-as剛好相反,IR的反匯編器,用來將.bc文件翻譯為.ll文件。
最後也提一下clang,它也是現在LLVM項目中一個很重要的前端工具。clang能夠調用整個編譯器的流程,也就是上邊其他工具調用的庫,它很多都同樣會調用。clang通過指定-emit-llvm參數,可以配合-S或-c生成.ll或.bc文件,這樣我們就能把Clang的部分和LLVM的後端分離開來獨立運行,對於觀察編譯器流程來說,很實用。
還有一些其他工具,就不舉例了,可以查看LLVM項目路徑下/src/tools/中查看。
❸ 如何使用clang+llvm+binutils+newlib+gdb搭建交叉編譯環境
測試環境:Windows8.1 + MSYS2 with Mingw, Clang, LLVM + GNU Tools for ARM Embedded Processor
首先用用Clang生成LLVM位元組碼
clang -emit-llvm --target=arm-none-eabi -mcpu=cortex-m3 -mthumb -mfloat-abi=soft
注意,需要手動添加GNU Tools for ARM Embedd的頭文件
然後用llc生成匯編代碼
接著,使用GNU Tools for ARM Embedded Processor的匯編器生成可執行文件
arm-none-eabi-as -mcpu=cortex-m3 -mthumb -mfloat-abi=soft
二進制文件用GNU Tools for ARM Embedded Processor里的arm-none-eabi-obj生成
一些需要注意的地方是Clang的默認配置可能和目標架構的匯編器不一致。比如arm-none-eabi-as會默認開啟short-enums,當直接使用arm-none-eabi-gcc時這不是問題,因為編譯器也默認開啟了這個選項,但Clang不會,所以需要手動加上-fshort-enums。
❹ 了解-clang編譯過程
第1步 : 創建源碼文件 hello.c 如下:
第2步 : 對其進行預編譯, 得到 .i 輸出文件, 使用命令:
從中可以看到預處理做的一些工作
第3步 :編譯,得到 .s 文件, 使用命令
第4步 : 匯編,得到 .o 文件, 使用命令
❺ Clang如何處理MSVC的編譯參數
LLVM裡面的Clang已經可以替換MSVC的cl.exe(MSVC的編譯過程的組織程序-driver),作為Visual Studio的獨立工具鏈,能生成PDB文件支持在Visual Studio裡面的源代碼調試。為了支持替換cl.exe,clang構建會生成可執行文件clang-cl.exe,接收cl.exe的大部分參數而在內部轉換成LLVM的參數形式。
雖然看起來是生成了一個單獨的clang-cl.exe,它實際上就是clang.exe的一個副本,如果程序名是clang.exe,還可以在命令行傳遞" --driver-mode=cl "參數啟用cl.exe的參數解析模式。所以clang-cl.exe和clang.exe是一樣的,都接受" --target= i686-pc-windows", 但是為什麼clang-cl.exe卻不能解析" -triple i686-pc-windows"而clang.exe卻可以呢?
程序本身通過檢查自身的文件名(argv[0])來檢測是不是要運行在兼容MSVC cl.exe的模式,如果文件名是"clang-cl.exe",則把對應的DriverMode放到main函數開始處的變數TargetAndMode裡面(ToolChain::)。下面的代碼顯示了對應關系,可以看到把文件名clang.exe改成cl.exe也會有一樣的效果。
在上面從程序名解析出target和mode後,main函數裡面緊接著的代碼檢查了返回的mode和命令行參數,只要以一個滿足則進入 ClangCLMode 。不過這里解析出來的ClangCLMode只用來處理命令行參數的分隔和cl.exe特有的環境變數,包括"CL"和"_CL_"。
再從main函數進入Driver類的對象TheDriver的 BuildCompilation 方法後,會調用 ParseDriverMode方法,裡面會根據程序名重新獲得driver mode(ToolChain::),然後把driver mode字元串傳給下面的 setDriverModeFromOption 方法。這個方法根據傳入的driver mode選項設置成員變數 Mode .
上面的 Driver類的對象 已經知道當前Mode,比如 CLMode ,下面會組織整個編譯過程,包括調用編譯器(clang.exe -cc1)和鏈接器(MSVC的link或者lld-link)。
BuildCompilation緊接著會調用ParseArgStrings。ParseArgStrings調用下面的 ,根據Driver的當前Mode得到include mask和exclude mask兩個掩碼,用於後面(在調用鏈ParseArgString->ParseArg->ParseOneArg的最後的方法ParseOneArg裡面)決定是否接受命令行參數。比如在CLMode下就只會接受ClOption和CoreOption。
那麼CLOption和CoreOption都有哪些具體參數呢?Clang的所有命令行參數選項都定義在llvm_root .td裡面,由tablegen轉成C/C++頭文件而被代碼引用。下面是從裡面截取的target的定義,看到"--target="選項是同時屬於DriverOption和 CoreOption ,而CoreOption在CLMode和非CLMode下均能使用。
以下是"-target"的定義,沒有定義Flags,所以在CLMode下也就不能解析,這也就解釋了最開始"clang-cl.exe"不接受"-triple i686-pc-windows"參數。
❻ Clang 比 GCC 編譯器好在哪裡
1:Clang編譯速度更快、編譯產出更小、出錯提示更友好。
2:clang還內置有靜態分析工具,可以對代碼進行靜態分析(clang --analyze)。這是gcc做不到的。
3:clang結構更簡單。因為clang只需要完成詞法和語法分析,代碼優化和機器代碼的生成工作由llvm完成。所以和全部由自己包下的gcc比起來,clang可以更專注地做好一件事。
4:Clang 的另一個優勢是代碼結構清晰,可以作為庫使用,成為其它 app(主要是 IDE)的內嵌 C/C++ parser。這樣,editor 工具可以使用和 compiler 一樣的 parser 來完成 edit-time 的語法檢查。GCC 的結構比較混亂。業界一直有說法是 FSF 故意如此,以便讓 GCC 無法作為其它 app 的內嵌部分。
5:Clang採用的是BSD協議。這是蘋果資助LLVM、FreeBSD淘汰GCC換用Clang的一個重要原因。
