1
1
from distutils .spawn import find_executable
2
2
from os import environ
3
- from os .path import (exists , join , dirname , split )
3
+ from os .path import join , dirname , split
4
+ from multiprocessing import cpu_count
4
5
from glob import glob
5
6
6
7
from pythonforandroid .recipe import Recipe
@@ -38,29 +39,34 @@ def include_dirs(self):
38
39
39
40
@property
40
41
def target (self ):
41
- target_data = self .command_prefix .split ('-' )
42
- return '-' .join (
43
- [target_data [0 ], 'none' , target_data [1 ], target_data [2 ]])
42
+ # As of NDK r19, the toolchains installed by default with the
43
+ # NDK may be used in-place. The make_standalone_toolchain.py script
44
+ # is no longer needed for interfacing with arbitrary build systems.
45
+ # See: https://developer.android.com/ndk/guides/other_build_systems
46
+ return '{triplet}{ndk_api}' .format (
47
+ triplet = self .command_prefix , ndk_api = self .ctx .ndk_api )
44
48
45
49
def get_env (self , with_flags_in_cc = True , clang = False ):
46
50
env = {}
47
51
52
+ # CFLAGS and CXXFLAGS
48
53
cflags = [
49
- '-DANDROID' ,
50
- '-fomit-frame-pointer' ,
51
- '-D__ANDROID_API__={}' .format (self .ctx .ndk_api )]
52
- if not clang :
53
- cflags .append ('-mandroid' )
54
- else :
55
- cflags .append ('-target ' + self .target )
56
- toolchain = '{android_host}-{toolchain_version}' .format (
57
- android_host = self .ctx .toolchain_prefix ,
58
- toolchain_version = self .ctx .toolchain_version )
59
- toolchain = join (self .ctx .ndk_dir , 'toolchains' , toolchain ,
60
- 'prebuilt' , build_platform )
61
- cflags .append ('-gcc-toolchain {}' .format (toolchain ))
62
-
54
+ '-target ' + self .target ,
55
+ '-fomit-frame-pointer' ]
63
56
env ['CFLAGS' ] = ' ' .join (cflags )
57
+ env ['CXXFLAGS' ] = env ['CFLAGS' ]
58
+
59
+ # CPPFLAGS (for macros and includes)
60
+ cppflags = [
61
+ '-DANDROID' ,
62
+ '-D__ANDROID_API__={}' .format (self .ctx .ndk_api ),
63
+ '-I{}/sysroot/usr/include/{}' .format (
64
+ self .ctx .ndk_dir , self .command_prefix ),
65
+ '-I' + join (self .ctx .get_python_install_dir (),
66
+ 'include/python{}' .format (
67
+ self .ctx .python_recipe .version [0 :3 ]))
68
+ ]
69
+ env ['CPPFLAGS' ] = ' ' .join (cppflags )
64
70
65
71
# Link the extra global link paths first before anything else
66
72
# (such that overriding system libraries with them is possible)
@@ -69,39 +75,14 @@ def get_env(self, with_flags_in_cc=True, clang=False):
69
75
for l in self .extra_global_link_paths
70
76
]) + ' '
71
77
72
- sysroot = join (self .ctx ._ndk_dir , 'sysroot' )
73
- if exists (sysroot ):
74
- # post-15 NDK per
75
- # https://android.googlesource.com/platform/ndk/+/ndk-r15-release/docs/UnifiedHeaders.md
76
- env ['CFLAGS' ] += ' -isystem {}/sysroot/usr/include/{}' .format (
77
- self .ctx .ndk_dir , self .ctx .toolchain_prefix )
78
- env ['CFLAGS' ] += ' -I{}/sysroot/usr/include/{}' .format (
79
- self .ctx .ndk_dir , self .command_prefix )
80
- else :
81
- sysroot = self .ctx .ndk_platform
82
- env ['CFLAGS' ] += ' -I{}' .format (self .ctx .ndk_platform )
83
- env ['CFLAGS' ] += ' -isysroot {} ' .format (sysroot )
84
- env ['CFLAGS' ] += '-I' + join (self .ctx .get_python_install_dir (),
85
- 'include/python{}' .format (
86
- self .ctx .python_recipe .version [0 :3 ])
87
- )
88
-
89
- env ['LDFLAGS' ] += '--sysroot {} ' .format (self .ctx .ndk_platform )
90
-
91
- env ["CXXFLAGS" ] = env ["CFLAGS" ]
92
-
93
- env ["LDFLAGS" ] += " " .join (['-lm' , '-L' + self .ctx .get_libs_dir (self .arch )])
94
-
95
- if self .ctx .ndk == 'crystax' :
96
- env ['LDFLAGS' ] += ' -L{}/sources/crystax/libs/{} -lcrystax' .format (self .ctx .ndk_dir , self .arch )
97
-
98
- toolchain_prefix = self .ctx .toolchain_prefix
99
- toolchain_version = self .ctx .toolchain_version
100
- command_prefix = self .command_prefix
101
-
102
- env ['TOOLCHAIN_PREFIX' ] = toolchain_prefix
103
- env ['TOOLCHAIN_VERSION' ] = toolchain_version
78
+ # LDFLAGS: Extra flags to give to compilers when they are supposed to
79
+ # invoke the linker, ld, such as -L.
80
+ env ['LDFLAGS' ] += ' -L' + self .ctx .get_libs_dir (self .arch )
81
+ # LDLIBS: Library flags or names given to compilers when they are
82
+ # supposed to invoke the linker.
83
+ env ['LDLIBS' ] = '-lm'
104
84
85
+ # CCACHE
105
86
ccache = ''
106
87
if self .ctx .ccache and bool (int (environ .get ('USE_CCACHE' , '1' ))):
107
88
# print('ccache found, will optimize builds')
@@ -110,18 +91,15 @@ def get_env(self, with_flags_in_cc=True, clang=False):
110
91
env ['NDK_CCACHE' ] = self .ctx .ccache
111
92
env .update ({k : v for k , v in environ .items () if k .startswith ('CCACHE_' )})
112
93
113
- if clang :
114
- llvm_dirname = split (
115
- glob (join (self .ctx .ndk_dir , 'toolchains' , 'llvm*' ))[- 1 ])[- 1 ]
116
- clang_path = join (self .ctx .ndk_dir , 'toolchains' , llvm_dirname ,
117
- 'prebuilt' , build_platform , 'bin' )
118
- environ ['PATH' ] = '{clang_path}:{path}' .format (
119
- clang_path = clang_path , path = environ ['PATH' ])
120
- exe = join (clang_path , 'clang' )
121
- execxx = join (clang_path , 'clang++' )
122
- else :
123
- exe = '{command_prefix}-gcc' .format (command_prefix = command_prefix )
124
- execxx = '{command_prefix}-g++' .format (command_prefix = command_prefix )
94
+ # Compiler: `CC` and `CXX`
95
+ llvm_dirname = split (
96
+ glob (join (self .ctx .ndk_dir , 'toolchains' , 'llvm*' ))[- 1 ])[- 1 ]
97
+ clang_path = join (self .ctx .ndk_dir , 'toolchains' , llvm_dirname ,
98
+ 'prebuilt' , build_platform , 'bin' )
99
+ environ ['PATH' ] = '{clang_path}:{path}' .format (
100
+ clang_path = clang_path , path = environ ['PATH' ])
101
+ exe = join (clang_path , 'clang' )
102
+ execxx = join (clang_path , 'clang++' )
125
103
126
104
cc = find_executable (exe , path = environ ['PATH' ])
127
105
if cc is None :
@@ -149,20 +127,27 @@ def get_env(self, with_flags_in_cc=True, clang=False):
149
127
execxx = execxx ,
150
128
ccache = ccache )
151
129
130
+ # Android's binaries
131
+ command_prefix = self .command_prefix
152
132
env ['AR' ] = '{}-ar' .format (command_prefix )
153
133
env ['RANLIB' ] = '{}-ranlib' .format (command_prefix )
154
- env ['LD' ] = '{}-ld' .format (command_prefix )
155
- env ['LDSHARED' ] = env ["CC" ] + " -pthread -shared " + \
156
- "-Wl,-O1 -Wl,-Bsymbolic-functions "
157
- if self .ctx .python_recipe and self .ctx .python_recipe .from_crystax :
158
- # For crystax python, we can't use the host python headers:
159
- env ["CFLAGS" ] += ' -I{}/sources/python/{}/include/python/' .\
160
- format (self .ctx .ndk_dir , self .ctx .python_recipe .version [0 :3 ])
161
134
env ['STRIP' ] = '{}-strip --strip-unneeded' .format (command_prefix )
162
- env ['MAKE' ] = 'make -j5'
135
+ env ['MAKE' ] = 'make -j{}' . format ( str ( cpu_count ()))
163
136
env ['READELF' ] = '{}-readelf' .format (command_prefix )
164
137
env ['NM' ] = '{}-nm' .format (command_prefix )
138
+ env ['LD' ] = '{}-ld' .format (command_prefix )
165
139
140
+ # Android's arch/toolchain
141
+ env ['ARCH' ] = self .arch
142
+ env ['NDK_API' ] = 'android-{}' .format (str (self .ctx .ndk_api ))
143
+ env ['TOOLCHAIN_PREFIX' ] = self .ctx .toolchain_prefix
144
+ env ['TOOLCHAIN_VERSION' ] = self .ctx .toolchain_version
145
+
146
+ # Custom linker options
147
+ env ['LDSHARED' ] = env ['CC' ] + (
148
+ ' -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions ' )
149
+
150
+ # Host python (used by some recipes)
166
151
hostpython_recipe = Recipe .get_recipe (
167
152
'host' + self .ctx .python_recipe .name , self .ctx )
168
153
env ['BUILDLIB_PATH' ] = join (
@@ -173,10 +158,11 @@ def get_env(self, with_flags_in_cc=True, clang=False):
173
158
174
159
env ['PATH' ] = environ ['PATH' ]
175
160
176
- env ['ARCH' ] = self .arch
177
- env ['NDK_API' ] = 'android-{}' .format (str (self .ctx .ndk_api ))
178
-
161
+ # Specific flags for crystax (can we remove this?)
179
162
if self .ctx .python_recipe and self .ctx .python_recipe .from_crystax :
163
+ # For crystax python, we can't use the host python headers:
164
+ env ["CPPFLAGS" ] += ' -I{}/sources/python/{}/include/python/' .\
165
+ format (self .ctx .ndk_dir , self .ctx .python_recipe .version [0 :3 ])
180
166
env ['CRYSTAX_PYTHON_VERSION' ] = self .ctx .python_recipe .version
181
167
182
168
return env
@@ -191,8 +177,9 @@ class ArchARM(Arch):
191
177
@property
192
178
def target (self ):
193
179
target_data = self .command_prefix .split ('-' )
194
- return '-' .join (
195
- ['armv7a' , 'none' , target_data [1 ], target_data [2 ]])
180
+ return '{triplet}{ndk_api}' .format (
181
+ triplet = '-' .join (['armv7a' , target_data [1 ], target_data [2 ]]),
182
+ ndk_api = self .ctx .ndk_api )
196
183
197
184
198
185
class ArchARMv7_a (ArchARM ):
0 commit comments