From b60887b36cbbc8a0459799cef2890617273a78da Mon Sep 17 00:00:00 2001 From: opacam Date: Tue, 30 Jul 2019 11:05:44 +0200 Subject: [PATCH] [recipe-stl] Rework of protobuf_cpp recipe 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 --- ci/constants.py | 1 - .../recipes/protobuf_cpp/__init__.py | 72 +++++++++---------- 2 files changed, 33 insertions(+), 40 deletions(-) diff --git a/ci/constants.py b/ci/constants.py index 6699d24cd3..f5ab1dad59 100644 --- a/ci/constants.py +++ b/ci/constants.py @@ -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) diff --git a/pythonforandroid/recipes/protobuf_cpp/__init__.py b/pythonforandroid/recipes/protobuf_cpp/__init__.py index 30ca030a2a..84a5e3c398 100644 --- a/pythonforandroid/recipes/protobuf_cpp/__init__.py +++ b/pythonforandroid/recipes/protobuf_cpp/__init__.py @@ -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 @@ -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): @@ -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) @@ -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