linux-nfc neard移植ARM之交叉编译

发布时间:2024年01月24日

1.移植依赖库

1.1移植dbus

dbus需要依赖expat,expat下载链接

https://nchc.dl.sourceforge.net/project/expat/expat/2.5.0/expat-2.5.0.tar.xz

下载链接:

https://dbus.freedesktop.org/releases/dbus/dbus-1.15.8.tar.xz

先编译expat,使用./configure --prefix=/home/?--host=arm-linux-gnueabihf?CFLAGS="-I/home/include " LDFLAGS="-L/home/lib"

注意,这个配置会贯穿所有库的交叉编译,后续其他交叉库编译时不需要额外的配置就使用这个即可。

注意 --prefix?后面跟的路径使后续使用make?install安装时,把库文件、头文件、可执行文件都安装到该PC路径下。因为是交叉编译,生成的文件最后需要拷贝到板子上运行,所以这个路径不要选择/usr这种系统路径,因为这些文件安装到PC上也运行不了。--host?后面跟的交叉编译的工具链,必须加到环境变量里,最简单的办法就是直接在终端输入arm-liux-gnueabihf看一下能不能使用。

CFLAGS和LDFLAGS中-I?和-L不能少,表示头文件路径和库路径。

还有其他可以调整的参数可以使用以下命令查看:

./configure --help

正常配置完成,可以编译expat了直接使用:

make
make install

就安装到/home/lib下了。主要是libexpat.so?libexpat.so.1?libexpat.so.1.8.10这三个文件,拷贝到板子上的/usr/lib里面就可以使用了。

如果这个路径没有添加到pkg-config的搜寻路径,在编译dbus的时候请先在终端运行:

export PKG_CONFIG_PATH=/home/lib/pkgconfig:$PKG_CONFIG_PATH

这个只会在当前终端生效,如果关闭再打开一个新的终端,就失效了。注意以上路径都根据实际自己configure的情况填写。

dbus中没有configure文件,可以使用autogen.sh生成,这中间报错不要紧,只要生成了configure就可以了,或者参考上一篇编译neard的文章,里面的方法也可以。

和上面的expat配置一样,然后直接先运行configure然后make &&?make?install。

ubus生成的库文件有?libdbus-1.so?libdbus-1.so.3?libdbus-1.so.3.38.0等,在/home/bin下面有生成的可执行文件:

开发板要使用dbus需要把这些可执行文件和库拷贝到板子。

注意还有/home/share/dbus-1里面会生成session.conf和system.conf以及session.d文件夹、system.d文件夹也需要搞到板子上。
运行dbus时需要注意:

dbus-launch --config-file=/tmp/system.conf

config-file是必须指定的,根据你使用的session还是system,启动后会打印两个环境变量,你需要把这两个环境变量添加到当前环境变量里!一个是地址,一个是PID。假如使用的system需要设置环境变量:

DBUS_SYSTEM_BUS_ADDRESS

使用session设置:

DBUS_SESSION_BUS_ADDRESS

DBUS_SESSION_BUS_PID

注意,在session.conf和system.conf中需要修改?listen,includedir,listen是启动dbus-daemon后生成的socket文件,includedir则是其他程序使用dbus的配置文件,现在里面是空的,以后使用neard有用。

启动后,会有以下进程:
?

1.2移植libnl

https://www.infradead.org/~tgr/libnl/files/libnl-3.2.25.tar.gz

从上述地址下载源码,使用上文中的配置方法配置与编译,基本相同不再赘述。

1.3移植glib

https://laotzu.ftp.acc.umu.se/pub/GNOME/sources/glib/2.56/glib-2.56.4.tar.xz

按上面的方法直接编译glib,发现少了libffi,先使用wget下载libffi:
ftp://sourceware.org/pub/libffi/libffi-3.3.tar.gz?

按照上文介绍的配置和安装方式安装到/home/后再次编译glib,发现以下错误:

这是因为libffi即使添加了pkgconfig还是不行,这时候可以临时添加以下两个环境变量到终端:

export LIBFFI_CFLAGS=-I/home/include
export LIBFFI_LIBS="-L/home/lib -lffi"

再次编译,会报以下错误:?

显示找不到libmount,而libmount是util-linux的一部分。

util-linux的git?clone地址:

Index of /pub/linux/utils/util-linux/

configure配置除了和之前的一样,需要多加一个--without-systemd,然后make &&?make?install

安装的目录里可以找到?:

然后需要和上面的libffi一样,export libmount的路径否则还是会报错:

export LIBMOUNT_CFLAGS=-I/home/include
export LIBMOUNT_LIBS="-L/home/lib -lmount"

回过头来继续编译glib,继续报错:

缺少libpcre,需要交叉编译此库,下载地址:

PCRE Activity

交叉编译和上文相同,安装完成后,回来继续编译glib,需要新增临时环境变量:

export PCRE_CFLAGS=-I/home//include
export PCRE_LIBS="-L/home/lib -lpcre"

继续回来编译glib,此时configure运行不会再报错,直接make,继续报错:

主要因为测试程序可能没办法运行,简单粗暴的方法是修改configure文件中检测的部分,在configure中搜索报错的原因:

把yes改成no即可。继续make继续报错:

很明显的错误,去/home/include下面查找发现确实没这个文件,不知道为什么lib下有libmount.so但是头文件没有,手动从util-linux的libmount文件夹里面找到这个头文件放在里面。

继续编译继续make继续报错:

这些符号来自于libgmodule,它被libgio需要,这个?libgmodule本来就是glib生成的,不知道为什么自己不链接自己生成的库。make?clean后添加临时环境变量:

export LD_LIBRARY_PATH="$PWD/gmodule/.libs -lgmodule-2.0"

再次make,第一次会报错,然后使用以下命令再次make:

make LDFLAGS="-rpath $PWD/gmodule/.libs"

然后需要先make?clean后再make继续编译,继续报错:

报错原因很明显是因为没有python这个可执行文件,这个是因为系统只自带python3,或者python2,只需链接一下即可:

sudo ln -s /usr/bin/python3 /usr/bin/python

终于编译完成glib。主要生成了libglib、libgio、?libgmodule、libgobject、libgthread。

2.编译neard

把上面交叉编译的dbus、nl、glib的库和头文件路径添加到临时环境变量:

export GLIB_LIBS="-L/home/lib -lglib-2.0"
export GLIB_CFLAGS=-I/home/include
export DBUS_LIBS="-L/home/lib -ldbus-1"
export DBUS_CFLAGS=-I/home/include
export LIBNL3_LIBS="-L/home/lib -lnl-3 -lnl-nf-3 -lnl-genl-3 -lnl-idiag-3 -lnl-route-3"
export LIBNL3_CFLAGS=-I/home/include
export CFLAGS="-I/home/toolchain/arm-linux-gnueabihf/libc/usr/include -I/home/toolchain/arm-linux-gnueabihf/include"
export LDFLAGS="-L/home/lib"

注意面的路径并不完整,因为还有部分头文件在/home/lib/下面,比如glib-2.0等。这些也需要添加到对应的CFLAGS里面。这里注意LIBNL3_CFLAGS的路径千万不要是/home/include/libnl3/netlink?这里的路径一定不能加netlink,否则会报错:

上面这个问题找了好久找不到错误,最后发现polkit.c这个文件中包含了errno.h(没有前缀),而netlink头文件里面也有errno.h,所以虽然路径包含了/交叉编译链/usr/include(正确的应该包含这里面的errno.h),?但是始终找不到宏定义,原因就是用了netlink下的errno.h。neard的源码中使用netlink头文件的时候都用的:

#include <netlink/xxx.h>

这里面包含了前缀,所以就算真需要包含netlink下面的errno.h也会是#include <netlink/errno.h>,这就不会和/交叉编译链/usr/include下的errno.h冲突。

3.总结

至此neard的移植就完成了,关于交叉编译的总结:

1.首先要在需要移植的库或者程序下生成configure文件,通常有以下几种方式:

--默认存在configure

--项目提供autogen.sh可以生成configure文件

--按照上一篇博客方式生成,一般都有configure.ac

--最复杂的是没有提供任何配置工具,这种情况只能自己写makefile了

2.配置安装目录、交叉编译工具链、包含必要的头文件和库文件,每个项目的configure可配置的项都大差不差,但是很有可能有几个独特的配置项,最好的方式是先./configure --help查看一下当前项目可以配置的选项都有哪些。最常用的:

CC:编译器比如arm-linux-enbi-gcc

CFLAGS:编译选项,比如-g,当然也可以在里面包含头文件比如 -I/usr/include

LDFLAGS:链接选项,一般都是添加动态库,比如 -lm,也可以添加库的路径比如 -L/usr/lib

--prefix:make?install后的安装目录

3.配置无误后可以直接make了,这一步如果出错就只能根据错误单独分析了,这一步没有什么规律,每个人遇到的问题可能都不同。但是make中的错误都有一个最笨也是最有效的解决方法:

把编译出错的那条指令单独拎出来,在shell中输入,然后逐一分析这条指令的参数、涉及的文件,总能解决问题,只是可能会很耗时。

4.make?install最简单,一般报错只涉及权限问题。

文章来源:https://blog.csdn.net/qwe5959798/article/details/135752970
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。