Cross compile a Qt application: building on Linux and target Windows using MinGW
I have a cross compiled Qt already
Use Qt Linguists tools from the host using find_package(Qt5LinguistTools) to build translations files
I’m using Ubuntu 20.04
The issue is that find_package won’t find the host’s Qt5LinguistTools because Qt5LinguistTools is in this directory: /usr/lib/x86_64-linux-gnu/cmake/Qt5LinguistTools/Qt5LinguistToolsConfig.cmake
And when cross compiling, cmake won’t look in this directory with find_package as CMAKE_LIB_ARCHITECTURE is empty.
I can workaround that issue by using -DCMAKE_PREFIX_PATH=/usr/lib/x86_64-linux-gnu/cmake, but that will work only for Debian derivatives on x86_64 cpu.
Is there a way to cleanly handle this case ?
I think about several solutions:
There is an option or something in CMake that can make this work more easily
Qt tools should not be in a arch-dependent directory to be usable when cross-compiling
Yeah, it’s a little ambiguous whether the program is intended to be used in the host or the target environment given just a plain find_program (e.g., the path might end up embedded into the target binary in some way). Same thing with find_package at the core. What I’ve normally done in this situation is make a CMake package named FooHostTools which is searched for when cross-compiling. This doesn’t help with Qt directly, but it might give you a path to making this work.
Alternatively, you can (ab)use binfmt_misc to let Linux just execute the Windows binary or you can try and set wine as the CMAKE_CROSSCOMPILING_EMULATOR (not sure if/how that applies to imported targets though).
The issue is that the Qt5LinguistTools package provides functions like qt_add_translation.
So the proposed solution would be to this ?
Add a package in the project for example in cmake/Qt5LinguistHostTools.cmake
In this file, use find_program to find host tools (lrelease and lupdate programs)
In this file, implement the qt_add_translation macro that uses host tools with the same behavior as the original /usr/lib/x86_64-linux-gnu/cmake/Qt5LinguistTools/Qt5LinguistToolsMacros.cmake
Currently, I’m doing this (join is a function that concat all glob results): CMAKE_PREFIX_PATH="/usr/lib/cmake;$(join ';' /usr/{lib/$(gcc -print-multiarch),lib*,share}/cmake)"
to match the find_package documentation where it is said to search paths matching this:
To me this bash solution seems to be less maintenance as I don’t need to maintain a copy of Qt’s cmake macros like qt_add_translation (but requires bash …)
Ah, yes. CMake APIs certainly do make it more difficult. Yes, something along those lines would be what I would recommend for a proper fix. VTK does it by having the APIs detect the host-side tools and using them if they’re available. Not perfect, but I don’t have a better solution on hand.