当前位置:首页 » 编程软件 » llvm编译

llvm编译

发布时间: 2022-01-19 00:03:25

Ⅰ 如何利用LLVM写一个编译

LLVM有自己的教程,如果你只想做个玩具,那可以首先试着实现LLVM Tutorial: Table of Contents的Kaleidoscope。深入的,请看他的文档http://llvm.org/docs/

Kaleidoscope是一个范式简单的脚本语言,教程里的词法,语法分析都是手写的,基本流程就是词法语法解析,利用LLVM的API生成中间代码并执行。

我用visual studio编译的LLVM(version 3.6)实现过Kaleidoscope,我遇到的坑不少,如果你想以visual studio编译的LLVM实现Kaleidoscope,你可能同样会遇到

1. LLVM的生成目标对象为ELF格式,在windows下使用JIT的API时会出现incompatible object format的错误警告,需要在通过重新设定Mole的triple,我的PC的getTargetTriple的结果是“i686-pc-windows-msvc”,直接在后面再加上“-elf”即可

TheMole->setTargetTriple("i686-pc-windows-msvc-elf");

2. LLVM不支持windows下通过动态链接导出函数,如果需要使用C/C++的函数,需要通过addSymbol进行注册

llvm::sys::DynamicLibrary::AddSymbol(/*std::string("_") +*/ "printd", &printd);

3. Kaleidoscope里使用的JIT的查找函数的API,getPointerToFunction已经被弃用了,需要替换为getFunctionAddress

Ⅱ 编译llvm和clang需要多大空间

:转自知乎 蓝色 我最近和Clang/LLVM打交道比较多,目前游离在LLVM IR和IBM WCode之间。对于学习Clang/LLVM来说,其实需要看你做什么,是研究C, C++, Objective-C在Clang的实现,抑或着是想利用Clang做AST层面的事情,还是说想要利用LLVM IR来做

Ⅲ 如何使用clang+llvm+binutils+newlib+gdb搭建交叉编译环境

1,Build llvm/clang/lldb/lld 3.5.0等组件

1.0 准备:

至少需要从llvm.org下载llvm, cfe, lldb, compiler-rt,lld等3.5.0版本的代码。

$tar xf llvm-3.5.0.src.tar.gz

$cd llvm-3.5.0.src

$mkdir -p tools/clang
$mkdir -p tools/clang/tools/extra
$mkdir -p tools/lld
$mkdir -p projects/compiler-rt

$tar xf cfe-3.5.0.src.tar.xz -C tools/clang --strip-components=1
$tar xf compiler-rt-3.5.0.src.tar.xz -C projects/compiler-rt --strip-components=1
$tar xf lldb-3.5.0.src.tar.xz -C tools/clang/tools/extra --strip-components=1
$tar xf lld-3.5.0.src.tar.xz -C tools/lld --strip-components=1
1.1 【可选】使用clang --stdlib=libc++时,自动添加-lc++abi。

libc++组件可以使用gcc libstdc++的supc++ ABI,也可以使用c++abi,cxxrt等,实际上自动添加-lc++abi是不必要的,这里这么处理,主要是为了方便起见。实际上完全可以在“clang++ -stdlib=libc++”时再手工添加-lc++abi给链接器。

这里涉及到链接时DSO隐式还是显式的问题,早些时候ld在链接库时会自动引入由库引入的依赖动态库,后来因为这个行为的不可控性,所以ld链接器的行为做了修改,需要显式的写明所有需要链接的动态库,才会有手工添加-lc++abi这种情况出现。

--- llvm-3.0.src/tools/clang/lib/Driver/ToolChain.cpp 2012-03-26 18:49:06.663029075 +0800
+++ llvm-3.0.srcn/tools/clang/lib/Driver/ToolChain.cpp 2012-03-26 19:36:04.260071355 +0800
@@ -251,6 +251,7 @@
switch (Type) {
case ToolChain::CST_Libcxx:
CmdArgs.push_back("-lc++");
+ CmdArgs.push_back("-lc++abi");
break;

case ToolChain::CST_Libstdcxx:
1.2 【必要】给clang++添加-fnolibgcc开关。

这个开关主要用来控制是否连接到libgcc或者libunwind。

注:libgcc不等于libunwind。libgcc_eh以及supc++的一部分跟libunwind功能相当。

注:libgcc_s和compiler_rt的一部分相当。

这个补丁是必要的, 不会对clang的正常使用造成任何影响 ,只有在使用“-fnolibgcc"参数时才会起作用。

之所以进行了很多unwind的引入,主要是为了避免不必要的符号缺失麻烦,这里的处理相对来说是干净的,通过as-needed规避了不必要的引入。

--- llvm-static-3.5.0.bak/tools/clang/lib/Driver/Tools.cpp 2014-09-10 13:46:02.581543888 +0800
+++ llvm-static-3.5.0/tools/clang/lib/Driver/Tools.cpp 2014-09-10 16:03:37.559019321 +0800
@@ -2060,9 +2060,15 @@
".a");

CmdArgs.push_back(Args.MakeArgString(LibClangRT));
- CmdArgs.push_back("-lgcc_s");
- if (TC.getDriver().CCCIsCXX())
- CmdArgs.push_back("-lgcc_eh");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else {
+ CmdArgs.push_back("-lgcc_s");
+ if (TC.getDriver().CCCIsCXX())
+ CmdArgs.push_back("-lgcc_eh");
+ }
}

static void addProfileRT(
@@ -7150,24 +7156,50 @@
bool isAndroid = Triple.getEnvironment() == llvm::Triple::Android;
bool StaticLibgcc = Args.hasArg(options::OPT_static_libgcc) ||
Args.hasArg(options::OPT_static);
+
+
+
if (!D.CCCIsCXX())
- CmdArgs.push_back("-lgcc");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else
+ CmdArgs.push_back("-lgcc");

if (StaticLibgcc || isAndroid) {
if (D.CCCIsCXX())
- CmdArgs.push_back("-lgcc");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else
+ CmdArgs.push_back("-lgcc");
} else {
if (!D.CCCIsCXX())
CmdArgs.push_back("--as-needed");
- CmdArgs.push_back("-lgcc_s");
+ if (Args.hasArg(options::OPT_fnolibgcc))
+ CmdArgs.push_back("-lunwind");
+ else
+ CmdArgs.push_back("-lgcc_s");
if (!D.CCCIsCXX())
CmdArgs.push_back("--no-as-needed");
}

if (StaticLibgcc && !isAndroid)
- CmdArgs.push_back("-lgcc_eh");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else
+ CmdArgs.push_back("-lgcc_eh");
else if (!Args.hasArg(options::OPT_shared) && D.CCCIsCXX())
- CmdArgs.push_back("-lgcc");
+ if (Args.hasArg(options::OPT_fnolibgcc)) {
+ CmdArgs.push_back("--as-needed");
+ CmdArgs.push_back("-lunwind");
+ CmdArgs.push_back("--no-as-needed");
+ } else
+ CmdArgs.push_back("-lgcc");

// According to Android ABI, we have to link with libdl if we are
// linking with non-static libgcc.
--- llvm-static-3.5.0.bak/tools/clang/include/clang/Driver/Options.td 2014-08-07 12:51:51.000000000 +0800
+++ llvm-static-3.5.0/tools/clang/include/clang/Driver/Options.td 2014-09-10 13:36:34.598511176 +0800
@@ -788,6 +788,7 @@
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>;
def fopenmp : Flag<["-"], "fopenmp">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
def fopenmp_EQ : Joined<["-"], "fopenmp=">, Group<f_Group>, Flags<[CC1Option]>;
+def fnolibgcc : Flag<["-"], "fnolibgcc">, Group<f_Group>, Flags<[CC1Option, NoArgumentUnused]>;
def fno_optimize_sibling_calls : Flag<["-"], "fno-optimize-sibling-calls">, Group<f_Group>;
def foptimize_sibling_calls : Flag<["-"], "foptimize-sibling-calls">, Group<f_Group>;
def force__cpusubtype__ALL : Flag<["-"], "force_cpusubtype_ALL">;
1.3 llvm的其他补丁。

llvm/clang将gcc toolchain的路径hard code在代码中,请查阅tools/clang/lib/Driver/ToolChains.cpp。

找到x86_64-redhat-linux之类的字符串。

如果没有你系统特有的gcc tripple string,请自行添加。

这个tripple string主要是给llvm/clang搜索gcc头文件等使用的,不影响本文要构建的toolchain

1.4 构建clang/llvm/lldb

本文使用ninja。顺便说一下,llvm支持configure和cmake两种构建方式。可能是因为工程太大,这两种构建方式的工程文件都有各种缺陷(主要表现在开关选项上,比如configure有,但是cmake却没有等)。llvm-3.4.1就是因为cmake工程文件的错误而导致了3.4.2版本的发布。

综合而言,cmake+ninja的方式是目前最快的构建方式之一,可以将构建时间缩短一半以上。

mkdir build
cd build

cmake \
-G Ninja \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_BUILD_TYPE="Release" \
-DCMAKE_CXX_FLAGS="-std=c++11" \
-DBUILD_SHARED_LIBS=OFF \
-DLLVM_ENABLE_PIC=ON \
-DLLVM_TARGETS_TO_BUILD="all" \
-DCLANG_VENDOR="MyOS" ..

ninja

ninja install
如果系统原来就有clang/clang++的可用版本,可以添加:

-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
这样就会使用系统的clang++来构建llvm/clang

2,测试clang/clang++。

自己找几个简单的c/cpp/objc等编译测试一下即可。完整测试可以在构建时作ninja check-all

3,libunwind/libc++/libc++abi,一套不依赖libgcc, libstdc++的c++运行库。

3.1 从https://github.com/pathscale/libunwind 获取代码。

libunwind有很多个实现,比如gnu的libunwind, path64的libunwind,还有libcxxabi自带的Unwinder.

这里作下说明:

1),gnu的libunwind会有符号缺失和冲突。

2),libcxxabi自带的Unwinder是给mac和ios用的,也就是只能在darwin体系构建。目前Linux的实现仍然不全,等linux实现完整了或许就不再需要path64的unwind实现了。

暂时建议使用pathscale的unwind实现。

mkdir -p build
cd build
cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_C_FLAGS="-m64" ..
ninja

mkdir -p /usr/lib
cp src/libunwind.so /usr/lib
cp src/libunwind.a /usr/lib
3.2 第一次构建libcxx.

必须先构建一次libcxx,以便后面构建libcxxabi。这里构建的libcxx实际上是使用gcc的libgcc/stdc++/supc++的。

打上这个补丁来禁止libgcc的引入:

diff -Nur libcxx/cmake/config-ix.cmake libcxxn/cmake/config-ix.cmake
--- libcxx/cmake/config-ix.cmake 2014-06-25 06:57:50.000000000 +0800
+++ libcxxn/cmake/config-ix.cmake 2014-06-25 09:05:24.980350544 +0800
@@ -28,5 +28,4 @@
check_library_exists(c printf "" LIBCXX_HAS_C_LIB)
check_library_exists(m ccos "" LIBCXX_HAS_M_LIB)
check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB)
-check_library_exists(gcc_s __gcc_personality_v0 "" LIBCXX_HAS_GCC_S_LIB)
编译安装:

mkdir build
cd build
cmake \
-G Ninja \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_C_COMPILER=clang \
-DCMAKE_CXX_COMPILER=clang++ \
..
ninja
ninja install
3.3,测试第一次构建的libcxx。

使用"clang++ -stdlib=libc++ -o test test.cpp -lstdc++"编译简单c++代码,检查是否出错。(如果前面构建clang是已经apply了c++abi的链接补丁,这里会出现找不到c++abi的情况,跳过即可)

使用"ldd test"查看test二进制动态库使用情况。可以发现,test依赖于libgcc_s/libc++/libstdc++。(多少有些不爽了吧?使用了libc++居然还要依赖libstdc++?)

Ⅳ llvm怎样将中间代码编译为可执行二进制文件

预编译。编译器将你的.c、.cpp源代码,通过解释其中的预编译指令,将源代码转换成相应的没有任何预编译指令的代码。

编译、优化。将上一步的代码编译成汇编指令,并作一定优化,形成对应的.s汇编代码
汇编。将.s文件汇编成机器码,形成对应的.o目标文件,此时是不可执行的二进制文件。生成对应的清单文件。为了连接需要,还会生成未定向符号表、导出符号表、地址重定向表等等。
连接。先根据对应的清单文件、连接文件及之间的调用关系,决定所有的目标文件及引用的库文件在最后可执行文件中的位置;然后做一些其他事情,比如根据符号表等将目标文件中的符号地址补全等等;最终得到可执行文件。
这只是我个人的简单理解,更详尽的解答都可以写成好几本书了=_=望采纳~

Ⅳ 有没有办法用Clang/LLVM编译Linux内核

内核,是一个操作系统的核心。它负责管理系统的进程、内存、设备驱动程序、文件和网络系统,决定着系统的性能和稳定性。Linux作为一个自由软件,
在广大爱好者的支持下,内核版本不断更新。新的内核修订了旧内核的bug,并增加了许多新的特性。如果用户想要使用这些新特性,或想根据自己的系统度身定
制一个更高效,更稳定的内核,就需要重新编译内核。本文将以RedHat Linux 6.0(kernel
2.2.5)为操作系统平台,介绍在Linux上进行内核编译的方法。

Ⅵ 怎么用llvm编译器编写c语言

LLVM的帮助。对于这个工具,我不知道改怎么去形容它,但是他给我的这个编译器的确带... 我们使用的工具是基于C/...LLVM是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-tim...

Ⅶ Gcc和llvm编译器有什么区别,我这配置哪个快

LLVM与GCC在三段式架构上并没有本质区别。LLVM与其它编译器最大的差别是,它不仅仅是Compiler Collection,也是Libraries Collection。举个例子,假如说我要写一个XYZ语言的优化器,我自己实现了PassXYZ算法,用以处理XYZ语言与其它语言差别最大的地方。而LLVM优化器提供的PassA和PassB算法则提供了XYZ语言与其它语言共性的优化算法。那么我可以选择XYZ优化器在链接的时候把LLVM提供的算法链接进来。LLVM不仅仅是编译器,也是一个SDK。

热点内容
c语言和vc的区别 发布:2024-11-15 16:19:23 浏览:118
linux是免费的吗 发布:2024-11-15 15:53:44 浏览:616
多控存储 发布:2024-11-15 15:52:42 浏览:282
一年级数学分解算法 发布:2024-11-15 15:41:08 浏览:410
安卓个人热点怎么分享 发布:2024-11-15 15:40:16 浏览:263
垫钱解压 发布:2024-11-15 15:38:54 浏览:335
miui4相当于安卓什么系统 发布:2024-11-15 15:37:54 浏览:708
rc4android 发布:2024-11-15 15:27:25 浏览:741
电脑服务器机箱图片 发布:2024-11-15 15:27:18 浏览:114
网页缓存文件提取 发布:2024-11-15 15:24:42 浏览:144