Unsolved Compile Qt 5.6 for Windows Ce 6.0 linking issue
-
Dear Community,
i'm trying to cross-compile Qt 5.6 for Windows CE 6.0. I have VS2008 set up, and the vendor's SDK (Motorola MC3100c60 Windows CE6.0 PSDK (ARMV4I)) installed, and i can compile/run a simple testapp from VS2008.
I set up a custom qmakespec for Qt, here:include(../common/wince/qmake.conf) CE_SDK = Motorola MC3100c60 Windows CE6.0 PSDK # replace with actual SDK name CE_ARCH = ARMV4I DEFINES += WINCE _WINDOWS WINDOWS_CE_OS _WIN32_WCE=0x600 UNDER_CE=0x600 ARM ARM ARMV4I _CRT_SECURE_NO_DEPRECATE $$CE_ARCH QT_NO_CLIPBOARD DEFINES += QT_NO_ACCESSIBILITY QT_NO_NATIVE_GESTURES QT_NO_DRAGANDDROP QT_NO_WIN_ACTIVEQT QT_NOSTANDARDSHELL_UI_MODEL ARMV4I _M_ARM arm _ARM_ ARM _M_ARM ARM _WIN32 __arm__ QMAKE_LFLAGS_CONSOLE = /SUBSYSTEM:WINDOWSCE,6.00 /MACHINE:THUMB QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWSCE,6.00 /MACHINE:THUMB QMAKE_LFLAGS_DLL = /MACHINE:THUMB /DLL /SAFESEH:NO /VERBOSE QMAKE_LIBFLAGS_RELEASE = /LTCG QMAKE_LIBS = coredll.lib corelibc.lib QMAKE_LIBS_CORE = corelibc.lib libcmt.lib ole32.lib oleaut32.lib uuid.lib commctrl.lib coredll.lib winsock.lib QMAKE_LIBS_GUI = ceshell.lib ole32.lib $$QMAKE_LIBS_CORE QMAKE_LIBS_NETWORK = ws2.lib $$QMAKE_LIBS_GUI QMAKE_LIBS_OPENGL = QMAKE_LIBS_COMPAT = QMAKE_RC = rc /DUNDER_CE=600 /D_WIN32_WCE=0x600
and i configure Qt from the corresponding environment as:
configure -platform win32-msvc2008 -xplatform wince60standard-armv4i-msvc2008 -opensource -nomake examples -no-compile-examples -qt-zlib -no-accessibility -no-native-gestures -qt-pcre -no-icu -no-gif -qt-libpng -no-opengl -skip winextras -confirm-license -verbose -release
The configure runs properly, but when building, the linking of QtCore fails with:
corelibc.lib(crtstrta.obj) : error LNK2019: unresolved external symbol main referenced in function "void __cdecl mainCRTStartupHelper(struct HINSTANCE__ *,unsigned short const *)" (?mainCRTStartupHelper@@YAXPAUHINSTANCE__@@PBG@Z) ..\..\lib\Qt5Core.dll : fatal error LNK1120: 1 unresolved externals
however, according to my understanding, it shouldn't look for 'main', but for "WinMain", which is in winmain_qt.cpp.
I've tried to specify custom \ENTRY points on the linker command line, but after that the linker was still looking for 'main()'.
Unfortunately my google-fu didn't help too much, i found only this unanswered question at the Qt devel mailing list:
http://lists.qt-project.org/pipermail/development/2014-October/018645.htmlI think/fear it's somewhat related to the SDK ("Windows CE Platform SDK v1.5.4 for MC3100c60" provided by Zebra).
Did anybody else seen (or even fixed...) this issue? -
After thinking on this more, my guess would be that the missing "main()" function is only could the one from the target executable, but as i'm builing a .dll here, it shouldn't be be a problem if it's not present at linking time. (As it will be linked runtime). So maybe the Visual Studio linker doesn't understand that it has to build a .dll (while the \DLL switch is set....)?
-
Hi
I'm having exactly the same problem. Have you found a solution after all? -
I have the same problem too. Is anybody have solution?
-
Found the reason for the problem in somebody else post:
link textThe reason the linker is looking for wmain, is because the C++ code is referencing __argv[].
__argv[] is the method console apps use to determine the command line arguments. For some reason, just by referencing this variable, the linker wants to start with wmain, which will allow that variable to be filled in. By commenting out the reference to __argv[], the linker no longer is looking for wmain, and starts with WinMain as expected.What a bizarre error, and very difficult to find. This seems to be unique to CE, as this is not the behavior for Win32.
I solved it in qcoreapplication.cpp by excluding the code that references __argv
#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) // Check whether the command line arguments match those passed to main() // by comparing to the global __argv/__argc (MS extension). // Deep comparison is required since argv/argc is rebuilt by WinMain for // GUI apps or when using MinGW due to its globbing. static inline bool isArgvModified(int argc, char **argv) { #if (!defined(Q_OS_WINCE) || _WIN32_WCE>0x600) if (__argc != argc || !__argv /* wmain() */) return true; if (__argv == argv) return false; for (int a = 0; a < argc; ++a) { if (argv[a] != __argv[a] && strcmp(argv[a], __argv[a])) return true; } #endif return false; }