【米尔 NXP i.MX93 开发板评测】buildroot交叉编译实践
本帖最后由 小麦克 于 2024-8-14 16:30 编辑# buildroot交叉编译实践
`buildroot`用来作为嵌入式linux系统开发还是非常方便的,编译器配置为`buildroot`自动生成。
`uboot`和`linux`内核采用开发板自带的。通过`buildroot`制作`rootfs`,然后再使用`buildroot`制作交叉编译的环境。这个环境中包含了我们之前加入的库,我们开发新的app就可以交叉编译并链接。
## 编译
当前的`buildroot`配置如下(保存为myirdeconfig放到`configs`目录)
```bash
BR2_aarch64=y
BR2_cortex_a55=y
BR2_ARM_FPU_VFPV4D16=y
BR2_KERNEL_HEADERS_6_1=y
BR2_PACKAGE_GLIBC_UTILS=y
BR2_TOOLCHAIN_BUILDROOT_CXX=y
BR2_PACKAGE_HOST_GDB=y
BR2_INIT_SYSTEMD=y
BR2_SYSTEM_DHCP="eth0"
BR2_SYSTEM_DEFAULT_PATH="/bin:/sbin:/usr/bin:/usr/sbin"
BR2_PACKAGE_ALSA_UTILS=y
BR2_PACKAGE_ALSA_UTILS_ALSACONF=y
BR2_PACKAGE_ALSA_UTILS_ACONNECT=y
BR2_PACKAGE_ALSA_UTILS_ALSALOOP=y
BR2_PACKAGE_ALSA_UTILS_ALSAUCM=y
BR2_PACKAGE_ALSA_UTILS_ALSATPLG=y
BR2_PACKAGE_ALSA_UTILS_AMIDI=y
BR2_PACKAGE_ALSA_UTILS_AMIXER=y
BR2_PACKAGE_ALSA_UTILS_APLAY=y
BR2_PACKAGE_ALSA_UTILS_APLAYMIDI=y
BR2_PACKAGE_ALSA_UTILS_ARECORDMIDI=y
BR2_PACKAGE_ALSA_UTILS_ASEQDUMP=y
BR2_PACKAGE_ALSA_UTILS_ASEQNET=y
BR2_PACKAGE_ALSA_UTILS_BAT=y
BR2_PACKAGE_ALSA_UTILS_IECSET=y
BR2_PACKAGE_ALSA_UTILS_SPEAKER_TEST=y
BR2_PACKAGE_FFMPEG_GPL=y
BR2_PACKAGE_FFMPEG_NONFREE=y
BR2_PACKAGE_FFMPEG_FFPLAY=y
BR2_PACKAGE_FFMPEG_FFPROBE=y
BR2_PACKAGE_FFMPEG_POSTPROC=y
BR2_PACKAGE_FLAC=y
BR2_PACKAGE_GSTREAMER1=y
BR2_PACKAGE_GSTREAMER1_CHECK=y
BR2_PACKAGE_GST1_PLUGINS_BASE_PLUGIN_APP=y
BR2_PACKAGE_GST1_PLUGINS_BAYER2RGB_NEON=y
BR2_PACKAGE_GST1_PLUGINS_GOOD=y
BR2_PACKAGE_GST1_LIBAV=y
BR2_PACKAGE_VLC=y
BR2_PACKAGE_TREE=y
BR2_PACKAGE_MMC_UTILS=y
BR2_PACKAGE_LIBPJSIP=y
BR2_PACKAGE_DHCPCD=y
BR2_PACKAGE_FREESWITCH=y
BR2_PACKAGE_OPENSSH=y
BR2_PACKAGE_TCPDUMP=y
BR2_PACKAGE_VSFTPD=y
BR2_PACKAGE_UTIL_LINUX_LIBFDISK=y
BR2_PACKAGE_UTIL_LINUX_HWCLOCK=y
BR2_PACKAGE_UTIL_LINUX_KILL=y
BR2_PACKAGE_UTIL_LINUX_LSFD=y
BR2_PACKAGE_UTIL_LINUX_MORE=y
BR2_TARGET_ROOTFS_EXT2=y
BR2_TARGET_ROOTFS_EXT2_SIZE="256M"
BR2_TARGET_ROOTFS_TAR_GZIP=y
BR2_PACKAGE_HOST_ENVIRONMENT_SETUP=y
```
注意这里打开了 `BR2_PACKAGE_HOST_ENVIRONMENT_SETUP` ,有了这个配置会生成`output/host/environment-setup`脚本,执行`source`命令即可当前开发环境设置为交叉编译,跨平台的`cmake`也搞好了,非常的方便。
配置并编译,等待编译成功
```bash
make myirdeconfig
make
# 将当前的环境设置为交叉编译
source output/host/environment-setup
# 测试一下变量
$ echo $CC
aarch64-buildroot-linux-gnu-gcc
```
可以大概看一下`environment-setup`脚本为我们做的事情。导出了很多变量,还有`configure`和`cmake`别名
编译`cmake`工程时,交叉编译配置都省了
```bash
cat <<'EOF'
_ _ _ _ _
| |___ _(_) | __| |_ __ ___ ___ | |_
| '_ \| | | | | |/ _` | '__/ _ \ / _ \| __|
| |_) | |_| | | | (_| | | | (_) | (_) | |_
|_.__/ \__,_|_|_|\__,_|_|\___/ \___/ \__|
Making embedded Linux easy!
Some tips:
* PATH now contains the SDK utilities
* Standard autotools variables (CC, LD, CFLAGS) are exported
* Kernel compilation variables (ARCH, CROSS_COMPILE, KERNELDIR) are exported
* To configure do "./configure $CONFIGURE_FLAGS" or use
the "configure" alias
* To build CMake-based projects, use the "cmake" alias
EOF
if [ x"$BASH_VERSION" != x"" ] ; then
SDK_PATH=$(dirname $(realpath "${BASH_SOURCE}"))
elif [ x"$ZSH_VERSION" != x"" ] ; then
SDK_PATH=$(dirname $(realpath $0))
else
echo "unsupported shell"
fi
export "AR=aarch64-buildroot-linux-gnu-gcc-ar"
export "AS=aarch64-buildroot-linux-gnu-as"
export "LD=aarch64-buildroot-linux-gnu-ld"
export "NM=aarch64-buildroot-linux-gnu-gcc-nm"
export "CC=aarch64-buildroot-linux-gnu-gcc"
export "GCC=aarch64-buildroot-linux-gnu-gcc"
export "CPP=aarch64-buildroot-linux-gnu-cpp"
export "CXX=aarch64-buildroot-linux-gnu-g++"
export "FC=aarch64-buildroot-linux-gnu-gfortran"
export "F77=aarch64-buildroot-linux-gnu-gfortran"
export "RANLIB=aarch64-buildroot-linux-gnu-gcc-ranlib"
export "READELF=aarch64-buildroot-linux-gnu-readelf"
export "STRIP=aarch64-buildroot-linux-gnu-strip"
export "OBJCOPY=aarch64-buildroot-linux-gnu-objcopy"
export "OBJDUMP=aarch64-buildroot-linux-gnu-objdump"
export "AR_FOR_BUILD=/usr/bin/ar"
export "AS_FOR_BUILD=/usr/bin/as"
export "CC_FOR_BUILD=/usr/bin/gcc"
export "GCC_FOR_BUILD=/usr/bin/gcc"
export "CXX_FOR_BUILD=/usr/bin/g++"
export "LD_FOR_BUILD=/usr/bin/ld"
export "CPPFLAGS_FOR_BUILD=-I$SDK_PATH/include"
export "CFLAGS_FOR_BUILD=-O2 -I$SDK_PATH/include"
export "CXXFLAGS_FOR_BUILD=-O2 -I$SDK_PATH/include"
export "LDFLAGS_FOR_BUILD=-L$SDK_PATH/lib -Wl,-rpath,$SDK_PATH/lib"
export "FCFLAGS_FOR_BUILD="
export "DEFAULT_ASSEMBLER=aarch64-buildroot-linux-gnu-as"
export "DEFAULT_LINKER=aarch64-buildroot-linux-gnu-ld"
export "CPPFLAGS=-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64"
export "CFLAGS=-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -g0 -D_FORTIFY_SOURCE=1"
export "CXXFLAGS=-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -O2 -g0 -D_FORTIFY_SOURCE=1"
export "LDFLAGS="
export "FCFLAGS= -O2 -g0"
export "FFLAGS= -O2 -g0"
export "PKG_CONFIG=pkg-config"
export "STAGING_DIR=$SDK_PATH/aarch64-buildroot-linux-gnu/sysroot"
export "INTLTOOL_PERL=/usr/bin/perl"
export "ARCH=arm64"
export "CROSS_COMPILE=aarch64-buildroot-linux-gnu-"
export "CONFIGURE_FLAGS=--target=aarch64-buildroot-linux-gnu --host=aarch64-buildroot-linux-gnu --build=x86_64-pc-linux-gnu --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --localstatedir=/var --program-prefix="
alias configure="./configure ${CONFIGURE_FLAGS}"
alias cmake="cmake -DCMAKE_TOOLCHAIN_FILE=$SDK_PATH/share/buildroot/toolchainfile.cmake -DCMAKE_INSTALL_PREFIX=/usr"
export "PATH=$SDK_PATH/bin:$SDK_PATH/sbin:$PATH"
```
## PSJIP测试
之前在开发板上面直接编译测试`pjsip`库,这次使用`buildroot`生成的交叉编译器来编译`app`调用`pjsip`库
新建`myapp.c`
```c
#include <pjsua-lib/pjsua.h>
#include <pj/log.h>
int main()
{
pj_status_t status;
status = pjsua_create();
PJ_LOG(3,("myapp.c", "Hello PJSIP! Bye PJSIP."));
pjsua_destroy();
return 0;
}
```
相同目录新建`Makefile`文件,变量`PJDIR` 需要根据实际情况调整。
```makefile
PJDIR = /home/bruce/Documents/buildroot/buildroot-2024.05.1/output/build/libpjsip-2.14
include $(PJDIR)/build.mak
myapp: myapp.o
$(PJ_CC) -o $@ $< $(PJ_LDFLAGS) $(PJ_LDLIBS)
myapp.o: myapp.c
$(PJ_CC) -c -o $@ $< $(PJ_CFLAGS)
clean:
rm -f myapp.o myapp
```
编译
```bash
make
$ file myapp
myapp: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 6.1.0, not stripped
```
生成成功,拷贝到开发板运行测试
## 结论
如果只是简单的交叉编译不依赖第三方库的应用程序还是挺简单的,但是一旦依赖第三方库交叉编译就会有各种奇怪的问题,buildroot为我们准备了非常好用的`environment-setup`
另外还可以搞个和目标机器相同的平台来编译软件。比如新建一个`arm64`的虚拟机直接编译,或者在`arm64`物理机(树莓派5)进行编译。编译好的软件可以直接拷贝到目标机器运行。
页:
[1]