Tk Source Code

View Ticket
Login
Ticket UUID: 447bd3e4abe17452d19a80e6840dcc8a2603fcbc
Title: tk.tcl not installed to correct directory
Type: Bug Version: 8.6.11
Submitter: ajstewart Created on: 2021-05-21 17:21:22
Subsystem: 84. Unix Build Assigned To: jan.nijtmans
Priority: 5 Medium Severity: Minor
Status: Open Last Modified: 2021-06-03 02:07:22
Resolution: None Closed By: nobody
    Closed on:
Description:
I'm a developer for the Spack package manager. I noticed that our tk package is experiencing non-deterministic installation behavior. 

If I install tk multiple times, sometimes tk.tcl ends up in <prefix>/lib/tk.tcl, sometimes it ends up in <prefix>/lib/tk8.6/tk.tcl, and sometimes it doesn't get installed at all. 

This has been observed on both macOS 10.15.7 with Apple Clang 12.0.0 and on Ubuntu 20.04 with GCC 9.3.0. Python's tkinter library seems to only search for <prefix>/lib/tk.tcl, so I would like to always install to this directory. 

Is there some way I can control this behavior? Note that we are installing tk and tcl to separate installation directories. See https://github.com/spack/spack/issues/23780 for some of my debugging steps.
User Comments: ajstewart added on 2021-06-03 02:07:22:
Thanks for the clarification! Is there any way to run "package require Tk" in an automated way? I see that I can write this to a file and run it with tclsh, but it would be even easier if tclsh had a flag like `python -c 'print("foo")'` or `bash -c 'echo foo'`.

jan.nijtmans added on 2021-06-02 08:28:46: (text/x-fossil-wiki)
TCLLIBPATH is only necessary when Tcl and Tk are installed in different directories, which should be possible and appears to be your situation. It should be set to the parent directory of the directory where tk.tcl is, so that should be (in your case) something like "/Users/Adam/spack/opt/spack/darwin-catalina-x86_64/apple-clang-12.0.0/tk-8.6.11-ydmhrbboheucxsuhrnyoxqaihgna5dfe/lib".

The directory containing "tk.tcl" should have a file "pkgIndex.tcl" too, and the Tk versions in it should match.

If you start tclsh8.6, and type "package require Tk", then Tk should be loaded. That's the simplest way to check if Tcl can find Tk. With "info loaded" you can see where Tk got it's shared library loaded from.

Hope this helps.

ajstewart added on 2021-05-28 23:55:24:
After speaking with the Python developers (https://bugs.python.org/issue44253) my current understanding is that tkinter links to tcl, and tcl is the one having trouble finding tk.tcl. It sounds like TCLLIBPATH is how tcl searches for tk.tcl, but I'm still not entirely sure what TCLLIBPATH should be set to. How can I test whether or not tcl can locate tk? If I know that I can add a test to our tk recipe to make sure it is being installed properly.

ajstewart added on 2021-05-28 17:41:23:
And... now it's not working again. Can you clarify what directory TCLLIBPATH should be set to? Are there any other env vars that can affect things? Not sure if TCL_LIBRARY or TK_LIBRARY affect tkinter...

ajstewart added on 2021-05-28 02:31:17:
I think I FINALLY figured out the problem. We were setting `TCLLIBPATH` to `<prefix>/lib/tk8.6` when it should be `<prefix>/lib`. With this change, tkinter seems to work for me. Thanks for all of your help!

P.S. Would you or any other Tcl/Tk developers be interested in helping maintain our Spack recipes? You don't have to know anything about Spack, it just gives us someone to ping on GitHub when a user reports a build/run issue with Tcl/Tk or submits a PR to modify the package.

ajstewart added on 2021-05-27 18:41:30:
For posterity, here is the issue I opened with Python: https://bugs.python.org/issue44253

ajstewart added on 2021-05-27 18:22:36:
Thanks, I'm not sure why tk.tcl is being installed in different locations for me. If `<prefix>/lib/tk8.6/tk.tcl` is the correct location, I'll open an issue with the Python developers so that Python's tkinter looks for tk.tcl in this location.

jan.nijtmans added on 2021-05-25 14:02:23: (text/x-fossil-wiki)
Well, tk.tcl should be installed in `<prefix>/lib/tk8.6/tk.tcl`, never in `<prefix>/lib/tk.tcl`. The reason: Tk 8.7 can be installed parallel to Tk 8.6, so where should it's tk.tcl be then? I'm not aware on any situation when tk.tcl would be installed in `<prefix>/lib/tk.tcl`, if that happens it's definitely a bug.

On MacOS, tk.tcl file (for Tk 8.6) is supposed to be installed in `/Library/Frameworks/Tk.framework/Versions/8.6/Resources/Scripts`. The configure option --enable-framework is taking care of this: using the MacOS standard framework layout in stead of the standard layout on other platforms. If you use the GNUmakefile for the build (in the macosx directory) all of this will be taken care of for you.

ajstewart added on 2021-05-22 16:21:11:
> The build portion definitely works in parallel, but I am uncertain that
the install portion works properly in parallel.

I tried running both the build and install steps in serial but it didn't help.

> Note that mismatched versioning is a separate issue.

Yes, I managed to solve this bug thanks to https://core.tcl-lang.org/tk/info/997b17c343444e48

Is there some global configuration file that controls which directory tk.tcl is installed to? Or some environment variable that affects this?

bll added on 2021-05-21 18:25:53:
You wrote:
> ...Maybe it's a parallel build bug...

The build portion definitely works in parallel, but I am uncertain that
the install portion works properly in parallel. 
I would separate those two steps.

Note that mismatched versioning
> RuntimeError: tk.h version (8.6) doesn't match libtk.a version (8.5)
is a separate issue.  I patch my init.tcl so it doesn't search in odd
places.