本文记录这个wifi配置工具的编译过程,步骤不少 ,涉及的开源代码包也比较多,以后很容易忘。
首先,稍稍介绍下wpa_supplicant,这是一个控制无线网络连接的工具,类似于iw/iwconfig,但现有的iwconfig已经比较旧了,很多功能都支持不了,这也是我非得费时费力搞这些的原因。
它由wpa_supplicant 和wpa_cli两部分组成,前者是一个daemon角色,后者则是控制工具的角色,wpa_cli实际与daemon通信,故无法独立运行。使用时, wpa_supplicant可带参数或配置脚本就能够完成所需的工作,不一定需要wpa_cli配合;但wpa_cli提供了很多子命令,便于调试,灵活配置,也能以此完成所有事情。
编译环境: Ubuntu-21.04
交叉工具链接:arm-linux-gnueabi-7.3.1
wpa_supplicant官网:http://w1.fi/wpa_supplicant/
GIT源:git://w1.fi/hostap.git
当前最新版本是wpa_supplicant-2.10.tar.gz
直接下载版本包并解压,或直接 git clone git://w1.fi/hostap.git 到本地/home(或子)目录下,
golden@ubuntu:~/workspace$ git clone git://w1.fi/hostap.git
.......
golden@ubuntu:~/workspace$ cd hostap/wpa_supplicant/
golden@ubuntu:~/workspace/hostap/wpa_supplicant$
该文件包含了编译配置变量。源码目录中,默认不存在.config,但提供了一些示例文件,如下。
$ ls *config
android.config defconfig
$ cp defconfig ok6410_defconfig
我本地不是android,故选文件defconfig作为参考,将其复制成自己的配置文件,方便后续修改。
为了避免后续报如下错误,需要修改编译ok6410_defconfig,将关联库的信息,添加入编译选项
/home/golden/workspace/tools/7.3.1/arm-linux-gnueabi/bin/ld: cannot find -lnl-3
/home/golden/workspace/tools/7.3.1/arm-linux-gnueabi/bin/ld: cannot find -lnl-genl-3
/home/golden/workspace/tools/7.3.1/arm-linux-gnueabi/bin/ld: cannot find -lnl-route-3
/home/golden/workspace/tools/7.3.1/arm-linux-gnueabi/bin/ld: cannot find -lssl
/home/golden/workspace/tools/7.3.1/arm-linux-gnueabi/bin/ld: cannot find -lcrypto
/usr/local/lib/pkgconfig/../../lib/libdbus-1.so: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status
make: *** [Makefile:1899: wpa_supplicant] Error 1
wpa_supplicant依赖工具包,按日志显示的前后顺序分别是 libnl 、openssl、dbus。我们必须事先在交叉工具链中准备好相关的依赖库和头文件,否则在上面的问题提示之前,就会提示缺少头文件,这一点,我是用ubuntu系统安装的头文件应付错误后,才后知后觉想到的。
为了叙述的连贯性,依赖包的安装,将在后续小中节说明,建议优先按后面小节准备好依赖包。
待准备好依赖库和头文件后,设置配置文件中的CFLAGS 和LIBS,让编译器知道其所在的路径。
ok6410_defconfig (原始的相关代码)
.....
# Uncomment following two lines and fix the paths if you have installed OpenSSL
# or GnuTLS in non-default location
#CFLAGS += -I/usr/local/openssl/include
#LIBS += -L/usr/local/openssl/lib
.....
# driver_nl80211.c requires libnl. If you are compiling it yourself
# you may need to point hostapd to your version of libnl.
#
#CFLAGS += -I$
#LIBS += -L$
....
# Add support for new DBus control interface
# (fi.w1.wpa_supplicant1)
CONFIG_CTRL_IFACE_DBUS_NEW=y
# Add introspection support for new DBus control interface
CONFIG_CTRL_IFACE_DBUS_INTRO=y
.....
将以下加亮部分的代码,加到ok6410_defconfig 开头即可(dbus部分不需要修改)
# //cross for ok6410 by Golden ,these will update by make.sh
CC=gcc
CROSSINC=/usr/include
CROSSLIB=/usr/lib
# // end
#上面三个变量将保存交叉编译工具链gcc名称和路径。工具链不同、路径不同,
# 都将影响设置,故此将这些设置提取成变量。但又没法直接传参,给.config文件中的变量赋值。
# 所以我将这些工作,通过make.sh脚本来处理,封装掉细节差异。
# Uncomment following two lines and fix the paths if you have installed OpenSSL
# or GnuTLS in non-default location
CFLAGS += -I$(CROSSINC)
LIBS += -L$(CROSSLIB)
.....
# driver_nl80211.c requires libnl. If you are compiling it yourself
# you may need to point hostapd to your version of libnl.
#
CFLAGS += -I$(CROSSINC)/libnl3
LIBS += -L$(CROSSLIB)/libnl/cli/cls/ -L$(CROSSLIB)/libnl/cli/qdisc/
.....
我将所有编译细节都包含到脚本make_wpa.sh中,源码如下:
make_wpa.sh:
#!/bin/bash
CROSS_COMPILE=arm-linux-gnueabi-
GCC_PATH=`which ${CROSS_COMPILE}gcc`
if [ -z $GCC_PATH ];then
echo "Please initialize cross-compile envirnment"
exit
fi
CC=${CROSS_COMPILE}gcc
CROSSLIB=${GCC_PATH%bin/*}lib
CROSSINC=${GCC_PATH%bin/*}include
# see cflag cc in defconfig
cp ok6410_defconfig .config
# Update cross-compile options in .config
sed -i "s/CC=gcc/CC=${CC}/g" .config
sed -i "s/CROSSLIB=\/usr\/lib/CROSSLIB=${CROSSLIB//\//\\/}/g" .config
sed -i 's/CROSSINC=\/usr\/include/CROSSINC='"${CROSSINC//\//\\/}"'/g' .config
make
上述代码中, 与环境相关,只有CROSS_COMPILE变量,其与实际主机有关。可根据实际工具链的情况进行修改。执行脚本之前,必须将工具链的所在路径加入到全局变量PATH中,例如:
golden@ubuntu:~/ $ PATH=$PATH:$HOME/tools/7.3.1/bin
将make_wpa.sh放在wpa_supplicant/目录下,然后执行编译脚本即可:./make_wpa.sh
如果工具链配置正确,就会自动编译;否则,将提示错误。
golden@ubuntu:~/workspace/hostap/wpa_supplicant$ gedit make_wpa.sh &
[1] 1188608
golden@ubuntu:~/workspace/hostap/wpa_supplicant$ chmod +x make_wpa.sh
golden@ubuntu:~/workspace/hostap/wpa_supplicant$
golden@ubuntu:~/workspace/hostap/wpa_supplicant$ ./make_wpa.sh
.....
golden@ubuntu:~/workspace/hostap/wpa_supplicant$ ls -dl ./wpa_cli ./wpa_passphrase ./wpa_supplicant systemd/
drwxrwxr-x 2 golden golden 4096 3月 12 14:45 systemd/
-rwxrwxr-x 1 golden golden 329645 3月 12 14:55 ./wpa_cli
-rwxrwxr-x 1 golden golden 245150 3月 12 14:55 ./wpa_passphrase
-rwxrwxr-x 1 golden golden 11353986 3月 12 14:55 ./wpa_supplicant
编译结束,得到 wpa_supplicant 和wpa_cli
golden@ubuntu:~/workspace/hostap/wpa_supplicant$ file wpa_supplicant
wpa_supplicant: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.16, with debug_info, not stripped
golden@ubuntu:~/workspace/hostap/wpa_supplicant$ file wpa_cli
wpa_cli: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3, for GNU/Linux 2.6.16, with debug_info, not stripped
以下所涉及的开源包,编译命令都是类似的,除了configure参数可能有差异,基本上如下:
# ./configure --prefix=.... --host=...
# make
# make install
其中,--prefix指定 "make install"安装编译结果的路径;
--host将指定用于什么架构,实际指定值也将用于配置CC、CPP编译项
为了减少重复,这里统一把编译过程概括成脚本,除了个别小节有特别说明之外,源码编译则用该脚本:make.sh 。
注意,如之前所述,执行脚本make.sh之前,须事先配置过交叉工具链的全局路径: PATH=$PATH:$HOME/tools/7.3.1/bin
在新打开的终端窗口中,执行过一次即可,确认PATH情况,可通过命令:echo $PATH
make.sh :
#!/bin/bash
CROSSPREFIX=arm-linux-gnueabi #不要以“-”结尾
GCC_PATH=`which ${CROSSPREFIX}-gcc`
if [ -z $GCC_PATH ];then
echo "Please initialize cross-compile envirnment"
exit
fi
CROSSROOT=${GCC_PATH%bin/*}
CROSSLIB=${CROSSROOT}lib
CROSSINC=${CROSSROOT}include
# --prefix 指定安装目录
# --host:指定目标主机类型,与gcc编译器前缀有关
# CFLAGS LDFLAGS 将arm-linux编译工具链的头文件和库路径加入引用配置
./configure --prefix=${CROSSROOT} --host=$CROSSPREFIX CFLAGS=-I${CROSSINC} LDFLAGS=-L${CROSSLIB}
make
make install
源码地址: https://www.linuxfromscratch.org/blfs/view/svn/basicnet/libnl.html
下载当前最新的libnl-3.5.0.tar.gz,并事先安装PC端的依赖包
# sudo apt-get install flex bison
注意,网络上有不少libnl下载地址,有些不是最新,比如libnl-3.2.25,那么在编译wpa_supplicant-2.10时,会提示缺少头文件以及函数未定义,这些问题在libnl-3.5.0上可避免。
../src/drivers/driver_macsec_linux.c:20:10: fatal error: netlink/route/link/macsec.h: No such file or directory
#include
下载源码并解压,得到
golden@ubuntu:~/workspace$ tar xvzf libnl-3.5.0.tar.gz
....
golden@ubuntu:~/workspace$ cd libnl-3.5.0/
golden@ubuntu:~/workspace/libnl-3.5.0$ ls
aclocal.m4 configure.ac libnl-3.0.pc.in libnl-genl-3.0.pc.in libnl-nf-3.0.pc.in libnl-xfrm-3.0.pc.in Makefile.in
build-aux COPYING libnl-3.sym libnl-genl-3.sym libnl-nf-3.sym libnl-xfrm-3.sym make.sh
ChangeLog etc libnl-cli-3.0.pc libnl-idiag-3.0.pc libnl-route-3.0.pc libtool man
config.log include libnl-cli-3.0.pc.in libnl-idiag-3.0.pc.in libnl-route-3.0.pc.in m4 python
config.status lib libnl-cli-3.sym libnl-idiag-3.sym libnl-route-3.sym Makefile src
configure libnl-3.0.pc libnl-genl-3.0.pc libnl-nf-3.0.pc libnl-xfrm-3.0.pc Makefile.am tests
将上面所说的默认脚本make.sh放置在源码目录下,执行即可:./make.sh
官网地址:https://www.openssl.org/source/
GIT源:https://github.com/openssl/openssl.git
直接下载当前最新的版本 :openssl-3.0.1.tar.gz ,并解压。
golden@ubuntu:~/workspace$ tar xvzf ./openssl-3.0.1.tar.gz
...
golden@ubuntu:~/workspace$ cd openssl-3.0.1/
golden@ubuntu:~/workspace/openssl-3.0.1$ ls
ACKNOWLEDGEMENTS.md config.com demos HACKING.md make_openssl.sh NOTES-UNIX.md README-ENGINES.md tools
apps configdata.pm doc include ms NOTES-VALGRIND.md README-FIPS.md util
appveyor.yml configdata.pm.in engines install NEWS.md NOTES-VMS.md README.md VERSION.dat
AUTHORS.md Configurations e_os.h INSTALL.md NOTES-ANDROID.md NOTES-WINDOWS.md README-PROVIDERS.md VMS
build.info Configure external LICENSE.txt NOTES-DJGPP.md os-dep ssl wycheproof
CHANGES.md CONTRIBUTING.md FAQ.md Makefile NOTES-NONSTOP.md pod2htmd.tmp SUPPORT.md
config crypto fuzz Makefile.in NOTES-PERL.md providers test
设置专门的编译脚本 make_openssl.sh:
#!/bin/bash
CROSS_COMPILE=arm-linux-gnueabi-
GCC_PATH=`which ${CROSS_COMPILE}gcc`
if [ -z $GCC_PATH ];then
echo "Please initialize cross-compile envirnment"
exit
fi
CROSSROOT=${GCC_PATH%bin/*}
# 指定cpu架构体系。配置项可搜索文件./Configurations/10-main.conf,例如 linux-mips32, -march项可默认不配置
# --prefix= 指定编译后安装路径
# --cross-compile-prefix=指定交叉编译工具链命令的前缀,以连接号结束
# shared作用是生成动态链接库
# no-asm表示不使用汇编代码,没有问题就不加,如果编译有问题再加:
# --openssldir=指定openssl配置文件的安装目录,如果不指定,默认安装到--prefix指定目录下的ssl目录
./Configure --prefix=${CROSSROOT} linux-armv4 -march=armv6 --cross-compile-prefix=${CROSS_COMPILE} no-asm shared
make
make install
脚本置于源码根目录,并执行: ./make_openssl.sh
自动将结果安装到工具链路径中。
当前最新版本是 dbus-1.14.0.tar.xz ,下载地址和详情介绍:https://www.linuxfromscratch.org/blfs/view/svn/general/dbus.html
GIT源:http://[email protected]:dbus/dbus.git
下载并解压源码:
golden@ubuntu:~/workspace$ xz -d dbus-1.14.0.tar.xz
golden@ubuntu:~/workspace$ tar xvf dbus-1.14.0.tar
....
golden@ubuntu:~/workspace$ cd dbus-1.14.0/
golden@ubuntu:~/workspace/dbus-1.14.0$ ls
aclocal.m4 cleanup-man-pages.sh config.status dbus-1.pc Doxyfile.in Makefile.am README README.wince
aminclude_static.am cmake configure dbus-1.pc.in install Makefile.in README.cmake stamp-h1
AUTHORS CMakeLists.txt configure.ac dbus-1-uninstalled.pc INSTALL make_dbus.sh README.cygwin test
autogen.sh config.h CONTRIBUTING.md dbus-1-uninstalled.pc.in libtool NEWS README.launchd tools
build-aux config.h.in COPYING doc m4 NEWS.pre-1-0 README.valgrind
bus config.log dbus Doxyfile Makefile NEWS.pre-1-2 README.win
保存以下脚本内容到源码目录中的make_dbus.sh, 并执行该脚本:./make_dbus.sh
#!/bin/bash
CROSSPREFIX=arm-linux-gnueabi # 结尾不要加‘-’
GCC_PATH=`which ${CROSSPREFIX}-gcc`
if [ -z $GCC_PATH ];then
echo "Please initialize cross-compile envirnment"
exit
fi
CROSSROOT=${GCC_PATH%bin/*}
CROSSLIB=${CROSSROOT}lib
CROSSINC=${CROSSROOT}include
# --prefix 指定安装目录
# --host:指定目标主机类型,与gcc编译器前缀有关
# CFLAGS LDFLAGS 将arm-linux编译工具链的头文件和库路径加入引用配置
./configure --prefix=${CROSSROOT} --host=$CROSSPREFIX CFLAGS=-I${CROSSINC} LDFLAGS=-L${CROSSLIB} --disable-doxygen-docs --disable-xml-doc --disable-tests
make
make install
编译的过程中, 先后提示错误:
#1: config-loader-expat.c:27:10: fatal error: expat.h: No such file or directory
----解决方法:交叉编译并安装 expat-2.4.7
#2: dbus-launch.c:45:10: fatal error: X11/Xlib.h: No such file or directory
----解决方法:交叉编译并安装 libX11-1.7.3
源码地址:https://sourceforge.net/projects/expat/
GIT源: https://github.com/libexpat/libexpat
目前最新版本/expat/2.4.7/expat-2.4.7.tar.xz
下载并解压: xz -d expat-2.4.7.tar.xz ;tar expat-2.4.7.tar
参考小节“1.交叉编译libnl”,放置并执行脚本:make.sh
源码地址:https://www.x.org/releases/individual/lib/
目前最新版本:libX11-1.6.10.tar.gz
下载并解压:tar xzvf libX11-1.6.10.tar.gz
如果使用默认编译脚本make.sh,会提示错误
checking whether malloc(0) returns NULL....Configure: error in /....
需要将“enable_malloc0returnsnull=yes” 配置进去,故使用新脚本如下:
./make_libx11.sh
#!/bin/bash
CROSSPREFIX=arm-linux-gnueabi
GCC_PATH=`which ${CROSSPREFIX}-gcc`
if [ -z $GCC_PATH ];then
echo "Please initialize cross-compile envirnment"
exit
fi
CROSSROOT=${GCC_PATH%bin/*}
CROSSLIB=${CROSSROOT}lib
CROSSINC=${CROSSROOT}include
# --prefix 指定安装目录
# --host:指定目标主机类型,与gcc编译器前缀有关
# CFLAGS LDFLAGS 将arm-linux编译工具链的头文件和库路径加入引用配置
# BUG fix for libX11: checking whether malloc(0) returns NULL
echo "enable_malloc0returnsnull=yes" > tmp.cache
./configure --prefix=${CROSSROOT} --host=$CROSSPREFIX CFLAGS=-I${CROSSINC} LDFLAGS=-L${CROSSLIB} --cache-file=tmp.cache
rm tmp.cache
make
make install
执行脚本./make_libx11.sh,编译过程先后依序出现如下错误提示:
#1 ../../../include/X11/Xlib.h:44:10: fatal error: X11/X.h: No such file or directory
----解决方法:交叉编译并安装 xproto-7.0.31.tar.gz
历史版本下载:https://xorg.freedesktop.org/archive/individual/proto/
解压后,并参考小节"1.交叉编译libnl",执行前面的编译脚本make.sh安装即可
#2 imTrans.c:59:10: fatal error: X11/Xtrans/Xtrans.h: No such file or directory
----解决方法:交叉编译并安装 xtrans-1.4.0.tar.gz
历史版本下载:https://xorg.freedesktop.org/archive/individual/lib/
解压后,并参考小节"1.交叉编译libnl",执行前面的编译脚本make.sh安装即可
#3 XKB.c:32:10: fatal error: X11/extensions/XKBproto.h: No such file or directory
----解决方法:交叉编译并安装 kbproto-1.0.7.tar.gz
历史版本下载:https://xorg.freedesktop.org/archive/individual/proto/
解压后,并参考小节"1.交叉编译libnl",执行前面的编译脚本make.sh安装即可
#4 XKBExtDev.c:35:10: fatal error: X11/extensions/XI.h: No such file or directory
----解决方法:交叉编译并安装 inputproto-2.3.2.tar.gz
历史版本下载:https://xorg.freedesktop.org/archive/individual/proto/
解压后,并参考小节"1.交叉编译libnl",执行前面的编译脚本make.sh安装即可
#5 ../include/X11/Xlib-xcb.h:7:10: fatal error: xcb/xcb.h: No such file or directory
----解决方法:交叉编译并安装 libxcb-1.14.tar.xz
历史版本下载:https://www.x.org/releases/individual/lib/
解压后,并参考小节"1.交叉编译libnl",执行前面的编译脚本make.sh,依次提示如下错误:
##(1) No package 'xcb-proto' found ; No package 'xorg-macros' found
----解决方法:ubuntu内安装依赖工具: sudo apt-get install xcb-proto
并且交叉编译并安装xcb-proto-1.14.1.tar.gz
历史版本下载:https://xorg.freedesktop.org/archive/individual/proto/
解压后,并参考小节"1.交叉编译libnl",执行前面的编译脚本make.sh安装即可
##(2) Make sure that xcb/proto installed it on your Python path.
----解决方法:ubuntu内安装依赖工具:sudo apt-get install python3-xcbgen
并修改make.sh脚本, 将“PYTHON=python3”添加到./configure参数列表中
./configure PYTHON=python3 --prefix=${CROSSROOT} --host=$CROSSPREFIX CFLAGS=-I${CROSSINC} LDFLAGS=-L${CROSSLIB}
##(3) xcb_auth.c:33:10: fatal error: X11/Xauth.h: No such file or directory
----解决方法:交叉编译并安装 libXau-1.0.9.tar.gz
历史版本下载:https://www.x.org/releases/individual/lib/
解压后,并参考小节"1.交叉编译libnl",执行前面的编译脚本make.sh安装即可
#6 Font.c:49:10: fatal error: X11/extensions/xf86bigfproto.h: No such file or directory
----解决方法:交叉编译并安装 xorgproto-2020.1.tar.bz2
历史版本下载:https://xorg.freedesktop.org/archive/individual/proto/
解压后,并参考小节"1.交叉编译libnl",执行前面的编译脚本make.sh安装即可
参考文章: 交叉编译libX11_ggggyj的专栏-CSDN博客_libx11交叉编译