Skip to content

[WIP][LIBS - PART VI] Rework of protobuf_cpp #1969

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

Merged
merged 1 commit into from
Aug 30, 2019
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
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