在windows下使用llvm+clang
clang是FreeBSD和Mac下C/C++語言的默認(rèn)編譯器。如果你在蘋果下做過開發(fā),那么應(yīng)該對(duì)它很熟悉。
這套工具鏈有很多優(yōu)點(diǎn):
clang只是一個(gè)前端,它背后用來生成二進(jìn)制機(jī)器碼的叫l(wèi)lvm。
llvm+clang 在windows下有兩種,一個(gè)是用mingw編譯的,使用gcc的頭文件和庫。一個(gè)是用vc編譯的,使用vc的頭文件和庫。
mingw版本的下載地址是:http://llvm.org/releases/3.4/LLVM-3.4-win32.exe?這是由官方提供的
vc版本的下載地址是:http://pan.baidu.com/s/1eQf6E90這是我自己編譯的,32位版本。
我建議你安裝vc版本的,
因?yàn)閮?yōu)點(diǎn)是:
但也有一些缺點(diǎn):
沒有安裝visual studio的可以從微軟的官方網(wǎng)站下載:?http://www.microsoft.com/en-us/download/details.aspx?id=40778?。沒有密鑰的發(fā)郵件找我要。
如果已經(jīng)有visual studio但是版本不是2013的,請(qǐng)安裝vc 2013的可再分發(fā)包:http://www.microsoft.com/en-us/download/details.aspx?id=40784
clang安裝好以后,你可以先打開它下面的bin目錄看一眼,里面有30多個(gè)exe。主要比較常用的是:
- clang: C語言編譯器,類似于gcc
- clang++: C++編譯器,類似于g++。clang++只是clang的一個(gè)別名。
- lld: 鏈接器,類似于ld。但是默認(rèn)不用它,默認(rèn)用vc的link.exe。
- clang-format:按照固定的規(guī)范格式化C/C++代碼,非常智能。文檔請(qǐng)見:http://clang.llvm.org/docs/ClangFormat.html
- clang-modernize:把按照C++98標(biāo)準(zhǔn)寫的代碼,轉(zhuǎn)成C++11標(biāo)準(zhǔn)的。文檔請(qǐng)見:http://clang.llvm.org/extra/ModernizerUsage.html
- llvm-as - LLVM 匯編器
- llvm-dis - LLVM 反匯編器
- opt - LLVM 優(yōu)化器
- llc - LLVM 靜態(tài)編譯器
- lli - LLVM的字節(jié)碼執(zhí)行器(某些平臺(tái)下支持JIT)
- llvm-link - LLVM的字節(jié)碼鏈接器
- llvm-ar - LLVM的靜態(tài)庫打包器,類似unix的ar。
- llvm-nm - 類似于unix的nm。
Hello World
然后寫一個(gè)hello world試下。
#include <windows.h>int main(){MessageBox(NULL,"hello\n",NULL,MB_OK); return 0; }
由于默認(rèn)情況下clang的鏈接器用的還是vc的鏈接器,所以在執(zhí)行編譯操作之前,得先設(shè)置vc所需要的環(huán)境變量。打開C:\Program Files (x86)\VS\Common7\Tools\Shortcuts,執(zhí)行那個(gè)名為“VS2013 x86 Native Tools Command Prompt”的快捷方式。
然后在這里面執(zhí)行
C:> clang++ -o hello.exe hello.cpp -Wl,”user32.lib”
?這個(gè)版本的clang有一個(gè)缺陷,它不會(huì)自動(dòng)把-lxxx 這樣的參數(shù)正確傳遞給vc的link.exe。所以我只能用-Wl這樣的方式傳。
編譯好的exe執(zhí)行結(jié)果如下:
Sanitizer
clang有一個(gè)王牌功能是sanitizer。它包含三種:AddressSanitizer、MemorySanitizer、ThreadSanitizer。AddressSanitizer和MemorySanitizer最初是google開發(fā)的,用于運(yùn)行時(shí)檢測(cè)C/C++程序中的內(nèi)存錯(cuò)誤。在編譯的時(shí)候加上-fsanitizer參數(shù),編譯器就會(huì)在生成的代碼中插入一些運(yùn)行時(shí)檢查。比如你可以拿下面的這段代碼試下:
#include <stdio.h> #include <string.h>int main(int argc,char* argv[]){char buf[4];strcpy(buf,argv[1]);printf("%s\n",buf);return 0; }它把命令行的第一個(gè)參數(shù)復(fù)制到一個(gè)臨時(shí)的緩存區(qū)中,然后打印出來。
這段代碼有兩個(gè)bug:
來,編譯試下:
C:>clang++ -fsanitize=address -o t.exe badcode.cpp -g3 -DDEBUG -D_DEBUG
然后運(yùn)行:
C:>t 3
3?
C:>t 355
355?
C:>t 3554664
=================================================================
==4044==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x0024fd44 at
pc 0x1274038 bp 0xdeadbeef sp 0x24fbf0?
WRITE of size 8 at 0x0024fd44 thread T0?
#0?0x127404c wrap_strcpy c:\users\cm\documents\os\llvm-3.4\projects\compile
r-rt\lib\asan\asan_interceptors.cc:490?
#1?0x12612a7 main+0x0x000002a7?
#2?0x1278212 __tmainCRTStartup f:\dd\vctools\crt\crtw32\startup\crt0.c:255?
#3?0x772d3369 BaseThreadInitThunk+0x0x00000011?
#4?0x77ba9f71 RtlInitializeExceptionChain+0x0x00000062?
#5?0x77ba9f44 RtlInitializeExceptionChain+0x0x00000035?
Address 0x0024fd44 is located in stack of thread T0 at offset 228 in frame
#0?0x126100f main+0x0x0000000f
This frame has 4 object(s):
[32, 36) ”
[96, 100) ”
[160, 164) ”
[224, 228) ‘buf’ <== Memory access at offset 228 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind
mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow???:0???
Shadow bytes around the buggy address:
0x20049f50: 00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?
0x20049f60: 00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?
0x20049f70: 00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?
0x20049f80: 00?00?00?00?00?00?00?00?00?00?00?00 f1 f1 f1 f1?
0x20049f90: 04 f4 f4 f4 f2 f2 f2 f2?04 f4 f4 f4 f2 f2 f2 f2?
=>0x20049fa0: 04 f4 f4 f4 f2 f2 f2 f2[04]f4 f4 f4 f3 f3 f3 f3?
0x20049fb0: 00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?
0x20049fc0: 00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?
0x20049fd0: 00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?
0x20049fe0: 00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?
0x20049ff0: 00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00?
Partially addressable: 01?02?03?04?05?06?07?
Heap left redzone: fa
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1?
Stack mid redzone: f2?
Stack right redzone: f3?
Stack partial redzone: f4?
Stack after return: f5?
Stack use after scope: f8?
Global redzone: f9?
Global init order: f6?
Poisoned by user: f7?
ASan internal: fe
==4044==ABORTING
它會(huì)提前把錯(cuò)誤檢測(cè)出來,并終止程序。
但是memory sanitizer目前在windows下還不能用。
This article is from:https://www.sunchangming.com/blog/post/4614.html
原文鏈接: http://blog.sunchangming.com/post/79532506473
總結(jié)
以上是生活随笔為你收集整理的在windows下使用llvm+clang的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win7 下配置 Qt5.1 for A
- 下一篇: 01:台风