交叉编译Qt for树莓派Arm64时socketCAN相关头文件未被找到
问题背景
在x86_64 Linux系统上交叉编译Qt 5.15.2(官方完整源码包)给树莓派Arm64时,configure阶段出现提示:
Note: QtSerialBus: Cannot find linux/can.h and linux/can/raw.h Linux headers for socketCAN support.
已确认sysroot路径/root/raspi/sysroot/usr/include/linux/can.h存在,且尝试在qmake.conf中添加INCLUDEPATH += /root/raspi/sysroot/usr/include无效,使用的configure命令如下:
./configure -release -opengl es2 -device linux-rasp-pi3-g++ -device-option CROSS_COMPILE=/root/raspi/arm-gnu-toolchain-12.2.mpacbti-rel1-x86_64-arm-none-eabi/bin/arm-none-eabi- -sysroot ~/raspi/sysroot -opensource -confirm-license -skip qtwayland -skip qtlocation -skip qtscript -make libs -prefix /usr/local/qt5pi -extprefix ~/raspi/qt5pi -hostprefix ~/raspi/qt5 -no-use-gold-linker -v -no-gbm
解决步骤
1. 统一sysroot路径为绝对路径
configure命令中-sysroot ~/raspi/sysroot的~可能因执行用户不同解析为不同路径(普通用户对应/home/user/raspi/sysroot,root用户对应/root/raspi/sysroot),直接替换为绝对路径避免解析错误:
-sysroot /root/raspi/sysroot
2. 验证交叉工具链能否正确找到头文件
用交叉编译工具链的预处理器手动测试,确认工具链能通过sysroot访问到目标头文件:
/root/raspi/arm-gnu-toolchain-12.2.mpacbti-rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-cpp -sysroot /root/raspi/sysroot -E - <<EOF #include <linux/can.h> #include <linux/can/raw.h> EOF
如果命令无报错输出,说明工具链能找到头文件;若报错,需检查sysroot结构是否完整,或工具链的sysroot配置是否正确。
3. 修正device的qmake.conf配置
找到对应设备的qmake.conf文件(路径为qtbase/mkspecs/devices/linux-rasp-pi3-g++/qmake.conf),修改为以下内容,确保通过$$SYSROOT变量传递正确的包含路径和sysroot参数:
QMAKE_CFLAGS += --sysroot=$$SYSROOT QMAKE_CXXFLAGS += --sysroot=$$SYSROOT QMAKE_INCDIR += $$SYSROOT/usr/include
修改后先执行make distclean清理之前的配置缓存,再重新运行configure。
4. 检查sysroot完整性
确保sysroot中不仅存在can.h,还包含其依赖的所有头文件(如linux/types.h等)。可通过以下命令测试编译可行性:
/root/raspi/arm-gnu-toolchain-12.2.mpacbti-rel1-x86_64-arm-none-eabi/bin/arm-none-eabi-gcc -sysroot /root/raspi/sysroot -c -o test.o -xc - <<EOF #include <linux/can.h> EOF
若编译失败,需从树莓派系统中同步完整的头文件到sysroot目录。
5. 手动指定socketCAN头文件路径(可选)
若自动检测仍失败,可在configure命令中手动指定socketCAN的头文件路径:
./configure ... -qt-serialbus -serialbus-socketcan-includes=/root/raspi/sysroot/usr/include
可先通过./configure -help | grep serialbus确认当前Qt版本是否支持该选项。
内容的提问来源于stack exchange,提问作者TSG

