FazBrowse GitHub Viewer
|
Trending
|
URL:
|
Home
Tools:
[Download Repo ZIP]
[View Raw Code]
[Original HTTPS Page]
python-for-android/pythonforandroid/bootstrap.py at master · gdyuldin/python-for-android · GitHub
gdyuldin
/
python-for-android
Public
forked from
kivy/python-for-android
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
Security and quality
0
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security and quality
Insights
Expand file tree
Breadcrumbs
python-for-android
/
pythonforandroid
/
bootstrap.py
Copy path
More file actions
More file actions
Latest commit
History
History
History
295 lines (263 loc) · 11.3 KB
Breadcrumbs
python-for-android
/
pythonforandroid
/
bootstrap.py
Copy path
File metadata and controls
295 lines (263 loc) · 11.3 KB
Raw
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
from
os
.
path
import
(
join
,
dirname
,
isdir
,
splitext
,
basename
,
realpath
)
from
os
import
listdir
,
mkdir
import
sh
import
glob
import
json
import
importlib
from
pythonforandroid
.
logger
import
(
warning
,
shprint
,
info
,
logger
,
debug
,
error
)
from
pythonforandroid
.
util
import
(
current_directory
,
ensure_dir
,
temp_directory
,
which
)
from
pythonforandroid
.
recipe
import
Recipe
class
Bootstrap
(
object
):
'''An Android project template, containing recipe stuff for
compilation and templated fields for APK info.
'''
name
=
''
jni_subdir
=
'/jni'
ctx
=
None
bootstrap_dir
=
None
build_dir
=
None
dist_dir
=
None
dist_name
=
None
distribution
=
None
recipe_depends
=
[
'sdl2'
]
can_be_chosen_automatically
=
True
'''Determines whether the bootstrap can be chosen as one that
satisfies user requirements. If False, it will not be returned
from Bootstrap.get_bootstrap_from_recipes.
'''
# Other things a Bootstrap might need to track (maybe separately):
# ndk_main.c
# whitelist.txt
# blacklist.txt
@
property
def
dist_dir
(
self
):
'''The dist dir at which to place the finished distribution.'''
if
self
.
distribution
is
None
:
warning
(
'Tried to access {}.dist_dir, but {}.distribution '
'is None'
.
format
(
self
,
self
))
exit
(
1
)
return
self
.
distribution
.
dist_dir
@
property
def
jni_dir
(
self
):
return
self
.
name
+
self
.
jni_subdir
def
check_recipe_choices
(
self
):
'''Checks what recipes are being built to see which of the alternative
and optional dependencies are being used,
and returns a list of these.'''
recipes
=
[]
built_recipes
=
self
.
ctx
.
recipe_build_order
for
recipe
in
self
.
recipe_depends
:
if
isinstance
(
recipe
, (
tuple
,
list
)):
for
alternative
in
recipe
:
if
alternative
in
built_recipes
:
recipes
.
append
(
alternative
)
break
return
sorted
(
recipes
)
def
get_build_dir_name
(
self
):
choices
=
self
.
check_recipe_choices
()
dir_name
=
'-'
.
join
([
self
.
name
]
+
choices
)
return
dir_name
def
get_build_dir
(
self
):
return
join
(
self
.
ctx
.
build_dir
,
'bootstrap_builds'
,
self
.
get_build_dir_name
())
def
get_dist_dir
(
self
,
name
):
return
join
(
self
.
ctx
.
dist_dir
,
name
)
@
property
def
name
(
self
):
modname
=
self
.
__class__
.
__module__
return
modname
.
split
(
"."
,
2
)[
-
1
]
def
prepare_build_dir
(
self
):
'''Ensure that a build dir exists for the recipe. This same single
dir will be used for building all different archs.'''
self
.
build_dir
=
self
.
get_build_dir
()
shprint
(
sh
.
cp
,
'-r'
,
join
(
self
.
bootstrap_dir
,
'build'
),
self
.
build_dir
)
if
self
.
ctx
.
symlink_java_src
:
info
(
'Symlinking java src instead of copying'
)
shprint
(
sh
.
rm
,
'-r'
,
join
(
self
.
build_dir
,
'src'
))
shprint
(
sh
.
mkdir
,
join
(
self
.
build_dir
,
'src'
))
for
dirn
in
listdir
(
join
(
self
.
bootstrap_dir
,
'build'
,
'src'
)):
shprint
(
sh
.
ln
,
'-s'
,
join
(
self
.
bootstrap_dir
,
'build'
,
'src'
,
dirn
),
join
(
self
.
build_dir
,
'src'
))
with
current_directory
(
self
.
build_dir
):
with
open
(
'project.properties'
,
'w'
)
as
fileh
:
fileh
.
write
(
'target=android-{}'
.
format
(
self
.
ctx
.
android_api
))
def
prepare_dist_dir
(
self
,
name
):
# self.dist_dir = self.get_dist_dir(name)
ensure_dir
(
self
.
dist_dir
)
def
run_distribute
(
self
):
# print('Default bootstrap being used doesn\'t know how '
# 'to distribute...failing.')
# exit(1)
with
current_directory
(
self
.
dist_dir
):
info
(
'Saving distribution info'
)
with
open
(
'dist_info.json'
,
'w'
)
as
fileh
:
json
.
dump
({
'dist_name'
:
self
.
ctx
.
dist_name
,
'bootstrap'
:
self
.
ctx
.
bootstrap
.
name
,
'archs'
: [
arch
.
arch
for
arch
in
self
.
ctx
.
archs
],
'recipes'
:
self
.
ctx
.
recipe_build_order
+
self
.
ctx
.
python_modules
},
fileh
)
@
classmethod
def
list_bootstraps
(
cls
):
'''Find all the available bootstraps and return them.'''
forbidden_dirs
=
(
'__pycache__'
, )
bootstraps_dir
=
join
(
dirname
(
__file__
),
'bootstraps'
)
for
name
in
listdir
(
bootstraps_dir
):
if
name
in
forbidden_dirs
:
continue
filen
=
join
(
bootstraps_dir
,
name
)
if
isdir
(
filen
):
yield
name
@
classmethod
def
get_bootstrap_from_recipes
(
cls
,
recipes
,
ctx
):
'''Returns a bootstrap whose recipe requirements do not conflict with
the given recipes.'''
info
(
'Trying to find a bootstrap that matches the given recipes.'
)
bootstraps
=
[
cls
.
get_bootstrap
(
name
,
ctx
)
for
name
in
cls
.
list_bootstraps
()]
acceptable_bootstraps
=
[]
for
bs
in
bootstraps
:
if
not
bs
.
can_be_chosen_automatically
:
continue
possible_dependency_lists
=
expand_dependencies
(
bs
.
recipe_depends
)
for
possible_dependencies
in
possible_dependency_lists
:
ok
=
True
for
recipe
in
possible_dependencies
:
recipe
=
Recipe
.
get_recipe
(
recipe
,
ctx
)
if
any
([
conflict
in
recipes
for
conflict
in
recipe
.
conflicts
]):
ok
=
False
break
for
recipe
in
recipes
:
try
:
recipe
=
Recipe
.
get_recipe
(
recipe
,
ctx
)
except
IOError
:
conflicts
=
[]
else
:
conflicts
=
recipe
.
conflicts
if
any
([
conflict
in
possible_dependencies
for
conflict
in
conflicts
]):
ok
=
False
break
if
ok
:
acceptable_bootstraps
.
append
(
bs
)
info
(
'Found {} acceptable bootstraps: {}'
.
format
(
len
(
acceptable_bootstraps
),
[
bs
.
name
for
bs
in
acceptable_bootstraps
]))
if
acceptable_bootstraps
:
info
(
'Using the first of these: {}'
.
format
(
acceptable_bootstraps
[
0
].
name
))
return
acceptable_bootstraps
[
0
]
return
None
@
classmethod
def
get_bootstrap
(
cls
,
name
,
ctx
):
'''Returns an instance of a bootstrap with the given name.
This is the only way you should access a bootstrap class, as
it sets the bootstrap directory correctly.
'''
# AND: This method will need to check user dirs, and access
# bootstraps in a slightly different way
if
name
is
None
:
return
None
if
not
hasattr
(
cls
,
'bootstraps'
):
cls
.
bootstraps
=
{}
if
name
in
cls
.
bootstraps
:
return
cls
.
bootstraps
[
name
]
mod
=
importlib
.
import_module
(
'pythonforandroid.bootstraps.{}'
.
format
(
name
))
if
len
(
logger
.
handlers
)
>
1
:
logger
.
removeHandler
(
logger
.
handlers
[
1
])
bootstrap
=
mod
.
bootstrap
bootstrap
.
bootstrap_dir
=
join
(
ctx
.
root_dir
,
'bootstraps'
,
name
)
bootstrap
.
ctx
=
ctx
return
bootstrap
def
distribute_libs
(
self
,
arch
,
src_dirs
,
wildcard
=
'*'
,
dest_dir
=
"libs"
):
'''Copy existing arch libs from build dirs to current dist dir.'''
info
(
'Copying libs'
)
tgt_dir
=
join
(
dest_dir
,
arch
.
arch
)
ensure_dir
(
tgt_dir
)
for
src_dir
in
src_dirs
:
for
lib
in
glob
.
glob
(
join
(
src_dir
,
wildcard
)):
shprint
(
sh
.
cp
,
'-a'
,
lib
,
tgt_dir
)
def
distribute_javaclasses
(
self
,
javaclass_dir
,
dest_dir
=
"src"
):
'''Copy existing javaclasses from build dir to current dist dir.'''
info
(
'Copying java files'
)
ensure_dir
(
dest_dir
)
for
filename
in
glob
.
glob
(
javaclass_dir
):
shprint
(
sh
.
cp
,
'-a'
,
filename
,
dest_dir
)
def
distribute_aars
(
self
,
arch
):
'''Process existing .aar bundles and copy to current dist dir.'''
info
(
'Unpacking aars'
)
for
aar
in
glob
.
glob
(
join
(
self
.
ctx
.
aars_dir
,
'*.aar'
)):
self
.
_unpack_aar
(
aar
,
arch
)
def
_unpack_aar
(
self
,
aar
,
arch
):
'''Unpack content of .aar bundle and copy to current dist dir.'''
with
temp_directory
()
as
temp_dir
:
name
=
splitext
(
basename
(
aar
))[
0
]
jar_name
=
name
+
'.jar'
info
(
"unpack {} aar"
.
format
(
name
))
debug
(
" from {}"
.
format
(
aar
))
debug
(
" to {}"
.
format
(
temp_dir
))
shprint
(
sh
.
unzip
,
'-o'
,
aar
,
'-d'
,
temp_dir
)
jar_src
=
join
(
temp_dir
,
'classes.jar'
)
jar_tgt
=
join
(
'libs'
,
jar_name
)
debug
(
"copy {} jar"
.
format
(
name
))
debug
(
" from {}"
.
format
(
jar_src
))
debug
(
" to {}"
.
format
(
jar_tgt
))
ensure_dir
(
'libs'
)
shprint
(
sh
.
cp
,
'-a'
,
jar_src
,
jar_tgt
)
so_src_dir
=
join
(
temp_dir
,
'jni'
,
arch
.
arch
)
so_tgt_dir
=
join
(
'libs'
,
arch
.
arch
)
debug
(
"copy {} .so"
.
format
(
name
))
debug
(
" from {}"
.
format
(
so_src_dir
))
debug
(
" to {}"
.
format
(
so_tgt_dir
))
ensure_dir
(
so_tgt_dir
)
so_files
=
glob
.
glob
(
join
(
so_src_dir
,
'*.so'
))
for
f
in
so_files
:
shprint
(
sh
.
cp
,
'-a'
,
f
,
so_tgt_dir
)
def
strip_libraries
(
self
,
arch
):
info
(
'Stripping libraries'
)
if
self
.
ctx
.
python_recipe
.
from_crystax
:
info
(
'Python was loaded from CrystaX, skipping strip'
)
return
env
=
arch
.
get_env
()
strip
=
which
(
'arm-linux-androideabi-strip'
,
env
[
'PATH'
])
if
strip
is
None
:
warning
(
'Can
\'
t find strip in PATH...'
)
return
strip
=
sh
.
Command
(
strip
)
filens
=
shprint
(
sh
.
find
,
join
(
self
.
dist_dir
,
'private'
),
join
(
self
.
dist_dir
,
'libs'
),
'-iname'
,
'*.so'
,
_env
=
env
).
stdout
.
decode
(
'utf-8'
)
logger
.
info
(
'Stripping libraries in private dir'
)
for
filen
in
filens
.
split
(
'
\n
'
):
try
:
strip
(
filen
,
_env
=
env
)
except
sh
.
ErrorReturnCode_1
:
logger
.
debug
(
'Failed to strip '
+
filen
)
def
fry_eggs
(
self
,
sitepackages
):
info
(
'Frying eggs in {}'
.
format
(
sitepackages
))
for
d
in
listdir
(
sitepackages
):
rd
=
join
(
sitepackages
,
d
)
if
isdir
(
rd
)
and
d
.
endswith
(
'.egg'
):
info
(
' '
+
d
)
files
=
[
join
(
rd
,
f
)
for
f
in
listdir
(
rd
)
if
f
!=
'EGG-INFO'
]
if
files
:
shprint
(
sh
.
mv
,
'-t'
,
sitepackages
,
*
files
)
shprint
(
sh
.
rm
,
'-rf'
,
d
)
def
expand_dependencies
(
recipes
):
recipe_lists
=
[[]]
for
recipe
in
recipes
:
if
isinstance
(
recipe
, (
tuple
,
list
)):
new_recipe_lists
=
[]
for
alternative
in
recipe
:
for
old_list
in
recipe_lists
:
new_list
=
[
i
for
i
in
old_list
]
new_list
.
append
(
alternative
)
new_recipe_lists
.
append
(
new_list
)
recipe_lists
=
new_recipe_lists
else
:
for
old_list
in
recipe_lists
:
old_list
.
append
(
recipe
)
return
recipe_lists
Back
|
FazBrowse Home
|
New Git URL