GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Tkinter fails to build with Tcl 9.0 due to `Tcl_AppInit()` undeclared · Issue #104363 · python/cpython

Tkinter fails to build with Tcl 9.0 due to Tcl_AppInit() undeclared #104363

New issue
Copy link
New issue
Copy link
Closed
Closed
Tkinter fails to build with Tcl 9.0 due to Tcl_AppInit() undeclared#104363
Copy link
Assignees
serhiy-storchaka
Labels
topic-tkinter

Description

@chrstphrchvz
chrstphrchvz
opened on May 10, 2023
Issue body actions

Since Tcl 8.0.5 (tcltk/tcl@17481a9), tcl.h has clarified that Tcl_AppInit() is not an exported Tcl library function, and declares Tcl_AppInit() for compatibility/convenience only:

/*
 *----------------------------------------------------------------------------
 * Convenience declaration of Tcl_AppInit for backwards compatibility. This
 * function is not *implemented* by the tcl library, so the storage class is
 * neither DLLEXPORT nor DLLIMPORT.
 */

extern Tcl_AppInitProc Tcl_AppInit;

This declaration is deprecated in Tcl 8.7 and removed in Tcl 9.0. Without it, _tkinter.c will fail to build if the compiler treats implicit function declarations as errors:

./Modules/_tkinter.c:713:9: error: call to undeclared function 'Tcl_AppInit'; ISO C99 and later do not support implicit function declarations [-Werror,-Wimplicit-function-declaration]
    if (Tcl_AppInit(v->interp) != TCL_OK) {
        ^
./Modules/_tkinter.c:713:9: note: did you mean 'Tcl_Init'?
/Users/user/tcl90p/include/tclDecls.h:513:13: note: 'Tcl_Init' declared here
EXTERN int              Tcl_Init(Tcl_Interp *interp);
                        ^

Although it seems possible to have _tkinter.c declare Tcl_AppInit() when tcl.h does not, I am not familiar enough with Tcl_AppInit() usage to know whether that is a good solution. From reading the Tcl_AppInit() documentation, it sounds like Tkinter could instead rename its Tcl_AppInit() in tkappinit.c to something else, which it then always declares in _tkinter.c.

Activity

  1. terryjreedy
    assigned
    terryjreedy
    and
    serhiy-storchaka
    and unassigned
    terryjreedy
    on May 10, 2023
  2. terryjreedy
    added
    topic-tkinter
    on May 10, 2023
  3. terryjreedy commented on May 30, 2023

    @terryjreedy
    terryjreedy
    on May 30, 2023
    Member
    More actions

    @serhiy-storchaka This issue is about patching _tkinter.

  4. serhiy-storchaka commented on Jun 4, 2024

    @serhiy-storchaka
    serhiy-storchaka
    on Jun 4, 2024
    Member
    More actions

    I agree with the analysis of @chrstphrchvz. I came to the same two possible quick solutions, and I also not qualified to decide what is better.

    For now, it looks safer to add the missing declaration of Tcl_AppInit:

    #if TK_MAJOR_VERSION >= 9
    int Tcl_AppInit(Tcl_Interp *);
    #endif

    If the user code uses an embedded Python or a custom build of Python with statically linked Tcl/Tk and third-party binary Tcl/Tk libraries, they will still be able to define a custom Tcl_AppInit().

    In future we may implement more modern approach, but this minimum is necessary to build Tkinter with Tcl/Tk 9.0.

    I'll add this change in #112681 because both changes are needed to unblock a build.

  5. serhiy-storchaka commented on Jun 4, 2024

    @serhiy-storchaka
    serhiy-storchaka
    on Jun 4, 2024
    Member
    More actions

    Tkinter builds now with Tcl 9.0. I leave this issue open for the case if we find better solution.

    Reacted by Data Scientist 89
  6. dkfellows commented on Mar 20, 2025

    @dkfellows
    dkfellows
    on Mar 20, 2025
    More actions

    It shouldn't be necessary to call at all; it's there for tclsh itself and Tcl only calls it from Tcl_Main (which tkinter definitely shouldn't use, as it is a never-return function!)

    Cutting out bits that ought to be ignorable, in Tcl 9.0 it's just (on POSIX; Windows has a different RC file name):

    int Tcl_AppInit(Tcl_Interp *interp) {
        if (Tcl_Init(interp) == TCL_ERROR) {
    	return TCL_ERROR;
        }
        (void) Tcl_EvalEx(interp,
    	    "set tcl_rcFileName [file tildeexpand ~/.tclshrc]",
    	    -1, TCL_EVAL_GLOBAL);
        return TCL_OK;
    }

    The setting of tcl_rcFileName is only relevant if you're running interactively, which I'm fairly sure is not a good idea for you either. Which means you can just replace the call to Tcl_AppInit with a call to Tcl_Init, which is exported.

  7. serhiy-storchaka commented on Jun 27, 2026

    @serhiy-storchaka
    serhiy-storchaka
    on Jun 27, 2026
    Member
    More actions

    The build failure itself was fixed in #112681 (gh-112681) by adding the missing declaration under #if TK_MAJOR_VERSION >= 9, and Tkinter has built against Tcl/Tk 9.0/9.1 since. I left this open in case a cleaner approach emerged, but on review the minimal declaration is the right one.

    The tempting alternative — rename our Tcl_AppInit to a private name and drop the version guard — would break a documented customization seam. configure sets -DWITH_APPINIT=1 on every standard build, so the live Tcl_AppInit is the one in Modules/tkappinit.c, which is the hook for statically linking Tcl/Tk packages (-DWITH_TIX/WITH_BLT/WITH_TOGL/…). Renaming it silently breaks anyone patching that file.

    @dkfellows is right that the name isn't special (Tcl only calls it from Tcl_Main, which we don't use) — which is exactly why declaring and calling our own is fine. And we can't reduce the call to a bare Tcl_Init, since our Tcl_AppInit also handles _tkinter_skip_tk_init and Tkinter_TkInit.

    So closing as completed. Retiring tkappinit.c/WITH_APPINIT altogether (Tix is gone in Tcl 9; BLT/Togl/static-PIL are long dead) is worth considering, but that's a separate cleanup.

  8. serhiy-storchaka
    closed this as completedon Jun 27, 2026
  9. dbxmcf
    added a commit that references this issue on Sep 11, 2026

    Add custom package repo overriding python to skip _tkinter at build time

    58d67a8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @serhiy-storchaka
    serhiy-storchaka

Labels

topic-tkinter

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.