Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions base/binaryplatforms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1067,12 +1067,20 @@ function select_platform(download_info::Dict, platform::AbstractPlatform = HostP
return nothing
end

# At this point, we may have multiple possibilities. E.g. if, in the future,
# Julia can be built without a direct dependency on libgfortran, we may match
# multiple tarballs that vary only within their libgfortran ABI. To narrow it
# down, we just sort by triplet, then pick the last one. This has the effect
# of generally choosing the latest release (e.g. a `libgfortran5` tarball
# rather than a `libgfortran3` tarball)
# At this point, we may have multiple possibilities. We now engage a multi-
# stage selection algorithm, where we first choose simpler matches over more
# complex matches. We define a simpler match as one that has fewer tags
# overall. As these candidate matches have already been filtered to match
# the given platform, the only other tags that exist are ones that are in
# addition to the tags declared by the platform. Hence, selecting the
# minimum in number of tags is equivalent to selecting the closest match.
min_tag_count = minimum(length(tags(p)) for p in ps)
filter!(p -> length(tags(p)) == min_tag_count, ps)

# Now we _still_ may continue to have multiple matches, so we now simply sort
# the candidate matches by their triplets and take the last one, so as to
# generally choose the latest release (e.g. a `libgfortran5` tarball over a
# `libgfortran3` tarball).
p = last(sort(ps, by = p -> triplet(p)))
return download_info[p]
end
Expand Down
17 changes: 14 additions & 3 deletions test/binaryplatforms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -315,8 +315,9 @@ end
P("x86_64", "linux"; libgfortran_version=v"5") => "linux8",

# Ambiguity test
P("aarch64", "linux"; libgfortran_version=v"3") => "linux4",
P("aarch64", "linux"; libgfortran_version=v"3") => "linux3",
P("aarch64", "linux"; libgfortran_version=v"3", libstdcxx_version=v"3.4.18") => "linux5",
P("aarch64", "linux"; libgfortran_version=v"3", libstdcxx_version=v"3.4.18", foo="bar") => "linux9",

# OS test
P("x86_64", "macos"; libgfortran_version=v"3") => "mac4",
Expand All @@ -327,8 +328,10 @@ end
@test select_platform(platforms, P("x86_64", "linux"; libgfortran_version=v"4")) == "linux7"

# Ambiguity test
@test select_platform(platforms, P("aarch64", "linux")) == "linux5"
@test select_platform(platforms, P("aarch64", "linux"; libgfortran_version=v"3")) == "linux5"
@test select_platform(platforms, P("aarch64", "linux")) == "linux3"
@test select_platform(platforms, P("aarch64", "linux"; libgfortran_version=v"3")) == "linux3"
# This one may be surprising, but we still match `linux3`, and since linux3 is shorter, we choose it.
@test select_platform(platforms, P("aarch64", "linux"; libgfortran_version=v"3", libstdcxx_version=v"3.4.18")) === "linux3"
@test select_platform(platforms, P("aarch64", "linux"; libgfortran_version=v"4")) === nothing

@test select_platform(platforms, P("x86_64", "macos")) == "mac4"
Expand All @@ -339,6 +342,14 @@ end

# Sorry, Alex. ;)
@test select_platform(platforms, P("x86_64", "freebsd")) === nothing

# The new "prefer shortest matching" algorithm is meant to be used to resolve ambiguities such as the following:
platforms = Dict(
# Typical binning test
P("x86_64", "linux") => "good",
P("x86_64", "linux"; sanitize="memory") => "bad",
)
@test select_platform(platforms, P("x86_64", "linux")) == "good"
end

@testset "Custom comparators" begin
Expand Down