@@ -40,10 +40,10 @@ struct Platform <: AbstractPlatform
40
40
# The "compare strategy" allows selective overriding on how a tag is compared
41
41
compare_strategies:: Dict{String,Function}
42
42
43
- function Platform (arch:: String , os:: String ;
43
+ # Passing `tags` as a `Dict` avoids the need to infer different NamedTuple specializations
44
+ function Platform (arch:: String , os:: String , _tags:: Dict{String} ;
44
45
validate_strict:: Bool = false ,
45
- compare_strategies:: Dict{String,<:Function} = Dict {String,Function} (),
46
- kwargs... )
46
+ compare_strategies:: Dict{String,<:Function} = Dict {String,Function} ())
47
47
# A wee bit of normalization
48
48
os = lowercase (os)
49
49
arch = CPUID. normalize_arch (arch)
@@ -52,8 +52,9 @@ struct Platform <: AbstractPlatform
52
52
" arch" => arch,
53
53
" os" => os,
54
54
)
55
- for (tag, value) in kwargs
56
- tag = lowercase (string (tag:: Symbol ))
55
+ for (tag, value) in _tags
56
+ value = value:: Union{String,VersionNumber,Nothing}
57
+ tag = lowercase (tag)
57
58
if tag ∈ (" arch" , " os" )
58
59
throw (ArgumentError (" Cannot double-pass key $(tag) " ))
59
60
end
@@ -70,8 +71,8 @@ struct Platform <: AbstractPlatform
70
71
if tag ∈ (" libgfortran_version" , " libstdcxx_version" , " os_version" )
71
72
if isa (value, VersionNumber)
72
73
value = string (value)
73
- elseif isa (value, AbstractString )
74
- v = tryparse (VersionNumber, String ( value) :: String )
74
+ elseif isa (value, String )
75
+ v = tryparse (VersionNumber, value)
75
76
if isa (v, VersionNumber)
76
77
value = string (v)
77
78
end
@@ -110,6 +111,19 @@ struct Platform <: AbstractPlatform
110
111
end
111
112
end
112
113
114
+ # Keyword interface (to avoid inference of specialized NamedTuple methods, use the Dict interface for `tags`)
115
+ function Platform (arch:: String , os:: String ;
116
+ validate_strict:: Bool = false ,
117
+ compare_strategies:: Dict{String,<:Function} = Dict {String,Function} (),
118
+ kwargs... )
119
+ tags = Dict {String,Any} (String (tag):: String => tagvalue (value) for (tag, value) in kwargs)
120
+ return Platform (arch, os, tags; validate_strict, compare_strategies)
121
+ end
122
+
123
+ tagvalue (v:: Union{String,VersionNumber,Nothing} ) = v
124
+ tagvalue (v:: Symbol ) = String (v)
125
+ tagvalue (v:: AbstractString ) = convert (String, v):: String
126
+
113
127
# Simple tag insertion that performs a little bit of validation
114
128
function add_tag! (tags:: Dict{String,String} , tag:: String , value:: String )
115
129
# I know we said only alphanumeric and dots, but let's be generous so that we can expand
@@ -698,21 +712,22 @@ function Base.parse(::Type{Platform}, triplet::AbstractString; validate_strict::
698
712
end
699
713
700
714
# Extract the information we're interested in:
715
+ tags = Dict {String,Any} ()
701
716
arch = get_field (m, arch_mapping)
702
717
os = get_field (m, os_mapping)
703
- libc = get_field (m, libc_mapping)
704
- call_abi = get_field (m, call_abi_mapping)
705
- libgfortran_version = get_field (m, libgfortran_version_mapping)
706
- libstdcxx_version = get_field (m, libstdcxx_version_mapping)
707
- cxxstring_abi = get_field (m, cxxstring_abi_mapping)
718
+ tags[ " libc" ] = get_field (m, libc_mapping)
719
+ tags[ " call_abi" ] = get_field (m, call_abi_mapping)
720
+ tags[ " libgfortran_version" ] = get_field (m, libgfortran_version_mapping)
721
+ tags[ " libstdcxx_version" ] = get_field (m, libstdcxx_version_mapping)
722
+ tags[ " cxxstring_abi" ] = get_field (m, cxxstring_abi_mapping)
708
723
function split_tags (tagstr)
709
724
tag_fields = split (tagstr, " -" ; keepempty= false )
710
725
if isempty (tag_fields)
711
726
return Pair{String,String}[]
712
727
end
713
- return map (v -> Symbol (v[1 ]) => v[2 ], split .(tag_fields, " +" ))
728
+ return map (v -> String (v[1 ]) => String ( v[2 ]) , split .(tag_fields, " +" ))
714
729
end
715
- tags = split_tags (m[" tags" ])
730
+ merge! ( tags, Dict ( split_tags (m[" tags" ])) )
716
731
717
732
# Special parsing of os version number, if any exists
718
733
function extract_os_version (os_name, pattern)
@@ -729,18 +744,9 @@ function Base.parse(::Type{Platform}, triplet::AbstractString; validate_strict::
729
744
if os == " freebsd"
730
745
os_version = extract_os_version (" freebsd" , r" .*freebsd([\d .]+)" )
731
746
end
747
+ tags[" os_version" ] = os_version
732
748
733
- return Platform (
734
- arch, os;
735
- validate_strict,
736
- libc,
737
- call_abi,
738
- libgfortran_version,
739
- cxxstring_abi,
740
- libstdcxx_version,
741
- os_version,
742
- tags... ,
743
- )
749
+ return Platform (arch, os, tags; validate_strict)
744
750
end
745
751
throw (ArgumentError (" Platform `$(triplet) ` is not an officially supported platform" ))
746
752
end
@@ -1067,4 +1073,9 @@ function select_platform(download_info::Dict, platform::AbstractPlatform = HostP
1067
1073
return download_info[p]
1068
1074
end
1069
1075
1076
+ # precompiles to reduce latency (see https://github.com/JuliaLang/julia/pull/43990#issuecomment-1025692379)
1077
+ Dict {Platform,String} ()[HostPlatform ()] = " "
1078
+ Platform (" x86_64" , " linux" , Dict {String,Any} (); validate_strict= true )
1079
+ Platform (" x86_64" , " linux" , Dict {String,String} (); validate_strict= false ) # called this way from Artifacts.unpack_platform
1080
+
1070
1081
end # module
0 commit comments