1

I was trying to build an executable using CMake, Qt and Visual Studio that doesn't show the console window.

I found this post and this answer

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ENTRY:mainCRTStartup")

But I was wondering how QtCreator is able to build an executable that doesn't show the console window without this /ENTRY flag?

Community
  • 1
  • 1
McLeary
  • 1,231
  • 2
  • 13
  • 21
  • I don't know what your question really is. Is it that the same binary opens a console when you start it from explorer and it does not when you start it within QtCreator? The reason is that QtCreator starts it in its own console (included in the GUI as Application Output window). Pretty much like when you open a console yourself with cmd and start it from there. – ypnos Aug 31 '13 at 22:40
  • My question is how the binary build with qt creator does *not* open the console when running through explorer since it does not provide the /entry flag when linking the application. – McLeary Aug 31 '13 at 22:55

1 Answers1

7

To avoid a console window in a Qt project, which uses CMake and Visual Studio, four entries in the CMakeLists.txt are necessary:

  1. SET(QT_USE_QMAIN true)
  2. INCLUDE(${QT_USE_FILE})
  3. ${QT_LIBARIES}
  4. Add WIN32 to ADD_EXECUTABLE

ADD_EXECUTABLE look then like this:

     ADD_EXECUTABLE(YourProject WIN32
           ...stuff...
     )

For Visual Studio all four steps are necessary. For MinGW step 4 seems to be sufficient. Step 1 must come before step 2.

What do those steps do?

QT_USE_QMAIN is defined in include/QtGui/qwindowdefs.h in the Qt sources. Surprisingly it does nothing else, but:

#if defined(QT_NEEDS_QMAIN)
#define main qMain
#endif

With this Qt defines its own entry point. Of course, this needs qMain to be defined somewhere. Therefore it is necessary to include an extra library, which is called QtMain.lib.

Step 2 is the usual CMake way to find libraries. In this case it includes: path/cmake-2.8/Modules/UseQt4.cmake (Qt4).

Step 3 actually links the found QtMain.lib.

Step 4 causes Windows to use the /subsystem:windows instead of /subsystem:console

The nice thing about this, is that step 1-3 might not be necessary under MinGW, but don't hurt either. So there is no need to distinguish between Visual Studio and MinGW. However, I tested only with Qt4. It might be different for Qt5.

Greenflow
  • 3,935
  • 2
  • 17
  • 28
  • Only this won't solve the problem since the entry point still is winmain instead of plain main. – McLeary Aug 31 '13 at 22:56
  • Solved my problem. Programs I compiled with it, did not show any console window anymore. But I don't use Visual Studio, but the MinGW. Wonder if this makes a difference. – Greenflow Aug 31 '13 at 23:14
  • Yes it does. Visual Studio try to use WinMain entry function. I had to set `CMAKE_EXE_LINKER_FLAGS` like in the question but I still don't know how Qt creator build is able to not show the console. – McLeary Aug 31 '13 at 23:43
  • This is interesting. I'll keep this in mind. But I doubt that QtCreator does anything special. It creates a project file and passes it to the compiler. It should not have any 'special powers'. It is just a frontend for all kinds of development tools. Whatever it creates from your CMakeLists.txt should be identical to what you get when you do it with the cmake tools. – Greenflow Aug 31 '13 at 23:54
  • Add SET(QT_USE_QMAIN true) before the INCLUDE( ${QT_USE_FILE} ) and link with ${QT_LIBARIES} after you do as this answer said. – drescherjm Sep 01 '13 at 01:21
  • 2
    @drescherjm, where on earth does this variable come from? I search google: One unique hit. Does not say much more than 'use this variable'. Search on kitware: Nothing. If this really solves McLeary's problem, you should make it a proper answer. Seems to be **very** rare. – Greenflow Sep 01 '13 at 01:37
  • 1
    I found it. In the Qt sources: `include/QtGui/qwindowdefs.h:#if defined(QT_NEEDS_QMAIN)`. As I said: If this really works, it needs a **good** answer. The documentation about this define is horribly thin. – Greenflow Sep 01 '13 at 01:51
  • 2
    I had to solve this same issue last week. I had vaguely remembered that the QTMAIN was needed to solve the linking of main so I googled and that led me to enabling QT_USE_QMAIN in my CMakeLists.txt – drescherjm Sep 01 '13 at 02:21
  • Anyone is a volunteer to post a proper answer? If no one is avaiable I'll post an answer myself, this need to be documented. – McLeary Sep 01 '13 at 02:57
  • Did it work? Though I am currently not working with Visual Studio, I am very interested in stuff like that. – Greenflow Sep 01 '13 at 02:59
  • If nobody beats me to it, I'll do it in a few hrs. Sleep time now. And I want to try if I can have the same solution for MinGW and Visual Studio. The QT_USE_QMAIN is not necessary for MinGW. But it would be nice, if it does not matter if it is nevertheless there, so it would not be necessary to differentiate between compilers. – Greenflow Sep 01 '13 at 03:19