嵌入式 Linux 系统中的应用程序由特定的交叉编译工具链编译得到,此工具链一般由芯片原厂提供或指定,因为系统的内核、libc 等程序运行的基础环境都由该工具链编译得到,所以应用程序最好也用此工具工具链来编译;
尽管如此,依然可以使用通用的交叉编译工具链来做测试,例如在 Ubuntu 下可以安装 gcc-arm-linux-gnueabi 或 gcc-arm-linux-gnueabihf 来编译针对 ARM 芯片的程序:
sudo apt install gcc-arm-linux-gnueabihf
交叉编译方法可大致分为以下 2 种:
-
自己写的代码直接使用工具链交叉编译即可;
arm-linux-gnueabihf-gcc main.c -o main.elf
-
公开的开源程序,一般使用下面的步骤交叉编译:
./configure --prefix=$(pwd)/cross_install --host=arm-linux-gnueabihf make make install
需要注意的是:
1、有的程序在以上步骤之前,需要先调用
autogen.sh
生成configure
文件;2、执行
configure
时可以传入不同的参数,可以执行./configure -h
进行学习;3、执行
make
时也可以传入不同的参数进行交叉编译配置,可以阅读 Makefile 来了解支持的配置;
如无特别说明,下面交叉编译后生成的文件均在 cross_install 目录中,只要将该目录下的文件拷贝到嵌入式设备上对应的目录即可正常使用;
BusyBox 是一个集成了三百多个最常用 Linux 命令和工具的软件。BusyBox 包含了一些简单的工具,例如 ls、cat和echo等等,还包含了一些更大、更复杂的工具,例 grep、find、mount 以及 telnet 。有些人将 BusyBox 称为 Linux 工具里的瑞士军刀。简单的说 BusyBox 就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令,也包含了 Linux 系统的自带的 shell。
-
下载代码,并更新到最近的稳定版本:
# download_busybox.sh git clone git://git.busybox.net/busybox cd busybox git reset --hard 1_33_2
-
采用默认配置,参考 https://busybox.net/FAQ.html 和
Makefile
进行交叉编译# build_busybox.sh make defconfig make -j 4 CROSS_COMPILE=arm-linux-gnueabihf- # 以下为静态交叉编译 # LDFLAGS="--static" make -j 4 CROSS_COMPILE=arm-linux-gnueabihf- make CONFIG_PREFIX=$(pwd)/cross_install install
BusyBox 使用参考链接:BusyBox - The Swiss Army Knife of Embedded Linux
glibc 是 GNU 发布的 libc 库,即 c 运行库。glibc 是 linux 系统中最底层的 api,几乎其它任何运行库都会依赖于 glibc。glibc 除了封装 linux 操作系统所提供的系统服务外,它本身也提供了许多其它一些必要功能服务的实现。由于 glibc 囊括了几乎所有的 UNIX 通行的标准,可以想见其内容包罗万象。而就像其他的 UNIX 系统一样,其内含的档案群分散于系统的树状目录结构中,像一个支架一般撑起整个操作系统。在 GNU/Linux 系统中,其 C 函式库发展史点出了 GNU/Linux 演进的几个重要里程碑,用 glibc 作为系统的 C 函式库,是 GNU/Linux 演进的一个重要里程碑。
-
下载代码并更新到需要的版本:
# download_glibc.sh git clone https://sourceware.org/git/glibc.git && cd glibc && git reset --hard glibc-2.34 && cd -
-
交叉编译:
# build_glibc.sh cd glibc INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} BUILD_DIR=cross_build mkdir -p ${BUILD_DIR} cd ${BUILD_DIR} ../configure --prefix=$(pwd)/../${INSTALL_DIR} --host=arm-linux-gnueabihf && { if false; then make uninstall make clean fi make -j 20 make install }
GDB 或 GNU 项目调试器是 GNU 项目,用于调试应用程序并分析程序执行期间发生的情况,允许开发者查看在另一个程序执行时“内部”发生了什么——或者另一个程序在它崩溃时正在做什么。
-
下载代码并更新到需要的版本:
# download_gdb.sh # git clone git://sourceware.org/git/binutils-gdb.git # 镜像下载 git clone https://mirrors.tuna.tsinghua.edu.cn/git/binutils-gdb.git && cd binutils-gdb && git reset --hard gdb-10.2-release && cd -
-
交叉编译:
# build_gdb.sh cd binutils-gdb INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf && { if true; then make uninstall make clean fi # 根据编译环境使用并行编译加快速度 make -j20 && make install }
GDB 使用参考链接:GDB调试指南、GDB Tutorial
iw 是一个无线设备命令行配置工具,支持内核中所有基于 nl80211 的驱动程序。 旧工具 Wireless Tools for Linux(iwconfig) 已弃用,强烈建议切换到 iw。
iw 依赖 libnl 库。
-
下载代码并更新到需要的版本:
# download_iw.sh git clone git://github.com/tgraf/libnl.git && cd libnl && git reset --hard libnl3_2_25 && cd - git clone http://git.sipsolutions.net/iw.git/ && cd iw && git reset --hard v5.9 && cd -
-
交叉编译 libnl:
# build_libnl.sh cd libnl ./autogen.sh INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf && { if true; then make uninstall make clean fi make && make install }
-
交叉编译 iw
# build_iw.sh cd iw make PREFIX=./cross_install PKG_CONFIG_PATH=../libnl/cross_install/lib/pkgconfig CC=arm-linux-gnueabihf-gcc
iw 使用参考链接:Linux iw命令使用详解、replace-iwconfig Linux Wireless
WPA 是 WiFi Protected Access 的缩写,中文含义为 “ WiFi 网络安全存取 ” 。WPA 是一种基于标准的可互操作的 WLAN 安全性增强解决方案,可大大增强现有以及未来无线局域网络的数据保护和访问控制水平。
wpa_supplicant 是一个连接、配置 WIFI 的工具,它主要包含 wpa_supplicant 与 wpa_cli 两个程序。通常情况下,可以通过 wpa_cli 来进行 WIFI 的配置与连接,如果有特殊的需要,可以编写应用程序直接调用 wpa_supplicant 的接口直接开发。
wpa_supplicant 的编译依赖 openssl 和 libnl。
-
下载代码并更新到需要的版本:
# download_wpa.sh git clone git://github.com/tgraf/libnl.git && cd libnl && git reset --hard libnl3_2_25 && cd - git clone git://git.openssl.org/openssl.git && cd openssl && git reset --hard OpenSSL_1_1_1 && cd - git clone git://w1.fi/srv/git/hostap.git && cd hostap && git reset --hard hostap_2_9 && cd -
-
交叉编译 libnl
# build_libnl.sh cd libnl ./autogen.sh INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf && { if true; then make uninstall make clean fi make && make install }
-
交叉编译 openssl
# build_openssl.sh cd openssl INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./Configure linux-generic32 --prefix=$(pwd)/${INSTALL_DIR} \ -lpthread \ --cross-compile-prefix=arm-linux-gnueabihf- && { if true; then make uninstall make clean fi make depend && make && make install }
-
交叉编译 wpa_supplicant
首先,复制缺省编译配置文件
cd hostap/wpa_supplicant cp defconfig .config
接着编辑 .config 文件,加入以下配置:
# 使用 WEXT 通过 ioctl 和驱动通信,典型工具如:ifconfig CONFIG_DRIVER_WEXT=y # 使用 NL80211 通过一个特殊的 socket 和驱动通信,典型工具如:iwconfig,使能该选项时需指定 libnl 库 CONFIG_DRIVER_NL80211=y # 指定 libnl 版本及其库文件位置 CONFIG_LIBNL32=y CFLAGS += -I../../libnl/cross_install/include/libnl3/ LIBS += -L../../libnl/cross_install/lib/ # 使用 openssl 作为 TLS 加密库并指定其位置 CONFIG_TLS = openssl CFLAGS += -I../../openssl/cross_install/include/ LIBS += -L../../openssl/cross_install/lib/
并注释掉dbus相关的配置(需要的话请另外交叉编译dbus):
#CONFIG_CTRL_IFACE_DBUS_NEW=y #CONFIG_CTRL_IFACE_DBUS_INTRO=y
然后进行交叉编译:
# build_wpa.sh INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} export LIBDIR=$(pwd)/${INSTALL_DIR}/lib/ export INCDIR=$(pwd)/${INSTALL_DIR}/include/ export BINDIR=$(pwd)/${INSTALL_DIR}/bin/ make CC=arm-linux-gnueabihf-gcc make install
wpa_supplicant 使用参考链接:Linux 使用wpa_supplicant手动配置连接wifi
TCPDUMP 是 Linux 系统下的一个强大的命令,可以将网络中传送的数据包完全截获下来提供分析。它支持针对网络层、协议、主机、网络或端口的过滤,并提供 and、or、not 等逻辑语句来帮助你去掉无用的信息;TCPDUMP 依赖于开源库 libpcap (无需单独交叉编译,可以随 TCPDUMP 一起交叉编译);
-
下载代码并更新到需要的版本:
# download_tcpdump.sh git clone https://github.com/the-tcpdump-group/tcpdump && cd tcpdump && git reset --hard tcpdump-4.99.1 && cd -
-
交叉编译 TCPDUMP:
# build_tcpdump.sh cd tcpdump INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf && { if true; then make uninstall make clean fi make && make install }
-
TCPDUMP 使用参考链接:Linux系统 tcpdump 抓包命令使用教程、tcpdump 使用指南、Man page of TCPDUMP、A tcpdump Tutorial with Examples
网络时间协议,英文名称:Network Time Protocol(NTP)是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS 等等)做同步化,它可以提供高精准度的时间校正(LAN 上与标准间差小于 1 毫秒,WAN 上几十毫秒),且可介由加密确认的方式来防止恶毒的协议攻击。NTP 的目的是在无序的 Internet 环境中提供精确和健壮的时间服务。
ntp 依赖 openssl;
-
下载代码:
# download_ntp.sh git clone https://github.com/openssl/openssl.git && cd openssl && git reset --hard OpenSSL_1_1_1 && cd - # github上为不稳定版本,可能编译失败 # git clone https://github.com/ntp-project/ntp.git # 直接下载稳定版本源码包 wget http://www.eecis.udel.edu/~ntp/ntp_spool/ntp4/ntp-4.2/ntp-4.2.8p15.tar.gz && tar -xzvf ntp-4.2.8p15.tar.gz -C ./
-
交叉编译 openssl:
# build_openssl.sh cd openssl INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./Configure linux-generic32 --prefix=$(pwd)/${INSTALL_DIR} \ -lpthread \ --cross-compile-prefix=arm-linux-gnueabihf- && { if true; then make uninstall make clean fi make depend && make && make install }
-
交叉编译 ntp:
# build_ntp.sh cd ntp-4.2.8p15 ./bootstrap INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf \ --with-yielding-select=no \ CFLAGS="-I$(pwd)/../openssl/cross_install/include" \ LDFLAGS="-L$(pwd)/../openssl/cross_install/lib" && { if false; then make uninstall make clean fi make && make install }
NTP 使用参考链接:linux同步时间命令
cURL 是一个命令行数据传输工具,支持HTTP、HTTPS、FTP、FTPS、DICT、TELNET、LDAP、FILE,和GOPHER等,cURL还包含了用于程序开发的库 libcurl。
curl 依赖 openssl;
-
下载代码:
# download_curl.sh git clone https://github.com/openssl/openssl.git && cd openssl && git reset --hard OpenSSL_1_1_1 && cd - # git下载 #git clone https://gitee.com/mirrors/curl.git && cd curl && git reset --hard tiny-curl-7_72_0 && cd - # 压缩包下载对应版本 wget https://curl.se/download/curl-7.72.0.tar.gz && tar xvf curl-7.72.0.tar.gz
-
交叉编译 openssl:
# build_openssl.sh cd openssl INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./Configure linux-generic32 --prefix=$(pwd)/${INSTALL_DIR} \ -lpthread \ --cross-compile-prefix=arm-linux-gnueabihf- && { if true; then make uninstall make clean fi make depend && make && make install }
-
交叉编译 curl:
# build_curl.sh cd curl-7.72.0 INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf \ LIBS="-lssl -lcrypto" \ CFLAGS="-I$(pwd)/../openssl/cross_install/include" \ LDFLAGS="-L$(pwd)/../openssl/cross_install/lib" && { if true; then make uninstall make clean fi make && make install }
curl 使用参考链接:README - Everything curl, curl - Tutorial
Protocol Buffers 是 Google 开发的一种数据格式,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面。它不依赖于语言和平台并且可扩展性极强。
使用方法可简述为:
- 使用 proto语言 编写待序列化的数据结构,其文件名以
.proto
为尾缀; - 下载
protobuf
和protobuf-c
源码,并编译(不是交叉编译),得到编译工具protoc-c
,使用其编译.proto
文件,得到对应的.c
和.h
文件即可用于应用代码编写;如果应用代码不是 C 语言,则使用protoc
工具得到对应语音即可; - 交叉编译
protobuf-c
源码,编译设置不使能protoc
工具,编译后生成的库文件即可用于应用代码链接库; - 应用代码中调用
protobuf
的例子可参考: protobuf-c之嵌入式平台使用 , [Google Protocol Buffer 的使用和原理(IBM)](Google Protocol Buffer 的使用和原理(IBM)_xiexievv的专栏-CSDN博客);
相关代码下载和编译:
-
服务器或 PC 端下载代码并编译
# download_protobuf.sh git clone https://gitee.com/mirrors/protobufsource.git && cd protobufsource && git reset --hard v3.19.4 ./autogen.sh && ./configure && make && sudo make install && sudo ldconfig git clone https://gitee.com/mirrors/protobuf-c.git && cd protobuf-c && git reset --hard v1.4.0 ./autogen.sh && ./configure && make && sudo make install && make clean
编译完成后即得到工具
protoc
和protoc-c
,使用他们来编译.proto
文件protoc-c --c_out=. example.proto
-
交叉编译
protobuf-c
# build_protobuf-c.sh cd protobuf-c INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf \ --disable-protoc && { \ if true; then make uninstall make clean fi make && make install }
更多 protobuf
使用参考链接:Tutorials | Protocol Buffers
Opus 是一个有损声音编码的格式,由 Xiph.Org 基金会开发,之后由 IETF(互联网工程任务组)进行标准化,目标是希望用单一格式包含声音和语音,取代 Speex 和 Vorbis,且适用于网络上低延迟的即时声音传输,标准格式定义于 RFC 6716 文件。Opus 格式是一个开放格式,使用上没有任何专利或限制。
Opus 包含有几个代码库,这里交叉编译 opus-tools 编解码工具及其依赖库opus、opusfile、libopusenc、ogg、opunssl;
-
下载代码并更新到需要的版本
# download_opus.sh git clone https://github.com/xiph/opus.git && cd opus && git reset --hard v1.2.1 && cd - git clone https://github.com/xiph/opusfile.git && cd opusfile && git reset --hard v0.9 && cd - git clone https://github.com/xiph/libopusenc.git && cd libopusenc && git reset --hard v0.2.1 && cd - git clone https://github.com/xiph/ogg.git && cd ogg && git reset --hard v1.3.5 && cd - git clone https://github.com/openssl/openssl.git && cd openssl && git reset --hard OpenSSL_1_1_1 && cd - git clone https://github.com/xiph/opus-tools.git && cd opus-tools && git reset --hard v0.2 && cd -
-
交叉编译 opus
# build_opus.sh cd opus ./autogen.sh INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf && { if true; then make uninstall make clean fi make && make install }
-
交叉编译 libopusenc
# build_libopusenc.sh cd libopusenc ./autogen.sh INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf \ --disable-examples \ DEPS_CFLAGS="-I../opus/${INSTALL_DIR}/include/opus/ -I../opus/${INSTALL_DIR}/include/" \ DEPS_LIBS="-L../opus/${INSTALL_DIR}/lib/" && { if true; then make uninstall make clean fi make && make install }
-
交叉编译 opusfile
# build_opusfile.sh cd opusfile ./autogen.sh INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf \ --disable-examples \ DEPS_CFLAGS="-I../ogg/${INSTALL_DIR}/include/ -I../opus/${INSTALL_DIR}/include/opus/ -I../opus/${INSTALL_DIR}/include/" \ URL_DEPS_CFLAGS="-I../openssl/${INSTALL_DIR}/include/ " \ DEPS_LIBS="-L../ogg/${INSTALL_DIR}/lib/ -L../opus/${INSTALL_DIR}/lib/" \ URL_DEPS_LIBS="-L../openssl/${INSTALL_DIR}/lib/" && { if true; then make uninstall make clean fi make && make install }
-
交叉编译 ogg
# build_ogg.sh cd ogg ./autogen.sh INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf && { if true; then make uninstall make clean fi make && make install }
-
交叉编译 openssl
# build_openssl.sh cd openssl INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} ./Configure linux-generic32 --prefix=$(pwd)/${INSTALL_DIR} \ -lpthread \ --cross-compile-prefix=arm-linux-gnueabihf- && { if true; then make uninstall make clean fi make depend && make && make install }
-
交叉编译 opus-tools
# build_opus_tools.sh cd opus-tools ./autogen.sh INSTALL_DIR=cross_install mkdir -p ${INSTALL_DIR} if false; then echo "Static library build" ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf \ --without-flac \ CFLAGS="-lm -ldl -pthread -I../opusfile/${INSTALL_DIR}/include/ -I../opusfile/${INSTALL_DIR}/include/opus/" \ OGG_CFLAGS="-I../ogg/${INSTALL_DIR}/include/" \ OGG_LIBS="-L../ogg/${INSTALL_DIR}/lib/ ../ogg/${INSTALL_DIR}/lib/libogg.a" \ OPUS_CFLAGS="-I../opus/${INSTALL_DIR}/include/ -I../opus/${INSTALL_DIR}/include/opus/" \ OPUS_LIBS="-L../opus/${INSTALL_DIR}/lib/ ../opus/${INSTALL_DIR}/lib/libopus.a \ -L../opusfile/${INSTALL_DIR}/lib/ ../opusfile/${INSTALL_DIR}/lib/libopusfile.a \ -L../openssl/${INSTALL_DIR}/lib/ ../openssl/${INSTALL_DIR}/lib/libssl.a ../openssl/${INSTALL_DIR}/lib/libcrypto.a \ -L../ogg/${INSTALL_DIR}/lib/ ../ogg/${INSTALL_DIR}/lib/libogg.a" \ OPUSFILE_CFLAGS="-I../opusfile/${INSTALL_DIR}/include/ -I../opusfile/${INSTALL_DIR}/include/opus/" \ OPUSFILE_LIBS="-L../opusfile/${INSTALL_DIR}/lib/ ../opusfile/${INSTALL_DIR}/lib/libopusfile.a" \ LIBOPUSENC_CFLAGS="-I../libopusenc/${INSTALL_DIR}/include/ -I../libopusenc/${INSTALL_DIR}/include/opus/" \ LIBOPUSENC_LIBS="-L../libopusenc/${INSTALL_DIR}/lib/ ../libopusenc/${INSTALL_DIR}/lib/libopusenc.a" \ OPUSURL_LIBS="-L../opusfile/${INSTALL_DIR}/lib/ ../opusfile/${INSTALL_DIR}/lib/libopusurl.a" \ OPUSURL_CFLAGS="-I../opusfile/${INSTALL_DIR}/include/" else echo "Shared library build" ./configure --prefix=$(pwd)/${INSTALL_DIR} --host=arm-linux-gnueabihf \ --without-flac \ CFLAGS="-I../opusfile/${INSTALL_DIR}/include/ -I../opusfile/${INSTALL_DIR}/include/opus/" \ OGG_CFLAGS="-I../ogg/${INSTALL_DIR}/include/" \ OGG_LIBS="-L../ogg/${INSTALL_DIR}/lib/ -logg" \ OPUS_CFLAGS="-I../opus/${INSTALL_DIR}/include/ -I../opus/${INSTALL_DIR}/include/opus/" \ OPUS_LIBS="-L../opus/${INSTALL_DIR}/lib/ -lopus \ -L../opusfile/${INSTALL_DIR}/lib/ -lopusfile \ -L../openssl/${INSTALL_DIR}/lib/ -lssl -lcrypto \ -L../ogg/${INSTALL_DIR}/lib/ -logg" \ OPUSFILE_CFLAGS="-I../opusfile/${INSTALL_DIR}/include/ -I../opusfile/${INSTALL_DIR}/include/opus/" \ OPUSFILE_LIBS="-L../opusfile/${INSTALL_DIR}/lib/ -lopusfile" \ LIBOPUSENC_CFLAGS="-I../libopusenc/${INSTALL_DIR}/include/ -I../libopusenc/${INSTALL_DIR}/include/opus/" \ LIBOPUSENC_LIBS="-L../libopusenc/${INSTALL_DIR}/lib/ -lopusenc" \ OPUSURL_LIBS="-L../opusfile/${INSTALL_DIR}/lib/ -lopusurl" \ OPUSURL_CFLAGS="-I../opusfile/${INSTALL_DIR}/include/" fi if [ $? = "0" ]; then if true; then make uninstall make clean fi make && make install fi
opus-tools 使用参考链接:Documentation – Opus Codec