Skip to content

Commit

Permalink
[recipe-stl] Rework of protobuf_cpp recipe
Browse files Browse the repository at this point in the history
In here we do:
  - inherit from CppCompiledComponentsPythonRecipe Because depends on android's STL library
  - make use of the base class methods for library recipes
  - Split build_arch into proper methods
  - Shorten some long lines (to be PEP8 friendly)
  - make generated library shared
  - remove recipe from CI/constants
  • Loading branch information
opacam committed Aug 30, 2019
1 parent e76aad9 commit b60887b
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 40 deletions.
1 change: 0 additions & 1 deletion ci/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ class TargetPython(Enum):
'ffpyplayer',
# requires `libpq-dev` system dependency e.g. for `pg_config` binary
'psycopg2',
'protobuf_cpp',
# most likely some setup in the Docker container, because it works in host
'pyjnius', 'pyopenal',
# SyntaxError: invalid syntax (Python2)
Expand Down
72 changes: 33 additions & 39 deletions pythonforandroid/recipes/protobuf_cpp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from pythonforandroid.recipe import PythonRecipe
from pythonforandroid.recipe import CppCompiledComponentsPythonRecipe
from pythonforandroid.logger import shprint, info_notify
from pythonforandroid.util import current_directory, shutil
from pythonforandroid.util import current_directory
from os.path import exists, join
import sh
from multiprocessing import cpu_count
Expand All @@ -9,13 +9,19 @@
import os


class ProtobufCppRecipe(PythonRecipe):
class ProtobufCppRecipe(CppCompiledComponentsPythonRecipe):
"""This is a two-in-one recipe:
- build labraru `libprotobuf.so`
- build and install python binding for protobuf_cpp
"""
name = 'protobuf_cpp'
version = '3.6.1'
url = 'https://github.com/google/protobuf/releases/download/v{version}/protobuf-python-{version}.tar.gz'
call_hostpython_via_targetpython = False
depends = ['cffi', 'setuptools']
site_packages_name = 'google/protobuf/pyext'
setup_extra_args = ['--cpp_implementation']
built_libraries = {'libprotobuf.so': 'src/.libs'}
protoc_dir = None

def prebuild_arch(self, arch):
Expand Down Expand Up @@ -65,42 +71,37 @@ def prebuild_arch(self, arch):
def build_arch(self, arch):
env = self.get_recipe_env(arch)

# Build libproto.a
# Build libproto.so
with current_directory(self.get_build_dir(arch.arch)):
env['HOSTARCH'] = 'arm-eabi'
env['BUILDARCH'] = shprint(sh.gcc, '-dumpmachine').stdout.decode('utf-8').split('\n')[0]
build_arch = (
shprint(sh.gcc, '-dumpmachine')
.stdout.decode('utf-8')
.split('\n')[0]
)

if not exists('configure'):
shprint(sh.Command('./autogen.sh'), _env=env)

shprint(sh.Command('./configure'),
'--host={}'.format(env['HOSTARCH']),
'--build={}'.format(build_arch),
'--host={}'.format(arch.command_prefix),
'--target={}'.format(arch.command_prefix),
'--disable-static',
'--enable-shared',
_env=env)

with current_directory(join(self.get_build_dir(arch.arch), 'src')):
shprint(sh.make, 'libprotobuf.la', '-j'+str(cpu_count()), _env=env)
shprint(sh.cp, '.libs/libprotobuf.a', join(self.ctx.get_libs_dir(arch.arch), 'libprotobuf.a'))

# Copy stl library
shutil.copyfile(
self.ctx.ndk_dir + '/sources/cxx-stl/gnu-libstdc++/' + self.ctx.toolchain_version + '/libs/' + arch.arch + '/libgnustl_shared.so',
join(self.ctx.get_libs_dir(arch.arch), 'libgnustl_shared.so'))

def build_compiled_components(self, arch):
# Build python bindings and _message.so
env = self.get_recipe_env(arch)
with current_directory(join(self.get_build_dir(arch.arch), 'python')):
hostpython = sh.Command(self.hostpython_location)
shprint(hostpython,
'setup.py',
'build_ext',
'--cpp_implementation', _env=env)

# Install python bindings
self.install_python_package(arch)

# Create __init__.py which is missing (cf. https://github.com/protocolbuffers/protobuf/issues/1296
# and https://stackoverflow.com/questions/13862562/google-protocol-buffers-not-found-when-trying-to-freeze-python-app)
open(join(self.ctx.get_site_packages_dir(), 'google', '__init__.py'), 'a').close()
_env=env, *self.setup_extra_args)

def install_python_package(self, arch):
env = self.get_recipe_env(arch)
Expand All @@ -114,32 +115,25 @@ def install_python_package(self, arch):
shprint(hostpython, 'setup.py', 'install', '-O2',
'--root={}'.format(self.ctx.get_python_install_dir()),
'--install-lib=.',
'--cpp_implementation',
_env=hpenv, *self.setup_extra_args)

# Create __init__.py which is missing, see also:
# - https://github.com/protocolbuffers/protobuf/issues/1296
# - https://stackoverflow.com/questions/13862562/
# google-protocol-buffers-not-found-when-trying-to-freeze-python-app
open(
join(self.ctx.get_site_packages_dir(), 'google', '__init__.py'),
'a',
).close()

def get_recipe_env(self, arch):
env = super(ProtobufCppRecipe, self).get_recipe_env(arch)
if self.protoc_dir is not None:
# we need protoc with binary for host platform
env['PROTOC'] = join(self.protoc_dir, 'bin', 'protoc')
env['TARGET_OS'] = 'OS_ANDROID_CROSSCOMPILE'
env['CFLAGS'] += (
' -I' + self.ctx.ndk_dir + '/platforms/android-' +
str(self.ctx.android_api) +
'/arch-' + arch.arch.replace('eabi', '') + '/usr/include' +
' -I' + self.ctx.ndk_dir + '/sources/cxx-stl/gnu-libstdc++/' +
self.ctx.toolchain_version + '/include' +
' -I' + self.ctx.ndk_dir + '/sources/cxx-stl/gnu-libstdc++/' +
self.ctx.toolchain_version + '/libs/' + arch.arch + '/include')
env['CFLAGS'] += ' -std=gnu++11'
env['CXXFLAGS'] = env['CFLAGS']
env['CXXFLAGS'] += ' -frtti'
env['CXXFLAGS'] += ' -fexceptions'
env['LDFLAGS'] += (
' -lgnustl_shared -landroid -llog' +
' -L' + self.ctx.ndk_dir +
'/sources/cxx-stl/gnu-libstdc++/' + self.ctx.toolchain_version +
'/libs/' + arch.arch)
env['CXXFLAGS'] += ' -std=c++11'
env['LDFLAGS'] += ' -lm -landroid -llog'
return env


Expand Down

0 comments on commit b60887b

Please sign in to comment.