Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. qmake for cross-compiling x86-64 --> armv7
Qt 6.11 is out! See what's new in the release blog

qmake for cross-compiling x86-64 --> armv7

Scheduled Pinned Locked Moved Solved Mobile and Embedded
5 Posts 2 Posters 3.0k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • R Offline
    R Offline
    robgu
    wrote on last edited by
    #1

    Hello,

    I'm struggling with the configuration of QtCreator for cross-compiling on a host x86-64 virtual machine to create executable for ARMv7 architecture using compiled (and cross-compiled) sources of Qt6.

    Here's what I've done so far:

    • Successful compilation of Qt6 sources for my Ubuntu x86-64 virtual machine (example applications run on it smoothly),
    • Successful cross-compilation of Qt6 sources for my arm device, and
    • Successful cross-compilation (on host machine, using cmake) of an example application; that application also runs ok on my arm device with the previously cross-compiled Qt6 sources.

    Now I'd like to push one step forward and make the QtCreator (v6.0.2) to be able to cross-compile for my arm device. I added my gcc/g++ cross compilers to it, but my problem comes from the Qt Versions:

    • I can add the host's qmake (or qmake6) as a Qt Version, but it is recognized with x86-64 ABI and thus incompatible with my cross-compilers (arm 32bits) when I create the Kit
    • I cannot add the target's qmake nor qmake6 as they are scripts calling the host's qmake6; QtCreator complains "Qmake Not Executable"
    • I cannot add the target's qmake (nor qmake6) which I forced to compile with -DQT_FORCE_BUILD_TOOLS=ON as it is cross-compiled for ARM and thus not executable on my virtual machine.

    Therefore, I imagine I need a x86-64 qmake which uses arm Qt6 libraries.
    I found on https://doc.qt.io/qt-6/configure-linux-device.html the following paragraph: "In order to get a qmake setup that is functional with cross-compilation, one will need to specify some of the legacy arguments to CMake or to configure."
    But nothing more than that.
    Is there anyone that could tell me how to achieve that? Or maybe the problem is somewhere else (QtCreator version too old)?

    jsulmJ 1 Reply Last reply
    0
    • R robgu

      Hello,

      I'm struggling with the configuration of QtCreator for cross-compiling on a host x86-64 virtual machine to create executable for ARMv7 architecture using compiled (and cross-compiled) sources of Qt6.

      Here's what I've done so far:

      • Successful compilation of Qt6 sources for my Ubuntu x86-64 virtual machine (example applications run on it smoothly),
      • Successful cross-compilation of Qt6 sources for my arm device, and
      • Successful cross-compilation (on host machine, using cmake) of an example application; that application also runs ok on my arm device with the previously cross-compiled Qt6 sources.

      Now I'd like to push one step forward and make the QtCreator (v6.0.2) to be able to cross-compile for my arm device. I added my gcc/g++ cross compilers to it, but my problem comes from the Qt Versions:

      • I can add the host's qmake (or qmake6) as a Qt Version, but it is recognized with x86-64 ABI and thus incompatible with my cross-compilers (arm 32bits) when I create the Kit
      • I cannot add the target's qmake nor qmake6 as they are scripts calling the host's qmake6; QtCreator complains "Qmake Not Executable"
      • I cannot add the target's qmake (nor qmake6) which I forced to compile with -DQT_FORCE_BUILD_TOOLS=ON as it is cross-compiled for ARM and thus not executable on my virtual machine.

      Therefore, I imagine I need a x86-64 qmake which uses arm Qt6 libraries.
      I found on https://doc.qt.io/qt-6/configure-linux-device.html the following paragraph: "In order to get a qmake setup that is functional with cross-compilation, one will need to specify some of the legacy arguments to CMake or to configure."
      But nothing more than that.
      Is there anyone that could tell me how to achieve that? Or maybe the problem is somewhere else (QtCreator version too old)?

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @robgu said in qmake for cross-compiling x86-64 --> armv7:

      Therefore, I imagine I need a x86-64 qmake which uses arm Qt6 libraries

      If you really did a cross compilation the qmake executable should be for the host architecture, not target. How exactly did you do cross compilation?

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      R 1 Reply Last reply
      0
      • jsulmJ jsulm

        @robgu said in qmake for cross-compiling x86-64 --> armv7:

        Therefore, I imagine I need a x86-64 qmake which uses arm Qt6 libraries

        If you really did a cross compilation the qmake executable should be for the host architecture, not target. How exactly did you do cross compilation?

        R Offline
        R Offline
        robgu
        wrote on last edited by robgu
        #3

        @jsulm Thanks for your reply.
        Yes, it is for my host architecture (see detail at the bottom of this post).
        I have first compiled the sources for the host and then for the target device, providing path to host executables and the toolchain file. The configuration command was as follows:

        $HOME/Qt654Src/Src/configure -release -opengl es2 -nomake examples -nomake tests -skip qtwebengine -skip qtwebview -skip qtgrpc -qt-host-path $HOME/qt6/bin_host -extprefix $HOME/qt6/bin_b6 -prefix /opt/qt6 -device-option CROSS_COMPILE=arm-poky-linux-gnueabi- -- -DCMAKE_TOOLCHAIN_FILE=$HOME/toolchain.cmake
        

        with the toolchain file:

        cmake_minimum_required(VERSION 3.18)
        include_guard(GLOBAL)
        
        set(CMAKE_SYSTEM_NAME Linux)
        set(CMAKE_SYSTEM_PROCESSOR arm)
        
        set(TARGET_SYSROOT /opt/we-wayland-qt5/2.7.4/sysroots/armv7at2hf-neon-poky-linux-gnueabi/)
        set(CMAKE_SYSROOT ${TARGET_SYSROOT})
        
        set(ENV{PKG_CONFIG_PATH} $PKG_CONFIG_PATH:${TARGET_SYSROOT}/usr/lib/pkgconfig)
        set(ENV{PKG_CONFIG_LIBDIR} /usr/lib/pkgconfig:/usr/share/pkgconfig/:${TARGET_SYSROOT}/usr/lib/pkgconfig)
        set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
        
        # if you use other version of gcc and g++ than gcc/g++ 9, you must change the following variables
        set(CMAKE_C_COMPILER arm-poky-linux-gnueabi-gcc)
        set(CMAKE_CXX_COMPILER arm-poky-linux-gnueabi-g++)
        
        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -fstack-protector-strong --sysroot=${TARGET_SYSROOT} -I${TARGET_SYSROOT}/usr/src/kernel-headers/include")
        
        set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
        
        set(QT_COMPILER_FLAGS "-march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security")
        set(QT_COMPILER_FLAGS_RELEASE "-O2 -std=gnu++1z -Wall -W -D_REENTRANT -fPIC -pipe")
        set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed")
        
        set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
        set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
        set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
        set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
        set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
        set(CMAKE_BUILD_RPATH ${TARGET_SYSROOT})
        
        
        include(CMakeInitializeConfigs)
        
        function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING)
          if (_PREFIX MATCHES "CMAKE_(C|CXX|ASM)_FLAGS")
            set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT "${QT_COMPILER_FLAGS}")
                
            foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
              if (DEFINED QT_COMPILER_FLAGS_${config})
                set(CMAKE_${CMAKE_MATCH_1}_FLAGS_${config}_INIT "${QT_COMPILER_FLAGS_${config}}")
              endif()
            endforeach()
          endif()
        
        
          if (_PREFIX MATCHES "CMAKE_(SHARED|MODULE|EXE)_LINKER_FLAGS")
            foreach (config SHARED MODULE EXE)
              set(CMAKE_${config}_LINKER_FLAGS_INIT "${QT_LINKER_FLAGS}")
            endforeach()
          endif()
        
          _cmake_initialize_per_config_variable(${ARGV})
        endfunction()
        

        It produces the qmake/qmake6 but it is not a full executable: host's one is 1.8M in size while the target's one is 271 bytes and it's a bash script:

        #!/bin/sh
        
        # The directory of this script is the expanded absolute path of the "$qt_prefix/bin" directory.
        script_dir_path=`dirname $0`
        script_dir_path=`(cd "$script_dir_path"; /bin/pwd)`
        
        /home/ubuntu/qt6/bin_host/bin/qmake6 -qtconf "$script_dir_path/target_qt.conf" $*
        

        Understand me well, it is fully operational and I can cross-compile my projects for my target device without problems from the command line (or using another script). But I cannot add it to QtCreator, which I really would like to achieve. Thus, my question about a qmake with cross-compilation compatibility. Or maybe the problem is the old version of QtCreator?

        jsulmJ 1 Reply Last reply
        0
        • R robgu

          @jsulm Thanks for your reply.
          Yes, it is for my host architecture (see detail at the bottom of this post).
          I have first compiled the sources for the host and then for the target device, providing path to host executables and the toolchain file. The configuration command was as follows:

          $HOME/Qt654Src/Src/configure -release -opengl es2 -nomake examples -nomake tests -skip qtwebengine -skip qtwebview -skip qtgrpc -qt-host-path $HOME/qt6/bin_host -extprefix $HOME/qt6/bin_b6 -prefix /opt/qt6 -device-option CROSS_COMPILE=arm-poky-linux-gnueabi- -- -DCMAKE_TOOLCHAIN_FILE=$HOME/toolchain.cmake
          

          with the toolchain file:

          cmake_minimum_required(VERSION 3.18)
          include_guard(GLOBAL)
          
          set(CMAKE_SYSTEM_NAME Linux)
          set(CMAKE_SYSTEM_PROCESSOR arm)
          
          set(TARGET_SYSROOT /opt/we-wayland-qt5/2.7.4/sysroots/armv7at2hf-neon-poky-linux-gnueabi/)
          set(CMAKE_SYSROOT ${TARGET_SYSROOT})
          
          set(ENV{PKG_CONFIG_PATH} $PKG_CONFIG_PATH:${TARGET_SYSROOT}/usr/lib/pkgconfig)
          set(ENV{PKG_CONFIG_LIBDIR} /usr/lib/pkgconfig:/usr/share/pkgconfig/:${TARGET_SYSROOT}/usr/lib/pkgconfig)
          set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})
          
          # if you use other version of gcc and g++ than gcc/g++ 9, you must change the following variables
          set(CMAKE_C_COMPILER arm-poky-linux-gnueabi-gcc)
          set(CMAKE_CXX_COMPILER arm-poky-linux-gnueabi-g++)
          
          set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -fstack-protector-strong --sysroot=${TARGET_SYSROOT} -I${TARGET_SYSROOT}/usr/src/kernel-headers/include")
          
          set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS}")
          
          set(QT_COMPILER_FLAGS "-march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard -fstack-protector-strong -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security -Werror=format-security")
          set(QT_COMPILER_FLAGS_RELEASE "-O2 -std=gnu++1z -Wall -W -D_REENTRANT -fPIC -pipe")
          set(QT_LINKER_FLAGS "-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed")
          
          set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
          set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
          set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
          set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
          set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
          set(CMAKE_BUILD_RPATH ${TARGET_SYSROOT})
          
          
          include(CMakeInitializeConfigs)
          
          function(cmake_initialize_per_config_variable _PREFIX _DOCSTRING)
            if (_PREFIX MATCHES "CMAKE_(C|CXX|ASM)_FLAGS")
              set(CMAKE_${CMAKE_MATCH_1}_FLAGS_INIT "${QT_COMPILER_FLAGS}")
                  
              foreach (config DEBUG RELEASE MINSIZEREL RELWITHDEBINFO)
                if (DEFINED QT_COMPILER_FLAGS_${config})
                  set(CMAKE_${CMAKE_MATCH_1}_FLAGS_${config}_INIT "${QT_COMPILER_FLAGS_${config}}")
                endif()
              endforeach()
            endif()
          
          
            if (_PREFIX MATCHES "CMAKE_(SHARED|MODULE|EXE)_LINKER_FLAGS")
              foreach (config SHARED MODULE EXE)
                set(CMAKE_${config}_LINKER_FLAGS_INIT "${QT_LINKER_FLAGS}")
              endforeach()
            endif()
          
            _cmake_initialize_per_config_variable(${ARGV})
          endfunction()
          

          It produces the qmake/qmake6 but it is not a full executable: host's one is 1.8M in size while the target's one is 271 bytes and it's a bash script:

          #!/bin/sh
          
          # The directory of this script is the expanded absolute path of the "$qt_prefix/bin" directory.
          script_dir_path=`dirname $0`
          script_dir_path=`(cd "$script_dir_path"; /bin/pwd)`
          
          /home/ubuntu/qt6/bin_host/bin/qmake6 -qtconf "$script_dir_path/target_qt.conf" $*
          

          Understand me well, it is fully operational and I can cross-compile my projects for my target device without problems from the command line (or using another script). But I cannot add it to QtCreator, which I really would like to achieve. Thus, my question about a qmake with cross-compilation compatibility. Or maybe the problem is the old version of QtCreator?

          jsulmJ Offline
          jsulmJ Offline
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @robgu said in qmake for cross-compiling x86-64 --> armv7:

          /home/ubuntu/qt6/bin_host/bin/qmake6

          Did you try to add that file as qmake executable in QtCreator?

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          R 1 Reply Last reply
          0
          • jsulmJ jsulm

            @robgu said in qmake for cross-compiling x86-64 --> armv7:

            /home/ubuntu/qt6/bin_host/bin/qmake6

            Did you try to add that file as qmake executable in QtCreator?

            R Offline
            R Offline
            robgu
            wrote on last edited by
            #5

            @jsulm Yes, I did try that in the "Kits" section. I get the following error:
            bfcd54d3-8399-450c-9392-de7ededca73a-image.png

            I just realized that the qmake/qmake6 I was trying to add to QtCreator (the script one) was trying to use the host tool that was not existing on the correct path: as in previous post the script tries to access

            /home/ubuntu/qt6/bin_host/bin/qmake6
            

            but this correct path is currently

            /opt/bin_host/bin/qmake6
            

            Once the script files fixed with the correct path I can successfully add the qmake/qmake6 and define my kit.

            @jsulm Thanks again for your questions and iterrest.

            1 Reply Last reply
            0
            • R robgu has marked this topic as solved on

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved