I'm trying to compile a simple C++ / Qt program on windows 10 using:
- msys2 / ucrt / gcc 12.2
- C++ standard 23
- msys2 / Qt6
- cmake 3.25.1
- ninja 1.11.1
I'm not using any IDE nor power shell, just notepad++ and the windows command prompt.
My program.cpp is:
#include <QApplication>
#include <QLabel>
int main()
{
int argc = 1;
const char* argv[1] { "prog" };
QApplication app { argc, const_cast<char**>(argv) };
QLabel *label = new QLabel("Hello Qt!");
label->show();
return app.exec();
}
toolchain.cmake:
set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_C_COMPILER gcc)
set(CMAKE_CXX_COMPILER g++)
My configure.bat is this:
cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=toolchain.cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_VERBOSE_MAKEFILE=ON .
My CMakeLists.txt is this:
cmake_minimum_required(VERSION 3.16)
set(CMAKE_VERBOSE_MAKEFILE on)
project(test_cmake_qt VERSION 0.1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Core Widgets)
qt_standard_project_setup()
qt_add_executable(program_qt_gpp_cmake
program.cpp
)
target_compile_options(program_qt_gpp_cmake PRIVATE -pedantic -Wall -Wextra -Werror=return-type -Wshadow=local -Wempty-body -fno-ms-extensions -fdiagnostics-color -s -Os -fmax-errors=3)
target_link_libraries(program_qt_gpp_cmake PRIVATE
Qt6::Widgets
)
set_target_properties(program_qt_gpp_cmake PROPERTIES
WIN32_EXECUTABLE ON
)
My build.bat script is this:
cmake --build . --config Debug --target program_qt_gpp_cmake
So, I proceed as follows:
configure.bat -> ok
build.bat -> error! undefined reference to `qMain(int, char**)'
(...) 4/4] cmd.exe /C "cd . && C:\programs\msys64\ucrt64\bin\g++.exe -g -mwindows CMakeFiles/program_qt_gpp_cmake.dir/program_qt_gpp_cmake_autogen/mocs_compilation.cpp.obj CMakeFiles/program_qt_gpp_cmake.dir/program.cpp.obj -o program_qt_gpp_cmake.exe -Wl,--out-implib,libprogram_qt_gpp_cmake.dll.a -Wl,--major-image-version,0,--minor-image-version,0 C:/programs/msys64/ucrt64/lib/libQt6Widgets.dll.a C:/programs/msys64/ucrt64/lib/libQt6Gui.dll.a C:/programs/msys64/ucrt64/lib/libQt6Core.dll.a -lmpr -luserenv -lmingw32 C:/programs/msys64/ucrt64/lib/libQt6EntryPoint.a -lshell32 -ld3d11 -ldxgi -ldxguid -ld3d12 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ." FAILED: program_qt_gpp_cmake.exe cmd.exe /C "cd . && C:\programs\msys64\ucrt64\bin\g++.exe -g -mwindows CMakeFiles/program_qt_gpp_cmake.dir/program_qt_gpp_cmake_autogen/mocs_compilation.cpp.obj CMakeFiles/program_qt_gpp_cmake.dir/program.cpp.obj -o program_qt_gpp_cmake.exe -Wl,--out-implib,libprogram_qt_gpp_cmake.dll.a -Wl,--major-image-version,0,--minor-image-version,0 C:/programs/msys64/ucrt64/lib/libQt6Widgets.dll.a C:/programs/msys64/ucrt64/lib/libQt6Gui.dll.a C:/programs/msys64/ucrt64/lib/libQt6Core.dll.a -lmpr -luserenv -lmingw32 C:/programs/msys64/ucrt64/lib/libQt6EntryPoint.a -lshell32 -ld3d11 -ldxgi -ldxguid -ld3d12 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ." C:/programs/msys64/ucrt64/bin/../lib/gcc/x86_64-w64-mingw32/13.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: C:/programs/msys64/ucrt64/lib/libQt6EntryPoint.a(qtentrypoint_win.cpp.obj):(.text+0x11b): undefined reference to `qMain(int, char**)' collect2.exe: error: ld returned 1 exit status ninja: build stopped: subcommand failed.
Why do I get this error? Where is qMain defined and what else should I link (I'm already using Qt6 in the CMakeLists.txt)?
The source of the problem is that the Qt's Windows-specific entrypoint lib expects
main
to have the signatureint main(int, char**)
. Curiously, when compiling with msvc,int main()
seems to work. (qMain
enters the equation only for mingw32 builds, as far as I know. This might explain this phenomenon.)Some background: for mingw32 builds,
#define main qMain
will "mask"main
by renaming it toqMain
.qMain
is declared asint qMain(int, char **);
. Thereforemain
must have signatureint main(int, char**)
.