Tk Source Code

View Ticket
Login
Ticket UUID: f6d40f990272964291b225db84525de190eef9d0
Title: Cross compiling trunk using x86_64-w64-mingw32-gcc fails since commit [03ce8fe9d1]
Type: Bug Version: trunk
Submitter: erikleunissen Created on: 2025-03-27 17:14:39
Subsystem: 85. Win Build Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Important
Status: Closed Last Modified: 2025-04-27 20:01:24
Resolution: Fixed Closed By: jan.nijtmans
    Closed on: 2025-04-27 20:01:24
Description:
Since commit [03ce8fe9d1], my cross compiler aborts with the appended errors.

This is probably due to the removal of various definitions from win/tkWinDialog.c
starting at line 192 with the following comment:

/*
 * The following definitions are required when using older versions of
 * Visual C++ (like 6.0) and possibly MingW. Those headers do not contain
 * required definitions for interfaces new to Vista that we need for
 * the new file dialogs. Duplicating definitions is OK because they
 * should forever remain unchanged.
 *
 * XXX - is there a better/easier way to use new data definitions with
 * older compilers? Should we prefix definitions with Tcl_ instead
 * of using the same names as in the SDK?
 */

Note that this comment relates to features for Vista and later.
My compiler did fine compiling trunk (i.e. including Vista features) until that
particular commit.

1. was the removal of those definitions premature?
2. which (cross)-gcc version should I use then?

Please see below for the compiler version and the error messages.
   
Regards,
Erik Leunissen

-- output --

> /usr/bin/x86_64-w64-mingw32-gcc --version
x86_64-w64-mingw32-gcc (SUSE Linux) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.

....

/usr/bin/x86_64-w64-mingw32-gcc -c -g -D__USE_MINGW_ANSI_STDIO=0 -Wall -Wextra -Wshadow -Wundef -Wwrite-strings -Wpointer-arith -Wc++-compat -fextended-identifiers  -I"/home/erik/priv/Develop/tk_collect_test_utils/tk/generic" -I"/home/erik/priv/Develop/tk_collect_test_utils/tk/win" -I"../../../SOURCES/tk-ctu/win/../xlib" -I"../../../SOURCES/tk-ctu/win/../bitmaps" -I"/usr/local/src/SOURCES/tcl-ctu/generic" -I"/usr/local/src/SOURCES/tcl-ctu/win" -pipe -DHAVE_CPUID=1 -finput-charset=UTF-8 -DPACKAGE_NAME=\"tk\" -DPACKAGE_TARNAME=\"tk\" -DPACKAGE_VERSION=\"9.1\" -DPACKAGE_STRING=\"tk\ 9.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DHAVE_STDIO_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_UNISTD_H=1 -DSTDC_HEADERS=1 -DMODULE_SCOPE=extern -DTCL_CFG_DO64BIT=1 -DHAVE_NO_SEH=1 -DHAVE_STDBOOL_H=1 -DHAVE_CAST_TO_UNION=1 -DHAVE_INTPTR_T=1 -DHAVE_UINTPTR_T=1 -DHAVE_INTPTR_T=1 -DHAVE_UINTPTR_T=1 -DZIPFS_BUILD=1  -DUSE_TCL_STUBS -DBUILD_tk -DBUILD_ttk "/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c" -o tkWinDialog.o
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c: In function 'GetFileNameVista':
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:787:33: error: 'IID_IFileOpenDialog' undeclared (first use in this function); did you mean 'CLSID_FileOpenDialog'?
  787 |          CLSCTX_INPROC_SERVER, &IID_IFileOpenDialog, (void **) &fdlgIf);
      |                                 ^~~~~~~~~~~~~~~~~~~
      |                                 CLSID_FileOpenDialog
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:787:33: note: each undeclared identifier is reported only once for each function it appears in
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:790:33: error: 'IID_IFileSaveDialog' undeclared (first use in this function); did you mean 'CLSID_FileSaveDialog'?
  790 |          CLSCTX_INPROC_SERVER, &IID_IFileSaveDialog, (void **) &fdlgIf);
      |                                 ^~~~~~~~~~~~~~~~~~~
      |                                 CLSID_FileSaveDialog
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:800:16: error: dereferencing pointer to incomplete type 'IFileDialog' {aka 'struct IFileDialog'}
  800 |     hr = fdlgIf->lpVtbl->GetOptions(fdlgIf, &flags);
      |                ^~
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:826:2: error: 'FOS_FORCEFILESYSTEM' undeclared (first use in this function); did you mean 'LFF_FORCEFILESYSTEM'?
  826 |  FOS_FORCEFILESYSTEM | /* Only want files, not other shell items */
      |  ^~~~~~~~~~~~~~~~~~~
      |  LFF_FORCEFILESYSTEM
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:827:2: error: 'FOS_NOVALIDATE' undeclared (first use in this function); did you mean 'OFN_NOVALIDATE'?
  827 |  FOS_NOVALIDATE |           /* Don't check for access denied etc. */
      |  ^~~~~~~~~~~~~~
      |  OFN_NOVALIDATE
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:828:2: error: 'FOS_PATHMUSTEXIST' undeclared (first use in this function); did you mean 'OFN_PATHMUSTEXIST'?
  828 |  FOS_PATHMUSTEXIST;           /* The *directory* path must exist */
      |  ^~~~~~~~~~~~~~~~~
      |  OFN_PATHMUSTEXIST
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:832:11: error: 'FOS_PICKFOLDERS' undeclared (first use in this function)
  832 |  flags |= FOS_PICKFOLDERS;
      |           ^~~~~~~~~~~~~~~
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:834:15: error: 'FOS_FILEMUSTEXIST' undeclared (first use in this function); did you mean 'OFN_FILEMUSTEXIST'?
  834 |      flags |= FOS_FILEMUSTEXIST; /* XXX - check working */
      |               ^~~~~~~~~~~~~~~~~
      |               OFN_FILEMUSTEXIST
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:839:11: error: 'FOS_ALLOWMULTISELECT' undeclared (first use in this function); did you mean 'OFN_ALLOWMULTISELECT'?
  839 |  flags |= FOS_ALLOWMULTISELECT;
      |           ^~~~~~~~~~~~~~~~~~~~
      |           OFN_ALLOWMULTISELECT
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:844:11: error: 'FOS_OVERWRITEPROMPT' undeclared (first use in this function); did you mean 'OFN_OVERWRITEPROMPT'?
  844 |  flags |= FOS_OVERWRITEPROMPT;
      |           ^~~~~~~~~~~~~~~~~~~
      |           OFN_OVERWRITEPROMPT
/home/erik/priv/Develop/tk_collect_test_utils/tk/win/tkWinDialog.c:935:16: error: dereferencing pointer to incomplete type 'IFileOpenDialog' {aka 'struct IFileOpenDialog'}
  935 |      hr = fodIf->lpVtbl->GetResults(fodIf, &multiIf);
      |                ^~
make: *** [Makefile:798: tkWinDialog.o] Error 1

-- end of message --
User Comments: jan.nijtmans added on 2025-04-27 20:01:24:

> Is there a reason for you to keep this ticket open?

No reason at all. Thanks for the reminder! Closing now


erikleunissen added on 2025-04-26 09:24:15:
- removed irrelevant version info from ticket title.
- see also ticket [59518a2d7a]

@Jan: I noticed that you applied the patch to core-9-0-branch and trunk.
      Is there a reason for you to keep this ticket open?

erikleunissen added on 2025-04-24 10:46:32:
I found the cause of the problem:

1. There is nothing wrong with my cross-compiler, version 9.0.2
   Since some definitions were removed in commit [03ce8fe9d1], I initially
   thought that the compiler might not provide the header files that defined
   symbols like IID_IFileOpenDialog.
   That appeared to be not true. The symbol IID_IFileOpenDialog (for example)
   is defined in the compiler-provided header file "shobjidl.h", and I checked
   that this header file is included during the build process.

2. The next question then is: why is the symbol IID_IFileOpenDialog not being
   defined during the build process?

   The reason is that:
   - this symbol is only defined when _WIN32_WINNT is higher than _WIN32_VISTA
   - the value for _WIN32_WINNT in my setup appears to be 0x502, which is the
     compiler-provided default, which is used when code file to compile
     doesn't define _WIN32_WINNT

3. The next question then is: why does my compiler use its internal default for
   _WIN32_WINNT when Tk defines it as 0x601 in tkWin.h (line 29)?

   The reason is that Tk includes tkWin.h only *after* it includes tkInt.h
   in file tkWinInt.h (lines 17 and following). This is too late because
   including tkInt.h triggers many other header file inclusions, amongst others
   compiler-provided headers that define interfaces that depend on the value of
   _WIN32_WINNT. Lacking a setting for _WIN32_WINNT, the compiler uses its internal
   default, being 0x502. ==> BANG !

So the remedy is to invert the order of header file inclusion in tkWinInt.h:
First include tkWin.h, and next include tkInt.h
Doing so made the cross-build complete flawlessly.

The corresponding patch is appended right hereafter, and also attached as file.

I did not check whether Tcl exhibits a similar issue with the order of
header file inclusions. Thus far, I experienced no such problem cross-compiling
Tcl. But - as this Tk case shows - such issues may crop up later when changing
definitions in Tcl/Tk code.

Erik.
--

--- win/tkWinInt.h
+++ win/tkWinInt.h
@@ -12,21 +12,23 @@
  */

 #ifndef _TKWININT
 #define _TKWININT

-#ifndef _TKINT
-#include "tkInt.h"
-#endif
-
 /*
- * Include platform specific public interfaces.
+ * Include platform specific public interfaces as the very first step. This is
+ * necessary because definitions provided by subsequent header files depend on
+ * the interface versions defined in tkWin.h
  */

 #ifndef _TKWIN
 #include "tkWin.h"
 #endif
+
+#ifndef _TKINT
+#include "tkInt.h"
+#endif

 /*
  * Define constants missing from older Win32 SDK header files.
  */


--

oehhar added on 2025-03-28 13:44:02:

Eric,

thanks for the test, I appreciate! sorry, I feared this will happen. THat is why I have asked explicitly for a test of all Win 8 compatible frameworks.

I removed the old compiler compatibility code which was necessary for older Windows frameworks. If your compile is truely Win 8 (minimum requirement), this should not happen.

As an alternate solution, you may restore the compatibility code. Please use an #ifdef for your specific case.

I personally don't want to have compatibility code in the code base forever. And it is great, that "CLSID_FileOpenDialog" is known, so there is partial support.

Sorry for the inconvenience. We will find a solution !

Thank you and take care, Harald


Attachments: