Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MinGW: CATCH_CONFIG_MAIN defines the non-standard WinMain instead of the standard main function #2437

Open
aminya opened this issue May 29, 2022 · 11 comments

Comments

@aminya
Copy link

aminya commented May 29, 2022

Describe the bug
Once you define the CATCH_CONFIG_MAIN definition on MinGW, it defines a non-standard main function called WinMain. This results in a lot of undefined references. This doesn't happen with other compilers.

https://github.com/aminya/cpp_vcpkg_project/runs/6542106054?check_suite_focus=true#step:6:203

[6/18] Linking CXX executable my_exe\test\Debug\my_exe_helpers_tests.exe
FAILED: my_exe/test/Debug/my_exe_helpers_tests.exe 
cmd.exe /C "cd . && C:\Users\runneradmin\gcc\mingw64\bin\g++.exe -g  my_exe/test/CMakeFiles/my_exe_helpers_tests.dir/Debug/tests.cpp.obj -o my_exe\test\Debug\my_exe_helpers_tests.exe -Wl,--out-implib,my_exe\test\Debug\libmy_exe_helpers_tests.dll.a -Wl,--major-image-version,0,--minor-image-version,0  vcpkg_installed/x64-mingw-static/debug/lib/libfmtd.a  --coverage  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
c:/users/runneradmin/gcc/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: c:/users/runneradmin/gcc/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o):crt0_c.c:(.text+0x46): undefined reference to `WinMain'
collect2.exe: error: ld returned 1 exit status
[7/18] Linking CXX executable my_lib\test\Debug\my_lib_tests.exe
FAILED: my_lib/test/Debug/my_lib_tests.exe my_lib/test/my_lib_tests_tests-84286ba.cmake D:/a/cpp_vcpkg_project/cpp_vcpkg_project/build/my_lib/test/my_lib_tests_tests-84286ba.cmake 
cmd.exe /C "cd . && C:\Users\runneradmin\gcc\mingw64\bin\g++.exe -g  my_lib/test/CMakeFiles/my_lib_tests.dir/Debug/tests.cpp.obj -o my_lib\test\Debug\my_lib_tests.exe -Wl,--out-implib,my_lib\test\Debug\libmy_lib_tests.dll.a -Wl,--major-image-version,0,--minor-image-version,0  my_lib/Debug/libmy_lib.a  --coverage  vcpkg_installed/x64-mingw-static/debug/lib/libfmtd.a  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cmd.exe /C "cd /D D:\a\cpp_vcpkg_project\cpp_vcpkg_project\build\my_lib\test && C:\Users\runneradmin\cmake\cmake-3.23.1-windows-x86_64\bin\cmake.exe -D TEST_TARGET=my_lib_tests -D TEST_EXECUTABLE=D:/a/cpp_vcpkg_project/cpp_vcpkg_project/build/my_lib/test/Debug/my_lib_tests.exe -D TEST_EXECUTOR= -D TEST_WORKING_DIR=D:/a/cpp_vcpkg_project/cpp_vcpkg_project/build/my_lib/test -D TEST_SPEC= -D TEST_EXTRA_ARGS= -D TEST_PROPERTIES= -D TEST_PREFIX= -D TEST_SUFFIX= -D TEST_LIST=my_lib_tests_TESTS -D TEST_REPORTER=xml -D TEST_OUTPUT_DIR= -D TEST_OUTPUT_PREFIX= -D TEST_OUTPUT_SUFFIX= -D CTEST_FILE=D:/a/cpp_vcpkg_project/cpp_vcpkg_project/build/my_lib/test/my_lib_tests_tests-84286ba.cmake -P D:/a/cpp_vcpkg_project/cpp_vcpkg_project/build/vcpkg_installed/x64-mingw-static/share/catch2/CatchAddTests.cmake""
c:/users/runneradmin/gcc/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: c:/users/runneradmin/gcc/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o):crt0_c.c:(.text+0x46): undefined reference to `WinMain'
collect2.exe: error: ld returned 1 exit status
[8/18] Building CXX object my_header_lib/test/constexpr/CMakeFiles/my_header_lib_relaxed_constexpr_tests.dir/Debug/constexpr_tests.cpp.obj
Checking D:\a\cpp_vcpkg_project\cpp_vcpkg_project\my_header_lib\test\constexpr\constexpr_tests.cpp ...
Checking D:\a\cpp_vcpkg_project\cpp_vcpkg_project\my_header_lib\test\constexpr\constexpr_tests.cpp: CATCH_CONFIG_MAIN=1;CATCH_CONFIG_RUNTIME_STATIC_REQUIRE=1;FMT_LOCALE=1;UNICODE=1;_UNICODE=1;CMAKE_INTDIR="Debug"...
ninja: build stopped: subcommand failed.
task: Failed to run task "coverage": task: Failed to run task "build_template": exit status 1

Expected behavior
CATCH_CONFIG_MAIN should define a standard main on MinGW

Reproduction steps

Platform information:

  • OS: Windows NT
  • Compiler+version: GCC v11
  • Catch version: v2.13.7

Additional context

Blocks aminya/project_options#129
Related issues:

@aminya
Copy link
Author

aminya commented Jun 1, 2022

There is an explicit code that results in this issue. I don't know why just Catch2 doesn't use main on Windows similar to others!

#if defined(CATCH_CONFIG_WCHAR) && defined(CATCH_PLATFORM_WINDOWS) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN)
// Standard C/C++ Win32 Unicode wmain entry point
extern "C" int wmain (int argc, wchar_t * argv[], wchar_t * []) {

@horenmar
Copy link
Member

horenmar commented Jun 5, 2022

I am pretty sure you are wrong here.

This linking error:

c:/users/runneradmin/gcc/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o):crt0_c.c:(.text+0x46): undefined reference to `WinMain'

means that libmingw32.a is missing the reference to WinMain (because Catch2 doesn't provide it, it isn't a GUI subsystem application).

From a quick google, the issue is that you need to add -municode when building the executable (likely the link step is enough) so that MinGW understands to target wmain entry point and not main entry point.

@aminya
Copy link
Author

aminya commented Jun 5, 2022

Adding -municode doesn't fix undefined references to `WinMain'
aminya/project_options#129

Why do you want to use non-standard wmain on Windows?

@horenmar
Copy link
Member

horenmar commented Jun 5, 2022

-municode needs to be added as link option, not compile option.

As to your question, wmain is used on Windows, when you provide _UNICODE define during compilation. This means that you require support for unicode, which requires wmain so that you can accept wchar_t (unicode-ish) arguments.

@aminya
Copy link
Author

aminya commented Jun 9, 2022

If you want to keep this Unicode default on MinGW, you should handle -municode inside Catch2's CMake files. By default, it is not possible to build a simple test on MinGW.

@aminya
Copy link
Author

aminya commented Jun 9, 2022

Adding -municode to the link options changes the error: undefined reference to 'wWinMain'

https://github.com/aminya/project_options/runs/6819912259?check_suite_focus=true#step:5:458

cmd.exe /C "cd . && C:\Users\runneradmin\gcc\mingw64\bin\g++.exe -O3 -DNDEBUG -municode CMakeFiles/main.dir/Release/src/main/main.cpp.obj -o Release\main.exe -Wl,--out-implib,Release\libmain.dll.a -Wl,--major-image-version,0,--minor-image-version,0  vcpkg_installed/x64-mingw-static/lib/libfmt.a  --coverage  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cmd.exe /C "cd /D D:\a\project_options\project_options\test\build && "C:\Program Files\PowerShell\7\pwsh.exe" -noprofile -executionpolicy Bypass -file C:/Users/runneradmin/vcpkg/scripts/buildsystems/msbuild/applocal.ps1 -targetBinary D:/a/project_options/project_options/test/build/Release/main.exe -installedDir D:/a/project_options/project_options/test/build/vcpkg_installed/x64-mingw-static/bin -OutVariable out""
c:/users/runneradmin/gcc/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: c:/users/runneradmin/gcc/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/11.3.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_w.o):crt0_w.c:(.text+0x41): undefined reference to `wWinMain'

@aminya
Copy link
Author

aminya commented Jun 20, 2022

Mingw doesn't use wmain as wWinMain. It might be because the function prototype looks different than what Catch2 is using.

https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/#unicode-applications

Current MinGW status:

  • Doesn't compile without Unicode because of an undefined reference to WinMain.
  • Doesn't compile with Unicode because of an undefined reference to wWinMain.

This can be simply fixed by using the standard main function!

@aminya
Copy link
Author

aminya commented Jul 13, 2022

@horenmar any update on my comments and pull request?

@msd
Copy link

msd commented Nov 26, 2022

My build worked using v.3.1.0 but gives undefined reference to WinMain at v.3.2.0. Turns out in cmake I needed to link with Catch2::Catch2WithMain instead of Catch2::Catch2

@dnwpark
Copy link

dnwpark commented Dec 31, 2023

For anyone who is still struggling with this, as a last resort you can provide your own main as per the example: https://github.com/catchorg/Catch2/blob/devel/docs/own-main.md

@tedli
Copy link

tedli commented Apr 7, 2024

-DDO_NOT_USE_WMAIN=ON
can make mingw happy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants