Tcl Source Code

View Ticket
Login
Ticket UUID: 3565485
Title: Building vfs with latest Tcl 8.6 and 8.5.12 fails on MinGW
Type: Bug Version: None
Submitter: zoro2 Created on: 2012-09-07 10:53:41
Subsystem: 52. Portability Support Assigned To: nijtmans
Priority: 5 Medium Severity:
Status: Closed Last Modified: 2012-09-07 21:15:57
Resolution: Invalid Closed By: nijtmans
    Closed on: 2012-09-07 11:26:46
Description:
Building TclVFS (and possibly many other extensions) fails with latest Tcl (trunk) and 8.5.12.

The error is Tcl_StatBuf being incomplete - vfs failed build log:

sources/vfs1.4/generic/vfs.c: In function 'VfsStat':
sources/vfs1.4/generic/vfs.c:1125:12: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1139:13: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1146:13: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1153:13: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1160:13: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1167:13: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1174:13: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1181:13: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1188:13: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1195:13: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1202:13: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1207:10: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1209:10: error: dereferencing pointer to incomplete type
sources/vfs1.4/generic/vfs.c:1212:10: error: dereferencing pointer to incomplete type

The reason is that _MSC_VER is not defined and condition below:

#   elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || defined(_USE_32BIT_TIME_T)

is not matched.

The fix is to:

-#   elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || defined(_USE_32BIT_TIME_T)
+#   elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || !defined(_MSC_VER) || defined(_USE_32BIT_TIME_T)

Attached are patches for 8.5 and 8.6.
User Comments: zoro2 added on 2012-09-07 21:15:57:
I have just thought of the same

#   elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || (defined(__MSVCRT_VERSION__) && (__MSVCRT_VERSION__ < 0x0800)) || defined(_USE_32BIT_TIME_T)

Works fine - I even checked after building - file sizes (even above 4GB) and their mtime is reported properly.

nijtmans added on 2012-09-07 21:12:26:
How about:
# elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || (defined(__MSVCRT_VERSION__) && (__MSVCRT_VERSION__ < 0x0800)) || defined(_USE_32BIT_TIME_T)

Would that make life easier for you? Or is it simpler to modify tclvfs, putting
#if defined(_WIN32) && !defined(_WIN64)
#   define _USE_32BIT_TIME_T
#endif
somewhere before the inclusion of <stat.h>? The
-D_USE_32BIT_TIME_T is only needed
for extensions actually using the Tcl_StatBuf
structure, and that's not so many.

Regards,
        Jan Nijtmans

zoro2 added on 2012-09-07 20:34:48:
I am not sure that the issue is closed. I also read #3474726 and it also seems related. My solution does not seem good, but I think current state of things is also wrong.

Tcl itself compiles fine because of tclWinPort.h setting _USE_32BIT_TIME_T - I think it should either not compile in the same way or the defining of _USE_32BIT_TIME_T when #ifndef _WIN64 should be put in tcl.h or other public header file. _USE_32BIT_TIME_T was also not created for my tclConfig.sh

Perhaps configure script should detect such case (i.e. which exact structure should be used for Tcl_StatBuf) and add an appropriate -D flag - both to Tcl compilation and to tclConfig.sh? Then extensions would pick it up automatically.

Also, even with latest MinGW, _stat32i64 is only defined if #if __MSVCRT_VERSION__ >= 0x0800. By default, MinGW is compiled with __MSVCRT_VERSION__ set to 0600 - from _mingw.h:

#ifndef __MSVCRT_VERSION__
/*  High byte is the major version, low byte is the minor. */
# define __MSVCRT_VERSION__ 0x0600
#endif 

It seems weird to assume Tcl can only compile with __MSVCRT_VERSION__ set to 0800 (hence requiring msvcrt80) only to support Tcl_StatBuf.

Is there a reason why _USE_32BIT_TIME_T when #ifndef _WIN64 (or some other define) is not put in Tcl's public headers? This would prevent requiring extensions to modify their configure scripts to correctly handle Tcl_StatBuf.

nijtmans added on 2012-09-07 18:31:49:
And, have a look at #3474726, which gives a better
description why this is a mingw bug.

nijtmans added on 2012-09-07 18:26:59:

allow_comments - 0

nijtmans added on 2012-09-07 18:26:46:

allow_comments - 1

No that's not the correct fix. vfs should explitely
define _USE_32BIT_TIME_T, in order to
assure that Tcl_StatBuf is defined as
struct _stati64 AND assuring that the time_t
field in it is 32-bit. That's the only way
to assure that Tcl_StatBuf has the same
binary structure, no matter which compiler
handles it.

Another possible solution: upgrade to
a newer mingw, which has struct _stat32i64
defined. The real bug is in  your older mingw
which is missing this definition. The workaround
requiring -D_USE_32BIT_TIME_T is
built in especially for users of older
mingw, who don't want to upgrade
their mingw installation.

See also bug #3288345.

zoro2 added on 2012-09-07 17:54:11:

File Added - 452737: tcl8512-mingw_msc_ver.patch

zoro2 added on 2012-09-07 17:53:45:

File Added - 452736: tcl86b2-mingw_msc_ver.patch

Attachments: