47

When I use cx_Freeze I get a keyerror KeyError: 'TCL_Library'while building my pygame program. Why do I get this and how do I fix it?

My setup.py is below:

from cx_Freeze import setup, Executable

setup(
    name = "Snakes and Ladders",
    version = "0.9",
    author = "Adam",
    author_email = "Omitted",
    options = {"build_exe": {"packages":["pygame"],
                         "include_files": ["main.py", "squares.py",
                         "pictures/Base Dice.png", "pictures/Dice 1.png",
                         "pictures/Dice 2.png", "pictures/Dice 3.png",
                         "pictures/Dice 4.png", "pictures/Dice 5.png",
                         "pictures/Dice 6.png"]}},
    executables = [Executable("run.py")],
    )
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Orange1861
  • 595
  • 1
  • 4
  • 10

7 Answers7

70

You can work around this error by setting the environment variables manually:

set TCL_LIBRARY=C:\Program Files\Python35-32\tcl\tcl8.6
set TK_LIBRARY=C:\Program Files\Python35-32\tcl\tk8.6

You can also do that in the setup.py script:

os.environ['TCL_LIBRARY'] = r'C:\Program Files\Python35-32\tcl\tcl8.6'
os.environ['TK_LIBRARY'] = r'C:\Program Files\Python35-32\tcl\tk8.6'

setup([..])

But I found that actually running the program doesn't work. On the cx_freeze mailinglist it was mentioned:

I have looked into it already and no, it is not just a simple recompile -- or it would have been done already! :-)

It is in progress and it looks like it will take a bit of effort. Some of the code in place to handle things like extension modules inside packages is falling over -- and that may be better solved by dropping that code and forcing the package outside the zip file (another pull request that needs to be absorbed). I should have some time next week and the week following to look into this further. So all things working out well I should put out a new version of cx_Freeze before the end of the year.

But perhaps you have more luck ... Here's the bug report.

Martin Tournoij
  • 26,737
  • 24
  • 105
  • 146
36

Instead of setting the environment variables using installation specific absolute paths like C:\\LOCAL_TO_PYTHON\\... you may also derive the necessary paths dynamically using the __file__ attribute of Python standard package like os:

import os.path
PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')

After this fix the executable file will be created, but you will probably get a "DLL not found error" when you try to execute it - at least with Python 3.5.3 and cx_Freeze 5.0.1 on Windows 10.

When you add the following options, the necessary DLL-files will be copied automatically from the Python-Installation directory to the build-output of cx-Freeze and you should be able to run your Tcl/Tk application:

options = {
    'build_exe': {
        'include_files':[
            os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'),
            os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'),
         ],
    },
}

# ...

setup(options = options,
      # ...
)
D. L. Müller
  • 461
  • 4
  • 2
  • Wow, this worked perfectly! I didn't even get a `DLL not found error`, so no need to add extra options as specified in the second part of your answer. I have Python 3.6 and my py-app uses Tkinter/TCL. – Alex Jan 16 '18 at 07:04
  • For cx_Freeze version 5.1.1, the DLLs need to be copied into a subdirectory `lib` of the build directory, see how in [my answer](https://stackoverflow.com/a/56495955/8516269). – jpeg Jun 18 '19 at 08:20
15

Just put this before the setup at setup.py

import os

os.environ['TCL_LIBRARY'] = "C:\\LOCAL_TO_PYTHON\\Python35-32\\tcl\\tcl8.6"
os.environ['TK_LIBRARY'] = "C:\\LOCAL_TO_PYTHON\\Python35-32\\tcl\\tk8.6"

And run it:

python setup.py bdist_msi

This worked fine for me.

Guilherme
  • 151
  • 1
  • 2
6

If you get following error with python 3.6:

copying C:\LOCAL_TO_PYTHON\Python35-32\tcl\tcl8.6 -> build\exe.win-amd64-3.6\tcl
error: [Errno 2] No such file or directory: 'C:\\LOCAL_TO_PYTHON\\Python35-32\\tcl\\tcl8.6'

Simply create LOCAL_TO_PYTHON dir in C:\ then create Python35-32 dir inside it. Now copy tcl dir from existing Python36 dir (in C:\) into Python35-32.

Then it works fine.

Mark Tomlin
  • 8,593
  • 11
  • 57
  • 72
Ben Wills
  • 61
  • 1
  • 1
0

If you get following error with python 3.6:

copying C:\LOCAL_TO_PYTHON\Python35-32\tcl\tcl8.6 -> build\exe.win-amd64-3.6\tcl error: [Errno 2] No such file or directory: 'C:\\LOCAL_TO_PYTHON\\Python35-32\\tcl\\tcl8.6'

Simply create LOCAL_TO_PYTHON dir in C:\ then create Python35-32 dir inside it. Now copy tcl dir from existing Python36 dir (in C:) into Python35-32.

Then it works fine.

**I did this steps and created a .exe file into the build dir but if ı try to click app dont wait on the screen instantly quick, my codes here **

from tkinter import *
import socket



window=Tk()
window.geometry("400x150")
window.title("IpConfiger")
window.config(background="black")

def goster():
    x=socket.gethostbyname(socket.gethostname())
    label=Label(window,text=x,fg="green",font=("Helvetica",16))
    label.pack()
def information():
    info=Label(window,text="Bu program anlık ip değerini 
    bastırır.",fg="green",font=("Helvetica",16),bg="black")
    info.pack()


information()
tikla=Button(window,text="ip göster",command=goster)

tikla.pack()
Xantium
  • 11,201
  • 10
  • 62
  • 89
0

D. L. Müller's answer need to be modified for cx_Freeze version 5.1.1 or 5.1.0. In these versions of cx_Freeze, packages get frozen into a subdirectory lib of the build directory. The TCL and TK DLLs need to be moved there as well. This can be achieved by passing a tuple (source, destination) to the corresponding entry of the include_files list option (see the cx_Freeze documentation).

Altogether the setup.py script needs to be modified as follows:

import os.path
PYTHON_INSTALL_DIR = os.path.dirname(os.path.dirname(os.__file__))
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR, 'tcl', 'tk8.6')

# ...

options = {
    'build_exe': {
        'include_files':[
            (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tk86t.dll'), os.path.join('lib', 'tk86t.dll'))
            (os.path.join(PYTHON_INSTALL_DIR, 'DLLs', 'tcl86t.dll'), os.path.join('lib', 'tcl86t.dll'))
         ],
    },
}

# ...

setup(options = options,
      # ...
)
jpeg
  • 2,372
  • 4
  • 18
  • 31
0

The initial KeyError problem:

KeyError

This worked for me with python 3.7 on windows 7:

from cx_Freeze import setup, Executable
import os
import sys

where = os.path.dirname(sys.executable)


os.environ['TCL_LIBRARY'] = where+"\\tcl\\tcl8.6"
os.environ['TK_LIBRARY'] = where+"\\tcl\\tk8.6"

build_exe_options = {"include_files": [where+"\\DLLs\\tcl86t.dll", where+"\\DLLs\\tk86t.dll"]}  


setup(
    name = "SudoCool",
    version = "0.1",
    description = "Programme de SUDOKU",
    options={"build_exe": build_exe_options},  
    executables = [Executable("sudoku.py")]
) 

Now cx_Freeze is working: it's working

enter image description here

enter image description here

My application is working: enter image description here

Raoul HATTERER
  • 522
  • 5
  • 5