本文共 3355 字,大约阅读时间需要 11 分钟。
本文主要针对需要在Ubuntu下用 clang
和 libc++
标准库学习 C++
的同学. 操作系统是Ubuntu 16.04的64位版. 安装必要的包: sudo apt install subversionsudo apt install cmake
建立目录(这里取名为 CL
): cd ~sudo mkdir CL cd CL
svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
下载 clang
: cd llvm/toolssvn co http://llvm.org/svn/llvm-project/cfe/trunk clangcd ../..
下载 clang
工具(可选) cd llvm/tools/clang/toolssvn co http://llvm.org/svn/llvm-project/clang-tools-extra/trunk extracd ../../../..
cd llvm/projectssvn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rtcd ../..
下载标准库 libcxx
(绝对要下载)还有 libcxxabi
(千万不要遗漏): cd llvm/projectssvn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxxsvn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabicd ../..
注意将默认的Debug模式换成Release模式. cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release ../llvmmakesudo make install
基于 c++11
使用 libc++
编译 x.cpp
并执行 a.out
clang++ -std=c++11 -stdlib=libc++ x.cpp.\a.out
验证 x.cpp
的正确性 clang x.cpp -fsyntax-only
输出 x.cpp
未优化的LLVM代码 clang x.cpp -S -emit-llvm -o -
输出 x.cpp
经过 O3
优化的LLVM代码 clang x.cpp -S -emit-llvm -o - -O3
输出 x.cpp
的原生机器码 clang x.cpp -S -O3 -o -
安装完毕之后, 如果不嫌麻烦的话, 可以用
clang
再编译安装一次:
CC=clang CXX=clang++ cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release ../llvm
后续步骤同上:-)
出错提示更友好,比如 clang 在编译过程可以直接指出相对简单的出错位置以及它 “ 认为 ” 正确的方式 。
内置有静态分析工具,可以对代码进行静态分析 (clang—analyze) 。这也是 gcc 做不到的 。
专注,因为 clang 只需要完成词法和语法分析,代码优化和机器代码的生成工作由 llvm 完成。所以和全部由自己包下的 gcc 比起来, clang 可以更专注地做好一件事。这种结构也使 clang 可以被单独拿出来用在其他的程序里,成为其它 app (主要是 IDE)的内嵌 C/C++ parser 。 对于 IDE 而言,代码补全、重构是重要的功能,然而如果没有底层的支持,只使用 tags 分析或是正则表达式匹配是很难达成的, clang正好充当了这一角色。 这样, editor 工具可以使用和 compiler 一样的 parser 来完成 edit-time 的语法检查 。 而 gcc 就没法很方便地做到这一点 。由于历史原因, GCC 是一个单一的可执行程序编译器,其内部完成了从预处理到最后代码生成的全部过程,中间诸多信息都无法被其他程序重用。
Clang采用的是BSD协议。这是苹果资助LLVM、FreeBSD淘汰GCC换用Clang的一个重要原因。
一些软件用 clang 编译会出现莫名其妙的错误,但是用 gcc 编译可以通过 。
GCC 在 5.0 之前一直都在准备用 C++ 实现模块化,期待 GCC 的 5.0 会有所突破,补上无法模块化的短板。
GCC:GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAVA、Fortran、Pascal、Object-C、Ada等语言。
GCC 是GCC中的GUN C Compiler(C 编译器)
g++是GCC中的GUN C++ Compiler(C++编译器)
一个有趣的事实就是,就本质而言,gcc和g++并不是编译器,也不是编译器的集合,它们只是一种驱动器,根据参数中要编译的文件的类型,调用对应的GUN编译器而已。
gcc and g++分别是GNU 的c & c++编译器 gcc /g++在执行编译工作的时候,总共需要4步
1.预处理,编译处理宏定义等宏命令(eg:#define),生成.i的文件[
预处理器cpp]
2.将预处理后的文件转换成汇编语言,生成文件.s[
编译器ccl]
3.由汇编变为二进制目标代码(机器代码)生成.o的文件[
汇编器as]
4.连接目标代码,生成可执行程序[
链接器ld], Eg: 将print.o文件连接合并到hello.o文件中
1. 对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译(c和cpp的语法强度是不一样的)
2. 对于 *.c和*.cpp文件,g++则统一当做cpp文件编译
3. 使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL
4. gcc在编译C文件时,可使用的预定义宏是比较少的
5. gcc在编译cpp文件时/g++在编译c文件和cpp文件时(这时候gcc和g++调用的都是cpp文件的编译器),会加入一些额外的宏,这些宏如下:
#define __private_extern__ extern
6.在用gcc编译c++文件时,为了能够使用STL,需要加参数 –lstdc++ ,但这并不代表 gcc –lstdc++ 和 g++等价,它们的区别不仅仅是这个
-g - turn on debugging (so GDB gives morefriendly output)
-Wall - turns on most warnings
-O or -O2 - turn on optimizations
-o - name of the output file
-c - output an object file (.o)
-I - specify an includedirectory
-L - specify a libdirectory
-l - link with librarylib.a
使用示例:g++ -ohelloworld -I/homes/me/randomplace/include helloworld.C
转载地址:http://qjqqf.baihongyu.com/