11from pythonforandroid .recipe import PythonRecipe
2- from pythonforandroid .logger import shprint
2+ from pythonforandroid .logger import shprint , info_notify
33from pythonforandroid .util import current_directory , shutil
44from os .path import exists , join , dirname
55import sh
66from multiprocessing import cpu_count
7-
8-
97from pythonforandroid .toolchain import info
8+ import sys
9+ import os
1010
1111
1212class ProtobufCppRecipe (PythonRecipe ):
1313 name = 'protobuf_cpp'
14- version = '3.1.0 '
14+ version = '3.5.1 '
1515 url = 'https://github.com/google/protobuf/releases/download/v{version}/protobuf-python-{version}.tar.gz'
1616 call_hostpython_via_targetpython = False
1717 depends = ['cffi' , 'setuptools' ]
1818 site_packages_name = 'google/protobuf/pyext'
19+ protoc_dir = None
20+
21+ def prebuild_arch (self , arch ):
22+ super (ProtobufCppRecipe , self ).prebuild_arch (arch )
23+ # During building, host needs to transpile .proto files to .py
24+ # ideally with the same version as protobuf runtime, or with an older one.
25+ # Because protoc is compiled for target (i.e. Android), we need an other binary
26+ # which can be run by host.
27+ # To make it easier, we download prebuild protoc binary adapted to the platform
28+
29+ info_notify ("Downloading protoc compiler for your platform" )
30+ url_prefix = "https://github.com/protocolbuffers/protobuf/releases/download/v{version}" .format (version = self .version )
31+ if sys .platform .startswith ('linux' ):
32+ info_notify ("GNU/Linux detected" )
33+ filename = "protoc-{version}-linux-x86_64.zip" .format (version = self .version )
34+ elif sys .platform .startswith ('darwin' ):
35+ info_notify ("Mac OS X detected" )
36+ filename = "protoc-{version}-osx-x86_64.zip" .format (version = self .version )
37+ else :
38+ info_notify ("Your platform is not supported, but recipe can still "
39+ "be built if you have a valid protoc (<={version}) in "
40+ "your path" .format (version = self .version ))
41+ return
42+
43+ protoc_url = join (url_prefix , filename )
44+ self .protoc_dir = join (self .ctx .build_dir , "tools" , "protoc" )
45+ if os .path .exists (join (self .protoc_dir , "bin" , "protoc" )):
46+ info_notify ("protoc found, no download needed" )
47+ return
48+ try :
49+ os .makedirs (self .protoc_dir )
50+ except OSError as e :
51+ # if dir already exists (errno 17), we ignore the error
52+ if e .errno != 17 :
53+ raise e
54+ info_notify ("Will download into {dest_dir}" .format (dest_dir = self .protoc_dir ))
55+ self .download_file (protoc_url , join (self .protoc_dir , filename ))
56+ with current_directory (self .protoc_dir ):
57+ shprint (sh .unzip , join (self .protoc_dir , filename ))
1958
2059 def build_arch (self , arch ):
2160 env = self .get_recipe_env (arch )
@@ -85,7 +124,9 @@ def install_python_package(self, arch):
85124
86125 def get_recipe_env (self , arch ):
87126 env = super (ProtobufCppRecipe , self ).get_recipe_env (arch )
88- env ['PROTOC' ] = '/home/fipo/soft/protobuf-3.1.0/src/protoc'
127+ if self .protoc_dir is not None :
128+ # we need protoc with binary for host platform
129+ env ['PROTOC' ] = join (self .protoc_dir , 'bin' , 'protoc' )
89130 env ['PYTHON_ROOT' ] = self .ctx .get_python_install_dir ()
90131 env ['TARGET_OS' ] = 'OS_ANDROID_CROSSCOMPILE'
91132 env ['CFLAGS' ] += (
@@ -103,7 +144,7 @@ def get_recipe_env(self, arch):
103144 env ['LDFLAGS' ] += (
104145 ' -L' + self .ctx .ndk_dir +
105146 '/sources/cxx-stl/gnu-libstdc++/' + self .ctx .toolchain_version +
106- '/libs/' + arch .arch + ' -lgnustl_shared -lpython2.7' )
147+ '/libs/' + arch .arch + ' -lgnustl_shared -lpython2.7 -landroid -llog ' )
107148
108149 env ['LDSHARED' ] = env ['CC' ] + ' -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions'
109150 return env
0 commit comments