Add custom Info.plist and Framework support to bdist_mac

#33 Merged at 8177090
  1. Dan McCombs

As I mentioned in pull request #32 I found I needed to add some additional keys to the Info.plist file generated in the app bundle by bdist_mac. Since there are so many possible keys and use cases I decided it made the most sense to allow a user to override the generated Info.plist file with a custom one of their own. This allows a user to either create a static file to use, or to use the plistlib Python module to create one as part of the freeze process from their

If custom-info-plist is specified, that file is used as the Info.plist. If that option is not specified, one is generated as usual.

Another option I found I needed was the ability to add OS X frameworks into the app bundle during build time. In my case, I'm using the Sparkle framework for keeping my application up to date, which needs to be copied to the Contents/Frameworks/ directory of the app bundle.

The include-frameworks option takes either a comma separated list of paths to frameworks on the command line, or a Python list from, and copies them to the correct directory in the app bundle.

Comments (12)

  1. Thomas Kluyver

    I wonder if it would make sense to start with our basic plist template, and allow the user some way to modify it, rather than replacing it?

    Pinging @rreilink , who knows about Mac stuff. Rob, any thoughts on this would be welcome.

    1. Dan McCombs author

      Yeah, that's an approach I considered, allowing the user to specify a set of keys/values to be added to the generated plist rather than replacing it, but I couldn't think of a very clean way to do that via the command line option besides from within Since plist key values can be dicts or arrays, representing those nested structures via the command line argument seemed like it wouldn't be very clean.

      We could allow the user to specify one plist to be merged/override the generated one, though I figured at that point we should just allow them to replace it. I'm certainly open to others thoughts though.

  2. rreilink

    Seems like a good idea to me to use a user-supplied info.plist. Indeed a plist can be easily generated (e.g. using the plistlib module which comes with Python) but as Dan mentions it would be troublesome to supply its contents via the command line.

    I would suggest to set the CFBundleExecutable variable from cx_freeze, also in a user-supplied plist. My proposed approach would be to load either the the user-supplied plist or the default using the plistlib module and then setting the appropriate key before writing the file to the destination. I.e., replace also the currently used templating code by the plistlib module (I didn't know of this module when I originally wrote the code)

  3. Dan McCombs author

    Alright, I've made the changes based on comments - we're now using plistlib to generate the Info.plist file, rather than the string template, and CFBundleExecutable is always set to the bundle_executable regardless of whether a custom plist was specified or not.

  4. Dan McCombs author

    Can I get a thumbs up or thumbs down on this? I have some other features that I'd like to open pull requests for, but they depend on this being merged first. Thanks!

      1. Dan McCombs author

        So, it looks like that .split() is a bug dating back a very long time - the documentation at says comma separated, but it doesn't work, it's space separated. Either users really aren't using those options on the command line, or they're realizing to use spaces which I would be surprised about and not get a bug report. Also, while some options are normalized like this, not all of them are - for instance "includes" is, but "include_files" is not.

        I think I'll open an issue about this and fix it separately.

        1. Thomas Kluyver

          Thanks for taking the time to test. I suspect that most users who need these options set them as real lists in the config file, not on the command line, which is why we haven't had reports. Yes, a fix in a separate PR is a good idea.

          I'll ping Anthony to merge this.