@@ -24,7 +24,7 @@ class Distribution(object):
24
24
ndk_api = None
25
25
26
26
archs = []
27
- '''The arch targets that the dist is built for.'''
27
+ '''The names of the arch targets that the dist is built for.'''
28
28
29
29
recipes = []
30
30
@@ -42,12 +42,19 @@ def __repr__(self):
42
42
return str (self )
43
43
44
44
@classmethod
45
- def get_distribution (cls , ctx , name = None , recipes = [],
46
- ndk_api = None ,
47
- force_build = False ,
48
- extra_dist_dirs = [],
49
- require_perfect_match = False ,
50
- allow_replace_dist = True ):
45
+ def get_distribution (
46
+ cls ,
47
+ ctx ,
48
+ * ,
49
+ arch_name , # required keyword argument: there is no sensible default
50
+ name = None ,
51
+ recipes = [],
52
+ ndk_api = None ,
53
+ force_build = False ,
54
+ extra_dist_dirs = [],
55
+ require_perfect_match = False ,
56
+ allow_replace_dist = True
57
+ ):
51
58
'''Takes information about the distribution, and decides what kind of
52
59
distribution it will be.
53
60
@@ -60,6 +67,12 @@ def get_distribution(cls, ctx, name=None, recipes=[],
60
67
name : str
61
68
The name of the distribution. If a dist with this name already '
62
69
exists, it will be used.
70
+ ndk_api : int
71
+ The NDK API to compile against, included in the dist because it cannot
72
+ be changed later during APK packaging.
73
+ arch_name : str
74
+ The target architecture name to compile against, included in the dist because
75
+ it cannot be changed later during APK packaging.
63
76
recipes : list
64
77
The recipes that the distribution must contain.
65
78
force_download: bool
@@ -77,17 +90,24 @@ def get_distribution(cls, ctx, name=None, recipes=[],
77
90
a new one with the current requirements.
78
91
'''
79
92
80
- existing_dists = Distribution .get_distributions (ctx )
93
+ possible_dists = Distribution .get_distributions (ctx )
81
94
82
- possible_dists = existing_dists
95
+ # Will hold dists that would be built in the same folder as an existing dist
96
+ folder_match_dist = None
83
97
84
- name_match_dist = None
85
-
86
- # 0) Check if a dist with that name already exists
98
+ # 0) Check if a dist with that name and architecture already exists
87
99
if name is not None and name :
88
- possible_dists = [d for d in possible_dists if d .name == name ]
100
+ possible_dists = [
101
+ d for d in possible_dists if
102
+ (d .name == name ) and (arch_name in d .archs )]
103
+
89
104
if possible_dists :
90
- name_match_dist = possible_dists [0 ]
105
+ # There should only be one folder with a given dist name *and* arch.
106
+ # We could check that here, but for compatibility let's let it slide
107
+ # and just record the details of one of them. We only use this data to
108
+ # possibly fail the build later, so it doesn't really matter if there
109
+ # was more than one clash.
110
+ folder_match_dist = possible_dists [0 ]
91
111
92
112
# 1) Check if any existing dists meet the requirements
93
113
_possible_dists = []
@@ -110,35 +130,37 @@ def get_distribution(cls, ctx, name=None, recipes=[],
110
130
else :
111
131
info ('No existing dists meet the given requirements!' )
112
132
113
- # If any dist has perfect recipes and ndk API, return it
133
+ # If any dist has perfect recipes, arch and NDK API, return it
114
134
for dist in possible_dists :
115
135
if force_build :
116
136
continue
117
137
if ndk_api is not None and dist .ndk_api != ndk_api :
118
138
continue
139
+ if arch_name is not None and arch_name not in dist .archs :
140
+ continue
119
141
if (set (dist .recipes ) == set (recipes ) or
120
142
(set (recipes ).issubset (set (dist .recipes )) and
121
143
not require_perfect_match )):
122
144
info_notify ('{} has compatible recipes, using this one'
123
145
.format (dist .name ))
124
146
return dist
125
147
126
- assert len (possible_dists ) < 2
127
-
128
148
# If there was a name match but we didn't already choose it,
129
149
# then the existing dist is incompatible with the requested
130
150
# configuration and the build cannot continue
131
- if name_match_dist is not None and not allow_replace_dist :
151
+ if folder_match_dist is not None and not allow_replace_dist :
132
152
raise BuildInterruptingException (
133
153
'Asked for dist with name {name} with recipes ({req_recipes}) and '
134
154
'NDK API {req_ndk_api}, but a dist '
135
155
'with this name already exists and has either incompatible recipes '
136
156
'({dist_recipes}) or NDK API {dist_ndk_api}' .format (
137
157
name = name ,
138
158
req_ndk_api = ndk_api ,
139
- dist_ndk_api = name_match_dist .ndk_api ,
159
+ dist_ndk_api = folder_match_dist .ndk_api ,
140
160
req_recipes = ', ' .join (recipes ),
141
- dist_recipes = ', ' .join (name_match_dist .recipes )))
161
+ dist_recipes = ', ' .join (folder_match_dist .recipes )))
162
+
163
+ assert len (possible_dists ) < 2
142
164
143
165
# If we got this far, we need to build a new dist
144
166
dist = Distribution (ctx )
@@ -152,9 +174,16 @@ def get_distribution(cls, ctx, name=None, recipes=[],
152
174
name = filen .format (i )
153
175
154
176
dist .name = name
155
- dist .dist_dir = join (ctx .dist_dir , dist .name )
177
+ dist .dist_dir = join (
178
+ ctx .dist_dir ,
179
+ generate_dist_folder_name (
180
+ name ,
181
+ [arch_name ] if arch_name is not None else None ,
182
+ )
183
+ )
156
184
dist .recipes = recipes
157
185
dist .ndk_api = ctx .ndk_api
186
+ dist .archs = [arch_name ]
158
187
159
188
return dist
160
189
@@ -182,7 +211,7 @@ def get_distributions(cls, ctx, extra_dist_dirs=[]):
182
211
with open (join (folder , 'dist_info.json' )) as fileh :
183
212
dist_info = json .load (fileh )
184
213
dist = cls (ctx )
185
- dist .name = folder . split ( '/' )[ - 1 ]
214
+ dist .name = dist_info [ 'dist_name' ]
186
215
dist .dist_dir = folder
187
216
dist .needs_build = False
188
217
dist .recipes = dist_info ['recipes' ]
@@ -210,7 +239,7 @@ def save_info(self, dirn):
210
239
with current_directory (dirn ):
211
240
info ('Saving distribution info' )
212
241
with open ('dist_info.json' , 'w' ) as fileh :
213
- json .dump ({'dist_name' : self .ctx . dist_name ,
242
+ json .dump ({'dist_name' : self .name ,
214
243
'bootstrap' : self .ctx .bootstrap .name ,
215
244
'archs' : [arch .arch for arch in self .ctx .archs ],
216
245
'ndk_api' : self .ctx .ndk_api ,
@@ -236,3 +265,23 @@ def pretty_log_dists(dists, log_func=info):
236
265
237
266
for line in infos :
238
267
log_func ('\t ' + line )
268
+
269
+
270
+ def generate_dist_folder_name (base_dist_name , arch_names = None ):
271
+ """Generate the distribution folder name to use, based on a
272
+ combination of the input arguments.
273
+
274
+ Parameters
275
+ ----------
276
+ base_dist_name : str
277
+ The core distribution identifier string
278
+ arch_names : list of str
279
+ The architecture compile targets
280
+ """
281
+ if arch_names is None :
282
+ arch_names = ["no_arch_specified" ]
283
+
284
+ return '{}__{}' .format (
285
+ base_dist_name ,
286
+ '_' .join (arch_names )
287
+ )
0 commit comments