Search code examples
pythonmacosbuildpyinstallerpy2app

How to create OS X app with Python on Windows


I need to automate a cross-platform application build. Entire build runs on Windows machine. Part of it is written in Python and compiles for OS X. Currently this part of build is done manually on OS X.

I tried pyinstaller but it looks like it only building for the platform that it is running on. I also tried py2app but it did not install on Windows.

Are there any tools to compile Python script to OS X app on Windows machine?


Solution

  • Short answer:

    Apparently, no simple way to do this with the standard set of tools you have mentioned. I outline a completely unprobable solution in the end that's probably too complex to consider.

    End result: Keep doing it manually, it's probably the best option so far.


    Drawing from credible and/or official sources:

    There's already a long and curated list of options specified in micheal0x2a's excellent answer in Create a single executable from a Python project which outlines most tools available for creating standalone distributions of a Python program. One line stands out:

    Also, unless otherwise noted, all programs listed below will produce an exe specifically for the operating system it's running in.

    I might have read things wrong but there's no explicit note of cross platform support.

    Similar lists can be found in in Distribution Utilities and Freezing Your Code — The Hitchhiker's Guide to Python. From these we can take a look at the Windows supported projects:


    bbfreeze: Not maintained, no documentation on limitations generally superseded by the rest in this list.


    PyInstaller: According to their documentation:

    PyInstaller is tested against Windows, Mac OS X, and Linux. However, it is not a cross-compiler: to make a Windows app you run PyInstaller in Windows; to make a Linux app you run it in Linux, etc. PyInstaller has been used successfully with AIX, Solaris, and FreeBSD, but is not tested against them.

    PyInstaller once tried to support cross-compilation (From Linux -> Windows) but later dropped the idea.


    cx_freeze: Looking at their Freezing for other platforms question in their Frequently Asked Questions list:

    cx_Freeze works on Windows, Mac and Linux, but on each platform it only makes an executable that runs on that platform. So if you want to freeze your program for Windows, freeze it on Windows; if you want to run it on Macs, freeze it on a Mac.


    py2app: This is not an option since py2app is supported only OSX machines based on their note:

    NOTE: py2app must be used on OSX to build applications, it cannot create Mac applications on other platforms.

    So installing it on windows is a no-go.

    This wraps out the tools available on for creating standalone applications on Windows. Even if not on Windows though, solutions don't exist for creating an OS agnostic tool.

    The general consensus for achieving these sort of things is via Virtual Machines; you create a VM image of the target OS, run the dedicated tool for that OS inside the vm and then transfer the bundled executable to compatible machines. Since OSX is generally not easy to virtualize, from what I know, you kinda run out of luck here.


    One complex probable way:

    Now, the reason why I said there is no simple way to do this is because there might be one but, from what I can see, it is so tedious you shouldn't even consider it. The general issue we're facing here is that executables for windows are simply not compatible with OSX, heck, Linux executables aren't either. So what we need is the ability to cross-compile things.

    One compiler that I've heard supports cross-compilation is clang. So, in order remedy the incompatibility of executables, you could theoretically use clang as a cross compiler. Problem is, this is not a simple task; it is probably way harder than what you're willing to do since it is riddled with complex issues (From OSX to Windows example).

    If you do actually find a way to that you now need a .cpp/.c file from your python scripts. Thankfully this is something that can be done by using tools like Nuitka or Cython.

    The gist of these is the same, enter .py exit .cpp/.c. The second tricky part might be setting up the clang compiler to be used with these. I honestly have no idea if anyone has done this.

    I haven't looked into them much, but for Nuitka, I know that it can also be used to create a standalone executable when passed the --standalone flag (See: Moving to other machines). So, theoretically you could use Nuitka with clang configured to cross-compile for OSX. Then you can rest; you've earned it.