Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt Creator and other tools
  4. I compiled Windows target on Linux, but is there a standard way to do it?
QtWS25 Last Chance

I compiled Windows target on Linux, but is there a standard way to do it?

Scheduled Pinned Locked Moved Unsolved Qt Creator and other tools
5 Posts 2 Posters 1.7k 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.
  • A.v.OA Offline
    A.v.OA Offline
    A.v.O
    wrote on last edited by
    #1

    Managed to Compile my Windows target on Linux

    It runs in Windows but it is compile with mingw gcc 9.3.
    Since Qt is build using gcc 8.1.0, I wonder how this is working at all?

    And..., Is there a standard solution for this by Qt?

    I have not found it yet.

    There are apparently multiple sets of cmake-files for different platforms which I did not expect.

    My Procedure to make it work

    1. Install the same Qt version (mine is 6.2.0 ) on a Windows Machine (mine is a virtual machine VirtualBox)
    2. Copy only the ./Qt/6.2.0/mingw81_64 directory to your Linux box.
    3. Replace cmake files where Qt finds its tools. (find cmake-files with ".exe" in it)
    4. Add symlink for libexec sub dir needed for the Linux tools.
    5. Install mingw 64 bit on Linux (packages gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64)
    6. Create a Windows Tool Chain cmake-file and include it in the CMakeLists.txt project.
    7. Since I used the STL in my project I needed to add the gcc 9.3 libstdc++-6.dll file in the exe-directory.
      The PATH environment variable was added the Qt path for DLL's (mine is P:\Qt\6.2.0\mingw81_64\bin)
      Using: C:\Windows\System32\rundll32.exe sysdm.cpl,EditEnvironmentVariables

    .

    CMake Windows tool chain file WindowsToolChain.cmake

    # Notify that this file was loaded.
    message("Linux compiling for Windows.")
    
    # Allow cmake to find the Qt library (this could be automated and version independent)
    list(APPEND CMAKE_PREFIX_PATH "/mnt/server/userdata/project/PROG/Qt/6.2.0/mingw81_64/lib/cmake/")
    
    # Targeted operating system.
    set(CMAKE_SYSTEM_NAME Windows)
    
    # Use mingw 64-bit compilers.
    set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc-posix)
    set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-c++-posix)
    set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32/)
    
    # Adjust the default behavior of the find commands:
    # search headers and libraries in the target environment
    set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
    set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
    
    # Search programs in the host environment
    set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
    

    CMake addition to invoke tool chain file when CROSS_WINDOWS is defined

    ---
    # Check if this is a cross compile for windows. (cmake -DCROSS_WINDOWS=ON)
    if (DEFINED CROSS_WINDOWS)
    	set(CMAKE_TOOLCHAIN_FILE com/cmake/SfWindowsToolChain.cmake)
    endif ()
    ---
    

    Bash script having all the parts that were done to make it happen

    #!/bin/bash
    
    ##
    ## Install only 64bit compilers.
    ##
    sudo apt install gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64
    
    # Directory where the Linux Qt library cmake files are located.
    DIR_FROM="${HOME}/lib/Qt/6.2.0/gcc_64/lib/cmake"
    # Root for the Windows Qt installed MinGW files.
    ROOT_DIR="/mnt/server/userdata/project/PROG/Qt/6.2.0/mingw81_64"
    # Directory where the Windows Qt library cmake files are located.
    DIR_TO="${ROOT_DIR}/lib/cmake"
    
    ##
    ## Create symlink in from ~/lib/Qt/6.2.0/gcc_64/libexec to ${ROOT_DIR}
    ##
    ln -s "${HOME}/lib/Qt/6.2.0/gcc_64/libexec" "${ROOT_DIR}/libexec"
    
    ##
    ## Replace all cmake files referencing windows EXE-tools.
    ## Found using (could be automated):
    ## 	find /mnt/server/userdata/project/PROG/Qt/6.2.0/mingw81_64 -type f -name "*.cmake" -exec grep -li "\.exe" {} \;
    ##
    declare -a MODULES=(
    	"Qt6AxContainerTools/Qt6AxContainerToolsTargets-relwithdebinfo.cmake"
    	"Qt6AxServerTools/Qt6AxServerToolsTargets-relwithdebinfo.cmake"
    	"Qt6DBusTools/Qt6DBusToolsTargets-relwithdebinfo.cmake"
    	"Qt6GuiTools/win/Qt6GuiToolsTargets-relwithdebinfo.cmake"
    	"Qt6LinguistTools/Qt6LinguistToolsTargets-relwithdebinfo.cmake"
    	"Qt6QmlTools/Qt6QmlToolsTargets-relwithdebinfo.cmake"
    	"Qt6RemoteObjectsTools/Qt6RemoteObjectsToolsTargets-relwithdebinfo.cmake"
    	"Qt6ScxmlTools/Qt6ScxmlToolsTargets-relwithdebinfo.cmake"
    	"Qt6SerialBusTools/Qt6SerialBusToolsTargets-relwithdebinfo.cmake"
    	"Qt6ToolsTools/Qt6ToolsToolsTargets-relwithdebinfo.cmake"
    	"Qt6WidgetsTools/Qt6WidgetsToolsTargets-relwithdebinfo.cmake"
    )
    # Iterate the string array using for loop
    for fn in "${MODULES[@]}" ; do
    	cp "${DIR_FROM}/${fn}" "${DIR_TO}/${fn}"
    done
    
    
    jsulmJ 1 Reply Last reply
    2
    • A.v.OA A.v.O

      Managed to Compile my Windows target on Linux

      It runs in Windows but it is compile with mingw gcc 9.3.
      Since Qt is build using gcc 8.1.0, I wonder how this is working at all?

      And..., Is there a standard solution for this by Qt?

      I have not found it yet.

      There are apparently multiple sets of cmake-files for different platforms which I did not expect.

      My Procedure to make it work

      1. Install the same Qt version (mine is 6.2.0 ) on a Windows Machine (mine is a virtual machine VirtualBox)
      2. Copy only the ./Qt/6.2.0/mingw81_64 directory to your Linux box.
      3. Replace cmake files where Qt finds its tools. (find cmake-files with ".exe" in it)
      4. Add symlink for libexec sub dir needed for the Linux tools.
      5. Install mingw 64 bit on Linux (packages gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64)
      6. Create a Windows Tool Chain cmake-file and include it in the CMakeLists.txt project.
      7. Since I used the STL in my project I needed to add the gcc 9.3 libstdc++-6.dll file in the exe-directory.
        The PATH environment variable was added the Qt path for DLL's (mine is P:\Qt\6.2.0\mingw81_64\bin)
        Using: C:\Windows\System32\rundll32.exe sysdm.cpl,EditEnvironmentVariables

      .

      CMake Windows tool chain file WindowsToolChain.cmake

      # Notify that this file was loaded.
      message("Linux compiling for Windows.")
      
      # Allow cmake to find the Qt library (this could be automated and version independent)
      list(APPEND CMAKE_PREFIX_PATH "/mnt/server/userdata/project/PROG/Qt/6.2.0/mingw81_64/lib/cmake/")
      
      # Targeted operating system.
      set(CMAKE_SYSTEM_NAME Windows)
      
      # Use mingw 64-bit compilers.
      set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc-posix)
      set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-c++-posix)
      set(CMAKE_FIND_ROOT_PATH /usr/x86_64-w64-mingw32/)
      
      # Adjust the default behavior of the find commands:
      # search headers and libraries in the target environment
      set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
      set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
      
      # Search programs in the host environment
      set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
      

      CMake addition to invoke tool chain file when CROSS_WINDOWS is defined

      ---
      # Check if this is a cross compile for windows. (cmake -DCROSS_WINDOWS=ON)
      if (DEFINED CROSS_WINDOWS)
      	set(CMAKE_TOOLCHAIN_FILE com/cmake/SfWindowsToolChain.cmake)
      endif ()
      ---
      

      Bash script having all the parts that were done to make it happen

      #!/bin/bash
      
      ##
      ## Install only 64bit compilers.
      ##
      sudo apt install gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64
      
      # Directory where the Linux Qt library cmake files are located.
      DIR_FROM="${HOME}/lib/Qt/6.2.0/gcc_64/lib/cmake"
      # Root for the Windows Qt installed MinGW files.
      ROOT_DIR="/mnt/server/userdata/project/PROG/Qt/6.2.0/mingw81_64"
      # Directory where the Windows Qt library cmake files are located.
      DIR_TO="${ROOT_DIR}/lib/cmake"
      
      ##
      ## Create symlink in from ~/lib/Qt/6.2.0/gcc_64/libexec to ${ROOT_DIR}
      ##
      ln -s "${HOME}/lib/Qt/6.2.0/gcc_64/libexec" "${ROOT_DIR}/libexec"
      
      ##
      ## Replace all cmake files referencing windows EXE-tools.
      ## Found using (could be automated):
      ## 	find /mnt/server/userdata/project/PROG/Qt/6.2.0/mingw81_64 -type f -name "*.cmake" -exec grep -li "\.exe" {} \;
      ##
      declare -a MODULES=(
      	"Qt6AxContainerTools/Qt6AxContainerToolsTargets-relwithdebinfo.cmake"
      	"Qt6AxServerTools/Qt6AxServerToolsTargets-relwithdebinfo.cmake"
      	"Qt6DBusTools/Qt6DBusToolsTargets-relwithdebinfo.cmake"
      	"Qt6GuiTools/win/Qt6GuiToolsTargets-relwithdebinfo.cmake"
      	"Qt6LinguistTools/Qt6LinguistToolsTargets-relwithdebinfo.cmake"
      	"Qt6QmlTools/Qt6QmlToolsTargets-relwithdebinfo.cmake"
      	"Qt6RemoteObjectsTools/Qt6RemoteObjectsToolsTargets-relwithdebinfo.cmake"
      	"Qt6ScxmlTools/Qt6ScxmlToolsTargets-relwithdebinfo.cmake"
      	"Qt6SerialBusTools/Qt6SerialBusToolsTargets-relwithdebinfo.cmake"
      	"Qt6ToolsTools/Qt6ToolsToolsTargets-relwithdebinfo.cmake"
      	"Qt6WidgetsTools/Qt6WidgetsToolsTargets-relwithdebinfo.cmake"
      )
      # Iterate the string array using for loop
      for fn in "${MODULES[@]}" ; do
      	cp "${DIR_FROM}/${fn}" "${DIR_TO}/${fn}"
      done
      
      
      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @A-v-O said in I compiled Windows target on Linux, but is there a standard way to do it?:

      Install the same Qt version (mine is 6.2.0 ) on a Windows Machine (mine is a virtual machine VirtualBox)

      Why don't you simply build your app on that Windows machine?
      If you want to cross compile you actually would need to cross compile Qt with MinGW. But I never did this as it is way easier to simply build on Windows.

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

      1 Reply Last reply
      0
      • A.v.OA Offline
        A.v.OA Offline
        A.v.O
        wrote on last edited by A.v.O
        #3

        @jsulm said in I compiled Windows target on Linux, but is there a standard way to do it?:

        If you want to cross compile you actually would need to cross compile Qt with MinGW. But I never did this as it is way easier to simply build on Windows.

        I did till now build on Windows, but it is to much of a hassle switch between Linux and Windows.
        Now I can easily select in my CLion IDE what target to compile with 2 clicks.

        713b58a6-d040-4420-a3e8-79aa2c36b02b-image.png

        WDebug is the cross compile version
        And it is easy to check if changes made in Linux als can be compiled in Windows. (#if WIN32 #else #endif)
        Even run the compiled code from the VM to check the result.

        My code is on a Linux server mounted on my workstation system with nfs.
        I tried compiling through Linux samba share on Windows which made it not happy being remote.
        Because of that you need local sources and use git creating unnecessary commits that are not even squashable before a push.
        The VM is on the server too by the way which I connect to on my workstation.

        cb052276-379e-4902-b386-a3af1dcf63be-image.png

        All in all, it is less time consuming this way.

        The Windows build from Linux is also a lot faster.

        jsulmJ 1 Reply Last reply
        0
        • A.v.OA A.v.O

          @jsulm said in I compiled Windows target on Linux, but is there a standard way to do it?:

          If you want to cross compile you actually would need to cross compile Qt with MinGW. But I never did this as it is way easier to simply build on Windows.

          I did till now build on Windows, but it is to much of a hassle switch between Linux and Windows.
          Now I can easily select in my CLion IDE what target to compile with 2 clicks.

          713b58a6-d040-4420-a3e8-79aa2c36b02b-image.png

          WDebug is the cross compile version
          And it is easy to check if changes made in Linux als can be compiled in Windows. (#if WIN32 #else #endif)
          Even run the compiled code from the VM to check the result.

          My code is on a Linux server mounted on my workstation system with nfs.
          I tried compiling through Linux samba share on Windows which made it not happy being remote.
          Because of that you need local sources and use git creating unnecessary commits that are not even squashable before a push.
          The VM is on the server too by the way which I connect to on my workstation.

          cb052276-379e-4902-b386-a3af1dcf63be-image.png

          All in all, it is less time consuming this way.

          The Windows build from Linux is also a lot faster.

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

          @A-v-O No problem!
          Thanks for sharing!

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

          1 Reply Last reply
          0
          • A.v.OA Offline
            A.v.OA Offline
            A.v.O
            wrote on last edited by
            #5

            Update on Cross-Compiling

            In the mean time I created GitHub repository which demonstrates the use of a privately hosted Docker image assembled by using this GitHub repository and its script cpp-builder.sh. (It is a lot easier to download/pull the Docker image from nexus.scanframe.com:8090/gnu-cpp:dev)
            It accommodates building Qt Linux and Windows targets as well as performing unit testing.
            A GitLab runner uses it to execute a pipeline which executes a CMakePreset-workflow.
            The same Docker image is used to build, run, debug and test locally by mounting the X-server socket into the Docker VM.
            Preset allow workflows and individual presets to be executed using the script docker-build.sh.

            db3a80ff-0a8f-4d5f-b91a-d3df52e0b3a2-image.png

            Hopefully someone can benefit from my work on this :)

            1 Reply Last reply
            0

            • Login

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