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

Example of packaging app using pyinstaller #135

Closed
GoogleCodeExporter opened this issue Aug 28, 2015 · 17 comments
Closed

Example of packaging app using pyinstaller #135

GoogleCodeExporter opened this issue Aug 28, 2015 · 17 comments

Comments

@GoogleCodeExporter
Copy link

GoogleCodeExporter commented Aug 28, 2015

Update
PyInstaller example for Windows was added in commit f94eaa6. See PyInstaller README for details.

ToDo: check if msvcpxx.dll is included by pyinstaller (Issue #359)


http://www.pyinstaller.org/

See also:

Original issue reported on code.google.com by [email protected] on 18 Aug 2014 at 7:45

@goldalworming
Copy link

got this problem today
FATAL : content_main_runner.cc(720)] Check failed: base::i18n::InitializeICU()

@cztomczak
Copy link
Owner

@goldalworming Looks like some of the binary files are missing

@nkiiiiid
Copy link

nkiiiiid commented Mar 9, 2017

@goldalworming i got the same problem, did you solve it?help

@cztomczak
Copy link
Owner

cztomczak commented Mar 9, 2017

All binary data files need to be included by pyinstaller when creating executable. There are .exe .dll .dat .bin .pak and other binary data in the cefpython package that need to be included. Take a look at an example configuration using py2exe: http://stackoverflow.com/questions/18630034/compiling-exe-with-py2exe-and-including-cefpython

Please ask questions and report problems on the Forum.

@cztomczak
Copy link
Owner

cztomczak commented Sep 5, 2017

PyInstaller example for Windows was added in commit f94eaa6.

See PyInstaller README for details.

@cztomczak
Copy link
Owner

Pyinstaller example supports all platforms now.

@nick4ever
Copy link

My apology for bothering you guys, but I faced this problem, would you mind guiding me a direction?

When I ran python pyinstaller.py, the result in ./build/pyinstaller/warnpyinstaller.txt

missing module named 'org.python' - imported by pickle
missing module named _subprocess - imported by subprocess
missing module named msvcrt - imported by subprocess
missing module named riscosenviron - imported by os
missing module named riscospath - imported by os
missing module named riscos - imported by os
missing module named ce - imported by os
missing module named _emx_link - imported by os
missing module named os2 - imported by os
missing module named nt - imported by os, ntpath
missing module named org - imported by copy
missing module named _sha512 - imported by hashlib
missing module named _sha256 - imported by hashlib
missing module named _md5 - imported by hashlib
missing module named _sha - imported by hashlib

Please help!!!

@cztomczak
Copy link
Owner

@rlaphoenix
Copy link

rlaphoenix commented Jun 14, 2020

Just a bit of advice to anyone trying to do this, in your setup.py, add a cmdclass argument to setup() and call it whatever, I used "pack", and use the following code in it (research how to use cmdclass):

from PyInstaller.utils.hooks import get_package_paths

...

subprocess.Popen([
      "pyinstaller", "--clean", "-F", "appname/__init__.py",
      "--add-data", f"{get_package_paths('cefpython3')[1]}:cefpython3",
      "--hidden-import", "pkg_resources.py2_warn", "-n", "AppName"
])

This removes the need for the entire pyinstaller.spec and hook-cefpython3.py files. Works like a charm for me, and is actually a smaller overall file then the one with the .spec (which never worked for me by the way)

Now all I need to do is, python setup.py pack and it will build it into /dist

@steveseguin
Copy link

steveseguin commented Jul 15, 2020

Just a bit of advice to anyone trying to do this, in your setup.py, add a cmdclass argument to setup() and call it whatever, I used "pack", and use the following code in it (research how to use cmdclass):

rlaPHOENiX, did you ever get this working with macOS ? I'm about to give up on cefpython as I just can't get it to bundle into a single binary in macOS with any of the tools out there. I've wasted a week and have only got it working with Windows.

error: icudtl.dat not found in bundle

Setting the framework_dir_path doesn't help, nor does including --add-data=cef-framework-path:cef.framework ,etc I feel like I've tried every combination under the sun here, trying to get the file to be included and referenced appropriately. File sizes are also pretty large; over 300mb, yet no luck. The existing example in the cepython examples folder also fails, nor does it bundle into a file.

Tried other apps, like nuitka, and also ran endless issues that seem unresolvable.

Again, only on macOS. Getting this all to work on Windows I had working on the first night.

@rlaphoenix
Copy link

Just a bit of advice to anyone trying to do this, in your setup.py, add a cmdclass argument to setup() and call it whatever, I used "pack", and use the following code in it (research how to use cmdclass):

rlaPHOENiX, did you ever get this working with macOS ? I'm about to give up on cefpython as I just can't get it to bundle into a single binary in macOS with any of the tools out there. I've wasted a week and have only got it working with Windows.

error: icudtl.dat not found in bundle

Setting the framework_dir_path doesn't help, nor does including --add-data=cef-framework-path:cef.framework ,etc I feel like I've tried every combination under the sun here, trying to get the file to be included and referenced appropriately. File sizes are also pretty large; over 300mb, yet no luck. The existing example in the cepython examples folder also fails, nor does it bundle into a file.

Tried other apps, like nuitka, and also ran endless issues that seem unresolvable.

Again, only on macOS. Getting this all to work on Windows I had working on the first night.

I don't have any device that uses Mac so I havent gotten any chance of checking it out for that, but your --add-data seems wrong. If you look at my example just above you should see that what I aim to do, is find the site-packages location of cefpython3, and then bundle it a folder of the same exact same of the package (cefpython3). A good idea also would be to try and do all of this with Python 3.7.x or edit the __init__.py in the site-packages and change elif sys.version_info[:2] == (3, 7): to elif sys.version_info[:2] in [(3, 7), (3, 8)]:, doing this supports Python 3.8 perfectly fine for me on Windows and Linux.

Perhaps the version check causes some kind of problem? Who knows.

@steveseguin
Copy link

steveseguin commented Jul 15, 2020 via email

@rlaphoenix
Copy link

rlaphoenix commented Jul 15, 2020

Thank you for the reply. It's a time suck for sure. I've tried different versions and it all gets to be somewhat of a mess after a while. I've managed to get it working if I include the frameworks folder alongside the exe, and point to it in the main.py code cef.init settings, tho the file size in total is pretty huge and slow loading. Not sure I'm going to get it better than this, so I'll probably need to abandon Python.

Yeah that indicates to me then, that it cant find cefpython3. You are doing the --add-data like I showed?

@steveseguin
Copy link

steveseguin commented Jul 15, 2020 via email

@rlaphoenix
Copy link

rlaphoenix commented Jul 15, 2020

The following is my cmdclass Pack Command for setup.py, it can be used in setup() by putting the following inside it:

setup(
  ...
  cmdclass={"pack": PackCommand}
)

Now you can do python setup.py pack

init.py thats imported by many of my cmdclass's like pack.py

import os
import sys
from shutil import rmtree

from APPNAME import meta


def print_bold(s):
    """Prints things in bold."""
    print("\033[1m{0}\033[0m".format(s))


def build_clean():
    print_bold("Removing previous builds…")
    try:
        rmtree(os.path.join(meta.ROOT_DIR, "dist"))
    except OSError:
        pass
    try:
        rmtree(os.path.join(meta.ROOT_DIR, "build"))
    except OSError:
        pass


def build():
    build_clean()
    print_bold("Ensuring an up-to-date environment…")
    os.system(
        "{0} -m pip install --user --upgrade setuptools wheel".format(sys.executable)
    )
    print_bold("Building Source and Wheel (universal) distribution…")
    os.system("{0} setup.py sdist bdist_wheel --universal".format(sys.executable))

pack.py:

import os
import subprocess
import sys

from setuptools import Command

from APPNAME import meta
from setup_commands import build_clean, print_bold


class PackCommand(Command):
    """Support setup.py pack."""

    description = "Pack the repo with PyInstaller."
    user_options = []

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    @staticmethod
    def run():
        from PyInstaller.utils.hooks import get_package_paths
        build_clean()
        print_bold("Ensuring supported environment…")
        if not meta.WINDOWS and not meta.LINUX and not meta.DARWIN:
            print("Sorry! Only Windows, Linux and Darwin platforms are supported.")
            sys.exit(1)
        print_bold("Ensuring PyInstaller is available…")
        os.system(
            "{0} -m pip install --user --upgrade pyinstaller".format(sys.executable)
        )
        print_bold("Packing with PyInstaller…")
        sep = ";" if meta.WINDOWS else ":"
        sub = subprocess.Popen(
            [
                "pyinstaller",
                "--clean",
                "-F",
                f"{meta.TITLE_PKG}/__init__.py",
                "--add-data",
                f"{meta.TITLE_PKG}/static{sep}static",
                "--add-data",
                get_package_paths("cefpython3")[1].replace("\\", "/")
                + f"{sep}.",
                "--hidden-import",
                "pkg_resources.py2_warn",
                "-n",
                "APPNAME",
            ]
        )
        sub.communicate()
        if sub.returncode != 0:
            print("Oh no! PyInstaller failed, code=%s" % sub.returncode)
            build_clean()
            sys.exit(1)
        sys.exit()

@rlaphoenix
Copy link

rlaphoenix commented Jul 15, 2020

I'll give your suggestion a go. :) Thank you.

I just realised with my above code example I actually used --add-data "bla bla:." not "bla bla:cefpython3", so the . makes it put it next to init.py flattening the files, which is probably why it works for me.

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

No branches or pull requests

7 participants