11using UUIDs
22
33export Dependency, BuildDependency, HostBuildDependency,
4- is_host_dependency, is_target_dependency, is_build_dependency, is_runtime_dependency
4+ is_host_dependency, is_target_dependency, is_build_dependency, is_runtime_dependency,
5+ filter_platforms
56
67
78# Pkg.PackageSpec return different types in different Julia versions so...
@@ -54,7 +55,7 @@ Return whether `dep` is a runtime dependency or not.
5455is_runtime_dependency
5556
5657"""
57- Dependency(dep::Union{PackageSpec,String}, build_version; compat)
58+ Dependency(dep::Union{PackageSpec,String}, build_version; compat, platforms )
5859
5960Define a binary dependency that is necessary to build the package and load the
6061generated JLL package. The argument can be either a string with the name of the
@@ -67,12 +68,19 @@ The optional keyword argument `compat` can be used to specify a string for use
6768in the `Project.toml` of the generated Julia package. If `compat` is non-empty
6869and `build_version` is not passed, the latter defaults to the minimum version
6970compatible with the `compat` specifier.
71+
72+ The optional keyword argument `platforms` is a vector of `AbstractPlatform`s
73+ which indicates for which platforms the dependency should be used. By default
74+ `platforms=[AnyPlatform()]`, to mean that the dependency is compatible with all
75+ platforms.
7076"""
7177struct Dependency <: AbstractDependency
7278 pkg:: PkgSpec
7379 build_version:: Union{VersionNumber,Nothing}
7480 compat:: String # semver string for use in Project.toml of the JLL
75- function Dependency (pkg:: PkgSpec , build_version = nothing ; compat:: String = " " )
81+ platforms:: Vector{<:AbstractPlatform}
82+ function Dependency (pkg:: PkgSpec , build_version = nothing ; compat:: String = " " ,
83+ platforms:: Vector{<:AbstractPlatform} = [AnyPlatform ()])
7684 if length (compat) > 0
7785 spec = PKG_VERSIONS. semver_spec (compat) # verify compat is valid
7886 if build_version === nothing
@@ -88,45 +96,64 @@ struct Dependency <: AbstractDependency
8896 throw (ArgumentError (" PackageSpec version and compat for $(pkg) are incompatible" ))
8997 end
9098 end
91- new (pkg, build_version, compat)
99+ new (pkg, build_version, compat, platforms )
92100 end
93101end
94- function Dependency (dep:: AbstractString , build_version = nothing ; compat:: String = " " )
95- return Dependency (PackageSpec (; name = dep), build_version, compat = compat)
102+ function Dependency (dep:: AbstractString , build_version = nothing ;
103+ compat:: String = " " , platforms:: Vector{<:AbstractPlatform} = [AnyPlatform ()])
104+ return Dependency (PackageSpec (; name = dep), build_version; compat, platforms)
96105end
97106is_host_dependency (:: Dependency ) = false
98107is_build_dependency (:: Dependency ) = true
99108is_runtime_dependency (:: Dependency ) = true
100109
101110"""
102- BuildDependency(dep::Union{PackageSpec,String})
111+ BuildDependency(dep::Union{PackageSpec,String}; platforms )
103112
104113Define a binary dependency that is necessary only to build the package. The
105- argument can be either a string with the name of the JLL package or a
114+ `dep` argument can be either a string with the name of the JLL package or a
106115`Pkg.PackageSpec`.
116+
117+ The optional keyword argument `platforms` is a vector of `AbstractPlatform`s
118+ which indicates for which platforms the dependency should be used. By default
119+ `platforms=[AnyPlatform()]`, to mean that the dependency is compatible with all
120+ platforms.
107121"""
108122struct BuildDependency <: AbstractDependency
109123 pkg:: PkgSpec
124+ platforms:: Vector{<:AbstractPlatform}
125+ BuildDependency (pkg:: PkgSpec ; platforms:: Vector{<:AbstractPlatform} = [AnyPlatform ()]) =
126+ new (pkg, platforms)
110127end
111- BuildDependency (dep:: AbstractString ) = BuildDependency (PackageSpec (; name = dep))
128+ BuildDependency (dep:: AbstractString ; platforms:: Vector{<:AbstractPlatform} = [AnyPlatform ()]) =
129+ BuildDependency (PackageSpec (; name = dep); platforms)
112130is_host_dependency (:: BuildDependency ) = false
113131is_build_dependency (:: BuildDependency ) = true
114132is_runtime_dependency (:: BuildDependency ) = false
115133
116134"""
117- HostBuildDependency(dep::Union{PackageSpec,String})
135+ HostBuildDependency(dep::Union{PackageSpec,String}; platforms )
118136
119137Define a binary dependency that is necessary only to build the package.
120138Different from the [`BuildDependency`](@ref), the artifact for the host
121139platform will be installed, instead of that for the target platform.
122140
123- The argument can be either a string with the name of the JLL package or a
141+ The `dep` argument can be either a string with the name of the JLL package or a
124142`Pkg.PackageSpec`.
143+
144+ The optional keyword argument `platforms` is a vector of `AbstractPlatform`s
145+ which indicates for which platforms the dependency should be used. By default
146+ `platforms=[AnyPlatform()]`, to mean that the dependency is compatible with all
147+ platforms.
125148"""
126149struct HostBuildDependency <: AbstractDependency
127150 pkg:: PkgSpec
151+ platforms:: Vector{<:AbstractPlatform}
152+ HostBuildDependency (pkg:: PkgSpec ; platforms:: Vector{<:AbstractPlatform} = [AnyPlatform ()]) =
153+ new (pkg, platforms)
128154end
129- HostBuildDependency (dep:: AbstractString ) = HostBuildDependency (PackageSpec (; name = dep))
155+ HostBuildDependency (dep:: AbstractString ; platforms:: Vector{<:AbstractPlatform} = [AnyPlatform ()]) =
156+ HostBuildDependency (PackageSpec (; name = dep); platforms)
130157is_host_dependency (:: HostBuildDependency ) = true
131158is_build_dependency (:: HostBuildDependency ) = true
132159is_runtime_dependency (:: HostBuildDependency ) = false
@@ -145,12 +172,20 @@ end
145172getname (x:: PkgSpec ) = x. name
146173getname (x:: AbstractDependency ) = getname (getpkg (x))
147174
175+ """
176+ filter_platforms(deps::AbstractVector{<:AbstractDependency}, p::AbstractPlatform)
177+
178+ Filter the dependencies `deps` which are compatible with platform `p`.
179+ """
180+ filter_platforms (deps:: AbstractVector{<:AbstractDependency} , p:: AbstractPlatform ) =
181+ [dep for dep in deps if any (x -> platforms_match (x, p), dep. platforms)]
182+
148183# Wrapper around `Pkg.Types.registry_resolve!` which keeps the type of the
149184# dependencies. TODO : improve this
150185function registry_resolve! (ctx, dependencies:: Vector{<:AbstractDependency} )
151186 resolved_dependencies = Pkg. Types. registry_resolve! (ctx, getpkg .(dependencies))
152187 for idx in eachindex (dependencies)
153- dependencies[idx] = typeof (dependencies[idx])(resolved_dependencies[idx])
188+ dependencies[idx] = typeof (dependencies[idx])(resolved_dependencies[idx]; platforms = dependencies[idx] . platforms )
154189 end
155190 return dependencies
156191end
@@ -222,7 +257,9 @@ for (type, type_descr) in ((Dependency, "dependency"), (BuildDependency, "buildd
222257 " compat" => getcompat (d),
223258 " version-major" => major (version (d)),
224259 " version-minor" => minor (version (d)),
225- " version-patch" => patch (version (d)))
260+ " version-patch" => patch (version (d)),
261+ " platforms" => triplet .(d. platforms),
262+ )
226263end
227264
228265# When deserialiasing the JSON file, the dependencies are in the form of
@@ -235,12 +272,13 @@ function dependencify(d::Dict)
235272 version = VersionNumber (d[" version-major" ], d[" version-minor" ], d[" version-patch" ])
236273 version = version == v " 0" ? nothing : version
237274 spec = PackageSpec (; name = d[" name" ], uuid = uuid, version = version)
275+ platforms = parse_platform .(d[" platforms" ])
238276 if d[" type" ] == " dependency"
239- return Dependency (spec; compat = compat )
277+ return Dependency (spec; compat, platforms )
240278 elseif d[" type" ] == " builddependency"
241- return BuildDependency (spec)
279+ return BuildDependency (spec; platforms )
242280 elseif d[" type" ] == " hostdependency"
243- return HostBuildDependency (spec)
281+ return HostBuildDependency (spec; platforms )
244282 end
245283 end
246284 error (" Cannot convert to dependency" )
0 commit comments