2

I have just packaged my app (OSX 10.12.15 - python3.6 - py2app 0.12) and my application works only if launched from the terminal with MyApp.app/Contents/MacOS/MyApp. If I click on the app in the GUI, it doesn't start.

This is my setup.py:

from setuptools import setup

    APP = ['mq.py']
    DATA_FILES = []
    OPTIONS = {
        'iconfile':'icons/mq.icns',
            'plist': {'CFBundleShortVersionString':'0.1.0',}
    }

    setup(
        app=APP,
        name='MyApp',
        data_files=DATA_FILES,
        options={'py2app': OPTIONS},
        setup_requires=['py2app'],
    )- 
Fabio Marzocca
  • 1,573
  • 16
  • 36
  • Could we get a little more information? How is the GUI created, do you get a traceback, and have you tried anything else? – Jacob Birkett Jun 26 '17 at 17:27
  • The application is tkinter/ttk python3, with no other libraries than few standard one. It works great as a script and also aftaer packaging, but only from the terminal, not from GUI. I don't have a traceback now, but it seems to me that pyhton distributable is not complete or maybe wrong. I was wrong when I said it didn't start: it starts but fails on a simple function that is looking fo a file on the system. But -again - only if I launch the application by double-clicking in the GUI. – Fabio Marzocca Jun 26 '17 at 18:46
  • That app packager in that case is probably using a temporary directory as the working directory for the bundle. Try resolving to `/` using absolute paths (or starting at an absolute base path and searching for the file from there). When you launch something from any terminal, it uses the path from where the terminal is active. If you have to `cd` to the script or app package, that's where the working path is going to be. – Jacob Birkett Jun 26 '17 at 18:51
  • This is the piece of code on which the app stops (and as it is a go/no-go point, the whole app can't continue. ` def checkifffmpeg(self): try: devnull = open(os.devnull) subprocess.call(['ffmpeg', '-version'], stderr=subprocess.STDOUT, stdout=devnull) except: return False return True ` It looks for ffmpeg installed in the system, in computer's PATH – Fabio Marzocca Jun 26 '17 at 18:54
  • Put it in a Hastebin, as I'm on a phone and that's difficult to read. https://hastebin.com – Jacob Birkett Jun 26 '17 at 18:56
  • Yes, sorry. Here it is (it looks for ffmpeg installed in the system's PATH): https://pastebin.com/CnBsY7Hs – Fabio Marzocca Jun 26 '17 at 18:58
  • I changed "ffmpeg" with "/usr/local/bin/ffmpeg" and it worked! But that's not fair, as ffmpeg could be installed in other locations, and my application is checking if it is in the computer's PATH environment! – Fabio Marzocca Jun 26 '17 at 19:13
  • Let me know if this works. https://pastebin.com/RQmjbFMP – Jacob Birkett Jun 26 '17 at 19:53
  • Well, that is exactly what that little bit that I gave you will do. I made that function, `get_ffmpeg()` that returns the path of FFMPEG. Then I tweaked your second function to see if it's there. You can use both, and if it exists, call FFMPEG from the absolute path returned from my function. It looks as if I accidentally removed the `-` from your subprocess call, just put it back. – Jacob Birkett Jun 26 '17 at 20:04
  • I will try it tomorrow morning, but looking at the code it should work. Thank you! – Fabio Marzocca Jun 26 '17 at 20:05
  • No problem! If it works, let me know and I would like to make it into an answer. Also, see edit to my previous comment. – Jacob Birkett Jun 26 '17 at 20:07
  • Looking again at the code (I am outside) I think it won't work. I should traverse all path directories looking for the program. In addition, the subprocess will not work that way, as the program will not find just "ffmpeg" but it needs the full path. Why py2app-ed applications are not loading system PATH environment? Is there a specific setup option for that? – Fabio Marzocca Jun 26 '17 at 20:12
  • This should not work: if "ffmpeg" in ent.lower(): you are just looking if the string "ffmpeg" is in the pathname (i.e: /usr/bin)... – Fabio Marzocca Jun 26 '17 at 20:15
  • Yes, but it checks each path that is in PATH, and checks if FFMPEG is in the string. If it is in the string, it returns it, because that's probably the path to it. – Jacob Birkett Jun 26 '17 at 20:23
  • 1. ffmpeg could be a file folder, not in the string (foldername)! 2. getenv (PATH) is not working in the app, as the app has no access to system's PATH (otherwise I didn't have any problem) 3. I hope there is an option in py2app for this... – Fabio Marzocca Jun 26 '17 at 20:24
  • Can I see the path to your FFMPEG installation? – Jacob Birkett Jun 26 '17 at 20:26
  • echo $PATH = /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin which ffmpeg = /usr/local/bin/ffmpeg – Fabio Marzocca Jun 26 '17 at 20:26
  • This was my original idea. https://repl.it/JCpx But see if since FFMPEG is LGPL 2.1, you can just bundle it in the app. – Jacob Birkett Jun 26 '17 at 20:35
  • unfortunately, I can't. ffmpeg installation is made of several dependecies, libraries and other files. It is a complex installation which has to be done with Homebrew. – Fabio Marzocca Jun 26 '17 at 20:42
  • I am still wondering why py2app completely disregards system's environmental variables.... – Fabio Marzocca Jun 26 '17 at 20:46
  • Looks bundle-able to me... In fact, I can almost swear that I did it once. https://www.ffmpeg.org/download.html – Jacob Birkett Jun 26 '17 at 20:47
  • Don't rely on that! If you need a real ffmpeg (with all functionalities) you have to install the brew package. Anyway, I have found that this problem in py2app is very old: http://pythonmac-sig.python.narkive.com/tEtB9SBs/environment-variable-issues-running-py2app-application – Fabio Marzocca Jun 26 '17 at 20:50
  • what you have linked to, is the source code of ffmpeg. If you look at it, it is made of tenths of libraries and (once compiled) they have to go into different folders. I told you, ffmpeg is a complex system (I am working on it on Linux since many years) – Fabio Marzocca Jun 26 '17 at 20:53
  • **FIXED** I have fixeed this by adding the following code as one of the first lines of the application: os.environ['PATH'] = '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin' + os.environ['PATH'] This should be done for any p2app bundle – Fabio Marzocca Jun 26 '17 at 21:02
  • Shorten it by doing this: `os.environ["PATH"] += "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"` – Jacob Birkett Jun 26 '17 at 21:41

0 Answers0