Opened 2 years ago

Closed 21 months ago

#17936 closed defect (fixed)

wxWidgets fail to build with current MinGW32

Reported by: pb101 Owned by: vadz
Priority: normal Milestone: 3.1.1
Component: build Version: dev-latest
Keywords: mingw Cc: pbfordev@…, m0081@…, igor.cali0@…
Blocked By: Blocking:
Patch: yes

Description

Attempt to build wxWidgets master with

mingw32-make -f makefile.gcc

resulted in

gcc -c -o gcc_mswud\wxtiff_tif_win32.o -g -O0 -mthreads  -DHAVE_W32API_H -DNDEBUG -I..\..\src\zlib -I..\..\src\jpeg -I..\..\src\tiff\libtiff   -MTgcc_mswud\wxtiff_tif_win32.o -MFgcc_mswud\wxtiff_tif_win32.o.d -MD -MP ../../src/tiff/libtiff/tif_win32.c
In file included from ../../src/tiff/libtiff/tiffio.h:257:0,
                 from ../../src/tiff/libtiff/tiffiop.h:59,
                 from ../../src/tiff/libtiff/tif_win32.c:30:
c:\mingw\include\stdio.h:345:12: error: expected '=', ',', ';', 'asm' or '__attribute__' before '__mingw__snprintf'
 extern int __mingw_stdio_redirect__(snprintf)(char*, size_t, const char*, ...);
            ^
makefile.gcc:6044: recipe for target 'gcc_mswud\wxtiff_tif_win32.o' failed
mingw32-make: *** [gcc_mswud\wxtiff_tif_win32.o] Error 1

MinGW32 installed via mingw-get.exe:
mingw32-base version 2013072200
gcc version 6.3.0

The same wxWidgets codebase could be built with previous MinGW version (GCC 5.3.0) without any issues.

Attachments (1)

tif_fix.patch download (748 bytes) - added by NewPagodi 2 years ago.
Fix compilation with latest MinGW32

Download all attachments as: .zip

Change History (11)

comment:1 Changed 2 years ago by vadz

Sorry, I have no idea what's going on here. I did build wx successfully with 6.2 AFAIR, so it could be instructive to look at the changes under include directory between these 2 versions (there shouldn't be many of them, hopefully).

I'll only be able to look at this when I upgrade any of my own projects to use MinGW with gcc6 (or, hopefully, 7 by the time it happens), but not right now.

comment:2 Changed 2 years ago by pb101

  • Cc pbfordev@… added

Sorry, I am not actually using MinGW myself (much). I just wanted to test an issue reported on the forum. I thought it could perhaps be simple to fix by a GCC savvy person, e.g. adding a missing include/define somewhere.

Nevertheless, I went through MinGW changelog on SF and a possibly relevant recent change I found was
https://sourceforge.net/p/mingw/mingw-org-wsl/ci/40982dff81a3c1dc0572cf2cd0a23156661ae98d/

After reverting that commit, wxWidgets could be built (tested only Debug Static build) successfully again. Unfortunately, I am not knowledgable enough to tell whether the issue needs to be fixed on wxWidgets (tiff library) or MinGW side.

comment:3 Changed 2 years ago by NewPagodi

  • Cc m0081@… added
  • Patch set

I've looked into this. The problem is in wx\src\tiff\libtiff\tif_config.h. Somewhere around line 387

/* MSVC 14 does have snprintf() and doesn't allow defining it */
#if !defined(_MSC_VER) || _MSC_VER < 1900
# define snprintf _snprintf
#endif

Apparently starting with GCC 6.3, the official release of MinGW32 has changed _snprintf so that it now gives the error above. It does however have snprintf. So I changed the check like so:

/* MSVC 14 does have snprintf() and doesn't allow defining it.  Also MinGW32
   starting with GCC 6.3 has changed _snprintf so that it is no longer suitable.
   It does have snprintf, so just use it. */
#if defined (__MINGW32__) && (__GNUC__ > 6 || (__GNUC__ == 6 && __GNUC_MINOR__ > 2))
  /* do nothing*/
#elif !defined(_MSC_VER) || _MSC_VER < 1900
# define snprintf _snprintf
#endif

This lets libtiff and the rest of wxWidgets build. It doesn't break MinGW64 with either the 32 or 64bit tool chain.

There's probably a much better way to write that check, so suggestions/corrections are welcome.


Note: I had to generate this patch in the wx\src\tiff folder since those files are no longer tracked by the main repo.

Changed 2 years ago by NewPagodi

Fix compilation with latest MinGW32

comment:4 follow-up: Changed 2 years ago by vadz

  • Milestone set to 3.1.1

Does this happen only with 6.3? I had previously tested with "gcc version 6.2.0 (i686-win32-sjlj-rev1, Built by MinGW-W64 project)" and I've just retested with "gcc version 7.2.0 (i686-win32-sjlj-rev0, Built by MinGW-W64 project)" and I don't see the problem with neither of them.

I guess we could still apply this fix, but I'd like to understand what's going on here...

Also, don't we need something similar for vsnprintf in tif_win32.c?

comment:5 in reply to: ↑ 4 Changed 2 years ago by NewPagodi

Replying to vadz:

Does this happen only with 6.3? I had previously tested with "gcc version 6.2.0 (i686-win32-sjlj-rev1, Built by MinGW-W64 project)" and I've just retested with "gcc version 7.2.0 (i686-win32-sjlj-rev0, Built by MinGW-W64 project)" and I don't see the problem with neither of them.

The problem is only with MinGW from mingw.org and only with their latest version of GCC (6.3.0).

I guess MinGW64 never had the same problem with their 32bit tool chains. I've checked i686-6.3.0-release-posix-dwarf-rt_v5-rev2 as well as the latest releases and they build fine both with and without the patch I placed above.


I guess we could still apply this fix, but I'd like to understand what's going on here...

I don't know much about MinGW so I don't know why they decided to change the function.


Also, don't we need something similar for vsnprintf in tif_win32.c?

I guess that's a slightly different check:

#if defined(_MSC_VER) && (_MSC_VER < 1500)
#  define vsnprintf _vsnprintf
#endif

I think that only applies that definition with visual c. So if it was OK before it should still be OK with MinGW. I think.

comment:6 Changed 2 years ago by vadz

  • Owner set to vadz
  • Status changed from new to accepted

Thanks, I finally got MinGW-w32 6.3 and could indeed reproduce the problem and now I even see where it comes from: in their stdio.h they have

#define __Wformat_snprintf      __Wformat_mingw_printf(3,4)
...
extern int __mingw_stdio_redirect__(snprintf)(char*, size_t, const char*, ...);

where __mingw_stdio_redirect__(x) is a macro which expands to __Wformat_mingw_x and so this does what you'd expect by default. But if we redefine snprintf as _snprintf, this breaks things as __Wformat__snprintf (notice two underscores in the middle) is not defined.

I've created a PR for this and will merge it soon, thanks a lot for your help with debugging this!

comment:7 Changed 2 years ago by Vadim Zeitlin <vadim@…>

  • Resolution set to fixed
  • Status changed from accepted to closed

In 879876e04/git-wxWidgets:

Fix libtiff compilation with MinGW-w32 6.3

Avoid redefining snprintf as this breaks -Wformat-related macros in this
compiler stdio.h -- and is unnecessary anyhow.

Closes #17936.

comment:8 Changed 21 months ago by vadz

  • Resolution changed from fixed to port to stable
  • Status changed from closed to portneeded

It would be nice to backport this to 3.0 if someone can do this.

comment:9 Changed 21 months ago by igi

  • Cc igor.cali0@… added

This issue still happens on fresh stable build 3.0.4.

comment:10 Changed 21 months ago by Vadim Zeitlin <vadim@…>

  • Resolution changed from port to stable to fixed
  • Status changed from portneeded to closed

In e831ef4f3/git-wxWidgets:

Fix libtiff compilation with MinGW-w32 6.3

Backport changes of 879876e047d9aabe4b144944449a5ffe5a37ffed from
master.

Closes #17936.

Closes https://github.com/wxWidgets/wxWidgets/pull/766

Note: See TracTickets for help on using tickets.