How to use host tools using find_package when cross-compiling (eg. Qt5LinguistTools)

Hi,

I’m trying to do this:

  • 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
  • Something else I don’t know yet :slight_smile:

Note: the exact context is building QJackCtl for Windows from a Ubuntu 20.04 system using github actions and a cross compiled Qt:
https://github.com/DISTRHO/PawPaw/pull/20#pullrequestreview-773246728

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:

<prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/
<prefix>/(lib/<arch>|lib*|share)/<name>*/
<prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/

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.