LLVM初步上手,使用Release版进行安装直接命令行调用。
确保环境正常,新打开一个cmd,如下:
clang :完成生成目标文件(.o)部分。
ld.lld :根据具体的环境路径,链接生成可执行目标文件(a.out)。
window下交叉编译arm-linux的hello程序
window下交叉编译x86-linux的hello程序
简单的三个源文件:
hello.c
#include "hello.h"
void hello_1()
{
printf("hello 1++++++++++++++++++++++++\n");
}
hello.h
#ifndef __HELLO_H
#define __HELLO_H
#include
void hello_1();
#endif
test.c
#include "hello.h"
int main()
{
hello_1();
printf("成功\n");
}
然后就开始吧。
由于之前已经使用了Linaro的交叉编译工具链进行编译,我直接使用该环境。(如果是自己搭建的话,可以参考下面的x86-linux)
linaro的安装文件夹:
该格式使用固定的hf后缀,即(hard-float,其头文件环境没有关于soft-float的,这个会有一个参数在下面)
第一步:生成目标文件(.o)
生成hello.o:
clang --target=arm-linux-guneabi -mfloat-abi=hard -I D:\Linaro\gcc-linaro-arm-linux-gnueabihf-4.9-2014.07\arm-linux-gnueabihf\libc\usr\include -c hello.c
这一步比较简单,主要要主要几个关键参数的设置:
--target=arm-linux-guneabi:该参数是必须的,需要指明目标的信息,格式是固定的。
-mfloat-abi=hard:该参数与我目前的环境是对应的,不添加会找不到所需的头文件,所以默认大概是soft.
-I /path/include:该参数是必须的,需要添加头文件的搜索路径。
生成test.o:
clang --target=arm-linux-guneabi -mfloat-abi=hard -I D:\Linaro\gcc-linaro-arm-linux-gnueabihf-4.9-2014.07\arm-linux-gnueabihf\libc\usr\include -c test.c
第二步:生成可执行文件(a.out)
这一步比较复杂,花费我比较多的时间,主要是命令编辑时比较头晕。
目前成功的命令如下:
ld.lld --sysroot=d:\linaro\gcc-linaro-arm-linux-gnueabihf-4.9-2014.07\bin\../arm-linux-gnueabihf/libc --build-id --eh-frame-hdr -dynamic-linker /lib/ld-linux-armhf.so.3 -X -m armelf_linux_eabi d:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../arm-linux-gnueabihf/libc/usr/lib/arm-linux-gnueabihf/crt1.o d:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../arm-linux-gnueabihf/libc/usr/lib/arm-linux-gnueabihf/crti.o d:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../lib/gcc/arm-linux-gnueabihf/4.9.1/crtbegin.o -Ld:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../lib/gcc/arm-linux-gnueabihf/4.9.1 -Ld:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../lib/gcc/arm-linux-gnueabihf -Ld:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../lib/gcc -Ld:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../lib/gcc/arm-linux-gnueabihf/4.9.1/../../../../arm-linux-gnueabihf/lib -Ld:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../arm-linux-gnueabihf/libc/lib/arm-linux-gnueabihf -Ld:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../arm-linux-gnueabihf/libc/lib -Ld:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../arm-linux-gnueabihf/libc/usr/lib/arm-linux-gnueabihf -Ld:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../arm-linux-gnueabihf/libc/usr/lib test.o hello.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed d:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../lib/gcc/arm-linux-gnueabihf/4.9.1/crtend.o d:/linaro/gcc-linaro-arm-linux-gnueabihf-4.9-2014.07/bin/../arm-linux-gnueabihf/libc/usr/lib/arm-linux-gnueabihf/crtn.o
该链接过程个人是参考了编译程序时使用 -v打印的编译信息,具体含义将以我目前的理解说明:
--sysroot=XXX:为编译时指定目录,个人感觉是为了动态链接时提供一个相对的概念,后续理解加深再说。
--build-id :该参数是生成buid-id,但是有些情况并没有生成,判断是我在linux中使用file a.out中并没有id信息,但是该id信息并不影响使用,如果--build-id=sha1指定就会出现,作用再说。
--eh-frame-hdr:未知
-dynamic-linker /lib/ld-linux-armhf.so.3:指定动态链接器。ld-linux-armhf.so.3这个是动态链接器的运行时的组件,它定位应用程序使用的动态库并将其加载到内存中。不添加的话个人测试会在运行时出现段错误。
-X:未知
-m armelf_linux_eabi:指定目标平台,不写好像也可以。
crt1.o, crti.o, crtbegin.o:启动、初始化、构造
-L path:指定window本地搜索动态库的路径。
test.o hello.o:所有的目标文件。
-lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed:目前看是固定的写法,但是这些库需要在之前的-L指定的路径中可以找到。
crtend.o, crtn.o:析构、结束。
环境搭建:
这里大概要明白,这个环境是我们交叉编译的代码所需的头文件目录,链接时需要的动态库目录等。
这里我十分傻地将linux的/lib和/usr两个文件夹拷贝到了window中!大概几个G,所需的应该没有那么多,先测试哈。从linux拷贝到window也不是那么简单的,如软连接都是自动消失的。window中大概没有软连接的概念,也许是快捷方式的等价?这里没有去探寻。而没有软连接是有可能出问题的。例如个人测试,在指定链接器模块时,ld-linux.so.2并没有找到!经过查询发现linux是有这么一个软连接的,连接到的是ld-2.24.so上,这里我目前的处理是拷贝一份,将名称修改为ld-linux.so.2,与对应的linux环境中一致。除了这一个libc.so.6也是相同的情况,同样操作即可。
第一步:生成目标文件(.o)
生成hello.o:
clang --target=i586-linux-guneabi -I D:\usr\include -I D:\usr\include\i386-linux-gnu -c hello.c
与arm是一致的说明,同样方式生成test.o
第二步:生成可执行文件(a.out)
ld.lld --sysroot=D:\ --build-id --eh-frame-hdr -m elf_i386 --hash-style=gnu -dynamic-linker /lib/ld-linux.so.2 D:\usr\lib\i386-linux-gnu\crt1.o D:\usr\lib\i386-linux-gnu\crti.o D:\usr\lib\gcc/i586-linux-gnu\4.9\crtbegin.o -LD:\usr\lib\gcc\i586-linux-gnu\4.9 -LD:\usr\lib\i386-linux-gnu test.o hello.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed D:\usr\lib\gcc\i586-linux-gnu\4.9\crtend.o D:\usr\lib\i386-linux-gnu\crtn.o
格式与arm大概是一致的。
运行也是成功的。
最后就是要进行删减不需要的一些文件。这里也只是测试简单的程序,更多测试后续有的话就添加。