Added a few MSYS/MINGW fixes and changed a bit of the PyQt4/PyQt5 hooks.

#80 Open
Repository
Graph9
Branch
default
Repository
anthony_tuininga
Branch
default

Bitbucket cannot automatically merge this request.

The commits that make up this pull request have been removed.

Bitbucket cannot automatically merge this request due to conflicts.

Review the conflicts on the Overview tab. You can then either decline the request or merge it manually on your local system using the following commands:

hg update default
hg pull -r default https://bitbucket.org/Graph9/cx_freeze
hg merge 5f471251be6f
hg commit -m 'Merged in Graph9/cx_freeze (pull request #80)'
Author
  1. Graph9
Reviewers
Description

Hello, I have been trying to compile and freeze programs in an msys2/mingw-w64 environment and had to handle a few issues that came up.

The first one was, that the compiler complained about the macro LIBDIR being set but not as a string in Console.c:

#ifdef LIBDIR
    sprintf(g_LibDirName, "%s%c%s", g_ExecutableDirName, SEP, LIBDIR);
#else
    strcpy(g_LibDirName, g_ExecutableDirName);
#endif

I had to escape the double quotes in setup.py that set the LIBDIR macro.

Additionally I had to change the cxfreeze-postinstall script, because there is no Scripts folder for a mingw python installation. This overlaps with the pull request #21.

After this I was able to compile and freeze python programs. Hooray!
Though none of the frozen programs actually worked. Not even the simple example program.

I kept getting the error Unable to calculate directory of executable!

Common.c

// get directory from executable name
    strcpy(g_ExecutableDirName, g_ExecutableName);
    ptr = strrchr(g_ExecutableDirName, SEP);
    if (!ptr)
        return FatalError("Unable to calculate directory of executable!");
    *ptr = '\0';

The reason was that SEP as defined in osdefs.h in Python set it to '/', but the path returned by GetModuleFileName has '\\'. So strrchr fails.

osdefs.h

/* Mod by chrish: QNX has WATCOM, but isn't DOS */
#if !defined(__QNX__)
#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2)
#if defined(PYOS_OS2) && defined(PYCC_GCC)
#define MAXPATHLEN 260
#define SEP '/'
#define ALTSEP '\\'
#else
#define SEP '\\'
#define ALTSEP '/'
#define MAXPATHLEN 256
#endif
#define DELIM ';'
#endif
#endif

/* Filename separator */
#ifndef SEP
#define SEP '/'
#endif

To fix this I could either redefine SEP or convert the backslashes to forward slashes. Since I now know that python uses forward slashes throughout the whole program I decided to convert the slashes. Also because the other paths would be based on the GetModuleFileName path.

Finally, after that was fixed, I got a new error that said that a module could not be loaded. Though it wasn't just one module, but rather all modules that were copied to the lib folder as a .pyd.
I double and triple checked that the modules were infact there, which they were.

The reason was that the __bootstrap__() loader couldn't find it.

freezer.py

def __bootstrap__():
    import imp, os, sys
    global __bootstrap__, __loader__
    __loader__ = None; del __bootstrap__, __loader__

    found = False
    for p in sys.path:
        if not os.path.isdir(p):
            continue
        f = os.path.join(p, "%s")
        if not os.path.exists(f):
            continue
        m = imp.load_dynamic(__name__, f)
        import sys
        sys.modules[__name__] = m
        found = True
        break
    if not found:
        del sys.modules[__name__]
        raise ImportError("No module named %%s" %% __name__)
__bootstrap__()

This was because sys.path did not contain the ./lib folder. So I looked at the ConsoleSetLibPath.py initscript, which seemed outdated and not used for this kind of action but rather to set it to one path only?
So I kinda bruteforced the path in.

Now for the PyQt4/5 hooks. I added a few checks for the implicit includes, because I knew that they are not being used. Basically this lets me add them to the excludes list so it doesn't clutter up the final build.
Additionally, I use the mingw-w64-x86_64-qt5-5.5.0-1-any.pkg.tar.xz package, which adds additional development dlls. Such as qwindowsd.dll and Qt5Guid.dll.
Because of the hook for the imageformats and platforms which contain some dev dlls they will be imported and their dependencies will be resolved which will include the Qt5Guid.dll, Qt5Cored.dll and others with a filesize of up to 600mb.

So I added another check for such files to not include them.


Regarding the path separator converter: I don't think this will work in all cases. Sadly the macro __MINGW32__ is not set when I tried to compile it. So I don't really know how to check when to convert and when not to...

Comments (0)