交叉编译的概念
本地编译
本地编译就是在当前的编译平台下,编译出来的程序只能在当前平台运行。常见的软件开发都属于本地编译。
例如,在x86平台使用本平台的工具开发针对平台本身的可执行程序,这个编译过程就称为本地编译。
交叉编译
与本地编译相对应的,交叉编译就是在当前平台下编译出来的程序能运行在架构不同的另一目标平台上,而进行编译的平台本身却不能运行该程序。
例如,在x86平台可以使用工具编译出能运行在基于ARM架构平台的程序,但编译得到的程序却不能在x86平台运行,必须在基于ARM架构的平台上才能运行。
交叉编译的实现(以Ubuntu20.04操作系统为例)
x86平台实现ARM平台的交叉编译
-
安装交叉编译工具
$ sudo apt install gcc-arm-linux-gnueabi
-
安装完成后,使用如下指令查看软件版本
$ arm-linux-gnueabi-gcc -v
屏幕输出如下内容,则说明软件安装成功(不同的软件版本可能有不同的输出内容)
Using built-in specs. COLLECT_GCC=arm-linux-gnueabi-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/arm-linux-gnueabi/9/lto-wrapper Target: arm-linux-gnueabi Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.2' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libitm --disable-libquadmath --disable-libquadmath-support --enable-plugin --with-system-zlib --without-target-system-zlib --enable-libpth-m2 --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-specs='%{mfloat-abi=hard:-march=armv7-a -mcpu=generic-armv7-a -mfloat-abi=hard}' --with-arch=armv5t --with-float=soft --disable-werror --enable-multilib --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=arm-linux-gnueabi --program-prefix=arm-linux-gnueabi- --includedir=/usr/arm-linux-gnueabi/include Thread model: posix gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)
-
使用arm-linux-gnueabi-gcc进行交叉编译
$ arm-linux-gnueabi-gcc <filename>.c -o <output filename>
注:所有gcc支持的选项,arm-linux-gnueabi-gcc均支持(至少-g、-D、-O2、-Wall、-o、-L可以支持),且使用规则均相同
例如,将hw.c以交叉编译的方式生成ARM架构下的helloworld可执行文件,应使用如下的指令(假定所有文件均位于当前文件目录下):
$ arm-linux-gnueabi-gcc hw.c -o helloworld
-
查看经交叉编译得到的文件信息
通过上述方式编译得到的程序无法在x86平台上运行,如果尝试执行则会报错。
以上面生成的helloworld程序为例,如果尝试运行其:
$ ./helloworld
则会有如下的错误提示:
bash: ./helloworld:无法执行二进制文件: 可执行文件格式错误
此时使用file指令查看helloworld的文件信息
$ file helloworld
发现该文件为ARM架构下的文件
helloworld: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, BuildID[sha1]=53396c2942e52c35c256b42b158960e0a0ba4d3b, for GNU/Linux 3.2.0, not stripped
x86平台实现ARM64位平台的交叉编译
-
安装交叉编译工具
$ sudo apt-get install gcc-aarch64-linux-gnu
-
安装完成后,使用如下指令查看软件版本
$ aarch64-linux-gnu-gcc -v
屏幕输出如下内容,则说明软件安装成功(不同的软件版本可能有不同的输出内容)
Using built-in specs. COLLECT_GCC=aarch64-linux-gnu-gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc-cross/aarch64-linux-gnu/9/lto-wrapper Target: aarch64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.2' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-libquadmath --disable-libquadmath-support --enable-plugin --enable-default-pie --with-system-zlib --without-target-system-zlib --enable-libpth-m2 --enable-multiarch --enable-fix-cortex-a53-843419 --disable-werror --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=aarch64-linux-gnu --program-prefix=aarch64-linux-gnu- --includedir=/usr/aarch64-linux-gnu/include Thread model: posix gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.2)
-
使用aarch64-linux-gnu-gcc进行交叉编译
$ aarch64-linux-gnu-gcc <filename>.c -o <output filename>
注:所有gcc支持的选项,aarch64-linux-gnu-gcc均支持(至少-g、-D、-O2、-Wall、-o、-L可以支持),且使用规则均相同
例如,将hw.c以交叉编译的方式生成ARM64位架构下的helloworld可执行文件,应使用如下的指令(假定所有文件均位于当前文件目录下):
$ aarch64-linux-gnu-gcc hw.c -o helloworld_arm64
-
查看经交叉编译得到的文件信息
通过上述方式编译得到的程序无法在x86平台上运行,如果尝试执行则会报错。
以上面生成的helloworld_arm64程序为例,如果尝试运行其:
$ ./helloworld_arm64
则会有如下的错误提示:
bash: ./helloworld_arm64:无法执行二进制文件: 可执行文件格式错误
此时使用file指令查看helloworld_arm64的文件信息
$ file helloworld_arm64
发现该文件为ARM64位架构下的文件
helloworld_arm64: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=915f36d57a3a1dbf3368a3b165ec0834cf85b846, for GNU/Linux 3.7.0, not stripped