What tools are there to cross-create an OSX installer for a python package?
Asked Answered
F

5

9

Distutils offers existing solutions to build a Windows self-extracting EXE. Notably, I can create the package even if I'm on Ubuntu (which is essential given our automated build process).

How do I build an osx installer from an Ubuntu machine?

(This is for python 2.7)

Fescue answered 4/5, 2012 at 5:30 Comment(2)
What exactly are your requirements? Do you just want a file which can be double-clicked to launch an installer, or would it be sufficient to distribute a package which can be installed with a one-line command that users can copy+paste? Or do you want to distribute your package inside of a .dmg file that invokes a nice GUI installer?Muticous
It should be as easily to install an ubuntu .deb or a windows .exe. We furthermore have dependencies (Setuptools) we wish to check for and automatically install if they are not present. Dependency installing is accomplished in the .deb via explicit dependency listing and in the windows .exe by specifying a pre-install-script to bdist_wininst. We also wish to have a post-install script that among other things notifies the user about installation success/failure/next steps.Fescue
S
4

You could do the following, since OS X has a UNIX foundation. (I'm assuming it also has some standard utilities like uudecode and unzip.);

  • Create a zipfile for your package with the standard Python packaging tools, like distutils.
  • Use uuencode file.zip file.zip >uu.txt to convert this zip-file to text.
  • Create a shell-script.
  • Put the text generated by uuencode as a here-document in that shell-script, that is fed to uudecode, to recreate the zipfile. This should be the second command in the shell-script. The first commands should check for neccesary utilities.
  • Use whatever Python setup tools you have to install the zipfile.
  • Do any post-install stuff you want.
  • Remove the zip-file.

To install the program, run the shell-script. On UNIX, this script should be run as root. Don't know how OS X handles that, though. Below is an example (the included zipfile contains two files with only random noise) ;

#!/bin/sh
# Install script for foo

# Check for special programs that are used in this script.
PROGS="uudecode unzip python"
for P in $PROGS; do
    which $P >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "$(basename $0): The program \"$P\" cannot be found."
        exit 1
    fi
done

uudecode <<"EOF"
begin 644 test.zip
M4$L#!`H``````(<!K$`````````````````$`!P`9F]O+U54"0`#OHZM3ZB.
MK4]U>`L``03I`P``!.D#``!02P,$"@``````A`&L0$EXM>H``@````(```<`
M'`!F;V\O8F%R550)``.XCJU/N(ZM3W5X"P`!!.D#```$Z0,``)DCNBVSM81_
MA%IQ!+LKC\;\19[/E]F!`J2J*2:9B_8#MC^KM*]]9P1]?1Y1@1+/H%Q"'2J'
M,;$7:C9E+WC]%M(BAUFN]4D\$%F63!^CA8O>'0C(-!YD?$\GQ[;M:?@>=A/[
M61XK<A/]\.?!0$QX<5]T\9<ZP$;_?PRMV-3O(NK)/<MTI,!RYA&OWRK6<8%4
M_1!T/+-'7H^V#C[AK)+U?T>UCU."G]D(+JU[8Z#1EI89@'^10B:8.2$$9Q*@
MY:L4MK'^TVF)A5)9\%"/FF+1T@;]8\,I)$CCHHF#E&,D.GVM1=2N];4J?6WR
M0+YH]DXZ"UQ$GVA^F(`5L![=/<ROX]9RQCRWJ=?+G4Y>56[H=8:!:GTA_V;V
M2V$%U5([0D;T19H]P7+^448+^&M3;[/VJDEJ-SU=Q8U=3,IV^<)A>C)]?@XG
M?-9$B@YZGML`!&`\-CP["]B'FC&K7Z)T6K_&W1K5?M&K8D&^'C^J;H[Q4/ST
M(>QL].68#X)_0@`?9<R3#:4Y#A'X-<NT9C\OM3:4[<)`)LEO@E=*/=0U@]VY
M_R!__:Q'_FP3((*8^6JQ"$_H&BIWDD.6<"3D,'<1^=^.9F^2Z7.:OE"1,SV[
M)M(9!&V(4):?M7^JFR^P"!H4U+(*A;U@Z0QA+]5ZIS]B1;K)&@LJ-Y,L9SQ.
M^Q-"&^@#KQG94$L#!`H``````(8!K$#%*"OR``(````"```'`!P`9F]O+V)A
M>E54"0`#O(ZM3[R.K4]U>`L``03I`P``!.D#``!NFMNGLA(C_K!_F=T%?;P3
M#TUC7%4F+!Y#A8<SFK[;E3M.%J`YT>1AVMNJPFOE58Q["7<#AWQFZ!SG_-RW
M*4`@@P.7\>+LGTBNTLH-7)CB(LJDMD)COV5'H]O8G_4I&C:PFTVC%4P=+X*B
M%A^I^$>BO+<!D\&8&GS:&VLQHJJ[!NFW0H5FD6+:'OUT2--U1HXQ2R?JF2,9
M(/@>A(/SU#.78MTFADG`ZZTK!6:Z6\;I`2?D6I;FE=_0V?4>_0MC;$0$P?H%
MDHQ]MCK4;,5W=<IZV<)<`7A_B7<_=U,:X[8/$_&/518\NNBDYS,\<',K2C]9
M4M.5UL/R<\'0E>G#$>`I>/[UX$QM.+T\LF4;D^WF6FX3.(L?2V<5B%5)$!5[
ME47K#7\&D*3Y>I)8#45-HL(!F7+$)%7C9,$_YYL]EG='3BN9W[&9!$.<.U?E
M#0L?=6@%J/32)NAMI48M",_)0#JRR!*Y2P:ZE@JWD)5/#UK!!3]*2M47V1GE
M'X0(FN%_*3BX_X'(6X!ONLKN!U/&_ML-L:^FD/24Q)S*-D8)Z>F4Y^+$]\_'
MB\$$;#D__S_RT(Y]MMK?B#%F1&C`>,)'7:12DX=F)T,/!*^(M*[,^N;6E4";
M31K\AG0@[@4L9MB.`1Z!`%@K5G)P<]0!?P\$RFUC/S:Y_Y\0*:\+$U+JEM%"
M9E!+`0(>`PH``````(<!K$`````````````````$`!@`````````$`#M00``
M``!F;V\O550%``.^CJU/=7@+``$$Z0,```3I`P``4$L!`AX#"@``````A`&L
M0$EXM>H``@````(```<`&````````````*2!/@```&9O;R]B87)55`4``[B.
MK4]U>`L``03I`P``!.D#``!02P$"'@,*``````"&`:Q`Q2@K\@`"`````@``
M!P`8````````````I(%_`@``9F]O+V)A>E54!0`#O(ZM3W5X"P`!!.D#```$
:Z0,``%!+!08``````P`#`.0```#`!```````
`
end
EOF

# Unpack your zipfile
unzip test.zip
# Go into the created subdirectory and install
cd foo
python setup.py install
# whatever post-install stuff you want goes here...
cd ..
rm -rf foo test.zip
Sukin answered 11/5, 2012 at 22:33 Comment(0)
A
5

Py2app, cx_freeze, and py2exe are for creating standalone applications, not installers.

You can use Python distutils to create a zip file of your package, and then wrap the zip file in a script that self-extracts and installs the package, like this: http://www.noah.org/wiki/Self-extracting_Python_Script

Or, if you want to create an installer that displays a GUI with a click-through license, then you need OS X PackageMaker to create an mpkg file. I don't think there's a Linux equivalent. If you want to try building an mpkg by hand, try this answer: PackageMaker for creating Mac packages on Windows/Linux

Alage answered 7/5, 2012 at 20:34 Comment(3)
Since you (@UsAaR33) want postinst-like capability, @Craig's answer is the right one. You'd either want to make an mpkg manually (the other answer he linked looks very promising, and not prohibitively difficult) or make a self-extracting binary. I don't like the particular self-extracting zip linked here for your case, since it doesn't actually extract, but it should be pretty apparent how the same basic formula can be used to make self-extracting, self-installing shell+tarball conglomerations. If you want GUI friendliness, though, that's probably a harder way to go.Muticous
@thepaul Thanks for the comment. I am still hoping for an easier solution (as easy as bdist_wininst is), as I figured this would be a common problem developers have (in my case we release very frequently and want to have a simple linux-based build/release process to handle all platforms). That said if no one provides an easier solution before the bounty expires, I'll accept Craig's answer -- and go with a modified form of the self-extracting zip (I'd rather not spend the time building a my own BOM file generator even though GUI installation is much preferred).Fescue
I don't think that a general analogue of bdist_wininst would work for you, though, since I don't believe there is any distutils-ish facility for specifying postinst actions. Something like py2app that works on *nix could exist, though, if that would meet the easiness requirement. Wouldn't be all that hard. I just don't think it's been done yet.Muticous
S
4

You could do the following, since OS X has a UNIX foundation. (I'm assuming it also has some standard utilities like uudecode and unzip.);

  • Create a zipfile for your package with the standard Python packaging tools, like distutils.
  • Use uuencode file.zip file.zip >uu.txt to convert this zip-file to text.
  • Create a shell-script.
  • Put the text generated by uuencode as a here-document in that shell-script, that is fed to uudecode, to recreate the zipfile. This should be the second command in the shell-script. The first commands should check for neccesary utilities.
  • Use whatever Python setup tools you have to install the zipfile.
  • Do any post-install stuff you want.
  • Remove the zip-file.

To install the program, run the shell-script. On UNIX, this script should be run as root. Don't know how OS X handles that, though. Below is an example (the included zipfile contains two files with only random noise) ;

#!/bin/sh
# Install script for foo

# Check for special programs that are used in this script.
PROGS="uudecode unzip python"
for P in $PROGS; do
    which $P >/dev/null 2>&1
    if [ $? -ne 0 ]; then
        echo "$(basename $0): The program \"$P\" cannot be found."
        exit 1
    fi
done

uudecode <<"EOF"
begin 644 test.zip
M4$L#!`H``````(<!K$`````````````````$`!P`9F]O+U54"0`#OHZM3ZB.
MK4]U>`L``03I`P``!.D#``!02P,$"@``````A`&L0$EXM>H``@````(```<`
M'`!F;V\O8F%R550)``.XCJU/N(ZM3W5X"P`!!.D#```$Z0,``)DCNBVSM81_
MA%IQ!+LKC\;\19[/E]F!`J2J*2:9B_8#MC^KM*]]9P1]?1Y1@1+/H%Q"'2J'
M,;$7:C9E+WC]%M(BAUFN]4D\$%F63!^CA8O>'0C(-!YD?$\GQ[;M:?@>=A/[
M61XK<A/]\.?!0$QX<5]T\9<ZP$;_?PRMV-3O(NK)/<MTI,!RYA&OWRK6<8%4
M_1!T/+-'7H^V#C[AK)+U?T>UCU."G]D(+JU[8Z#1EI89@'^10B:8.2$$9Q*@
MY:L4MK'^TVF)A5)9\%"/FF+1T@;]8\,I)$CCHHF#E&,D.GVM1=2N];4J?6WR
M0+YH]DXZ"UQ$GVA^F(`5L![=/<ROX]9RQCRWJ=?+G4Y>56[H=8:!:GTA_V;V
M2V$%U5([0D;T19H]P7+^448+^&M3;[/VJDEJ-SU=Q8U=3,IV^<)A>C)]?@XG
M?-9$B@YZGML`!&`\-CP["]B'FC&K7Z)T6K_&W1K5?M&K8D&^'C^J;H[Q4/ST
M(>QL].68#X)_0@`?9<R3#:4Y#A'X-<NT9C\OM3:4[<)`)LEO@E=*/=0U@]VY
M_R!__:Q'_FP3((*8^6JQ"$_H&BIWDD.6<"3D,'<1^=^.9F^2Z7.:OE"1,SV[
M)M(9!&V(4):?M7^JFR^P"!H4U+(*A;U@Z0QA+]5ZIS]B1;K)&@LJ-Y,L9SQ.
M^Q-"&^@#KQG94$L#!`H``````(8!K$#%*"OR``(````"```'`!P`9F]O+V)A
M>E54"0`#O(ZM3[R.K4]U>`L``03I`P``!.D#``!NFMNGLA(C_K!_F=T%?;P3
M#TUC7%4F+!Y#A8<SFK[;E3M.%J`YT>1AVMNJPFOE58Q["7<#AWQFZ!SG_-RW
M*4`@@P.7\>+LGTBNTLH-7)CB(LJDMD)COV5'H]O8G_4I&C:PFTVC%4P=+X*B
M%A^I^$>BO+<!D\&8&GS:&VLQHJJ[!NFW0H5FD6+:'OUT2--U1HXQ2R?JF2,9
M(/@>A(/SU#.78MTFADG`ZZTK!6:Z6\;I`2?D6I;FE=_0V?4>_0MC;$0$P?H%
MDHQ]MCK4;,5W=<IZV<)<`7A_B7<_=U,:X[8/$_&/518\NNBDYS,\<',K2C]9
M4M.5UL/R<\'0E>G#$>`I>/[UX$QM.+T\LF4;D^WF6FX3.(L?2V<5B%5)$!5[
ME47K#7\&D*3Y>I)8#45-HL(!F7+$)%7C9,$_YYL]EG='3BN9W[&9!$.<.U?E
M#0L?=6@%J/32)NAMI48M",_)0#JRR!*Y2P:ZE@JWD)5/#UK!!3]*2M47V1GE
M'X0(FN%_*3BX_X'(6X!ONLKN!U/&_ML-L:^FD/24Q)S*-D8)Z>F4Y^+$]\_'
MB\$$;#D__S_RT(Y]MMK?B#%F1&C`>,)'7:12DX=F)T,/!*^(M*[,^N;6E4";
M31K\AG0@[@4L9MB.`1Z!`%@K5G)P<]0!?P\$RFUC/S:Y_Y\0*:\+$U+JEM%"
M9E!+`0(>`PH``````(<!K$`````````````````$`!@`````````$`#M00``
M``!F;V\O550%``.^CJU/=7@+``$$Z0,```3I`P``4$L!`AX#"@``````A`&L
M0$EXM>H``@````(```<`&````````````*2!/@```&9O;R]B87)55`4``[B.
MK4]U>`L``03I`P``!.D#``!02P$"'@,*``````"&`:Q`Q2@K\@`"`````@``
M!P`8````````````I(%_`@``9F]O+V)A>E54!0`#O(ZM3W5X"P`!!.D#```$
:Z0,``%!+!08``````P`#`.0```#`!```````
`
end
EOF

# Unpack your zipfile
unzip test.zip
# Go into the created subdirectory and install
cd foo
python setup.py install
# whatever post-install stuff you want goes here...
cd ..
rm -rf foo test.zip
Sukin answered 11/5, 2012 at 22:33 Comment(0)
C
0

py2app is the Mac counterpart to py2exe, but I don’t know if you can run it from Ubuntu.

Careerist answered 5/5, 2012 at 16:6 Comment(0)
H
0

pyinstaller can create OSX executables, but I've only used it on OSX myself, so I don't know if it works from Ubuntu.

I learned about this program reading the documentation for kivy, here: http://kivy.org/docs/guide/packaging-macosx.html

I hope some of this is helpful.

Hallagan answered 13/5, 2012 at 20:12 Comment(1)
FAQ states that it can't create OSX (or windows) binaries on linux.Fescue
J
0

You have similar trouble that I suffered with.

On mac. I bet you want use dmg package instead of Installer unless you really need to install driver or some sort of DRM.

So I'll just assume that you want make your .app directory and packaging it as dmg file so that you can distribute your application easily.

To build a .app directory out of python code, you might wanna use Pyinstaller. Pros

  1. It's Cross Platform.
  2. Works good on mac, windows, linux
  3. You can control everything on command line.
  4. It's still actively developing.
  5. It packs required dependencies automatically and doesn't create conflict with installed Python on local machine.
  6. Good Documentation.

Cons

  1. bit of inconsistency between new version and old version.

To build .app using Pyinstaller, here's related document link

and to build dmg file, you can use free options out there, but for me, DMG Canvas was pretty useful.

Pros

  1. support command line
  2. support template (Create pretty background and folders using GUI and reuse it on command line)
  3. support license agreement

Cons

  1. Not Free

As far as I know, there's no unified solution from .py to build .app file and to dmg or installer.

So you should write some code to automatize it, but it's pretty straight forward, since both of them support

Command line.

Jupiter answered 14/5, 2012 at 12:53 Comment(4)
Both tools must be run on osxFescue
@Fescue yes both tools surely run on osx.Jupiter
I'm confused. Your answer is very useful on how to make osx installers, but the question was in regards to building an osx installer on linux.Fescue
Possibly this answer is subtly suggesting: get an OSX machine and control it's tools remotely, say using a remote shell?Saval

© 2022 - 2024 — McMap. All rights reserved.