Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PyInstaller executable issue #58

Open
ardoramor opened this issue Jan 7, 2015 · 25 comments
Open

PyInstaller executable issue #58

ardoramor opened this issue Jan 7, 2015 · 25 comments

Comments

@ardoramor
Copy link

After testing the application to work from source, I've built an executable:
pyinstaller.exe --onefile app.py

When I run the app.exe from the cmd, it prints the following error to the log:

Traceback (most recent call last):
File "", line 146, in
File "C:...\build\app\out00-PYZ.pyz\gooey.python_bindings.gooey_decorator", line 86, in inner
IOError: [Errno 2] No such file or directory: 'C:\Users...\AppData\Local\Temp_MEI108682\gooey_tmp\app.exe'

Does Gooey play well with PyInstaller or it hasn't been tested?

@chriskiehl
Copy link
Owner

You're a bit of a pioneer :) I haven't dug into PyInstaller and what all Gooey needs in order to be packaged up nicely.

Try running it without --onefile. I know in the past there was an issue with PyInstaller that, for whatever reason, would cause it to throw an error whenever you packaged a python app that used multiprocessing with --onefile. I dunno if that's still the case, but it could be a good starting point for debugging.

(note: typing this at work.. so it's just a quick off the top of my head guess at one possible issue)

I'll hopefully dig into the issue soon.

@ardoramor
Copy link
Author

I got the following output while compiling without --onefile:

Traceback (most recent call last):
File "", line 151, in
File "C:\Users...\Documents\Projects\app\build\App\out00-PYZ.pyz\gooey.python_bindings.gooey_decorator", line 86, in inner
IOError: [Errno 2] No such file or directory: 'C:\Users...\DOCUME1\PROJ1\Ap1\dist\Ap1\gooey_tmp\App.exe'

The following directory exists:
'C:\Users...\DOCUME1\PROJ1\Ap1\dist\Ap1
But gooey_tmp\App.exe does not exist.

Looking at PyInstaller's warning output, I noticed the following:
W: delayed import hack detected at line 0 - gooey.python_bindings.modules (C:\Python27\lib\site-packages\gooey-0.1.0-py2.7.egg\gooey\python_bindings\modules.pyc)
W: delayed import hack detected at line 0 - gooey.python_bindings.gooey_decorator (C:\Python27\lib\site-packages\gooey-0.1.0-py2.7.egg\gooey\python_bindings\gooey_decorator.pyc)

@thoppe
Copy link
Contributor

thoppe commented Apr 2, 2015

I can confirm this error as well, with perhaps a bit more traceback:

Traceback (most recent call last):
  File "<string>", line 24, in <module>
  File "Z:\...\build\build\test\out00-PYZ.pyz\gooey.python_bindings.gooey_decorator", line 96, in inner
  File "Z:\...\build\build\test\out00-PYZ.pyz\gooey.gui.lang.i18n", line 41, in load
IOError: [Errno Language file not found. Make sure that your ] translation file is in the languages directory, 
err:seh:setup_exception_record stack overflow 1568 bytes in thread 0009 eip 7bc4629f esp 00240d10 stack 0x240000-0x241000-0x340000

using the compile options

wine python pyinstaller/pyinstaller.py --hidden-import=gooey test.py

and the test file

import gooey
from gooey import GooeyParser

@gooey.Gooey()
def main():
    parser = GooeyParser()
    parser.add_argument('-i', widget='FileChooser')
    args = parser.parse_args()
    print "DONE"



if __name__ == '__main__':
  main()

@Roshgar
Copy link
Contributor

Roshgar commented Jun 9, 2015

So, I tried messing around and compiling gooey. It did not work out but since there is an open issue i'll try to add in what i have.

I got passed the part where it complains about the language files (Thank you .spec file), with these files :

My test.py File

from gooey import Gooey
from gooey import GooeyParser
import argparse

@Gooey
def toto():
    parser = GooeyParser()
    parser.add_argument("toto")
    print("After add_argument")
    parser.parse_args()
toto()
print("Hello World!")

My test.spec File : (As a --onefile)

# -*- mode: python -*-
#Gooey_languages and gooey_images are used to fetch the files and solve the problem that was occuring preivously. (i.e : Language file not found)
gooey_languages = Tree('C:/Python27/Lib/site-packages/gooey/languages', prefix = 'gooey/languages')
gooey_images = Tree('C:/Python27/Lib/site-packages/gooey/images', prefix = 'gooey/images')
a = Analysis(['test.py'],
             pathex=['c:\\Python27\\Scripts'],
             hiddenimports=[],
             hookspath=None,
             runtime_hooks=None)
pyz = PYZ(a.pure)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          gooey_languages, # Add them in to collected files
          gooey_images, # Same here.
          name='test.exe',
          debug=False,
          strip=None,
          upx=True,
          console=True )

Commandline :
pyinstaller test.spec

Some warnings pop up, however since no reference to import issues are made when launched, i'm assuming they're uneventful.

C:\Python27\lib\site-packages\PyInstaller\hooks\hook-wx.lib.pubsub.core.py:11: RuntimeWarning: Parent module 'PyInstaller.hooks.hook-wx.lib.pubsub' not found while handling absolute import
  import os
C:\Python27\lib\site-packages\PyInstaller\hooks\hook-wx.lib.pubsub.core.py:12: RuntimeWarning: Parent module 'PyInstaller.hooks.hook-wx.lib.pubsub' not found while handling absolute import
  import PyInstaller.hooks.hookutils
C:\Python27\lib\site-packages\PyInstaller\hooks\hook-wx.lib.pubsub.core.py:14: RuntimeWarning: Parent module 'PyInstaller.hooks.hook-wx.lib.pubsub' not found while handling absolute import
  from PyInstaller.hooks.hookutils import logger

And it outputs an executable. Yay! However when launched, it displays a Gooey window, allows you to enter the arguments, but once you hit start it outputs an error that always sticks to these lines :

File "c:\.....\appdata\temp\tmp_xxxxx.py", line 1
SyntaxError : Non-ASCII character '\x90' in file
c:\......\tmp_xxxxx,py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details.

So on I go to see what this says. And it is due to python believing all files are encoded in ascii since nothing else was specified. Very well. I meddled with site.py to set the default encoding to utf-8 and see if that would help. It did not. (Printing sys.getdefaultencoding() returns utf-8 so i know it has been set and that the character in question is among the utf-8 set.)
As for adding the # -*- encoding : utf-8 -*- to every file (gooey and all included) i didn't have the courage so i do not know if it could help.

As far as trying to do a directory build (and not a --onefile which is wht my spec file does) I could not figure out a way to bypass "missing python27.dll". Adding it to binaries did not work, it is present in both sys directories (32 and 64) so i must be doing something wrong on that side and thus cannot really test it that way.

But if the people who can manage a clean build without --onefile could throw in the lines that i added to fetch the language/image packs in the .spec file, it might solve the problem noted by @thoppe

@daranguiz
Copy link

@Roshgar, found the issue!

In gooey\python_bindings\config_generator.py, change:

run_cmd = 'python {}'.format(source_path)

to

if hasattr(sys, 'frozen'):
    run_cmd = source_path
else:
    run_cmd = 'python {}'.format(source_path)

Gooey is trying to launch your file as if it were a python file, ie python myfile.exe, leading to the weird encoding issues. Just tell it to launch as-is instead of prepending python, and it works great.

@8BitAce
Copy link
Contributor

8BitAce commented Aug 7, 2015

Combining the solutions by @Roshgar and @daranguiz works great for me.

@daranguiz: Will you be creating a PR for this fix? I can do so instead if it's easier.

I'm also going to try to take a look at helping PyInstaller work out of the box with Gooey. They seem like a perfect combination.

@daranguiz
Copy link

@8BitAce: It'd be easier for me if you submitted the PR, thank you!

@iodbh
Copy link

iodbh commented Nov 3, 2015

I also have the issue where the language file are not found at runtime - @Roshgar 's method of editing the spec file does not help. The only difference I can see is that I'm using Linux, but I've adjusted the paths accordingly.

@chriskiehl
Copy link
Owner

@iodbh There's a pull request by @Shura1oplot here ( #118) that says it has fixes for the numerous path issues. Do you wanna check out that branch and see if it fixes your problem?

@iodbh
Copy link

iodbh commented Nov 4, 2015

Done. The fix works if I copy the languages and images directories into dist/gooey; but the files are not found if I add them to pyInstaller's collect files (via @Roshgar 's edits in the spec file). The new error message is more explicit :

IOError: cannot locate Gooey resources. It seems that the program was frozen, but resource files were not copied to directory of the executable file. Please copy `languages` and `images` folders from gooey module directory into `/home/user/projects/gooeytest/dist/gooey/` directory.

So the generated executable is now runnable if the directories are copied.

@tandreas
Copy link

tandreas commented Nov 5, 2015

I had this same issue as @iodbh today, @Roshgar's method was not working with the latest version 0.8.14.0. Unfortunately copying the directories dist/gooey directory is not an option when using PyInstaller onefile.

I downgraded to 0.8.12.0 and it started working again. This is on Windows.

@chriskiehl
Copy link
Owner

@tandreas : (

Arg... Alright, next task at the top of my TODO is to solve all these packaging woes!

@Shura1oplot
Copy link
Contributor

Please try this #123.

@chriskiehl
Copy link
Owner

@tandreas

Minor progress! I figured out how to make --onefile play nice with the external resources! No more manual copying stuff. Turns out that part of the magic of onefile is that it unpacks all of the resources into a temp directory on startup. See here: https://pythonhosted.org/PyInstaller/#run-time-operation

With that info, a quick update to @Shura1oplot's get_resource_handler so that it grabs the _MEIPASS directory when frozen and all seems to work nicely now.

I'm still facing missing import issues with multiprocessing, but.. at least the non-code resources load!

@Shura1oplot
Copy link
Contributor

@chriskiehl
Commit 660b0b0 breaks support of cx_freeze as it does not set sys._MEIPASS. Both freezers should work with PR #123.

@chriskiehl
Copy link
Owner

@Shura1oplot Doh! I hadn't looked at that pull. I'll revert f0c3771 and merge in #123.

I think we can almost call this issue officially solved! I can package using both PyInstaller and cxFreeze on both Windows and Linux. Wiki entry on the topic is in progress (On my win8 machine, I'm needing a small hack to force stdout to flush when using pyinstaller).

The last piece of this is just sanity checking that it packages okie-dokie on OSX. Once that's confirmed, this issue is done!

@joauea
Copy link

joauea commented Mar 8, 2016

@chriskiehl Has OSX packaging been confirmed? If so, are there special instructions I need to follow? I can't get it to work for me.

@nxion
Copy link

nxion commented Apr 13, 2016

I had the same issue as the binary would not run as it complained that it was missing the image folder and language folders. I followed the spec file that @Roshgar referenced above and it works as one file now. This has saved me a lot of work. Thank you @Roshgar .

@jocijuma
Copy link

jocijuma commented Apr 25, 2016

I tried to build a simple demo using pyinstaller. It compiles without errors, and the UI entry form comes up when I run the .exe, but nothing happens when I click the start button. No error message. The window just stays as is (except the start button does "depress" when it is clicked)
The script works if not compiled.
Environment: Windows 7. Python 2.7, 64 bit. Gooey 0.9.2.3, pyinstaller 3.1.1
I tried the spec file as detailed under "Packaging Gooey as a Distributable Application", and the one at https://github.com/chriskiehl/Gooey/files/29568/build.spec.txt. (They are different by a couple lines. Same result for both)
If I add the stdout fix lines, I get fatal error: ....exe returned -1
If no entry is made for a required argument, then the expected error popup does come up after I click start.
Any thoughts on what's wrong, or suggestions to try, would be a huge help. Thank you. - Chris

@Fury1
Copy link

Fury1 commented May 23, 2016

I tried to build a simple demo using pyinstaller. It compiles without errors, and the UI entry form comes up when I run the .exe, but nothing happens when I click the start button. No error message. The window just stays as is (except the start button does "depress" when it is clicked)
The script works if not compiled.

^ Im having the EXACT same problem, its been driving me nuts....would love to find a solution to get rid of the error or the console window. In addition, I had to compile with pyinstaller 3.1 instead of 3.2.

@bastula
Copy link
Contributor

bastula commented Jun 15, 2016

My own module uses subprocess and I ran into the same issue. However, a strange thing happens (which is unrelated) where if I issue subprocess.call when frozen, a console comes up for every call instance. My program works as intended though.

@bastula
Copy link
Contributor

bastula commented Jun 15, 2016

Actually I fixed my own subprocess issue by following the comment here:
https://groups.google.com/d/msg/pyinstaller/-4Fdy7suh0U/0o9Yqa78zCEJ

Turns out you just need to addd a startupinfo object to your subprocess call.

It's also documented here on the PyInstaller website: https://github.com/pyinstaller/pyinstaller/wiki/Recipe-subprocess

So after all this, my frozen Gooey executable works perfectly. Thanks so much for this project!

@sodwyer
Copy link
Contributor

sodwyer commented Jul 5, 2016

"but nothing happens when I click the start button"

I'm also having this issue, anyone have any ideas?

@sodwyer
Copy link
Contributor

sodwyer commented Jul 6, 2016

I managed to track this a bit further.

It seems ProcessController.run hits an exception when calling subprocess.Popen, if the --noconsole option is supplied when running pyinstaller.
http://stackoverflow.com/questions/33020644/python-subprocess-popen-with-pyinstaller

It works for me if I enable console in the build.spec
console=True,

Of course, that enables a big console window in the background :( but it's a workaround

@asfaltboy
Copy link

To use cx_freeze with Gooey on OSX, I had to specify the language/image resources to include:

import os
import gooey
from cx_Freeze import setup, Executable


def get_resources():
    target_prefix = 'gooey'
    source_dir = os.path.dirname(gooey.__file__)
    subdirs = ['languages', 'images']
    includes = []
    for directory in subdirs:
        path = os.path.join(source_dir, directory)
        for file in os.listdir(path):
            file_path = os.path.join(path, file)
            relative_path = os.path.join(target_prefix, directory, file)
            includes.append((file_path, relative_path))
    return includes


setup(
    name="my_gooey_app",
    version="0.1",
    description="My Gooey App",
    options={"build_exe": {'include_files': get_resources()}},
    executables=[
        Executable("my_gooey_app.py", base=base),
    ]
)

I also to make sure to use a python version compiled with support for GUI applications (--enable-shared or --enable-framework). I use pyenv, so I had to follow these instructions.

I guess this confirms it for OSX.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests