cloudmatrix / esky

an auto-update framework for frozen python apps
BSD 3-Clause "New" or "Revised" License
362 stars 74 forks source link

cxfreeze on mac os #103

Closed timeyyy closed 6 years ago

timeyyy commented 8 years ago

@JPFrancoia probably first thing is to test how far we get with cx freeze then we can do py2app

i created this repository for testing some stuff. https://github.com/timeyyy/freeze_future

you should start off by cloning it and cloning my esky/py3k repository,

you will need to add some code here, in the best case it is the same as the linux one.. https://github.com/timeyyy/esky/blob/py3k/esky/bdist_esky/f_cxfreeze.py#L186

JPFrancoia commented 8 years ago

Ok, let's go. I've to mention this is the first time I'm running this kind of tests, so I'll detail what I did to make sure I didn't screw it up. Please correct me if I do something wrong.

git clone https://github.com/timeyyy/esky
cd esky
git checkout -b py3k remotes/origin/py3k
pip3 uninstall esky
pip2 uninstall esky
cd ..
pip3 install ./esky
pip2 install ./esky
cd Desktop/freeze_future/freeze_future/tests

I first cloned your repo. cd to it, checke out to the py3k branch. Uninstalled all previous versions of esky, both on python 2 and 3. Installed your version of esky, for python 2 and 3.

Then I started to run the tests (python 2 is the default version on OSX):

python -m pytest test_cxfreeze.py 
============================================================================= test session starts ==============================================================================
platform darwin -- Python 2.7.10, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
rootdir: /Users/chembrows/Desktop/freeze_future, inifile: 
collected 0 items / 1 errors 

==================================================================================== ERRORS ====================================================================================
____________________________________________________________ ERROR collecting freeze_future/tests/test_cxfreeze.py _____________________________________________________________
/usr/local/lib/python2.7/site-packages/_pytest/python.py:606: in _importtestmodule
    mod = self.fspath.pyimport(ensuresyspath=importmode)
/usr/local/lib/python2.7/site-packages/py/_path/local.py:650: in pyimport
    __import__(modname)
../__init__.py:1: in <module>
    from .freeze_future import *
../freeze_future.py:24: in <module>
    from .tests.utils import setup_logger, preserve_cwd, extract_zipfile, create_zipfile,\
utils.py:17: in <module>
    from esky.util import get_platform
/usr/local/lib/python2.7/site-packages/esky/__init__.py:43: in <module>
    from esky.sudo import SudoProxy, has_root, allow_from_sudo
/usr/local/lib/python2.7/site-packages/esky/sudo/__init__.py:41: in <module>
    from esky.util import lazy_import
E     File "/usr/local/lib/python2.7/site-packages/esky/util.py", line 823
E       >>>>>>> ifsa:wq
E        ^
E   SyntaxError: invalid syntax
=========================================================================== 1 error in 0.27 seconds ============================================================================

There is a typo at the end of the file util.py. After removing it, I restarted the tests:

python2_test1.txt

Not much of a success for python 2.

For python 3:

python3 -m pytest test_cxfreeze.py
============================================================================= test session starts ==============================================================================
platform darwin -- Python 3.4.3, pytest-2.8.3, py-1.4.30, pluggy-0.3.1
rootdir: /Users/chembrows/Desktop/freeze_future, inifile: 
collected 10 items 

test_cxfreeze.py ....X.....

===================================================================== 9 passed, 1 xpassed in 14.85 seconds =====================================================================

Much better. Can you confirm what I did was correct before we move on ?

timeyyy commented 8 years ago

It looks like you did everything correct, the tests are made such that you can run pytest with the -x flag which will exit testing after the first error. The first test is checking if it can build a simple hellow world with cxfreeze, since this fails none of the tests after can pass because they require cxfreeze to be building, I have never seen this errorr so.now we havve to fix it :-). So start by looking at the first failing test.

JPFrancoia commented 8 years ago

I commented the except block in /usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/core.py:

________________________________________________________________________ test_cxfreeze_builds_and_runs _________________________________________________________________________

    def test_cxfreeze_builds_and_runs():
        '''Test a small script to make sure it builds properly'''
        setup, options, new_script = cxfreeze_setup('Simple Working', WORKING_SCRIPT)
>       setup(**options)

test_cxfreeze.py:56: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/lib/python2.7/site-packages/cx_Freeze/dist.py:362: in setup
    distutils.core.setup(**attrs)
/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/core.py:151: in setup
    dist.run_commands()
/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py:953: in run_commands
    self.run_command(cmd)
/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py:972: in run_command
    cmd_obj.run()
/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/command/build.py:127: in run
    self.run_command(cmd_name)
/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/cmd.py:326: in run_command
    self.distribution.run_command(command)
/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py:972: in run_command
    cmd_obj.run()
/usr/local/lib/python2.7/site-packages/cx_Freeze/dist.py:232: in run
    freezer.Freeze()
/usr/local/lib/python2.7/site-packages/cx_Freeze/freezer.py:650: in Freeze
    copyDependentFiles = False)
/usr/local/lib/python2.7/site-packages/cx_Freeze/freezer.py:166: in _CopyFile
    shutil.copystat(source, target)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

src = '/System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl', dst = 'build/exe.macosx-10.10-x86_64-2.7/tcl'

    def copystat(src, dst):
        """Copy all stat info (mode bits, atime, mtime, flags) from src to dst"""
        st = os.stat(src)
        mode = stat.S_IMODE(st.st_mode)
        if hasattr(os, 'utime'):
            os.utime(dst, (st.st_atime, st.st_mtime))
        if hasattr(os, 'chmod'):
            os.chmod(dst, mode)
        if hasattr(os, 'chflags') and hasattr(st, 'st_flags'):
            try:
>               os.chflags(dst, st.st_flags)
E               OSError: [Errno 1] Operation not permitted: 'build/exe.macosx-10.10-x86_64-2.7/tcl'

/usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/shutil.py:103: OSError

Then modified the block in shutil.py to get infos:

try:
    print(dst)
    print(st.st_flags)
    os.chflags(dst, st.st_flags)

And I get, when it crashes:

copying /System/Library/Frameworks/Tcl.framework/Versions/8.5/Tcl -> build/exe.macosx-10.10-x86_64-2.7/tcl
build/exe.macosx-10.10-x86_64-2.7/tcl
524320

It should normally print something like that:

copying /usr/local/Cellar/python/2.7.10_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-dynload/strop.so -> build/exe.macosx-10.10-x86_64-2.7/strop.so
build/exe.macosx-10.10-x86_64-2.7/strop.so
0

So I imagine there is a problem with st.st_flags. st is basically this object:

st = os.stat(fn)

So there must be some sort of problem when trying to copy the infos of the files.

timeyyy commented 8 years ago

Let us just back up a bit, im assuming you can build a working script with cxfreeze using python2 on mac? If so the problem is with the tests and not distutils or something like that. Could you walk me through the steps? Are they different for python3? What commands are you running and how do your setup scripts look?

JPFrancoia commented 8 years ago

Yep, I can create a working script using python2 on mac.

If I use the scripts from this page: https://bitbucket.org/anthony_tuininga/cx_freeze/src/aebc9c32615c14137c948c521a8d91562559237c/cx_Freeze/samples/simple/?at=default

I have a setup.py:

from cx_Freeze import setup, Executable

executables = [
    Executable('hello.py')
]

setup(name='hello',
      version='0.1',
      description='Sample cx_Freeze script',
      executables=executables
      )

And hello.py:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from datetime import datetime
import sys
from sys import stdout

stdout.write('Hello from cx_Freeze\n')
stdout.write('The current date is %s\n\n' %
             datetime.today().strftime('%B %d, %Y %H:%M:%S'))

stdout.write('Executable: %r\n' % sys.executable)
stdout.write('Prefix: %r\n' % sys.prefix)
stdout.write('File system encoding: %r\n\n' % sys.getfilesystemencoding())

stdout.write('ARGUMENTS:\n')
for a in sys.argv:
    stdout.write('%s\n' % a)
stdout.write('\n')

stdout.write('PATH:\n')
for p in sys.path:
    stdout.write('%s\n' % p)
stdout.write('\n')

Then I simply run

python setup.py build

Or python3, if needed.

In both cases, the exe are runnable.

rfk commented 8 years ago

So there must be some sort of problem when trying to copy the infos of the files.

Sounds likely; it's copying a system file so it may be attempting to copy some system flags that require super-user privs to set. man chflags lists a few, I'll see if I can dig into which it might be.

rfk commented 8 years ago

Two things we could do to work around this:

A good start might be copying just the UF_* flags listed in https://docs.python.org/2/library/os.html#os.chflags

timeyyy commented 8 years ago

@rfk all this test does is check if we can build a hello world cx freeze script (not using esky), he is able to build successfuly running from the cmdline so my feeling is it could be something with test? just making sure you did not jump the gun and miss anything

timeyyy commented 8 years ago

If we.can keep making head way with this would be great, testing in py3 will mean we are catching more errors and have the tests to guide us

rfk commented 8 years ago

all this test does is check if we can build a hello world cx freeze script (not using esky)

Ah, thanks, I had missed that this traceback from coming from cx-freeze. All the stuff I said is probably still valuable advice, but for the logic inside cx-freeze rather than inside esky :-P

rfk commented 6 years ago

Unfortunately this project is no longer actively maintained, so I'm going to move it into archive mode:

https://rfk.id.au/blog/entry/archiving-open-source-projects/