Linux-交叉编译-gpsd:从依赖库构建到嵌入式部署的完整指南

张开发
2026/4/17 12:53:30 15 分钟阅读

分享文章

Linux-交叉编译-gpsd:从依赖库构建到嵌入式部署的完整指南
1. 为什么需要交叉编译gpsd在嵌入式Linux开发中我们经常遇到一个尴尬的局面开发机的CPU架构比如x86和目标板的CPU架构比如ARM完全不同。这就好比你想在Windows电脑上运行一个专为iPhone开发的App直接运行肯定行不通。交叉编译就是为了解决这个水土不服的问题。gpsd作为一款开源的GPS数据解析服务在车载导航、无人机定位、航海设备等场景应用广泛。我最近在给AM5728开发板移植gpsd时就踩了不少坑。比如开发机上编译好的程序放到板子上直接Segmentation fault或者提示libusb not found。这些问题大多源于交叉编译环境配置不当。2. 搭建交叉编译环境2.1 准备Ubuntu开发环境建议使用Ubuntu 18.04或20.04 LTS版本稳定性更有保障。我实测在Ubuntu 22.04上会遇到一些Python版本兼容问题。首先安装基础工具sudo apt update sudo apt install -y build-essential git wget2.2 安装交叉编译工具链针对AM5728这类ARM Cortex-A15/A7架构的芯片我们需要arm-linux-gnueabihf工具链sudo apt install -y gcc-arm-linux-gnueabihf验证安装是否成功arm-linux-gnueabihf-gcc --version如果看到类似gcc version 7.5.0的输出说明工具链就绪。这里有个坑要注意有些开发板厂商会提供定制化的工具链这时候就需要用厂商提供的版本替代系统默认的。2.3 安装SCons构建工具gpsd使用SCons而不是常见的make来管理构建过程sudo apt install -y sconsSCons类似于更现代的CMake用Python脚本描述构建规则。我在第一次使用时发现它比make更智能能自动处理头文件依赖关系。3. 交叉编译依赖库3.1 libusb的交叉编译libusb是USB设备通信的基础库gpsd通过它读取GPS模块数据。下载源码wget https://downloads.sourceforge.net/project/libusb/libusb-1.0/libusb-1.0.22/libusb-1.0.22.tar.bz2 tar -xjf libusb-1.0.22.tar.bz2 cd libusb-1.0.22配置交叉编译参数./configure CCarm-linux-gnueabihf-gcc \ --hostarm-linux \ --prefix$PWD/arm_install \ --disable-udev这里有几个关键点--hostarm-linux告诉configure生成ARM平台的代码--disable-udev避免依赖udev简化移植prefix指定安装目录方便后续打包编译并安装make -j$(nproc) make install生成的库文件位于arm_install/lib目录下。我建议用tar打包整个目录保留软链接关系tar -czf libusb-arm.tar.gz -C arm_install .3.2 libncurses的交叉编译libncurses提供终端界面处理能力虽然gpsd不一定需要但有些工具会依赖wget https://ftp.gnu.org/pub/gnu/ncurses/ncurses-6.1.tar.gz tar -xzf ncurses-6.1.tar.gz cd ncurses-6.1配置时特别注意--with-shared参数./configure CCarm-linux-gnueabihf-gcc \ --hostarm-linux \ --prefix$PWD/arm_install \ --with-shared编译过程中会遇到tic工具的平台兼容问题。解决方法是用本地tic替换交叉编译生成的版本find /usr/bin/ -name tic -exec cp {} progs/ \; make install3.3 处理libtinfo软链接libtinfo是ncurses的子集通过软链接方式创建cd arm_install/lib ln -s libncurses.so.6 libtinfo.so.6 ln -s libtinfo.so.6 libtinfo.so这一步经常被忽略导致后续gpsd编译时报libtinfo not found错误。4. 交叉编译gpsd4.1 获取源码建议从官方仓库获取最新稳定版git clone https://gitlab.com/gpsd/gpsd.git cd gpsd git checkout release-3.234.2 配置SCons缓存创建.scons-option-cache文件指定交叉编译参数libgpsmm False python False prefix /usr/local/gpsd target arm-linux-gnueabihf这些配置告诉SCons不编译C绑定libgpsmm不编译Python模块指定目标平台前缀4.3 处理依赖库将之前编译好的libusb和libncurses解压到gpsd源码目录tar -xzf libusb-arm.tar.gz tar -xzf ncurses-arm.tar.gz设置库文件搜索路径export LD_LIBRARY_PATH$PWD/arm_install/lib:$LD_LIBRARY_PATH4.4 执行编译基础编译命令scons如果需要时间服务支持配合ntpd使用scons timeserviceyes nmea0183yes编译完成后安装到临时目录scons install4.5 处理udev规则可选如果设备需要USB热插拔支持scons udev-install这会在系统中生成udev规则文件自动加载GPS设备。5. 部署到目标板5.1 文件清单需要拷贝到开发板的文件包括sbin/gpsd主程序arm_install/lib/下的所有.so文件gpsd/gpsd.conf配置文件5.2 库文件部署建议将库文件放到开发板的/usr/lib目录scp -r arm_install/lib/* roottarget:/usr/lib ldconfig5.3 测试运行在开发板上执行gpsd -N -n -D3 /dev/ttyUSB0参数说明-N前台运行-n不等待客户端连接-D3调试级别3用cgps或gpsmon工具验证数据输出gpsmon /dev/ttyUSB06. 常见问题排查6.1 库版本不匹配错误提示类似libusb-1.0.so.0: version LIBUSB_1.0 not found。解决方法readelf -a libusb-1.0.so | grep LIBUSB_1.0确保开发板和编译环境的库版本一致。6.2 段错误(Segmentation fault)通常是架构不匹配导致。用file命令检查file gpsd应显示ARM aarch32而不是x86-64。6.3 USB设备权限问题如果gpsd无法打开/dev/ttyUSB0尝试chmod 666 /dev/ttyUSB0或者更规范的作法是将用户加入dialout组usermod -aG dialout username7. 性能优化建议7.1 静态链接减少运行时依赖scons staticyes这会显著增大二进制体积但部署更简单。7.2 裁剪功能关闭不需要的特性scons bluetoothno alsano7.3 交叉编译dbus支持可选如果需要dbus接口scons dbusyes但要注意dbus本身也需要交叉编译过程较为复杂。

更多文章