一朵小草 2024-03-29 23:19 采纳率: 45.5%
浏览 9

Qt交叉编译到另一台电脑执行报错重新编译

因为使用Qt在x86架构下使用交叉编译出arm64的可执行文件,移动至arm真机执行后有终端加载信息报错如下:
qrc:/xxxxxx/mainWinqml: File was compiled ahead of time with an incompatible version of Qt and the original file cannot be found. Please recompile
编译确认没问题,使用编译操作系统为ubuntu18.0.2

  • 写回答

2条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-03-29 23:19
    关注

    引自免费微信小程序:皆我百晓生

    解决Qt交叉编译到另一台电脑执行报错重新编译的问题的具体步骤如下:

    1. 下载Qt库: 可通过https://www.qt.io/downloads/releases/各版本的Qt官方下载文件包,根据系统需求选择对应的安装版本。

      • Linux系统:建议使用Qt 5.x系列。
      • macOS系统:建议使用Qt 5.9或更高版本。
      • Windows系统:推荐使用Qt 5.13或更高版本,支持Windows Server、Linux和macOS的混合编译环境。
    2. 编译Qt源代码: 打开Qt源码仓库(例如GitHub、GitLab等)并导航至build/qmake/qmake文件夹下,找到包含交叉编译相关的Makefile文件,按照其提示进行如下操作:

      # 指定生成目标平台(X86/ARM)
      target-os := $(strip armv$(sysname))
      
      # 如果跨平台是通过交叉编译实现的,此处设置相应的交叉构建指令
      ifneq ($(target-os), arm)
        target-arch := $(strip i386 arm)
      
        # 编译链接库文件
        qmake .. -target $^ @complete
      else
        target-arch := $(strip i386 x86_64)
      
        # 编译头文件和库文件
        qmake .. -target i386 $^ @complete -target $^ $(strip all)
      fi
      
      # 制作可执行文件(适用于ARM设备)
      ifeq ($(target-os), arm)
        qmake -o $@ -r *.cpp $(addprefix $(-out)/,$(foreach dir in $(libdir)),$(wildcard $(dir)/*.a))
      else
        qmake -o $@ -r *.cpp $(addprefix $(out)/,$(foreach dir in $(libdir)),$(wildcard $(dir)/*.so)))
      fi
      
      # 配置头文件和链接器
      ifeq ($(target-os), arm)
        $(MAKE) $(TARGETOS)-shared=$(DISTNAME) lib/$(@:.so=%.a)
      else
        $(MAKE) $(TARGETOS)-shared=$(DISTNAME) lib/$(@:.so=%.so)
      fi
      
      # 创建和挂载可执行文件目录
      mkdir -p $(DESTDIR)$(OUT)/$(@:%)
      mv $(@:.o)/$(distName) $(DESTDIR)$(OUT)/$(@:%)
      
      # 更新配置文件 (optional, for improved cross-compilation)
      qmake -f $(CONFIG_FILE) --update-target-link
      
    3. 安装QLibrary (.dll/obj): 在目标平台上运行时,通常要依赖特定的QLibrary文件,如OpenGL、QtUI、QtSql等。以下是如何在Ubuntu 18.0.2中安装上述Libraries的步骤:

      • sudo apt-get install glFW32:i386: 若目标平台为Windows,需要安装GLFW,这是跨平台使用Qt GUI的核心组件之一,可以在命令行界面运行glfw32:i386命令下载安装包。

      • sudo apt-get install qt5-default: 这里主要用于安装Qt 5.x系列,具体依赖项取决于目标平台。对于Linux或macOS系统,可以下载相应的发行版文件包,如Qt 5.13的.tar.gz或Qt 5.15的.tar.gz,并将其解压到~/.local/lib/qt-<version>目录下,如~/.local/lib/qt-5.13. 注意,有些应用程序可能需要更高的权限才能安装,如sudo apt-get install qtbase5-dev

    4. 安装所需驱动程序和硬件相关软件(若适用)

      • 对于特定的物理设备或板卡,如GPU、HDMI或USB设备等,可能需要安装驱动程序,这些信息可以通过网络搜索或查阅系统发行版文档获取。

      • 下载针对目标平台的驱动程序,并将它们解压到相应的安装目录,如~/.local/lib/qt-<version>/plugins~/.local/lib/qt-<version>/modifications

      • 安装与所选硬件兼容的板卡驱动程序和软件包,如NVIDIA Driver or Intel HBA driver等,如果需支持高版本硬件,请确保已经正确更新到最新版本。

    5. 测试交叉编译过程:在当前目录下运行以下命令检查是否顺利完成交叉编译并成功生成了可执行文件:

      val mainWinqml = "main.qml"
      val sourceDir = "/path/to/source"
      val outputDir = "/path/to/output"
      
      val cmake = """-DQT_BUILD_QML=ON -DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS=-std=c++17""`
      val qmakeArgs = ["-DQT_INSTALL_DIR=$(out)/", "-DPYTHON_EXECUTABLE=$(python3)"]
      
      val qmakeCommand = qmake(qmakeArgs, srcDir, outputDir, mainWinqml)
      qmakeCommand.execute()
      
      if ! [ $? -eq 0 ]; then
          echo "Cross-compilation failed."
      else
          echo "Cross-compilation successful!"
      fi
      

      在这段代码中,-DQT_BUILD_QML=ON指定了Qt是否启用QML开发,-DCMAKE_CXX_COMPILER=g++ -DCMAKE_CXX_FLAGS=-std=c++17表示构建基于g++编译器的C++程序,-DPYTHON_EXECUTABLE=$(python3)指定了Python作为QML的脚本处理器。

    6. 创建Windows用户账户(强制使用管理员权限):在目标机器上启动Windows系统,并尝试再次运行Qt交叉编译。确保Windows用户已创建并且具有足够的管理员权限,以便正常运行生成的可执行文件。

    7. 验证双工开发模式下的运行环境:如果已成功编译了可执行文件,确保Windows系统中的Qt集成环境支持Qt的双工开发模式。双工开发模式允许Qt框架支持多个线程,因此,在编译过程中需要添加 `-DQT_NO这条标志来禁用这一功能。以下是修改后的QMake和CMake代码:

      # ...
      
      # 不包含 "-DQT_NO" 标志,以启用双工开发模式
      cmake_args += "--DQT_NO”。
      
      # ...
      
    8. 验证在虚拟环境中测试交叉编译

      • 在Linux或macOS系统中安装了一个名为“QEMU”的虚拟环境工具,用于在不同的机器之间运行Qt应用。
      • 使用qemu-system-i386 -smp 2 -m 4096 -cpu cortex-a77 -abi aarch64 -device virtio-modeside -dev virtio-smbus -device virtio-serial-pci -device virtio-serial -net bridge命令在目标主机上启动QEMU并运行Qt模拟器。
      • 确保虚拟环境中没有限制双工开发的其他模块,以确保在所有平台上都能够在目标平台上编译并运行Qt。
    9. 关闭安全措施(部分情况下):在某些操作系统中,由于安全性原因,可能会对桌面环境的默认端口(通常是22)设定防火墙策略阻止Qt的访问,这可能导致在外部网络连接上的错误。在这种情况下,可能需要在CMake配置文件中设置允许远程连接,或者在安装Qt时手动指定一个适当的端口。以下是修改后的配置:

      -DCMAKE_DEFAULT_HOST_PLATFORMS=i386 arm
      -DCMAKEヽBINARY_EXTRACT_NAME?=binaries/${distName}-${QtBuild}-$(shell date +%Y%m%d%H%M%S).tar.gz
      -DBUILD_SHARED_LIBS:=YES
      -DBUILD_TESTING:=NO
      -DQT_ROOT_DIR=/usr/lib/qt-5
      
    10. 调整虚拟机内核(在某些情况下):在有些情况下,由于内核差异或交叉编译的内核移植不够完善,导致虚拟机的运行速度较慢或系统稳定性较差。在这种情况下,可以尝试增加虚拟机内核的缓存大小或优化内核编译参数以提高性能。以下是修改后的CMake代码:

    -DCMAKE_REMAP_KERNEL_IN_VIRTDEVICE=OFF
    -DCMAKE_ENABLE_KEXT_PREEMPTIVITY=ON
    -DQMAKE_CONFIG_FLAG=-DSIM使我内核支持内存映射技术
    -DQT_DRIVER_PATH=${HOME}/virtualisation/qemu-${distName}
    
    1. 配置编译选项: 在交叉编译过程中,可适当调整编译选项以优化性能和运行效率。一些常用的编译选项包括:
    • -O3-Os 选择低级别编译,减少代码量,同时降低代码精度。
    • -Werror-Wall 关闭警告输出,特别是有助于调试和发现潜在问题。
    • -I/home/user/virtualisation 调整路径,以指向Qt集成开发环境的包含路径。
    • -L/home/user/virtualisation 相关库路径,用于添加和卸载第三方库。
    • -l${distName} 引入Qt库及其对应头文件,生成可执行文件时,需要加入此标志,这样
    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 3月29日

悬赏问题

  • ¥20 论文AlphaTensor复现(有偿)
  • ¥15 (有偿)在ANSYS中 .anf文件
  • ¥45 关于#芯片#的问题:组合逻辑电路设计
  • ¥15 基与机器学习和时间序列分析预测养老服务需求趋势
  • ¥100 求连续两帧图像在水平和垂直上偏移
  • ¥15 mysql全文索引查找指定必须关键词word无效
  • ¥15 Verilog hdl密码锁设计
  • ¥35 基于python的有ssl加密传输的socket聊天室
  • ¥15 数码管亮度控制器设计
  • ¥15 kafka客户端跨网段访问,看日志提示连接的还剩内网地址,且访问不通