Skip to content

Commit 98abc4e

Browse files
committed
fucking buildozer isn't even preparing the python binary as portable. that's a foundational issue; let me try pyinstaller.
1 parent d2f73ad commit 98abc4e

File tree

2 files changed

+395
-253
lines changed

2 files changed

+395
-253
lines changed

build/mac/buildDmg-buildozer.sh

Lines changed: 368 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,368 @@
1+
#!/bin/bash
2+
set -x
3+
################################################################################
4+
# File: mac/buildDmg.sh
5+
# Purpose: Builds a self-contained dmg for a simple Hello World
6+
# GUI app using kivy. See also:
7+
#
8+
# * https://kivy.org/doc/stable/installation/installation-osx.html
9+
# * https://kivy.org/doc/stable/guide/packaging-osx.html
10+
# * https://github.com/kivy/buildozer/issues/494#issuecomment-390262889
11+
#
12+
# Authors: Michael Altfield <[email protected]>
13+
# Created: 2020-06-22
14+
# Updated: 2020-06-22
15+
# Version: 0.1
16+
################################################################################
17+
18+
# TODO: remove this after testing replacement with other python binaries that are available
19+
mkdir -p buildozer/dist
20+
cp /usr/bin/python3 buildozer/dist/usr-bin-python3
21+
cp /usr/local/bin/python3 buildozer/dist/usr-local-bin-python3
22+
23+
exit 0
24+
25+
############
26+
# SETTINGS #
27+
############
28+
29+
PYTHON_PATH='/usr/bin/python3'
30+
APP_NAME='helloWorld'
31+
32+
PYTHON_VERSION="`${PYTHON_PATH} --version | cut -d' ' -f2`"
33+
PYTHON_EXEC_VERSION="`echo ${PYTHON_VERSION} | cut -d. -f1-2`"
34+
35+
# attempt to overwrite brew's /usr/local/bin/python3 with /usr/bin/python3
36+
alias python3='${PYTHON_PATH}'
37+
38+
########
39+
# INFO #
40+
########
41+
42+
# print some info for debugging failed builds
43+
44+
uname -a
45+
sw_vers
46+
which python2
47+
python2 --version
48+
which python3
49+
python3 --version
50+
${PYTHON_PATH} --version
51+
echo $PATH
52+
pwd
53+
ls -lah
54+
55+
echo "INFO: list of python* in /usr/bin/"
56+
ls -lah /usr/bin/python*
57+
find /usr/bin -type f -name python | xargs --version
58+
find /usr/bin -type f -name python3 | xargs --version
59+
md5 /usr/bin/python*
60+
61+
echo "INFO: list of python* in /usr/local/bin/"
62+
ls -lah /usr/local/bin/python*
63+
find /usr/local/bin -type f -name python | xargs --version
64+
find /usr/local/bin -type f -name python3 | xargs --version
65+
md5 /usr/local/bin/python*
66+
67+
###################
68+
# INSTALL DEPENDS #
69+
###################
70+
71+
# install os-level depends
72+
brew install wget
73+
brew cask install platypus
74+
75+
# first update our PATH so installed depends can be executed
76+
PATH=${PATH}:/Users/runner/Library/Python/${PYTHON_EXEC_VERSION}/bin
77+
78+
# everything here is python3, except these bits. python2 is used in
79+
# package_app.py, which is used by buildozer and has a few depends
80+
sudo /usr/bin/python2 -m ensurepip
81+
/usr/bin/python2 -m pip install --upgrade --user docopt sh
82+
83+
# setup a virtualenv to isolate our app's python depends
84+
sudo ${PYTHON_PATH} -m ensurepip
85+
${PYTHON_PATH} -m pip install --upgrade --user pip setuptools
86+
#${PYTHON_PATH} -m pip install --upgrade --user virtualenv
87+
#${PYTHON_PATH} -m virtualenv /tmp/kivy_venv
88+
89+
# install kivy and all other python dependencies with pip into our virtual env
90+
#source /tmp/kivy_venv/bin/activate
91+
${PYTHON_PATH} -m pip install -r requirements.txt
92+
93+
kivyVersion="`${PYTHON_PATH} -m pip list | grep -i 'kivy ' | awk '{print $2}'`"
94+
95+
# install buildozer
96+
${PYTHON_PATH} -m pip install --upgrade git+http://github.com/kivy/buildozer
97+
98+
# install a bunch of other shit so buildozer doesn't fail with python3
99+
# see: https://github.com/kivy/buildozer/issues/494#issuecomment-390262889
100+
101+
## Install platypus
102+
if [[ $(which platypus > /dev/null; echo $?) != "0" ]]; then
103+
pushd ~/Downloads
104+
wget https://www.sveinbjorn.org/files/software/platypus/platypus5.2.zip
105+
unzip platypus5.2.zip
106+
rm platypus5.2.zip
107+
108+
sudo cp Platypus-5.2/Platypus.app/Contents/Resources/platypus_clt /usr/local/bin/
109+
sudo mv /usr/local/bin/platypus_clt /usr/local/bin/platypus
110+
111+
sudo mkdir -p /usr/local/share/platypus
112+
sudo cp Platypus-5.2/Platypus.app/Contents/Resources/ScriptExec /usr/local/share/platypus
113+
sudo chmod +x /usr/local/share/platypus/ScriptExec
114+
sudo cp -R Platypus-5.2/Platypus.app/Contents/Resources/MainMenu.nib /usr/local/share/platypus
115+
116+
rm -Rf Platypus-5.2
117+
popd
118+
else
119+
echo "Platypus is already installed..."
120+
fi
121+
122+
## Install GStreamer
123+
if [[ ! -d /Library/Frameworks/GStreamer.framework ]]; then
124+
pushd ~/Downloads
125+
126+
# You need both, gstreamer runtime binaries and libs and the development package including the headers.
127+
128+
wget https://gstreamer.freedesktop.org/data/pkg/osx/1.14.0/gstreamer-1.0-devel-1.14.0-x86_64.pkg
129+
sudo /usr/sbin/installer -pkg gstreamer-1.0-devel-1.14.0-x86_64.pkg -target /
130+
rm gstreamer-1.0-devel-1.14.0-x86_64.pkg
131+
132+
wget https://gstreamer.freedesktop.org/data/pkg/osx/1.14.0/gstreamer-1.0-1.14.0-x86_64.pkg
133+
sudo /usr/sbin/installer -pkg gstreamer-1.0-1.14.0-x86_64.pkg -target /
134+
rm gstreamer-1.0-1.14.0-x86_64.pkg
135+
136+
popd
137+
else
138+
echo "GStreamer is already installed..."
139+
fi
140+
141+
## Install SDL2 stuff
142+
if [[ ! -d /Library/Frameworks/SDL2.framework ]]; then
143+
pushd ~/Downloads
144+
wget https://www.libsdl.org/release/SDL2-2.0.4.dmg
145+
hdiutil attach SDL2-2.0.4.dmg && sudo cp -R /Volumes/SDL2/SDL2.framework /Library/Frameworks
146+
hdiutil detach /Volumes/SDL2
147+
rm SDL2-2.0.4.dmg
148+
popd
149+
else
150+
echo "SDL2 is already installed..."
151+
fi
152+
153+
if [[ ! -d /Library/Frameworks/SDL2_image.framework ]]; then
154+
pushd ~/Downloads
155+
wget https://www.libsdl.org/projects/SDL_image/release/SDL2_image-2.0.1.dmg
156+
hdiutil attach SDL2_image-2.0.1.dmg && sudo cp -R /Volumes/SDL2_image/SDL2_image.framework /Library/Frameworks
157+
hdiutil detach /Volumes/SDL2_image
158+
rm SDL2_image-2.0.1.dmg
159+
popd
160+
else
161+
echo "SDL2_image is already installed..."
162+
fi
163+
164+
if [[ ! -d /Library/Frameworks/SDL2_ttf.framework ]]; then
165+
pushd ~/Downloads
166+
wget https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-2.0.14.dmg
167+
hdiutil attach SDL2_ttf-2.0.14.dmg && sudo cp -R /Volumes/SDL2_ttf/SDL2_ttf.framework /Library/Frameworks
168+
hdiutil detach /Volumes/SDL2_ttf
169+
rm SDL2_ttf-2.0.14.dmg
170+
popd
171+
else
172+
echo "SDL2_ttf is already installed..."
173+
fi
174+
175+
if [[ ! -d /Library/Frameworks/SDL2_mixer.framework ]]; then
176+
pushd ~/Downloads
177+
wget https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.dmg
178+
hdiutil attach SDL2_mixer-2.0.1.dmg && sudo cp -R /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks
179+
hdiutil detach /Volumes/SDL2_mixer
180+
rm SDL2_mixer-2.0.1.dmg
181+
popd
182+
else
183+
echo "SDL2_mixer is already installed..."
184+
fi
185+
186+
#####################
187+
# PREPARE BUILDOZER #
188+
#####################
189+
190+
# create and enter our new dir for buildozer
191+
mkdir buildozer
192+
cp requirements.txt buildozer/
193+
194+
# hack to fix "ERROR: You must give at least one requirement to install"
195+
echo "pip" >> buildozer/requirements.txt
196+
197+
pushd buildozer
198+
199+
# create buildozer.spec file
200+
cat > buildozer.spec << EOF
201+
[app]
202+
title = Hello World
203+
package.name = ${APP_NAME}
204+
package.domain = org.test
205+
source.dir = ../src/
206+
source.include_exts = py,png,jpg,kv,atlas
207+
version = 0.1
208+
requirements = kivy
209+
orientation = portrait
210+
osx.python_version = 3
211+
osx.kivy_version = 1.9.1
212+
fullscreen = 0
213+
[buildozer]
214+
log_level = 2
215+
warn_on_root = 1
216+
EOF
217+
218+
## Change buildozer to use a python3.7 virtual environment instead of python2.7
219+
#pushd /usr/local/lib/$PYTHON_EXEC_VERSION/site-packages/buildozer
220+
#sed -i '' 's;virtualenv --python=python2.7;virtualenv --python=python3.7;g' __init__.py
221+
#popd
222+
#
223+
## Change the osx target to use python3 to run the package_app.py script.
224+
#pushd /usr/local/lib/$PYTHON_EXEC_VERSION/site-packages/buildozer/targets
225+
#sed -i '' "s;'python', 'package_app.py';'python3', 'package_app.py';g" osx.py
226+
#popd
227+
228+
# First run fails but is necessary to create the directory .buildozer
229+
buildozer osx debug
230+
if [[ "$?" != 0 ]]; then
231+
echo "[INFO] First run of buildozer failed as expected."
232+
fi
233+
234+
# Go into the kivy sdk directory to create the file Kivy.app
235+
pushd .buildozer/osx/platform/kivy-sdk-packager-master/osx
236+
rm -Rf Kivy3.dmg
237+
sed -i '' "s;3.5.0;$PYTHON_VERSION;g" create-osx-bundle.sh
238+
sed -i '' "s;python3.5;$PYTHON_EXEC_VERSION;g" create-osx-bundle.sh
239+
sed -i '' "s;rm {};rm -f {};g" create-osx-bundle.sh
240+
241+
./create-osx-bundle.sh ${kivyVersion} ${PYTHON_VERSION}
242+
243+
# TODO: remove this after you fix the python binary issues
244+
ls -lah /Users/runner/.pyenv/versions/
245+
ls -lah /Users/runner/.pyenv/versions/*/bin/
246+
md5 /Users/runner/.pyenv/versions/*/bin/*
247+
ls -lah Kivy.app/Contents/Resources/venv/bin/
248+
ls -lah Kivy.app/Contents/Frameworks/python/${PYTHON_VERSION}/bin
249+
md5 Kivy.app/Contents/Frameworks/python/${PYTHON_VERSION}/bin/*
250+
251+
# Repair symlink
252+
pushd Kivy.app/Contents/Resources/venv/bin/
253+
rm ./python3
254+
ln -s ../../../Frameworks/python/$PYTHON_VERSION/bin/python3 .
255+
popd
256+
257+
# Go into kivy sdk directory and fix the script package_app.py to use the specified python version.
258+
cp package_app.py package_app.py.orig
259+
echo "===package_app.py.orig======================================================="
260+
cat package_app.py.orig
261+
echo "===package_app.py.orig======================================================="
262+
sed -i '' "s;3.5.0;$PYTHON_VERSION;g" package_app.py
263+
264+
# prevent auto-thinning
265+
sed -i '' "s;if not strip:;if True:;g" package_app.py
266+
267+
## Make it python3 compatible by removing decode(...) calls.
268+
#sed -i '' "s;\.decode('utf-8');;g" package_app.py
269+
diff package_app.py.orig package_app.py
270+
popd
271+
272+
#############
273+
# BUILD APP #
274+
#############
275+
276+
# buildozer should now be able to build our .app file
277+
buildozer osx debug
278+
279+
# TODO: remove this after you fix the python binary issues
280+
echo "INFO: list of python binaries in the new .app dir"
281+
find /Users/runner/runners/2.263.0/work/cross-platform-python-gui/ -type f -name python
282+
find /Users/runner/runners/2.263.0/work/cross-platform-python-gui/ -type f -name python | xargs --version
283+
find /Users/runner/runners/2.263.0/work/cross-platform-python-gui/ -type f -name python | xargs md5
284+
find /Users/runner/runners/2.263.0/work/cross-platform-python-gui/ -type f -name python3
285+
find /Users/runner/runners/2.263.0/work/cross-platform-python-gui/ -type f -name python3 | xargs --version
286+
find /Users/runner/runners/2.263.0/work/cross-platform-python-gui/ -type f -name python3 | xargs md5
287+
288+
############
289+
# THIN APP #
290+
############
291+
292+
# remove unnecessary libs
293+
pushd .buildozer/osx/platform/kivy-sdk-packager-master/osx
294+
295+
# TODO: remove this after you fix the python binary issues
296+
ls -lah Kivy.app/Contents/Resources/
297+
ls -lah Kivy.app/Contents/Resources/python
298+
ls -lah Kivy.app/Contents/Resources/venv/bin/
299+
ls -lah Kivy.app/Contents/Resources/venv/bin/python
300+
ls -lah Kivy.app/Contents/Frameworks/python/3.7.3/bin/
301+
ls -lah Kivy.app/Contents/Frameworks/python/3.7.3/bin/python
302+
ls -lah Kivy.app/Contents/Frameworks/python/3.7.3/bin/python3.7
303+
md5 Kivy.app/Contents/Frameworks/python/3.7.3/bin/python3.7
304+
Kivy.app/Contents/Frameworks/python/3.7.3/bin/python3.7 --version
305+
cp /usr/bin/python3 helloWorld.app/Contents/usr-bin-python3
306+
cp /usr/local/bin/python3 helloWorld.app/Contents/usr-local-bin-python3
307+
308+
# GStreamer is the easiest; ~150M gone
309+
rm -rf "${APP_NAME}.app/Contents/Frameworks/GStreamer.framework"
310+
311+
# TODO: after you actually get a working build, uncomment and test this thinning
312+
## kivy build, doc, and examples dirs total to ~50M
313+
#rm -rf "${APP_NAME}.app/Contents/Resources/kivy/build/"
314+
#rm -rf "${APP_NAME}.app/Contents/Resources/kivy/doc/"
315+
#rm -rf "${APP_NAME}.app/Contents/Resources/kivy/examples/"
316+
#
317+
## somehow it still works for me with this gone, but I wonder if it's because it
318+
## finds python outside the .app dir? Anyway, this python dir is ~150M
319+
#rm -rf "${APP_NAME}.app/Contents/Frameworks/python"
320+
#
321+
## the whole lib dir isn't necessary for our simple kivy app; I imagine if your
322+
## app has more depends, you'll have to be more selective here
323+
#rm -rf "${APP_NAME}.app/Contents/Resources/venv/lib"
324+
325+
#############
326+
# BUILD DMG #
327+
#############
328+
329+
# TODO: remove this after fixing .dmg generation
330+
# the dmg generation below fails on headless builds because you have to click
331+
# a button in a dialog granting finder some permissions from the apple script.
332+
# for now we include the .app
333+
mkdir -p ../../../../../dist
334+
cp -r "${APP_NAME}.app" ../../../../../dist/
335+
336+
# create a .dmg file from the .app file
337+
sudo ./create-osx-dmg.sh "${APP_NAME}.app"
338+
339+
# create the dist dir for our result to be uploaded as an artifact
340+
mkdir -p ../../../../../dist
341+
cp "${APP_NAME}.dmg" ../../../../../dist/
342+
343+
popd # return to the buildozer dir in the sandbox root
344+
popd # return to the sandbox root dir
345+
346+
#######################
347+
# OUTPUT VERSION INFO #
348+
#######################
349+
350+
uname -a
351+
sw_vers
352+
which python2
353+
python2 --version
354+
which python3
355+
python3 --version
356+
${PYTHON_PATH} --version
357+
pwd
358+
echo $PATH
359+
ls -lah /Users/runner/Library/Python/3.7/bin
360+
ls -lah
361+
ls -lah dist
362+
363+
##################
364+
# CLEANUP & EXIT #
365+
##################
366+
367+
# exit cleanly
368+
exit 0

0 commit comments

Comments
 (0)