@@ -24,7 +24,7 @@ class Distribution(object):
2424 ndk_api = None
2525
2626 archs = []
27- '''The arch targets that the dist is built for.'''
27+ '''The names of the arch targets that the dist is built for.'''
2828
2929 recipes = []
3030
@@ -42,12 +42,19 @@ def __repr__(self):
4242 return str (self )
4343
4444 @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+ ):
5158 '''Takes information about the distribution, and decides what kind of
5259 distribution it will be.
5360
@@ -60,6 +67,12 @@ def get_distribution(cls, ctx, name=None, recipes=[],
6067 name : str
6168 The name of the distribution. If a dist with this name already '
6269 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.
6376 recipes : list
6477 The recipes that the distribution must contain.
6578 force_download: bool
@@ -77,17 +90,24 @@ def get_distribution(cls, ctx, name=None, recipes=[],
7790 a new one with the current requirements.
7891 '''
7992
80- existing_dists = Distribution .get_distributions (ctx )
93+ possible_dists = Distribution .get_distributions (ctx )
8194
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
8397
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
8799 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+
89104 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 ]
91111
92112 # 1) Check if any existing dists meet the requirements
93113 _possible_dists = []
@@ -110,35 +130,37 @@ def get_distribution(cls, ctx, name=None, recipes=[],
110130 else :
111131 info ('No existing dists meet the given requirements!' )
112132
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
114134 for dist in possible_dists :
115135 if force_build :
116136 continue
117137 if ndk_api is not None and dist .ndk_api != ndk_api :
118138 continue
139+ if arch_name is not None and arch_name not in dist .archs :
140+ continue
119141 if (set (dist .recipes ) == set (recipes ) or
120142 (set (recipes ).issubset (set (dist .recipes )) and
121143 not require_perfect_match )):
122144 info_notify ('{} has compatible recipes, using this one'
123145 .format (dist .name ))
124146 return dist
125147
126- assert len (possible_dists ) < 2
127-
128148 # If there was a name match but we didn't already choose it,
129149 # then the existing dist is incompatible with the requested
130150 # 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 :
132152 raise BuildInterruptingException (
133153 'Asked for dist with name {name} with recipes ({req_recipes}) and '
134154 'NDK API {req_ndk_api}, but a dist '
135155 'with this name already exists and has either incompatible recipes '
136156 '({dist_recipes}) or NDK API {dist_ndk_api}' .format (
137157 name = name ,
138158 req_ndk_api = ndk_api ,
139- dist_ndk_api = name_match_dist .ndk_api ,
159+ dist_ndk_api = folder_match_dist .ndk_api ,
140160 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
142164
143165 # If we got this far, we need to build a new dist
144166 dist = Distribution (ctx )
@@ -152,9 +174,16 @@ def get_distribution(cls, ctx, name=None, recipes=[],
152174 name = filen .format (i )
153175
154176 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+ )
156184 dist .recipes = recipes
157185 dist .ndk_api = ctx .ndk_api
186+ dist .archs = [arch_name ]
158187
159188 return dist
160189
@@ -182,7 +211,7 @@ def get_distributions(cls, ctx, extra_dist_dirs=[]):
182211 with open (join (folder , 'dist_info.json' )) as fileh :
183212 dist_info = json .load (fileh )
184213 dist = cls (ctx )
185- dist .name = folder . split ( '/' )[ - 1 ]
214+ dist .name = dist_info [ 'dist_name' ]
186215 dist .dist_dir = folder
187216 dist .needs_build = False
188217 dist .recipes = dist_info ['recipes' ]
@@ -210,7 +239,7 @@ def save_info(self, dirn):
210239 with current_directory (dirn ):
211240 info ('Saving distribution info' )
212241 with open ('dist_info.json' , 'w' ) as fileh :
213- json .dump ({'dist_name' : self .ctx . dist_name ,
242+ json .dump ({'dist_name' : self .name ,
214243 'bootstrap' : self .ctx .bootstrap .name ,
215244 'archs' : [arch .arch for arch in self .ctx .archs ],
216245 'ndk_api' : self .ctx .ndk_api ,
@@ -236,3 +265,23 @@ def pretty_log_dists(dists, log_func=info):
236265
237266 for line in infos :
238267 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