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

Building in MSYS2/MinGW with GCC 13.2 fails: undefined reference to `WinMain@16' #1755

Closed
LigH-de opened this issue Nov 13, 2023 · 11 comments · Fixed by #1802
Closed

Building in MSYS2/MinGW with GCC 13.2 fails: undefined reference to `WinMain@16' #1755

LigH-de opened this issue Nov 13, 2023 · 11 comments · Fixed by #1802
Assignees

Comments

@LigH-de
Copy link

LigH-de commented Nov 13, 2023

Compiling libavif project in media-autobuild suite, a set of scripts for a MSYS2/MinGW build environment which keeps itself up-to-date before compiling ffmpeg including a lot of codecs.

CPPFLAGS: 
CFLAGS: -D_FORTIFY_SOURCE=2 -fstack-protector-strong -mtune=generic -O2 -pipe -D__USE_MINGW_ANSI_STDIO=1 -mthreads
CXXFLAGS: -D_FORTIFY_SOURCE=2 -fstack-protector-strong -mtune=generic -O2 -pipe -D__USE_MINGW_ANSI_STDIO=1
LDFLAGS: -D_FORTIFY_SOURCE=2 -fstack-protector-strong -mtune=generic -O2 -pipe -D__USE_MINGW_ANSI_STDIO=1 -static-libgcc -static-libstdc++
ninja -j4 
{...}
[37/38] Linking CXX executable avifdec.exe
FAILED: avifdec.exe 
cmd.exe /C "cd . && G:\MABS\msys64\mingw32\bin\ccache.exe  g++ -D_FORTIFY_SOURCE=2 -fstack-protector-strong -mtune=generic -O2 -pipe -D__USE_MINGW_ANSI_STDIO=1 -O3 -DNDEBUG -D_FORTIFY_SOURCE=2 -fstack-protector-strong -mtune=generic -O2 -pipe -D__USE_MINGW_ANSI_STDIO=1 -static-libgcc -static-libstdc++ CMakeFiles/avifdec.dir/apps/avifdec.c.o -o avifdec.exe -Wl,--out-implib,libavifdec.dll.a -Wl,--major-image-version,0,--minor-image-version,0  libavif_apps.a  libavif.a  G:/MABS/local32/lib/libdav1d.a  G:/MABS/local32/lib/librav1e.a  -LG:/MABS/local32/lib  -lrav1e  -lkernel32  -ladvapi32  -lbcrypt  -lntdll  -luserenv  -lws2_32  -lkernel32  -ladvapi32  -lbcrypt  -lntdll  -luserenv  -lws2_32  -Wl,--allow-multiple-definition  G:/MABS/local32/lib/libaom.a  G:/MABS/local32/lib/libsharpyuv.a  -lm  -lntdll  -luserenv  -lws2_32  -lbcrypt  G:/MABS/local32/lib/libpng.a  G:/MABS/msys64/mingw32/lib/libz.a  G:/MABS/msys64/mingw32/lib/libjpeg.a  -lmingwthrd  -lmingwthrd  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
G:/MABS/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/13.2.0/../../../../i686-w64-mingw32/bin/ld.exe: G:/MABS/msys64/mingw32/lib/../lib/libmingw32.a(lib32_libmingw32_a-crtexewin.o): in function `main':

C:/M/B/src/mingw-w64/mingw-w64-crt/crt/crtexewin.c:67:(.text.startup+0xd0): undefined reference to `WinMain@16'

collect2.exe: error: ld returned 1 exit status
[38/38] Linking CXX executable avifenc.exe
FAILED: avifenc.exe 
cmd.exe /C "cd . && G:\MABS\msys64\mingw32\bin\ccache.exe  g++ -D_FORTIFY_SOURCE=2 -fstack-protector-strong -mtune=generic -O2 -pipe -D__USE_MINGW_ANSI_STDIO=1 -O3 -DNDEBUG -D_FORTIFY_SOURCE=2 -fstack-protector-strong -mtune=generic -O2 -pipe -D__USE_MINGW_ANSI_STDIO=1 -static-libgcc -static-libstdc++ CMakeFiles/avifenc.dir/apps/avifenc.c.o -o avifenc.exe -Wl,--out-implib,libavifenc.dll.a -Wl,--major-image-version,0,--minor-image-version,0  libavif_apps.a  libavif.a  G:/MABS/local32/lib/libdav1d.a  G:/MABS/local32/lib/librav1e.a  -LG:/MABS/local32/lib  -lrav1e  -lkernel32  -ladvapi32  -lbcrypt  -lntdll  -luserenv  -lws2_32  -lkernel32  -ladvapi32  -lbcrypt  -lntdll  -luserenv  -lws2_32  -Wl,--allow-multiple-definition  G:/MABS/local32/lib/libaom.a  G:/MABS/local32/lib/libsharpyuv.a  -lm  -lntdll  -luserenv  -lws2_32  -lbcrypt  G:/MABS/local32/lib/libpng.a  G:/MABS/msys64/mingw32/lib/libz.a  G:/MABS/msys64/mingw32/lib/libjpeg.a  -lmingwthrd  -lmingwthrd  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
G:/MABS/msys64/mingw32/bin/../lib/gcc/i686-w64-mingw32/13.2.0/../../../../i686-w64-mingw32/bin/ld.exe: G:/MABS/msys64/mingw32/lib/../lib/libmingw32.a(lib32_libmingw32_a-crtexewin.o): in function `main':

C:/M/B/src/mingw-w64/mingw-w64-crt/crt/crtexewin.c:67:(.text.startup+0xd0): undefined reference to `WinMain@16'

collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

There is no C:\M\B directory on my Windows partitions. I wonder why these paths are contained in the files CMakeDetermineCompilerABI_C.bin and CMakeDetermineCompilerABI_CXX.bin in build/libavif-git/build-32bit/CMakeFiles/3.27.7

@waldonnis suspects this commit as possible reason in a MABS issue.

logs.zip collected by MABS

@wantehchang
Copy link
Collaborator

Vincent: Could you take a look at this? Thanks.

LigH: I am not familiar with MSYS2/MinGW. The current main branch of libavif uses wmain() instead of main() as the starting point of the avifdec.c, avifenc.c, and are_images_equal.cc programs on Windows so that we can receive the command-line arguments as wchar_t strings. It is common to do this in Windows applications, so there must be a way to build this kind of program in MSYS2/MinGW. Do you know what the trick is? Thanks.

@LigH-de
Copy link
Author

LigH-de commented Nov 13, 2023

Unfortunately, I am not at all a C/C++ developer. Just a halfwit running the script and interpreting error messages. But the MABS team has a good amount of experience, too...

@waldonnis
Copy link

Chiming in since I narrowed it down to this commit in the bug report mentioned above...

I'll admit I'm also a little lost on mingw specifics, but mingw-w64 gcc supports a -municode option (gcc docs) that properly defines the UNICODE (and other) preprocessor macros and uses the correct startup code (that supports unicode) when linking. I tested this with a rudimentary patch that added -municode to the linker args only for avifdec/enc and it did allow them to link successfully. I have not run any tests against the resulting binaries at this time to check unicode input is functional, though. Compiling with MSVC likely doesn't need any of this, since it seems to be a mingw target specific issue.

Below is my rudimentary patch. The conditional should probably be modified to only apply to a mingw-w64 target since gcc docs mention it's the only target that supports -municode (and I have no idea what, if anything, can be done for mingw-w32 targets). I also just used PUBLIC for target_link_options for testing purposes, but can/should probably be changed as well. There may be a better way to fix this, but I don't know libavif nor mingw-w64 well enough to suggest alternatives.

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9d28ae3..a47eec0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -793,6 +793,10 @@ if(AVIF_BUILD_APPS)
         set_target_properties(avifdec PROPERTIES LINKER_LANGUAGE "CXX")
     endif()
     target_link_libraries(avifdec avif_apps)
+    if(WIN32 AND MINGW)
+           target_link_options(avifenc PUBLIC "SHELL:-municode")
+           target_link_options(avifdec PUBLIC "SHELL:-municode")
+    endif()

     if(NOT SKIP_INSTALL_APPS AND NOT SKIP_INSTALL_ALL)
         install(

@kmilos
Copy link
Contributor

kmilos commented Nov 14, 2023

Note that you don't need "WIN32 AND MINGW", checking for MINGW is sufficient (implies WIN32).

@vrabaud
Copy link
Collaborator

vrabaud commented Nov 14, 2023

Hi, we are actually trying something simpler to deal with UTF8 and it reverts the commit you are mentioning: does #1752 work for you? Thx

@wantehchang
Copy link
Collaborator

If we use the -municode solution, we should also add -DUNICODE and possibly also -D_UNICODE for all compilers on Windows, so that all compilers on Windows define the UNICODE macro when compiling libavif.

@waldonnis
Copy link

Hi, we are actually trying something simpler to deal with UTF8 and it reverts the commit you are mentioning: does #1752 work for you? Thx

Unfortunately not, since mt.exe is only provided by the Windows SDK (which may not be installed or in the path) and there doesn't seem to be an equivalent in msys/mingw.

@vtorri
Copy link
Contributor

vtorri commented Nov 17, 2023

maybe more informations here : https://sourceforge.net/p/mingw-w64/wiki2/Unicode%20apps/

@vtorri
Copy link
Contributor

vtorri commented Nov 17, 2023

basically :

  1. if only wmain() is used (no other unicode version of functions) : -municode is sufficient
  2. if unicode version of functions are used (like CreateFile, which would be replaced with CreateFileW), -DUNICODE should be passed to the compiler

if I'm not mistaken, the commit only uses wmain() explicitely and convert argv to UTF8 with WideCharToMultiByte(), so -municode should be sufficient, and works for me btw. But passing -DUNICODE and -D_UNICODE will not hurt and will avoid possible future errors if unicode version of functions are wanted (unless you explicitely use the unicode version, like CreateFileW() instead of just CreateFile())

@vtorri
Copy link
Contributor

vtorri commented Nov 17, 2023

and to finish : visual studio solutions sets unicode by default

@vrabaud
Copy link
Collaborator

vrabaud commented Nov 23, 2023

Thx for the pointers. Would #1802 work for MINGW then ?

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

Successfully merging a pull request may close this issue.

6 participants