dkriegner / micro-flakes

https://dkriegner.github.io/micro-flakes/
GNU General Public License v3.0
0 stars 0 forks source link

create standalone executable for easier distribution of the program #13

Open dkriegner opened 1 year ago

dkriegner commented 1 year ago

we might want to use something like PyInstaller to create an executable which people without python knowledge can use

ji-ze commented 1 year ago

I've just tested PyInstaller. It doesn't work for me: <-img width="958" alt="image" src="https://github.com/dkriegner/micro-flakes/assets/44098973/93f45747-5c31-4910-9b6e-45b14dcccaf5">

image image

I uploaded an executable project by auto-py-to-exe. But it doesn't work for me. The script falls after opening.

dkriegner commented 1 year ago

two things:

  1. The executable should not be in the git tree. It can potentially be uploaded if we make a release.
  2. I believe you tried to generate the executable from the main file. I believe this has to be done from the installed script since the main file in the source directory is not executable.
ji-ze commented 1 year ago

I made an exe-file from main.py, but I included other py-files.

ji-ze commented 1 year ago

Should I copy all parts of the code to main.py before compilation to exe?

dkriegner commented 1 year ago

in my opinion any python to executable converter has to include all things its needs itself. It can not be necessary to copy all to main!

ji-ze commented 1 year ago

I've done it. It works well!

dkriegner commented 1 year ago

One important thing: please add the command(s) you used to generate the exe somewhere in the documentation/readme. We will need it for future reference. I also believe the exe should not be part of the git sources. we should generate a release and attach the exe as a binary file. Likely the same should be done with the GUI version.

I would therefore propose

  1. generate a release readme file which is aimed at the developer(you) to help you generate the executable(s)
  2. lets make an initial release (e.g. version 0.0.1.)
  3. then ask a windows user to test the code/executable. Since I do not use windows this can't be me. maybe Helena
ji-ze commented 1 year ago

I moved to releases.

dkriegner commented 1 year ago

I am still missing the readme on how to regenerate the executables when a new version is releases.

Also in the release I believe we should have two exe files. One with the GUI and one with the command line code.

dkriegner commented 1 year ago

Also is there an option to get a single exe file? If it includes all the dll files it would be easier for the user to move around the exe file.

dkriegner commented 1 year ago

In order to avoid copying the code and needing to make main.py directly executable we should look into this option of pyinstaller: https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Setuptools-Entry-Point

It should allow to create the exe file directly from the entry point definition and we do not need to change the code for it.

ji-ze commented 12 months ago

pyinstaller --noconfirm --onefile --windowed --icon "C:/Users/jirka/Documents/Test/EXE/ICON.ico" --name "GUI_0.0.6" --add-data "C:/Users/jirka/Documents/Test/EXE/ICON.ico;." "C:/Users/jirka/Documents/Test/EXE/main_GUI.py"

dkriegner commented 11 months ago

From your command I constructed the following console_script.spec file

# -*- mode: python ; coding: utf-8 -*-

def Entrypoint(dist, group, name, **kwargs):
    import pkg_resources

    # get toplevel packages of distribution from metadata
    def get_toplevel(dist):
        distribution = pkg_resources.get_distribution(dist)
        if distribution.has_metadata('top_level.txt'):
            return list(distribution.get_metadata('top_level.txt').split())
        else:
            return []

    kwargs.setdefault('hiddenimports', [])
    packages = []
    for distribution in kwargs['hiddenimports']:
        packages += get_toplevel(distribution)

    kwargs.setdefault('pathex', [])
    # get the entry point
    ep = pkg_resources.get_entry_info(dist, group, name)
    # insert path of the egg at the verify front of the search path
    kwargs['pathex'] = [ep.dist.location] + kwargs['pathex']
    # script name must not be a valid module name to avoid name clashes on import
    script_path = os.path.join(workpath, name + '-script.py')
    print("creating script for entry point", dist, group, name)
    with open(script_path, 'w') as fh:
        print("import", ep.module_name, file=fh)
        print("%s.%s()" % (ep.module_name, '.'.join(ep.attrs)), file=fh)
        for package in packages:
            print("import", package, file=fh)

    return Analysis(
        [script_path] + kwargs.get('scripts', []),
        **kwargs
    )

a = Entrypoint('Detector', 'console_scripts', 'flakes-detector')

pyz = PYZ(a.pure)

exe = EXE(
    pyz,
    a.scripts,
    a.binaries,
    a.datas,
    [],
    name='flakes-detector',
    debug=False,
    bootloader_ignore_signals=False,
    strip=False,
    upx=True,
    upx_exclude=[],
    runtime_tmpdir=None,
    console=True,
    disable_windowed_traceback=False,
    argv_emulation=False,
    target_arch=None,
    codesign_identity=None,
    entitlements_file=None,
)

calling pyinstaller console_script.spec should generate the executable for the terminal version. A very similar script would work for the GUI version. Please test it in windows. If this works we can upload the spec file and generate a github action which will build the executables (at least for windows).