交叉编译
嵌入式 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 来了解支持的配置;
一些开源程序针对 ARM 芯片的编译方法
如无特别说明,下面交叉编译后生成的文件均在 cross_install 目录中,只要将该目录下的文件拷贝到嵌入式设备上对应的目录即可正常使用;
BusyBox
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 install # 编译后生成的可执行程序在 _install 目录下
BusyBox 使用参考链接:BusyBox - The Swiss Army Knife of Embedded Linux
glibc
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
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
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_supplicant
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
首先,复制缺省编译配置文件
```shell
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
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
NTP
网络时间协议,英文名称: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同步时间命令
Opus
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
```shell
# 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