Skip to content

Commit

Permalink
Update docs and move deps in requirements.txt
Browse files Browse the repository at this point in the history
  • Loading branch information
misl6 committed Dec 13, 2023
1 parent 9c4a21a commit f50854f
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 86 deletions.
105 changes: 40 additions & 65 deletions osx/README.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
Kivy packaging for OS X
=======================
Kivy packaging for macOS
========================

This repository contains the scripts for packaging a Kivy based app into a installable dmg.

**Important notice:** macOS 11 (or greater), with XCode 12.2 (or greater) is required to build a fully working universal2 ``.app`` due to https://bugs.python.org/issue42619

Kivy versions supported: ``2.0.0+``. For older Kivy versions, use the corresponding stable branch.
Kivy versions supported: ``2.2.0+``. For older Kivy versions, use the corresponding stable branch.

The packaged dmg contains a Python virtualenv, Kivy and its binary dependencies such as SDL2. Kivy
provides an existing dmg containing the virtualenv and Kivy pre-installed that can be used
as a base into which your app can be installed and packaged again as a dmg. Below are the steps:
The packaged ``.app`` contains a Python virtualenv with ``kivy`` and its dependencies pre-installed.

SDL2 frameworks are included in the app bundle, and the Kivy installation is configured to use them.

Kivy, on every release, provides a ``Kivy.app`` that can be used as a base for your app, so you don't need to build it from scratch.
Below are the steps to use the ``Kivy.app`` as a base for your app, or to build your app from scratch.

* Get the Kivy sdk repo with e.g.
``git clone https://github.com/kivy/kivy-sdk-packager.git`` and ``cd`` into
Expand All @@ -19,7 +22,8 @@ as a base into which your app can be installed and packaged again as a dmg. Belo

./create-osx-bundle.sh -n MyApp -k ...

See in ``create-osx-bundle.sh`` for all the configuration options.
For all the configuration options, you can run ``./create-osx-bundle.sh -h``.

This will build from scratch all the requirements (openssl, SDL2, SDL2_image, SDL2_mixer, SDL2_ttf, python3).
A ``build`` directory is created to contain the``MyApp.app`` directory, where ``MyApp`` is the app's name.
* To use the existing Kivy app bundle:
Expand All @@ -46,7 +50,7 @@ as a base into which your app can be installed and packaged again as a dmg. Belo
source kivy_activate
popd

On the default mac shell you **must** be in the bin directory containing ``activate`` to be
On the default macOS shell (zsh) you **must** be in the bin directory containing ``activate`` to be
able to ``activate`` the virtualenv. ``kivy_activate`` is only necessary if you'll run
Kivy in the environment - it sets up the Kivy home, and other Kivy environment
variables.
Expand All @@ -64,13 +68,19 @@ as a base into which your app can be installed and packaged again as a dmg. Belo
@executable_path/Contents/Frameworks/MyFramework.framework/Versions/A/MyFramework

This should be customized for each framework. See the ``create-osx-bundle.sh`` script for examples.
* Install your dependencies with e.g. ``pip``::
* By using the ``prepare-wheels.py`` helper, download and prepare wheels before installing them.
This script will download the wheels, accordingly to your ``MACOSX_DEPLOYMENT_TARGET`` and merge them into a single ``universal2`` wheel if one is not available from PyPI.

python -m pip install ...
If no compatible wheel is available, the script will download the source distribution.

* Install your app::
To see all the available options, and usage instructions, run::

python -m pip install myapp
python prepare-wheels.py -h

Since this tool is rapidly evolving, and the process to install the downloaded
wheels is done via ``pip``, consider looking at ``create-osx-bundle.sh`` for examples on how to use the downloaded artifacts.

:warning: Never install dependencies via ``pip`` from the virtual environment, without using the ``prepare-wheels.py`` helper, as it will install the architecture-specific wheels, and not the ``universal2`` ones.

* Deactivate the virtualenv by running ``deactivate`` in the shell.
* Reduce app size (optional):
Expand Down Expand Up @@ -124,8 +134,14 @@ A complete example using ``Kivy.app`` with a entry_point pointing to your app as

git clone https://github.com/user/myapp.git
git clone https://github.com/kivy/kivy-sdk-packager.git

python3 -m venv venv
source venv/bin/activate

cd kivy-sdk-packager/osx

pip install -r requirements.txt

curl -O -L https://xxx/Kivy-xxx.dmg
hdiutil attach Kivy-xxx.dmg -mountroot .

Expand All @@ -134,12 +150,17 @@ A complete example using ``Kivy.app`` with a entry_point pointing to your app as
./fix-bundle-metadata.sh MyApp.app -n MyApp -v "0.1.1" -a "Name" -o \
"org.myorg.myapp" -i "../../myapp/doc/source/images/myapp_icon.png"

# Prepare a my-app-requirements.txt file with your app's dependencies (even indirect ones)
# and run the following command to prepare the distributions to later be installed in the
# virtualenv.
python prepare-wheels.py --requirements-file my-app-requirements.txt --output-folder my-app-wheels

pushd MyApp.app/Contents/Resources/venv/bin
source activate
popd

python -m pip install --upgrade pyobjus plyer ...
python -m pip install ../../myapp/
SITE_PACKAGES_DIR=$(python -c "import site; print(site.getsitepackages()[0])")
pip install --platform macosx_11_0_universal2 --find-links=./my-app-wheels --no-deps --target $SITE_PACKAGES_DIR -r my-app-requirements.txt

# Reduce app size
./cleanup-app.sh MyApp.app
Expand All @@ -156,58 +177,12 @@ A complete example using ``Kivy.app`` with a entry_point pointing to your app as
Example create app from scratch
-------------------------------

A complete example creating a bundle and building a dmg without using the prepared Kivy.app.
Also using a entry_point pointing to your app as described above
(notice the metadata and download URLs need to be replaced with actual metadata and URLs).
The dependencies versions and url should be updated as needed. Note that gstreamer is not
included::

# configure kivy
export CC=clang
export CXX=clang
export FFLAGS='-ff2c'
export USE_SDL2=1

# get the dependencies
export PLATYPUS=5.3

curl -O -L "http://www.sveinbjorn.org/files/software/platypus/platypus$PLATYPUS.zip"

unzip platypus$PLATYPUS.zip
gunzip Platypus.app/Contents/Resources/platypus_clt.gz
gunzip Platypus.app/Contents/Resources/ScriptExec.gz
mkdir -p /usr/local/bin
mkdir -p /usr/local/share/platypus
cp Platypus.app/Contents/Resources/platypus_clt /usr/local/bin/platypus
cp Platypus.app/Contents/Resources/ScriptExec /usr/local/share/platypus/ScriptExec
cp -a Platypus.app/Contents/Resources/MainMenu.nib /usr/local/share/platypus/MainMenu.nib
chmod -R 755 /usr/local/share/platypus

# create app
git clone https://github.com/user/myapp.git
git clone https://github.com/kivy/kivy-sdk-packager.git
cd kivy-sdk-packager/osx

./create-osx-bundle.sh -k master -n MyApp -v "0.1.1" -a "Name" -o \
"org.myorg.myapp" -i "../../myapp/doc/source/images/myapp_icon.png" -g 0

pushd build/MyApp.app/Contents/Resources/venv/bin
source activate
popd

python -m pip install --upgrade pyobjus plyer ...
python -m pip install ../../../myapp/

# reduce app size
./cleanup-app.sh MyApp.app

# the link needs to be created relative to the yourapp path, so go to that directory
pushd build/MyApp.app/Contents/Resources/
ln -s ./venv/bin/myapp yourapp
popd
``create-osx-bundle.sh`` can be used to create a app bundle from scratch. It will download and
build all the dependencies, and create a app bundle with a virtualenv with the dependencies
installed.

./relocate.sh build/MyApp.app
./create-osx-dmg.sh build/MyApp.app MyApp
You can later use the same steps as above to install your app and its dependencies, and create a
dmg.


Dev note:: Buildozer uses this repository for its OS X packaging process.
40 changes: 20 additions & 20 deletions osx/create-osx-bundle.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,6 @@
set -x # verbose
set -e # exit on error

USAGE="Creates a Kivy bundle that can be used to build your app into a dmg. See documentation.
Usage: create-osx-bundle.sh [options]
-k --kivy <Kivy version or path, default:master> The local path to Kivy source or a git tag/branch/commit.
-e --extras <Kivy extras selection, default:base> The extras selection (base, full, dev ...).
-p --python <Python version, default:3.9.9> The Python version to use.
-n --name <App name, default:Kivy> The name of the app.
-v --version <App version, default:master> The version of the app.
-a --author <Author, default:Kivy Developers> The author name.
-o --org <org, default:org.kivy.osxlauncher> The org id used for the app.
-i --icon <icon, default:data/icon.icns> A icns icon file path.
-s --script <app_main_script, default:data/script> The script to run when the user clicks the app.
Requirements::
Platypus needs to be installed. Finally, any python3 version must be available for
initial scripting.
"

KIVY_PATH="master"
EXTRAS="base"
PYVER="3.11.2"
Expand All @@ -32,6 +13,25 @@ APP_ORG="org.kivy.osxlauncher"
ICON_PATH="data/icon.icns"
APP_SCRIPT="data/script"

USAGE="Creates a Kivy bundle that can be used to build your app into a dmg. See documentation.
Usage: create-osx-bundle.sh [options]
-k --kivy <Kivy version or path, default:${KIVY_PATH}> The local path to Kivy source or a git tag/branch/commit.
-e --extras <Kivy extras selection, default:${EXTRAS}> The extras selection (base, full, dev ...).
-p --python <Python version, default:${PYVER}> The Python version to use.
-n --name <App name, default:${APP_NAME}> The name of the app.
-v --version <App version, default:${APP_VERSION}> The version of the app.
-a --author <Author, default:${AUTHOR}> The author name.
-o --org <org, default:${APP_ORG}> The org id used for the app.
-i --icon <icon, default:${ICON_PATH}> A icns icon file path.
-s --script <app_main_script, default:${APP_SCRIPT}> The script to run when the user clicks the app.
Requirements::
Platypus needs to be installed. Finally, any python3 version must be available for
initial scripting.
"

while [[ "$#" -gt 0 ]]; do
# empty arg?
if [ -z "$2" ]; then
Expand Down Expand Up @@ -186,7 +186,7 @@ pip install pip-tools
pip-compile kivy-app-requirements.in --no-annotate --no-header -o kivy-app-requirements.txt

echo "-- Call prepare-wheels.py to download (and fuse) all the wheels and source distributions"
pip install delocate distlib packaging
pip install ../requirements.txt
WHEELS_FOLDER=$(pwd)/wheels
$PYTHON ../prepare-wheels.py --requirements-file kivy-app-requirements.txt --python-version $PYVER --deployment-target $MACOSX_DEPLOYMENT_TARGET --output-folder $WHEELS_FOLDER

Expand Down
5 changes: 4 additions & 1 deletion osx/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
docopt==0.6.2
sh==1.14.2
sh==1.14.2
distlib~=0.3.7
delocate~=0.10.6
packaging~=23.2

0 comments on commit f50854f

Please sign in to comment.