🍏 Improves iOS support
Updates & fixes support for iOS target, covers the following: - Build integration test - Updates to new kivy-ios structure - Bumps to ios-deploy 1.10.0 (`make` replaced by `xcodebuild`) - Makes it possible to toggle code signing (now disabled by default) Note this is the first iteration of a longer serie. Subsequent pull requests will try to improve the following: - code signing process (toggle not fully integrated) - actual deployment (not yet tested) - unit tests (mainly `buildozer/targets/ios.py`) - other forms of technical debt
This commit is contained in:
parent
af577b6138
commit
020a5504f3
5 changed files with 64 additions and 26 deletions
2
.github/workflows/android.yml
vendored
2
.github/workflows/android.yml
vendored
|
@ -17,7 +17,7 @@ jobs:
|
||||||
- name: Setup environment
|
- name: Setup environment
|
||||||
run: |
|
run: |
|
||||||
pip install -e .
|
pip install -e .
|
||||||
pip install Cython==0.29.19
|
pip install Cython
|
||||||
- run: buildozer --help
|
- run: buildozer --help
|
||||||
- run: buildozer init
|
- run: buildozer init
|
||||||
- name: SDK, NDK and p4a download
|
- name: SDK, NDK and p4a download
|
||||||
|
|
24
.github/workflows/ios.yml
vendored
Normal file
24
.github/workflows/ios.yml
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
on: [push, pull_request]
|
||||||
|
name: iOS
|
||||||
|
jobs:
|
||||||
|
Integration:
|
||||||
|
runs-on: macOS-latest
|
||||||
|
steps:
|
||||||
|
- name: Setup python
|
||||||
|
uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: 3.8
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup environment
|
||||||
|
run: |
|
||||||
|
pip install -e .
|
||||||
|
pip install Cython cookiecutter pbxproj
|
||||||
|
- run: buildozer --help
|
||||||
|
- run: buildozer init
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
brew install autoconf automake libtool pkg-config
|
||||||
|
- name: buildozer ios debug
|
||||||
|
run: |
|
||||||
|
touch main.py
|
||||||
|
buildozer ios debug
|
|
@ -1,8 +1,9 @@
|
||||||
Buildozer
|
Buildozer
|
||||||
=========
|
=========
|
||||||
|
|
||||||
[![Build](https://github.com/kivy/buildozer/workflows/Tests/badge.svg)](https://github.com/kivy/buildozer/actions?query=workflow%3ATests)
|
[![Tests](https://github.com/kivy/buildozer/workflows/Tests/badge.svg)](https://github.com/kivy/buildozer/actions?query=workflow%3ATests)
|
||||||
[![Build](https://github.com/kivy/buildozer/workflows/Android/badge.svg)](https://github.com/kivy/buildozer/actions?query=workflow%3AAndroid)
|
[![Android](https://github.com/kivy/buildozer/workflows/Android/badge.svg)](https://github.com/kivy/buildozer/actions?query=workflow%3AAndroid)
|
||||||
|
[![iOS](https://github.com/kivy/buildozer/workflows/iOS/badge.svg)](https://github.com/kivy/buildozer/actions?query=workflow%3AiOS)
|
||||||
[![Coverage Status](https://coveralls.io/repos/github/kivy/buildozer/badge.svg)](https://coveralls.io/github/kivy/buildozer)
|
[![Coverage Status](https://coveralls.io/repos/github/kivy/buildozer/badge.svg)](https://coveralls.io/github/kivy/buildozer)
|
||||||
[![Backers on Open Collective](https://opencollective.com/kivy/backers/badge.svg)](#backers)
|
[![Backers on Open Collective](https://opencollective.com/kivy/backers/badge.svg)](#backers)
|
||||||
[![Sponsors on Open Collective](https://opencollective.com/kivy/sponsors/badge.svg)](#sponsors)
|
[![Sponsors on Open Collective](https://opencollective.com/kivy/sponsors/badge.svg)](#sponsors)
|
||||||
|
|
|
@ -22,7 +22,7 @@ source.include_exts = py,png,jpg,kv,atlas
|
||||||
#source.exclude_exts = spec
|
#source.exclude_exts = spec
|
||||||
|
|
||||||
# (list) List of directory to exclude (let empty to not exclude anything)
|
# (list) List of directory to exclude (let empty to not exclude anything)
|
||||||
#source.exclude_dirs = tests, bin
|
#source.exclude_dirs = tests, bin, venv
|
||||||
|
|
||||||
# (list) List of exclusions using pattern matching
|
# (list) List of exclusions using pattern matching
|
||||||
#source.exclude_patterns = license,images/*/*.jpg
|
#source.exclude_patterns = license,images/*/*.jpg
|
||||||
|
@ -263,7 +263,10 @@ ios.kivy_ios_branch = master
|
||||||
#ios.ios_deploy_dir = ../ios_deploy
|
#ios.ios_deploy_dir = ../ios_deploy
|
||||||
# Or specify URL and branch
|
# Or specify URL and branch
|
||||||
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
|
ios.ios_deploy_url = https://github.com/phonegap/ios-deploy
|
||||||
ios.ios_deploy_branch = 1.7.0
|
ios.ios_deploy_branch = 1.10.0
|
||||||
|
|
||||||
|
# (bool) Whether or not to sign the code
|
||||||
|
ios.codesign.allowed = false
|
||||||
|
|
||||||
# (str) Name of the certificate to use for signing the debug version
|
# (str) Name of the certificate to use for signing the debug version
|
||||||
# Get a list of available identities: buildozer ios list_identities
|
# Get a list of available identities: buildozer ios list_identities
|
||||||
|
|
|
@ -66,6 +66,9 @@ class TargetIos(Target):
|
||||||
def check_requirements(self):
|
def check_requirements(self):
|
||||||
checkbin = self.buildozer.checkbin
|
checkbin = self.buildozer.checkbin
|
||||||
cmd = self.buildozer.cmd
|
cmd = self.buildozer.cmd
|
||||||
|
executable = sys.executable or 'python'
|
||||||
|
self._toolchain_cmd = f"{executable} toolchain.py "
|
||||||
|
self._xcodebuild_cmd = "xcodebuild "
|
||||||
|
|
||||||
checkbin('Xcode xcodebuild', 'xcodebuild')
|
checkbin('Xcode xcodebuild', 'xcodebuild')
|
||||||
checkbin('Xcode xcode-select', 'xcode-select')
|
checkbin('Xcode xcode-select', 'xcode-select')
|
||||||
|
@ -99,10 +102,21 @@ class TargetIos(Target):
|
||||||
branch='1.7.0',
|
branch='1.7.0',
|
||||||
owner='phonegap')
|
owner='phonegap')
|
||||||
|
|
||||||
|
def toolchain(self, cmd, **kwargs):
|
||||||
|
kwargs.setdefault('cwd', self.ios_dir)
|
||||||
|
return self.buildozer.cmd(self._toolchain_cmd + cmd, **kwargs)
|
||||||
|
|
||||||
|
def xcodebuild(self, cmd='', **kwargs):
|
||||||
|
return self.buildozer.cmd(self._xcodebuild_cmd + cmd, **kwargs)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def code_signing_allowed(self):
|
||||||
|
allowed = self.buildozer.config.getboolean("app", "ios.codesign.allowed")
|
||||||
|
allowed = "YES" if allowed else "NO"
|
||||||
|
return f"CODE_SIGNING_ALLOWED={allowed}"
|
||||||
|
|
||||||
def get_available_packages(self):
|
def get_available_packages(self):
|
||||||
available_modules = self.buildozer.cmd(
|
available_modules = self.toolchain("recipes --compact", get_stdout=True)[0]
|
||||||
'./toolchain.py recipes --compact',
|
|
||||||
cwd=self.ios_dir, get_stdout=True)[0]
|
|
||||||
return available_modules.splitlines()[0].split()
|
return available_modules.splitlines()[0].split()
|
||||||
|
|
||||||
def compile_platform(self):
|
def compile_platform(self):
|
||||||
|
@ -139,11 +153,10 @@ class TargetIos(Target):
|
||||||
return
|
return
|
||||||
|
|
||||||
modules_str = ' '.join(ios_requirements)
|
modules_str = ' '.join(ios_requirements)
|
||||||
self.buildozer.cmd('./toolchain.py build {}'.format(modules_str),
|
self.toolchain(f"build {modules_str}")
|
||||||
cwd=self.ios_dir)
|
|
||||||
|
|
||||||
if not self.buildozer.file_exists(self.ios_deploy_dir, 'ios-deploy'):
|
if not self.buildozer.file_exists(self.ios_deploy_dir, 'ios-deploy'):
|
||||||
self.buildozer.cmd('make ios-deploy', cwd=self.ios_deploy_dir)
|
self.xcodebuild(cwd=self.ios_deploy_dir)
|
||||||
|
|
||||||
self.buildozer.state['ios.requirements'] = ios_requirements
|
self.buildozer.state['ios.requirements'] = ios_requirements
|
||||||
self.buildozer.state.sync()
|
self.buildozer.state.sync()
|
||||||
|
@ -170,12 +183,10 @@ class TargetIos(Target):
|
||||||
|
|
||||||
self.app_project_dir = join(self.ios_dir, '{0}-ios'.format(app_name.lower()))
|
self.app_project_dir = join(self.ios_dir, '{0}-ios'.format(app_name.lower()))
|
||||||
if not self.buildozer.file_exists(self.app_project_dir):
|
if not self.buildozer.file_exists(self.app_project_dir):
|
||||||
create_cmd = './toolchain.py create {0}{1} {2}'.format(frameworks_cmd, app_name,
|
cmd = f"create {frameworks_cmd}{app_name} {self.buildozer.app_dir}"
|
||||||
self.buildozer.app_dir)
|
|
||||||
self.buildozer.cmd(create_cmd, cwd=self.ios_dir)
|
|
||||||
else:
|
else:
|
||||||
update_cmd = './toolchain.py update {0}{1}-ios'.format(frameworks_cmd, app_name)
|
cmd = f"update {frameworks_cmd}{app_name}-ios"
|
||||||
self.buildozer.cmd(update_cmd, cwd=self.ios_dir)
|
self.toolchain(cmd)
|
||||||
|
|
||||||
# fix the plist
|
# fix the plist
|
||||||
plist_fn = '{}-Info.plist'.format(app_name.lower())
|
plist_fn = '{}-Info.plist'.format(app_name.lower())
|
||||||
|
@ -194,8 +205,9 @@ class TargetIos(Target):
|
||||||
# ok, write the modified plist.
|
# ok, write the modified plist.
|
||||||
plistlib.writePlist(plist, plist_rfn)
|
plistlib.writePlist(plist, plist_rfn)
|
||||||
|
|
||||||
mode = 'Debug' if self.build_mode == 'debug' else 'Release'
|
mode = self.build_mode.capitalize()
|
||||||
self.buildozer.cmd('xcodebuild -configuration {} ENABLE_BITCODE=NO clean build'.format(mode),
|
self.xcodebuild(
|
||||||
|
f"-configuration {mode} ENABLE_BITCODE=NO {self.code_signing_allowed} clean build",
|
||||||
cwd=self.app_project_dir)
|
cwd=self.app_project_dir)
|
||||||
ios_app_dir = '{app_lower}-ios/build/{mode}-iphoneos/{app_lower}.app'.format(
|
ios_app_dir = '{app_lower}-ios/build/{mode}-iphoneos/{app_lower}.app'.format(
|
||||||
app_lower=app_name.lower(), mode=mode)
|
app_lower=app_name.lower(), mode=mode)
|
||||||
|
@ -221,8 +233,7 @@ class TargetIos(Target):
|
||||||
self.buildozer.rmdir(intermediate_dir)
|
self.buildozer.rmdir(intermediate_dir)
|
||||||
|
|
||||||
self.buildozer.info('Creating archive...')
|
self.buildozer.info('Creating archive...')
|
||||||
self.buildozer.cmd((
|
self.xcodebuild((
|
||||||
'/usr/bin/xcodebuild'
|
|
||||||
' -alltargets'
|
' -alltargets'
|
||||||
' -configuration {mode}'
|
' -configuration {mode}'
|
||||||
' -scheme {scheme}'
|
' -scheme {scheme}'
|
||||||
|
@ -233,8 +244,7 @@ class TargetIos(Target):
|
||||||
cwd=build_dir)
|
cwd=build_dir)
|
||||||
|
|
||||||
self.buildozer.info('Creating IPA...')
|
self.buildozer.info('Creating IPA...')
|
||||||
self.buildozer.cmd((
|
self.xcodebuild((
|
||||||
'/usr/bin/xcodebuild'
|
|
||||||
' -exportArchive'
|
' -exportArchive'
|
||||||
' -exportFormat IPA'
|
' -exportFormat IPA'
|
||||||
' -archivePath "{xcarchive}"'
|
' -archivePath "{xcarchive}"'
|
||||||
|
@ -301,13 +311,13 @@ class TargetIos(Target):
|
||||||
self.buildozer.error('Icon {} does not exists'.format(icon_fn))
|
self.buildozer.error('Icon {} does not exists'.format(icon_fn))
|
||||||
return
|
return
|
||||||
|
|
||||||
self.buildozer.cmd('./toolchain.py icon {} {}'.format(
|
self.toolchain(f"icon {self.app_project_dir} {icon_fn}")
|
||||||
self.app_project_dir, icon_fn),
|
|
||||||
cwd=self.ios_dir)
|
|
||||||
|
|
||||||
def check_configuration_tokens(self):
|
def check_configuration_tokens(self):
|
||||||
errors = []
|
errors = []
|
||||||
config = self.buildozer.config
|
config = self.buildozer.config
|
||||||
|
if not config.getboolean('app', 'ios.codesign.allowed'):
|
||||||
|
return
|
||||||
identity_debug = config.getdefault('app', 'ios.codesign.debug', '')
|
identity_debug = config.getdefault('app', 'ios.codesign.debug', '')
|
||||||
identity_release = config.getdefault('app', 'ios.codesign.release',
|
identity_release = config.getdefault('app', 'ios.codesign.release',
|
||||||
identity_debug)
|
identity_debug)
|
||||||
|
|
Loading…
Reference in a new issue