clang是FreeBSD和Mac下C/C++语言的默认编译器。如果你在苹果下做过开发,那么应该对它很熟悉。

这套工具链有很多优点:

  1. 代码很新,架构优良。
  2. 错误信息更友好。
  3. 静态检查功能更强大。
  4. 版权限制小,易于自定义模块来扩展它的功能。
  5. 背后有Apple和Google这两家商业公司的大力支持。比如XCode现在只支持clang而不支持gcc。
  6. 支持JIT。这使得C/C++可以像java那样半编译半解释,一次编译到处执行。
  7. 支持所有主流的操作系统。

clang只是一个前端,它背后用来生成二进制机器码的叫llvm。

llvm+clang 在windows下有两种,一个是用mingw编译的,使用gcc的头文件和库。一个是用vc编译的,使用vc的头文件和库。

mingw版本的下载地址是:http://llvm.org/releases/3.4/LLVM-3.4-win32.exe 这是由官方提供的

vc版本的下载地址是:http://pan.baidu.com/s/1eQf6E90这是我自己编译的,32位版本。

我建议你安装vc版本的,

因为优点是:

  1. 它编译出来的是更原生态的程序。不依赖于mingw,只依赖于vc的dll。
  2. 我自己编译的这个版本功能更全,包含了llvm的JIT执行器、clang的扩展工具(如把老风格的代码转换成c++11)等等。
  3. 性能更高。

但也有一些缺点:

  1. 必须依赖于visual studio。请先安装visual studio再安装llvm。

没有安装visual studio的可以从微软的官方网站下载: http://www.microsoft.com/en-us/download/details.aspx?id=40778 。没有密钥的发邮件找我要。

如果已经有visual studio但是版本不是2013的,请安装vc 2013的可再分发包:http://www.microsoft.com/en-us/download/details.aspx?id=40784

clang安装好以后,你可以先打开它下面的bin目录看一眼,里面有30多个exe。主要比较常用的是:

  • clang: C语言编译器,类似于gcc
  • clang++: C++编译器,类似于g++。clang++只是clang的一个别名。
  • lld: 链接器,类似于ld。但是默认不用它,默认用vc的link.exe。
  • clang-format:按照固定的规范格式化C/C++代码,非常智能。文档请见:http://clang.llvm.org/docs/ClangFormat.html
  • clang-modernize:把按照C++98标准写的代码,转成C++11标准的。文档请见:http://clang.llvm.org/extra/ModernizerUsage.html
  • llvm-as - LLVM 汇编器
  • llvm-dis - LLVM 反汇编器
  • opt - LLVM 优化器
  • llc - LLVM 静态编译器
  • lli - LLVM的字节码执行器(某些平台下支持JIT)
  • llvm-link - LLVM的字节码链接器
  • llvm-ar - LLVM的静态库打包器,类似unix的ar。
  • llvm-nm - 类似于unix的nm。

Hello World

然后写一个hello world试下。

#include <windows.h>int main(){MessageBox(NULL,"hello\n",NULL,MB_OK);  return 0;
}

由于默认情况下clang的链接器用的还是vc的链接器,所以在执行编译操作之前,得先设置vc所需要的环境变量。打开C:\Program Files (x86)\VS\Common7\Tools\Shortcuts,执行那个名为“VS2013 x86 Native Tools Command Prompt”的快捷方式。

然后在这里面执行

C:> clang++ -o hello.exe hello.cpp -Wl,”user32.lib”

这个版本的clang有一个缺陷,它不会自动把-lxxx 这样的参数正确传递给vc的link.exe。所以我只能用-Wl这样的方式传。

编译好的exe执行结果如下:

Sanitizer

clang有一个王牌功能是sanitizer。它包含三种:AddressSanitizer、MemorySanitizer、ThreadSanitizer。AddressSanitizer和MemorySanitizer最初是google开发的,用于运行时检测C/C++程序中的内存错误。在编译的时候加上-fsanitizer参数,编译器就会在生成的代码中插入一些运行时检查。比如你可以拿下面的这段代码试下:

#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;
}

它把命令行的第一个参数复制到一个临时的缓存区中,然后打印出来。

这段代码有两个bug:

  1. 在访问argv的时候可能会越界。(用户执行时没有加任何参数)
  2. buf不够长,写入时可能会越界,这将会造成严重的安全漏洞。

来,编译试下:

C:>clang++ -fsanitize=address -o t.exe badcode.cpp -g3 -DDEBUG -D_DEBUG

然后运行:

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

它会提前把错误检测出来,并终止程序。

但是memory sanitizer目前在windows下还不能用。

This article is from:https://www.sunchangming.com/blog/post/4614.html

原文链接: http://blog.sunchangming.com/post/79532506473

在windows下使用llvm+clang相关推荐

  1. windows上的LLVM pass瞎折腾记录

    windows上的LLVM pass瞎折腾记录 想了解下LLVM的代码风格和优化过程,就从写LLVM pass入手吧,做个踩坑记录- 文章最后有逐步骤的操作记录,Tips内记录关键点和思路 Tips: ...

  2. Windows下LLVM环境配置

    Windows下LLVM环境配置 目录 Windows下LLVM环境配置 1. 命令行下载并构建VS 2017项目 2. 项目构建过程中出现的细节 3. 心得体会 4. 参考文献 1. 命令行下载并构 ...

  3. win命令安装 安装cmake_win10下VSCode+CMake+Clang+GCC环境搭建教程图解

    打算用C/C++把基本的数据结构与算法实现一遍, 为考研做准备, 因为只是想实现算法和数据结构, 就不太想用VisualStudio, 感觉VSCode不错, 遂在网上找了一些教程, 结合自己的需求, ...

  4. 在windows下使用vim

    最主要的就是解决lua和clang的问题. 下载支持lua和其他扩展的vim. 解决lua 下载lua53.dll并将其放在与gvim.exe相同的文件夹下. 解决clang 下载clang_for_ ...

  5. ARM 之七 主流编译器(armcc、iar、gcc for arm、LLVM(clang))详细介绍

    必备   在讲解各编译器之前,必须先了解一下以下这些文件.这些文件在编译器目录下或者编译生成目标平台的可执行程序时经常见到.此外,还需要注意区分 Windows 平台 和 Linux 平台的文件. . ...

  6. 【转】ARM 之七 主流编译器(armcc、iar、gcc for arm、LLVM(clang))详细介绍

    转自:ARM 之七 主流编译器(armcc.iar.gcc for arm.LLVM(clang))详细介绍_itexp-CSDN博客_armcc 必备   在讲解各编译器之前,必须先了解一下以下文件 ...

  7. vscode在Windows下配置C语言环境,设置三个配置文件

    一.需要下载的安装包: 1.vscode 直接在微软官方下载最新的vscode 2.MinGw64 里面包含了gcc.gdb等前一个是编译器,后一个是debug的 传送链接: MinGW64 往下拉点 ...

  8. windows下使用vscode开发stm32

    Windows下使用vscode开发stm32 写在开头 有条件的用clion,方法更简单,具体教程参考知乎稚晖君教程<配置CLion用于STM32开发[优雅の嵌入式开发>(点击跳转) 起 ...

  9. LLVM Clang前端编译与调试

    LLVM Clang前端编译与调试 iOS 关于编译 o 一.Objective-C 编译过程 o 为什么需要重新编译? o 编译步骤 o 二.编译步骤的详细说明 o 1.预处理 o 2.编译 o 词 ...

最新文章

  1. 【数据库】阿里云教你快速掌握SQL语句使用
  2. HTTP Continuation or non-HTTP traffic
  3. 异常处理汇总-开发工具
  4. Android四大组件之BroadCastReceiver
  5. 图解VC++版PE文件解析器源码分析
  6. docker logs 日志原理
  7. 流式视频处理架构设计
  8. 三大主流ETL工具选型
  9. SOFA 源码分析 — 连接管理器
  10. c调python_py_initialize:C调Python出错 是初始化错误?
  11. oracle安装后新建数据库实例及配置
  12. iPhone 12 Pro系列变贵的原因在这儿!
  13. laravel框架学习之路(一)前后台用户认证分离
  14. 新型智慧城市投融资经验分享
  15. 暴走P图APP隐私政策
  16. Python使用selenium自动打开谷歌浏览器和网页
  17. 架构模式之 CS和BS的区别
  18. aes 和 rsa
  19. 让数字内容被平等获取 | Android 开发者故事
  20. form.submit() 提交部分浏览器不管用

热门文章

  1. 【IOC 控制反转】Android 事件依赖注入 ( 事件依赖注入具体的操作细节 | 获取 Activity 中的所有方法 | 获取方法上的注解 | 获取注解上的注解 | 通过注解属性获取事件信息 )
  2. 【Android 插件化】Hook 插件化框架 ( Hook Activity 启动流程 | 主线程创建 Activity 实例之前使用插件 Activity 类替换占位的组件 )
  3. 【Flutter】StatefulWidget 组件 ( FloatingActionButton 组件 | RefreshIndicator 组件 )
  4. R语言基础篇——数据对象
  5. go语言中将函数作为变量传递
  6. ThinkPHP 中M方法和D方法的具体区别
  7. 利用mk-table-checksum监测Mysql主从数据一致性操作记录
  8. hdu2041java
  9. 按钮在执行frame动画的时候怎么响应触发事件?
  10. C++11中的bool变量不进行初始化,结果随机,可能是false也可能是true,所以一定要初始化