目录
前言
在Linux下,我们习惯了使用gcc、g++或其它交叉编译工具链,对C/C++应用程序进行编译。但是,在鸿蒙系统设备开发指导文档中,我们发现编写1个“Hello World”应用程序,是通过编辑BUILD.gn文件,与完整的鸿蒙系统全套代码一起整体编译打包的,整个流程耗时很长,耦合性太高。
因此,本文将详细解析鸿蒙设备开发中的代码编译原理,将代码编译和鸿蒙源码编译解耦,达到Linux下编译的效果,并提供一些第三方库交叉编译的案例,例如libcurl、openssl库等
一、编译原理
1、编译解析
在Linux下将hello.c编译成可执行文件,在控制台中执行下面命令:
gcc hello.c -o hello
看似一条简单的命令,实际上编译工具隐藏了很多信息,我们可以在编译命令中多加一个`-v`, 也就是`gcc hello.c -o hello -v`, 它会把编译时使用的全部选项都打印出来:
通过打印信息可知,gcc编译工具实际上是另外一个编译工具文件,并且编译的时候后面添加了很多参数,如:编译的目标系统 'Target: x86_64-linux-gnu' 、cpu架构 '-march=x86-64'
查看一下gcc到底是什么,输入:
ls -l /usr/bin/gcc*
可知,gcc或g++实际上也是指向某个交叉编译工具链的软连接。
由此,可以想到,只要我们找到一个类似于gcc的编译工具,再在编译的时候指定一些链接参数,就可以为鸿蒙系统的编译各种应用了。
2、Clang/LLVM开源编译器工具链
在后来的开发中,通过各种打印信息,发现鸿蒙系统下使用BUILD.gn配置文件对应用进行打包编译,使用了clang这个编译工具对代码进行编译,那么clang是什么东西呢?
Clang/LLVM是一套开源的编译器工具链,用于开发编译器前端、后端、运行时及相关工具。Clang是LLVM项目的一部分,用以作为C、C++、Objective-C等语言的编译器前端,而LLVM则主要提供后端技术,可广泛应用于Windows、Linux、macOS、iOS、Android、ARM-Linux等平台。
Clang设计目标是提供一个基于LLVM的高性能、易于使用且具有出色诊断(错误与警告信息)和GCC兼容性的编译器。Clang的一大特点是它的模块化设计,允许它被用在多种不同的情境中,比如作为IDE的代码分析工具。
LLVM(Low Level Virtual Machine)是一个编译器基础设施,提供了一套完整的编译器组件。LLVM定义了一个中间表示(IR)语言,并提供了生成和优化IR的工具。IR是一个与硬件无关的指令集,允许编译器先将程序源码编译成IR,然后LLVM可以将IR优化和转换成针对不同机器目标平台的机器码。
在使用Clang/LLVM编译器的时候 ,通过设定一些编译器的链接参数,就能将代码编译成目标平台上的代码,可也不是什么目标都支持,就比如OpenHarmony是一个新的操作系统,官方的Clang/LLVM就暂时还不支持,所以,我们不能用apt-get下载官方版Clang/LLVM来编译,必须用鸿蒙代码路径下的Clang/LLVM版本,这是华为公司为了OpenHarmony而特殊定制的Clang/LLVM版本,
二、鸿蒙clang交叉编译应用(编译解耦)
1、clang交叉编译hello.c示例
鸿蒙代码路径下的Clang/LLVM版本,安装在OpenHarmony源码路径的prebuilts下,查看clang的版本信息:
/home/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang -v
从打印信息中,可知clang安装目录和当前clang依赖的gcc版本。
Clang在设计的时候,为了兼顾gcc使用者的使用习惯,继承了gcc绝大部分选项习惯,你几乎可以将gcc全套命令照搬过来,只是把gcc换成clang命令,再加上一些编译链参数即可,如下:
(1)设置"--target"选项,指定为"--target=arm-linux-ohos"
(2)设置"--sysroot"选项,用于指定编译器在编译某个芯片开发板过程中所使用的标准库和头文件所在的目录, 在OpenHarmony源码执行过某个开发板完整编译后的编译输出路径中找到这个目录(out/目录下)
(3)其它链接器的相关设置:
浮点运算,比如 "-mfloat-abi=softfp”;
cpu类型,比如 ”-mcpu=cortex-a55“ ;(也可不设)
处理器架构,比如 ”-march=armv7-a“ ;(也可不设)
...
例如:为RK3568开发板的鸿蒙系统编译hello.c
/home/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm/bin/clang \ -o hello hello.c -Wall \ --target=arm-linux-ohos \ --sysroot=/home/openharmony/out/rk3568/obj/third_party/musl \ -march=armv7-a -mfloat-abi=softfp
file指令可查看编译出来的可执行文件格式:
file hello
2、clang交叉编译C/C++项目Makefile示例
Makefile:
################################################# #description: OpenHarmony make c/c++ #author: zyh #date: 2023-11-17 ################################################# OHOS_TOOLCHAIN:=/home/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm OHOS_SYSROOT_RK3568:=/home/openharmony/out/rk3568/obj/third_party/musl CC:=$(OHOS_TOOLCHAIN)/bin/clang CXX:=$(OHOS_TOOLCHAIN)/bin/clang++ AR:=$(OHOS_TOOLCHAIN)/bin/llvm-ar AS:=$(OHOS_TOOLCHAIN)/bin/llvm-as NM:=$(OHOS_TOOLCHAIN)/bin/llvm-nm STRIP:=$(OHOS_TOOLCHAIN)/bin/llvm-strip RANLIB:=$(OHOS_TOOLCHAIN)/bin/llvm-ranlib LD:=$(OHOS_TOOLCHAIN)/bin/ld.lld LDFLAGS:="--rtlib=compiler-rt -fuse-ld=lld" #OHOS_CFLAGS_RK3568:= --target=arm-linux-ohos --sysroot=$(OHOS_SYSROOT_RK3568) -march=armv7-a -mfloat-abi=softfp -mcpu=cortex-a55 -mfpu=neon OHOS_CFLAGS_RK3568:= --target=arm-linux-ohos --sysroot=$(OHOS_SYSROOT_RK3568) -march=armv7-a -mfloat-abi=softfp TARGET=test_app SRC_DIR:= . src SRC_DIR+= INC_DIR:= $(SRC_DIR) SRCS:= $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.c)) SRCS+= $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.cpp)) INCS:= $(addprefix -I ,$(INC_DIR)) OBJS:= $(SRCS:.c=.o) OBJS:= $(OBJS:.cpp=.o) #CFLAGS:= -Wall -D_RK3568_OHOS CFLAGS:= -Wall LIBS:= -lpthread #LIBS+= -L libs_ohos/ all: $(TARGET) %.o: %.c $(CC) -c $< -o $@ $(INCS) $(CFLAGS) $(OHOS_CFLAGS_RK3568) %.o: %.cpp $(CXX) -c $< -o $@ $(INCS) $(CFLAGS) $(OHOS_CFLAGS_RK3568) $(TARGET): $(OBJS) $(CC) -o $@ $^ $(LIBS) $(OHOS_CFLAGS_RK3568) clean: rm -f $(OBJS) $(TARGET)
3、打包迁移clang编译工具和sysroot到别的服务器
根据上述的编译过程,我们可知,编译只需要依赖clang编译工具和sysroot文件,那么将鸿蒙源码下的clang编译工具和out目录下相关开发板的sysroot目录打包迁移到别的linux服务器上,我们照样可以编译,打包指令如下:
cd /home/openharmony tar -zcf rk_ohos_cross.tar.gz prebuilts/clang/ohos/linux-x86_64/llvm out/rk3568/obj/third_party/musl
压缩文件放到其它linux服务器的某个目录下,解压即可:
tar -zxf rk_ohos_cross.tar.gz
三、鸿蒙第三方库交叉编译
1、编译zlib
- 下载源码
wget https://zlib.net/current/zlib.tar.gz tar -zxf zlib.tar.gz cd zlib-1.3/ mkdir my_build
- 鸿蒙系统开发编译环境下(建议使用官方docker容器),为rk3568开发板编译:
#配置环境变量:路径需根据实际修改 //OHOS_TOOLCHAIN:是clang编译工具的实际路径 //OHOS_SYSROOT:绝对路径,用于指定编译器在编译某个芯片开发板过程中所使用的标准库和头文件所在的目录, 在OpenHarmony源码执行过完整编译后的编译输出路径中找到这个目录(out/..) export OHOS_TOOLCHAIN=/home/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm export OHOS_SYSROOT=/home/openharmony/out/rk3568/obj/third_party/musl export CC=${OHOS_TOOLCHAIN}/bin/clang export CPP=${OHOS_TOOLCHAIN}/bin/clang++ export AR=${OHOS_TOOLCHAIN}/bin/llvm-ar export AS=${OHOS_TOOLCHAIN}/bin/llvm-as export NM=${OHOS_TOOLCHAIN}/bin/llvm-nm export STRIP=${OHOS_TOOLCHAIN}/bin/llvm-strip export RANLIB=${OHOS_TOOLCHAIN}/bin/llvm-ranlib export LD=${OHOS_TOOLCHAIN}/bin/ld.lld export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld" export CFLAGS="--target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp" #编译安装,指定安装路径(prefix) ./configure --prefix=$(pwd)/my_build make -j4 make install
2、编译openssl
- 下载源码
wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz tar -xvf openssl-1.1.1a.tar.gz cd openssl-1.1.1a/ mkdir my_build
- 鸿蒙系统开发编译环境下(建议使用官方docker容器),为rk3568开发板编译:
#配置环境变量:路径需根据实际修改 //OHOS_TOOLCHAIN:是clang编译工具的实际路径 //OHOS_SYSROOT:绝对路径,用于指定编译器在编译某个芯片开发板过程中所使用的标准库和头文件所在的目录, 在OpenHarmony源码执行过完整编译后的编译输出路径中找到这个目录(out/..) export OHOS_TOOLCHAIN=/home/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm export OHOS_SYSROOT=/home/openharmony/out/rk3568/obj/third_party/musl export CC=${OHOS_TOOLCHAIN}/bin/clang export CXX=${OHOS_TOOLCHAIN}/bin/clang++ export AR=${OHOS_TOOLCHAIN}/bin/llvm-ar export AS=${OHOS_TOOLCHAIN}/bin/llvm-as export NM=${OHOS_TOOLCHAIN}/bin/llvm-nm export STRIP=${OHOS_TOOLCHAIN}/bin/llvm-strip export RANLIB=${OHOS_TOOLCHAIN}/bin/llvm-ranlib export LD=${OHOS_TOOLCHAIN}/bin/ld.lld export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld" export CFLAGS="--target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp" #编译安装到指定目录(--prefix) #./Configure linux-aarch64 --prefix=$(pwd)/my_build no-asm shared ./Configure linux-armv4 --prefix=$(pwd)/my_build no-asm shared make clean make -j4 make install
3、编译mosquitto(mqtt)
- 下载源码
wget https://mosquitto.org/files/source/mosquitto-1.6.9.tar.gz tar xzvf mosquitto-1.6.9.tar.gz cd mosquitto-1.6.9/ mkdir my_build
修改成自己的安装路径:
vim config.mk
- 鸿蒙系统开发编译环境下(建议使用官方docker容器),为rk3568开发板编译:
#配置环境变量:路径需根据实际修改 //OHOS_TOOLCHAIN:是clang编译工具的实际路径 //OHOS_SYSROOT:绝对路径,用于指定编译器在编译某个芯片开发板过程中所使用的标准库和头文件所在的目录, 在OpenHarmony源码执行过完整编译后的编译输出路径中找到这个目录(out/..) export OHOS_TOOLCHAIN=/home/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm export OHOS_SYSROOT=/home/openharmony/out/rk3568/obj/third_party/musl export CC=${OHOS_TOOLCHAIN}/bin/clang export CXX=${OHOS_TOOLCHAIN}/bin/clang++ export AR=${OHOS_TOOLCHAIN}/bin/llvm-ar export AS=${OHOS_TOOLCHAIN}/bin/llvm-as export NM=${OHOS_TOOLCHAIN}/bin/llvm-nm export STRIP=${OHOS_TOOLCHAIN}/bin/llvm-strip export RANLIB=${OHOS_TOOLCHAIN}/bin/llvm-ranlib export LD=${OHOS_TOOLCHAIN}/bin/ld.lld unset CFLAGS unset CPPFLAGS unset LDFLAGS #编译安装,需指定openssl头文件和库路径 make clean make WITH_SRV=no \ CFLAGS="--target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp -I/home/openharmony/samples/sutpc_project/openssl-1.1.1a/my_build/include" \ CPPFLAGS="--target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp -I/home/openharmony/samples/sutpc_project/openssl-1.1.1a/my_build/include" \ LDFLAGS="--target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp --rtlib=compiler-rt -fuse-ld=lld -L/home/openharmony/samples/sutpc_project/openssl-1.1.1a/my_build/lib -lssl -lcrypto" make install
4、编译libevent
4.1 下载源码
也可手动去官网下载:https://libevent.org
wget https://github.com/libevent/libevent/releases/download/release-2.1.12-stable/libevent-2.1.12-stable.tar.gz tar -zxf libevent-2.1.12-stable.tar.gz cd libevent-2.1.12-stable/ mkdir my_build
4.2 交叉编译
鸿蒙系统开发编译环境下(建议使用官方docker容器),为rk3568开发板编译
如果不需要openssl,完整编译指令:
#配置环境变量:路径需根据实际修改 //OHOS_TOOLCHAIN:是clang编译工具的实际路径 //OHOS_SYSROOT:绝对路径,用于指定编译器在编译某个芯片开发板过程中所使用的标准库和头文件所在的目录, 在OpenHarmony源码执行过完整编译后的编译输出路径中找到这个目录(out/..) export OHOS_TOOLCHAIN=/home/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm export OHOS_SYSROOT=/home/openharmony/out/rk3568/obj/third_party/musl export CC="${OHOS_TOOLCHAIN}/bin/clang -v" #export CXX=${OHOS_TOOLCHAIN}/bin/clang++ #export CPP=${OHOS_TOOLCHAIN}/bin/clang++ export AR=${OHOS_TOOLCHAIN}/bin/llvm-ar export AS=${OHOS_TOOLCHAIN}/bin/llvm-as export NM=${OHOS_TOOLCHAIN}/bin/llvm-nm export STRIP=${OHOS_TOOLCHAIN}/bin/llvm-strip export RANLIB=${OHOS_TOOLCHAIN}/bin/llvm-ranlib export LD=${OHOS_TOOLCHAIN}/bin/ld.lld export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld" unset CXX unset CPP export CFLAGS="-fPIC --target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp" export CPPFLAGS="-fPIC --target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp" //后续make编译提示找不到lc、lgcc、lgcc_s库等 //所以手动导入/usr目录下的库路径,需根据实际的开发板系统,选择arm gcc路径 export LIBRARY_PATH=/usr/lib/gcc-cross/arm-linux-gnueabi/7:/usr/arm-linux-gnueabi/lib #编译安装到指定目录(--prefix),暂时不考虑openssl,所以选择参数--disable-openssl ./configure --host=arm-linux \ --prefix=$(pwd)/my_build \ --disable-openssl make clean //后续make编译提示找不到 crti.o、crtbeginS.o、 crtendS.o、crtn.o //所以手动复制/usr目录下的这些文件到当前目录,需根据实际的开发板系统,选择arm gcc路径的文件 cp /usr/lib/gcc-cross/arm-linux-gnueabi/7/crtbeginS.o ./ cp /usr/lib/gcc-cross/arm-linux-gnueabi/7/crtendS.o ./ cp /usr/arm-linux-gnueabi/lib/crtn.o ./ cp /usr/arm-linux-gnueabi/lib/crti.o ./ make V=1 -j4 make install
如果需要openssl,完整编译指令:
#配置环境变量:路径需根据实际修改 //OHOS_TOOLCHAIN:是clang编译工具的实际路径 //OHOS_SYSROOT:绝对路径,用于指定编译器在编译某个芯片开发板过程中所使用的标准库和头文件所在的目录, 在OpenHarmony源码执行过完整编译后的编译输出路径中找到这个目录(out/..) export OHOS_TOOLCHAIN=/home/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm export OHOS_SYSROOT=/home/openharmony/out/rk3568/obj/third_party/musl export CC="${OHOS_TOOLCHAIN}/bin/clang -v" #export CXX=${OHOS_TOOLCHAIN}/bin/clang++ #export CPP=${OHOS_TOOLCHAIN}/bin/clang++ export AR=${OHOS_TOOLCHAIN}/bin/llvm-ar export AS=${OHOS_TOOLCHAIN}/bin/llvm-as export NM=${OHOS_TOOLCHAIN}/bin/llvm-nm export STRIP=${OHOS_TOOLCHAIN}/bin/llvm-strip export RANLIB=${OHOS_TOOLCHAIN}/bin/llvm-ranlib export LD=${OHOS_TOOLCHAIN}/bin/ld.lld //指定openssl库的路径 export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld -L/home/openharmony/samples/sutpc_project/openssl-1.1.1a/my_build/lib -lssl -lcrypto" unset CXX unset CPP //指定openssl头文件路径 export CFLAGS="-I/home/openharmony/samples/sutpc_project/openssl-1.1.1a/my_build/include -fPIC --target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp" export CPPFLAGS="-I/home/openharmony/samples/sutpc_project/openssl-1.1.1a/my_build/include -fPIC --target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp" //后续make编译提示找不到lc、lgcc、lgcc_s库等 //所以手动导入/usr目录下的库路径,需根据实际的开发板系统,选择arm gcc路径 export LIBRARY_PATH=/usr/lib/gcc-cross/arm-linux-gnueabi/7:/usr/arm-linux-gnueabi/lib #编译安装到指定目录(--prefix),暂时不考虑openssl,所以选择参数--disable-openssl ./configure --host=arm-linux \ --prefix=$(pwd)/my_build make clean //后续make编译提示找不到 crti.o、crtbeginS.o、 crtendS.o、crtn.o //所以手动复制/usr目录下的这些文件到当前目录,需根据实际的开发板系统,选择arm gcc路径的文件 cp /usr/lib/gcc-cross/arm-linux-gnueabi/7/crtbeginS.o ./ cp /usr/lib/gcc-cross/arm-linux-gnueabi/7/crtendS.o ./ cp /usr/arm-linux-gnueabi/lib/crtn.o ./ cp /usr/arm-linux-gnueabi/lib/crti.o ./ make V=1 -j4 make install
4.3 过程中出现的问题总结
make编译提示找不到lc、lgcc、lgcc_s库,crti.o、crtbeginS.o、 crtendS.o、crtn.o等:
先使用clang -v查看当前clang当前依赖系统里面的哪个gcc版本(我的是版本7):
再寻找/usr/目录下这些库的路径:
find /usr/ -name libgcc_s* find /usr/ -name libc.so*
因为当前clang依赖的是gcc 7版本,而且我们是为arm开发板编译的,所以选择arm的gcc路径
手动导入库路径:
export LIBRARY_PATH=/usr/lib/gcc-cross/arm-linux-gnueabi/7:/usr/arm-linux-gnueabi/lib
再次执行,lib库能找到了,还剩下 crti.o、crtbeginS.o、 crtendS.o、crtn.o
那么从编译器详细信息来看,是想将当前目录下的 crti.o、crtbeginS.o、 crtendS.o、crtn.o一起编译。(编译器打印详细信息:可在clang 后面加参数 clang -v, 在make 后面加参数make V=1)
再寻找/usr/目录下这些文件的路径:
find /usr/ -name crti.o find /usr/ -name crtbeginS.o
发现文件就在我们上面手动导入LIBRARY_PATH的gcc库路径里面,因此手动复制这些文件到当前目录即可。
最后执行make,还提示:
ld.lld: error: relocation R_ARM_REL32 cannot be used against symbol bufferevent_ops_filter; recompile with -fPIC
因此,我们只需要在CFLAGS后面加-fPIC参数就好了。
更新环境变量:
export CFLAGS="-fPIC --target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp" export CPPFLAGS="-fPIC --target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp"
最后,重新执行configure更新Makefile,make clean后,再次复制crtbeginS.o等文件到当前目录下,再make就通过了。
5、编译libcurl
- 下载源码
wget https://curl.haxx.se/download/curl-7.71.1.tar.gz tar -zxf curl-7.71.1.tar.gz cd curl-7.71.1 mkdir my_build
- 鸿蒙系统开发编译环境下(建议使用官方docker容器),为rk3568开发板编译:
#配置环境变量:路径需根据实际修改 //OHOS_TOOLCHAIN:是clang编译工具的实际路径 //OHOS_SYSROOT:绝对路径,用于指定编译器在编译某个芯片开发板过程中所使用的标准库和头文件所在的目录, 在OpenHarmony源码执行过完整编译后的编译输出路径中找到这个目录(out/..) export OHOS_TOOLCHAIN=/home/openharmony/prebuilts/clang/ohos/linux-x86_64/llvm export OHOS_SYSROOT=/home/openharmony/out/rk3568/obj/third_party/musl export CC=${OHOS_TOOLCHAIN}/bin/clang export AR=${OHOS_TOOLCHAIN}/bin/llvm-ar export AS=${OHOS_TOOLCHAIN}/bin/llvm-as export NM=${OHOS_TOOLCHAIN}/bin/llvm-nm export STRIP=${OHOS_TOOLCHAIN}/bin/llvm-strip export RANLIB=${OHOS_TOOLCHAIN}/bin/llvm-ranlib export LD=${OHOS_TOOLCHAIN}/bin/ld.lld export LDFLAGS="--rtlib=compiler-rt -fuse-ld=lld" unset CPP unset CXX export CFLAGS="-fPIC --target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp" export CPPFLAGS="-fPIC --target=arm-linux-ohos --sysroot=${OHOS_SYSROOT} -march=armv7-a -mfloat-abi=softfp" //后续make编译提示找不到lc、lgcc、lgcc_s库等 //所以手动导入/usr目录下的库路径,需根据实际的开发板系统,选择arm gcc路径 export LIBRARY_PATH=/usr/lib/gcc-cross/arm-linux-gnueabi/7:/usr/arm-linux-gnueabi/lib #编译安装到指定目录(--prefix),需指定openssl头文件和库路径(--with-ssl) ./configure --host=arm-linux \ --target=arm-linux-ohos \ --prefix=$(pwd)/my_build \ --with-ssl=/home/openharmony/samples/sutpc_project/openssl-1.1.1a/my_build \ --enable-shared --enable-static make clean //后续make编译提示找不到 crti.o、crtbeginS.o、 crtendS.o、crtn.o //所以手动复制/usr目录下的这些文件到当前lib/目录下,需根据实际的开发板系统,选择arm gcc路径的文件 cp /usr/lib/gcc-cross/arm-linux-gnueabi/7/crtbeginS.o lib/ cp /usr/lib/gcc-cross/arm-linux-gnueabi/7/crtendS.o lib/ cp /usr/arm-linux-gnueabi/lib/crtn.o lib/ cp /usr/arm-linux-gnueabi/lib/crti.o lib/ make -j4 make install