Cross-compile Qt 5.9.1 with MSVC 2017 x64 to x86 fails with linker error
I have been trying to build Qt 5.9.1 from source on a 64bit Windows 10 machine to x86 Windows platforms. I know that Qt binaries are shipped for 32 bit too, but in the case of 5.9.1 only for MSVC 2015 and not MSVC 2017. For other reasons I must use MSVC 2017.
To cross-compile I have used the MSVC 2017 amd64 to x86 cross compiler. (Set up my environment by running vcvars.bat amd64_x86). I checked my path to make sure and it seems that it points to the correct toolchain, which is x64 host, x86 target.
Then I ran the Qt configuration script such as:
configure -debug -nomake docs -nomake examples -nomake demos -no-webkit -fast -opensource
I have also tried to set the -platform and -xplatform arguments but in the case of MSVC it seems that I can not make any difference as both 32 and 64 bit platforms would use the mkspec of win32-msvc. (And if not set, xplatform seems to default to platform)
The configuration fails at the step when it tries to link qmake.exe with the following:
libcmt.lib(chkstk.obj) : module machine type 'X86' conflicts with target machine type 'x64'
So it seems that it tries to make qmake for a 64 bit machine - I suppose to be able to use it on my 64 bit machine to build the Qt libraries (is that right?).
Could you help me figure this out and be able to cross compile Qt 5.9.1 from x64 to x86? (I know I could build natively on a x86 machine with native toolchain, but as for now, let us assume that this is not an option. )
Also if you find some conceptional error in the way of work please let me know.
Thank you for your help,
But vs 2015 and vs 2017 are compatible ?
( for the first time)
Are you sure you need to compile anything your self?
AFAIK they are. Still I would like to know what happens, it should be feasible to cross compile Qt from x64 to x86.
So far it seems, no matter what I do (tried passing -device-options, creating own mkspec for specific 32 bit platform, not to use the common msvc mkspec), after configuration my target architecture is set to x86_64 in qtbase/mkspecs/qconfig.pri. Also at the configuration phase when running config tests I get the message that target platform is x86_64.
What parameters shall I pass to the configure script to make it change? Has anyone tried this before?
Did you try the
x86 Native Tools Command Prompt?
Also, how did you setup your build environment for the cross-compilation ?
Thanks for the response!
I might have a conceptional misunderstanding. I have tried to set MSVC to x64 to x86 cross-compilation, thus ran vcvars.bat amd64_x86. Isn't the x86 Native Tool Command Prompt (i.e. vcvars.bat x86) for native compilation? Meaning that compile on a x86 host to a x86 target? I aim to build on a x64 host to a x86 machine, which means that all my build tools (e.g. qmake) shall be compiled with a native compiler (because I would run them on my 64-bit host), and all the libs I intend to deploy should be compiled to x86.
(So basically this is how I set my build environment for CC, running visual studio 2017's configuration script - vcvars.bat)
@v5exp4 There is no need to compile the build tools for x86 as x86_64 can execute x86 binaries.
@jsulm Yes, that is true. However if I set my environment to a x86 toolchain (either amd64_x86 cross or even native x86) it would throw me the same error, meaning that the linker is targeting x64 for my build tools, such as qmake, while my libraries are compiled to x86. Therefore I get the architecture mismatch mentioned in my original post.
It seems that during the configuration of the Qt build it tries and discovers the host platform and sets the target for qmake automatically. Which is fine for me, as I would run qmake on x64 however I need my libraries built for x86 targets.
@SGaist I tried using the native tools, but it would throw me the very same error.
I was wrong before. I could properly compile with x86 native tools on x64. The problem was that after previous configurations the cache files were not cleaned properly and setup was stuck for x64 target.
So the problem is worked around, however I still expect that it should be possible to compile with the x64_x86 cross tools. When I run the configure.bat script, the target architecture is listed as x64 (should be i386). Seems that no matter what I do, what flags I try to pass, this is unchanged. Seems that this value is somehow derived from the compiler itself and I am unable to set it to i386 instead of x64.
Does anybody know what flags are necessary to be passed to actually set the target architecture to i386?
Thank you for all your help,
Is it me or does it look like QTBUG-43457 ?
@SGaist Exactly! Thank you for finding it. I will apply the patch, see how it goes and mark this as solved.
I have checked the source code of the qmakeevaluator and the changes are present in version 5.9.1, still it does not recognize the platform. Even if I try to hardcode to the qmake evaluator the following:
vars[ProKey("QMAKE_TARGET.arch")] = ProString("x86");
It does not change a thing, still tries to link qmake to x64.