Skip to content

Commit b50d66e

Browse files
committed
Try harder to keep targets in a consistent order
For some reason the order of targets is different in the macos CI compared to other systems. The Target class does not define a total order, so try to use a consistent sorting algorithm that does not depend on the underlying python implementation.
1 parent 7592c28 commit b50d66e

File tree

1 file changed

+21
-25
lines changed

1 file changed

+21
-25
lines changed

pycheribuild/targets.py

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -194,36 +194,22 @@ def reset(self) -> None:
194194
self._project_class.targets_reset()
195195

196196
# noinspection PyProtectedMember
197-
def __lt__(self, other: "Target"):
198-
# print(self, "__lt__", other)
197+
def should_run_before(self, other: "Target"):
199198
# if this target is one of the dependencies order it before
200199
other_deps = other.project_class.cached_full_dependencies()
201200
# print("other deps:", other_deps)
202201
if self in other_deps:
203202
# print(self, "is in", other, "deps -> is less")
204203
return True
205204
# and if it is the other way around we are not less
206-
if other in self.project_class.cached_full_dependencies():
205+
self_deps = self.project_class.cached_full_dependencies()
206+
if other in self_deps:
207207
# print(other, "is in", self, "deps -> is greater")
208208
return False
209-
if other.name.startswith("run") and not self.name.startswith("run"):
210-
return True # run must be executed last
211-
elif self.name.startswith("run"):
212-
return False
213-
if other.name.startswith("disk-image") and not self.name.startswith("disk-image"):
214-
return True # disk-image should be done just before run
215-
elif self.name.startswith("disk-image"):
216-
return False
217-
# print(self, "is not in", other, "deps -> is not less")
218-
# otherwise just keep everything in order
219-
return False
220-
# This was previously done
221-
# ownDeps = self.project_class.all_dependency_names()
222-
# if len(ownDeps) < len(other_deps):
223-
# return True
224-
# if len(ownDeps) > len(other_deps):
225-
# return False
226-
# return self.name < other.name # not a dep and number of deps is the same -> compare name
209+
# Run targets come last, preceded by disk-image targets. Otherwise the order is unspecified
210+
self_order = (self.name.startswith("run"), self.name.startswith("disk-image"))
211+
other_order = (other.name.startswith("run"), other.name.startswith("disk-image"))
212+
return self_order < other_order
227213

228214
def __repr__(self) -> str:
229215
return "<Target " + self.name + ">"
@@ -492,10 +478,20 @@ def get_target(
492478

493479
@staticmethod
494480
def sort_in_dependency_order(targets: "typing.Iterable[Target]") -> "list[Target]":
495-
# pythons sorted() is guaranteed to be stable:
496-
sorted_targets = list(sorted(targets))
497-
# remove duplicates (insert into an orderdict to keep order
498-
return list(OrderedDict((x, True) for x in sorted_targets).keys())
481+
# remove duplicates (insert into an orderdict to keep order)
482+
result = list(OrderedDict((x, True) for x in targets).keys())
483+
n = len(result)
484+
if n <= 1:
485+
return result
486+
for i in range(0, n):
487+
tgt_i = result[i]
488+
for j in range(i + 1, n):
489+
tgt_j = result[j]
490+
if tgt_j.should_run_before(tgt_i):
491+
assert not tgt_i.should_run_before(tgt_j), "circular dependency found"
492+
tgt_i = result.pop(j)
493+
result.insert(i, tgt_i)
494+
return result
499495

500496
def get_all_targets(self, explicit_targets: "list[Target]", config: CheriConfig) -> "list[Target]":
501497
chosen_targets: "list[Target]" = []

0 commit comments

Comments
 (0)