Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bytes/unicode issues in android recipe #1516

Merged
merged 2 commits into from
Dec 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,5 @@ before_script:
- tox

script:
- docker build --tag=p4a .
- docker build --tag=p4a --file Dockerfile.py2 .
- docker run p4a /bin/sh -c "$COMMAND"
2 changes: 1 addition & 1 deletion Dockerfile → Dockerfile.py2
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# - python-for-android dependencies
#
# Build with:
# docker build --tag=p4a .
# docker build --tag=p4a --file Dockerfile.py2 .
#
# Run with:
# docker run -it --rm p4a /bin/sh -c '. venv/bin/activate && p4a apk --help'
Expand Down
132 changes: 132 additions & 0 deletions Dockerfile.py3
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Dockerfile with:
# - Android build environment
# - python-for-android dependencies
#
# Build with:
# docker build --tag=p4apy3 .
#
# Run with:
# docker run -it --rm p4apy3 /bin/sh -c '. venv/bin/activate && p4a apk --help'
#
# Or for interactive shell:
# docker run -it --rm p4apy3
#
# Note:
# Use 'docker run' without '--rm' flag for keeping the container and use
# 'docker commit <container hash> <new image>' to extend the original image

FROM ubuntu:18.04

ENV ANDROID_HOME="/opt/android"

RUN apt -y update -qq \
&& apt -y install -qq --no-install-recommends curl unzip \
&& apt -y autoremove \
&& apt -y clean


ENV ANDROID_NDK_HOME="${ANDROID_HOME}/android-ndk"
ENV ANDROID_NDK_VERSION="16b"
ENV ANDROID_NDK_HOME_V="${ANDROID_NDK_HOME}-r${ANDROID_NDK_VERSION}"

# get the latest version from https://developer.android.com/ndk/downloads/index.html
ENV ANDROID_NDK_ARCHIVE="android-ndk-r${ANDROID_NDK_VERSION}-linux-x86_64.zip"
ENV ANDROID_NDK_DL_URL="https://dl.google.com/android/repository/${ANDROID_NDK_ARCHIVE}"

# download and install Android NDK
RUN curl --location --progress-bar --insecure \
"${ANDROID_NDK_DL_URL}" \
--output "${ANDROID_NDK_ARCHIVE}" \
&& mkdir --parents "${ANDROID_NDK_HOME_V}" \
&& unzip -q "${ANDROID_NDK_ARCHIVE}" -d "${ANDROID_HOME}" \
&& ln -sfn "${ANDROID_NDK_HOME_V}" "${ANDROID_NDK_HOME}" \
&& rm -rf "${ANDROID_NDK_ARCHIVE}"


ENV ANDROID_SDK_HOME="${ANDROID_HOME}/android-sdk"

# get the latest version from https://developer.android.com/studio/index.html
ENV ANDROID_SDK_TOOLS_VERSION="3859397"
ENV ANDROID_SDK_TOOLS_ARCHIVE="sdk-tools-linux-${ANDROID_SDK_TOOLS_VERSION}.zip"
ENV ANDROID_SDK_TOOLS_DL_URL="https://dl.google.com/android/repository/${ANDROID_SDK_TOOLS_ARCHIVE}"

# download and install Android SDK
RUN curl --location --progress-bar --insecure \
"${ANDROID_SDK_TOOLS_DL_URL}" \
--output "${ANDROID_SDK_TOOLS_ARCHIVE}" \
&& mkdir --parents "${ANDROID_SDK_HOME}" \
&& unzip -q "${ANDROID_SDK_TOOLS_ARCHIVE}" -d "${ANDROID_SDK_HOME}" \
&& rm -rf "${ANDROID_SDK_TOOLS_ARCHIVE}"

# update Android SDK, install Android API, Build Tools...
RUN mkdir --parents "${ANDROID_SDK_HOME}/.android/" \
&& echo '### User Sources for Android SDK Manager' \
> "${ANDROID_SDK_HOME}/.android/repositories.cfg"

# accept Android licenses (JDK necessary!)
RUN apt -y update -qq \
&& apt -y install -qq --no-install-recommends openjdk-8-jdk \
&& apt -y autoremove \
&& apt -y clean
RUN yes | "${ANDROID_SDK_HOME}/tools/bin/sdkmanager" --licenses > /dev/null

# download platforms, API, build tools
RUN "${ANDROID_SDK_HOME}/tools/bin/sdkmanager" "platforms;android-19" && \
"${ANDROID_SDK_HOME}/tools/bin/sdkmanager" "platforms;android-27" && \
"${ANDROID_SDK_HOME}/tools/bin/sdkmanager" "build-tools;26.0.2" && \
chmod +x "${ANDROID_SDK_HOME}/tools/bin/avdmanager"


ENV USER="user"
ENV HOME_DIR="/home/${USER}"
ENV WORK_DIR="${HOME_DIR}" \
PATH="${HOME_DIR}/.local/bin:${PATH}"

# install system dependencies
RUN apt -y update -qq \
&& apt -y install -qq --no-install-recommends \
python3 virtualenv python3-pip wget lbzip2 patch sudo \
&& apt -y autoremove \
&& apt -y clean

# build dependencies
# https://buildozer.readthedocs.io/en/latest/installation.html#android-on-ubuntu-16-04-64bit
RUN dpkg --add-architecture i386 \
&& apt -y update -qq \
&& apt -y install -qq --no-install-recommends \
build-essential ccache git python3 python3-dev \
libncurses5:i386 libstdc++6:i386 libgtk2.0-0:i386 \
libpangox-1.0-0:i386 libpangoxft-1.0-0:i386 libidn11:i386 \
zip zlib1g-dev zlib1g:i386 \
&& apt -y autoremove \
&& apt -y clean

# specific recipes dependencies (e.g. libffi requires autoreconf binary)
RUN apt -y update -qq \
&& apt -y install -qq --no-install-recommends \
autoconf automake cmake gettext libltdl-dev libtool pkg-config \
&& apt -y autoremove \
&& apt -y clean


# prepare non root env
RUN useradd --create-home --shell /bin/bash ${USER}

# with sudo access and no password
RUN usermod -append --groups sudo ${USER}
RUN echo "%sudo ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers


RUN pip3 install --upgrade cython==0.28.6

WORKDIR ${WORK_DIR}
COPY . ${WORK_DIR}

# user needs ownership/write access to these directories
RUN chown --recursive ${USER} ${WORK_DIR} ${ANDROID_SDK_HOME}
USER ${USER}

# install python-for-android from current branch
RUN virtualenv --python=python3 venv \
&& . venv/bin/activate \
&& pip3 install -e .
38 changes: 26 additions & 12 deletions pythonforandroid/recipes/android/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
from __future__ import unicode_literals
from pythonforandroid.recipe import CythonRecipe, IncludedFilesBehaviour
from pythonforandroid.util import current_directory
from pythonforandroid.patching import will_build
from pythonforandroid import logger

from os.path import join
from sys import version_info


class AndroidRecipe(IncludedFilesBehaviour, CythonRecipe):
Expand All @@ -26,27 +26,35 @@ def get_recipe_env(self, arch):

def prebuild_arch(self, arch):
super(AndroidRecipe, self).prebuild_arch(arch)
ctx_bootstrap = self.ctx.bootstrap.name

# define macros for Cython, C, Python
tpxi = 'DEF {} = {}\n'
th = '#define {} {}\n'
tpy = '{} = {}\n'

bootstrap = self.ctx.bootstrap.name
bootstrap = bootstrap_name = bootstrap if version_info >= (3, ) else bootstrap.decode('utf-8')
# make sure bootstrap name is in unicode
if isinstance(ctx_bootstrap, bytes):
ctx_bootstrap = ctx_bootstrap.decode('utf-8')
bootstrap = bootstrap_name = ctx_bootstrap

is_sdl2 = bootstrap_name in ('sdl2', 'sdl2python3', 'sdl2_gradle')
is_pygame = bootstrap_name in ('pygame',)
is_webview = bootstrap_name in ('webview',)

if is_sdl2 or is_webview:
if is_sdl2:
bootstrap = 'sdl2'
java_ns = u'org.kivy.android'
jni_ns = u'org/kivy/android'
java_ns = 'org.kivy.android'
jni_ns = 'org/kivy/android'
elif is_pygame:
java_ns = 'org.renpy.android'
jni_ns = 'org/renpy/android'
java_ns = b'org.renpy.android'
jni_ns = b'org/renpy/android'
else:
logger.error('unsupported bootstrap for android recipe: {}'.format(bootstrap_name))
logger.error((
'unsupported bootstrap for android recipe: {}'
''.format(bootstrap_name)
))
exit(1)

config = {
Expand All @@ -58,22 +66,28 @@ def prebuild_arch(self, arch):
'JNI_NAMESPACE': jni_ns,
}

# create config files for Cython, C and Python
with (
current_directory(self.get_build_dir(arch.arch))), (
open(join('android', 'config.pxi'), 'w')) as fpxi, (
open(join('android', 'config.h'), 'w')) as fh, (
open(join('android', 'config.py'), 'w')) as fpy:

for key, value in config.items():
fpxi.write(tpxi.format(key, repr(value)))
fpy.write(tpy.format(key, repr(value)))
fh.write(th.format(key,
value if isinstance(value, int)
else '"{}"'.format(value)))

fh.write(th.format(
key,
value if isinstance(value, int) else '"{}"'.format(value)
))
self.config_env[key] = str(value)

if is_sdl2:
fh.write('JNIEnv *SDL_AndroidGetJNIEnv(void);\n')
fh.write('#define SDL_ANDROID_GetJNIEnv SDL_AndroidGetJNIEnv\n')
fh.write(
'#define SDL_ANDROID_GetJNIEnv SDL_AndroidGetJNIEnv\n'
)
elif is_pygame:
fh.write('JNIEnv *SDL_ANDROID_GetJNIEnv(void);\n')

Expand Down