Can pyinstaller make a desktop file (with an icon) for an Ubuntu python app

Question:

I’m building a python app which is to pack up as a single executable and work on Windows, MacOS and Linux. Have made a lot of progress and am using a workflow on Github to build using pyinstaller for each OS. Most things are working fine.

Right now I am working on getting an icon onto the executable instead of the default system icon.

I have a spec file for pyinstaller and I have a section where the icon is mentioned:

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.zipfiles,
    a.datas,
    [],
    name='my_app_name',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=False,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
    icon='images/my_icon.ico'
)

This seems to work well for Windows and the output exe file has my icon which is great.
My question is, is there a way to do this for Linux. I know that normally for Linux you need to build a .desktop file, so I guess the question is three-fold:

  1. Is there a way to give a file an icon without a desktop file (in Linux)?

or

  1. Is there a way to somehow build and connect a desktop file to my Linux file in pyinstaller?

or

  1. Is there some python way to self-create a desktop file for my python app?

Thanks

Asked By: Kibi

||

Answers:

There’s such a pip library as a auto-py-to-exe. It’s UI for pyinstaller and it makes it quite easier to create exe. Try to apply icon though that stuff.
I think it also should work for Linux as for Windows. But for me there were some errors if l created few files with same name and different icons. Not sure if it was problem of pyinstaller.

  1. It gives you a possibility to select icon (.ico file). I can guess that your error with icon due to wrong path to file or place from where you run cmd
  2. You can try to write another script that use pyinstaller to do it. But if clearly understood – you can create exe only using this library. If you need shortcut – it can be created by using os.system by another python script.
    Auto-py-to-exe UI
Answered By: Volodymyr Safiyanyk

OK, so I found a a way to do it – not really in pyinstaller, but it works for me.

I am building my app(s) using Github’s Workflow feature – so we have a file called python_build.yml under /.github/workflows

So, after building the executable with pyinstaller into a single file I have:

- name: Assign artifacts
  if: github.event_name == 'release'
  uses: knicknic/[email protected]
  with:
    macos: echo "artifact_path=My_app.dmg" >> $GITHUB_ENV
    windows: echo "artifact_path=dist/my_app.exe" >> $env:GITHUB_ENV
    linux: echo "artifact_path=dist/my_app.deb" >> $GITHUB_ENV
- name: Create DMG app (for MacOS)
  if: github.event_name == 'release' && runner.os == 'macOS'
  run: |
    rm -rf dist/my_app
    brew install create-dmg
    create-dmg --app-drop-link 100 100 "${{env.artifact_path}}" dist/
- name: Create DEB file for Ubuntu
  if: github.event_name == 'release' && runner.os == 'linux'
  run: |
    cp dist/my_app my-app/usr/share/bin/my_app 
    rm -rf my-app/usr/share/bin/hold
    fakeroot dpkg-deb --build my-app
- name: Sleep while DEB build happens
  if: github.event_name == 'release' && runner.os == 'linux'
  run: sleep 30s
  shell: bash
- name: Copy over DEB to dist folder
  if: github.event_name == 'release' && runner.os == 'linux'
  run: |
    cp my-app.deb dist/my-appi.deb
    rm -rf dist/my_app
- name: Add artifacts to release
  if: github.event_name == 'release'
  uses: ncipollo/[email protected]
  with:
    allowUpdates: true
    replacesArtifacts: false
    artifacts: ${{env.artifact_path}} 

So, there’s a couple of important points to add to this. I have saved in my Git repository a small directory structure named my-app. I don’t think this is the web page I used but it’s similar. Basically a folder named my-app with two folders underneath it : DEBIAN and usr. In the DEBIAN there is one file called control with something like this in it:

Package: my-app
Version: 1.1-7
Section: Utility
Priority: optional
Architecture: i386
Depends: 
Homepage: https://www.ourwebsite.com/
Maintainer: Kibi Hofmann <[email protected]>
Installed-Size: 31300
Description: Useful app for your use
 No dependencies or significant conflicts.
 This app is used to do your stuff

Under usr is a folder share which has three more folders under it applications, bin and icons.
The bin folder has (in my Git repository) an empty file called hold just so that the directory structure is maintained in Git – you can see that the hold file is deleted and replaced by the compiled binary after pyinstaller is finished. The Desktop file itself is under applications and looks like this:

[Desktop Entry]
Type=Application
Name=My App
GenericName=My cool app
Comment=Keep your computer happy
Exec=/usr/share/bin/my-app
Icon=myr_icon
Terminal=false
Categories=Application

Hope this helps someone!

Answered By: Kibi
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.