1
1
from pythonforandroid .recipe import PythonRecipe
2
- from pythonforandroid .logger import shprint
2
+ from pythonforandroid .logger import shprint , info_notify
3
3
from pythonforandroid .util import current_directory , shutil
4
4
from os .path import exists , join , dirname
5
5
import sh
6
6
from multiprocessing import cpu_count
7
-
8
-
9
7
from pythonforandroid .toolchain import info
8
+ import sys
9
+ import os
10
10
11
11
12
12
class ProtobufCppRecipe (PythonRecipe ):
13
13
name = 'protobuf_cpp'
14
- version = '3.1.0 '
14
+ version = '3.5.1 '
15
15
url = 'https://github.com/google/protobuf/releases/download/v{version}/protobuf-python-{version}.tar.gz'
16
16
call_hostpython_via_targetpython = False
17
17
depends = ['cffi' , 'setuptools' ]
18
18
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 ))
19
58
20
59
def build_arch (self , arch ):
21
60
env = self .get_recipe_env (arch )
@@ -85,7 +124,9 @@ def install_python_package(self, arch):
85
124
86
125
def get_recipe_env (self , arch ):
87
126
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' )
89
130
env ['PYTHON_ROOT' ] = self .ctx .get_python_install_dir ()
90
131
env ['TARGET_OS' ] = 'OS_ANDROID_CROSSCOMPILE'
91
132
env ['CFLAGS' ] += (
@@ -103,7 +144,7 @@ def get_recipe_env(self, arch):
103
144
env ['LDFLAGS' ] += (
104
145
' -L' + self .ctx .ndk_dir +
105
146
'/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 ' )
107
148
108
149
env ['LDSHARED' ] = env ['CC' ] + ' -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions'
109
150
return env
0 commit comments