11using UUIDs
22
3- export Dependency, BuildDependency, HostBuildDependency,
3+ export Dependency, RuntimeDependency, BuildDependency, HostBuildDependency,
44 is_host_dependency, is_target_dependency, is_build_dependency, is_runtime_dependency,
55 filter_platforms
66
@@ -18,11 +18,20 @@ Concrete subtypes of `AbstractDependency` are
1818
1919* [`Dependency`](@ref): a JLL package that is necessary for to build the package
2020 and to load the generated JLL package.
21+ * [`RuntimeDependency`](@ref): a JLL package that is necessary only at runtime. Its
22+ artifact will not be installed in the prefix during the build.
2123* [`BuildDependency`](@ref): a JLL package that is necessary only to build the
2224 package. This will not be a dependency of the generated JLL package.
2325* [`HostBuildDependency`](@ref): similar to `BuildDependency`, but it will
2426 install the artifact for the host platform, instead of that for the target
2527 platform.
28+
29+ Subtypes of `AbstractDependency` should define the following traits:
30+
31+ * [`is_host_dependency`](@ref)
32+ * [`is_target_dependency`](@ref)
33+ * [`is_build_dependency`](@ref)
34+ * [`is_runtime_dependency`](@ref)
2635"""
2736abstract type AbstractDependency end
2837
@@ -81,7 +90,7 @@ struct Dependency <: AbstractDependency
8190 platforms:: Vector{<:AbstractPlatform}
8291 function Dependency (pkg:: PkgSpec , build_version = nothing ; compat:: String = " " ,
8392 platforms:: Vector{<:AbstractPlatform} = [AnyPlatform ()])
84- if length (compat) > 0
93+ if ! isempty (compat)
8594 spec = PKG_VERSIONS. semver_spec (compat) # verify compat is valid
8695 if build_version === nothing
8796 # Since we usually want to build against the oldest compatible
@@ -107,6 +116,44 @@ is_host_dependency(::Dependency) = false
107116is_build_dependency (:: Dependency ) = true
108117is_runtime_dependency (:: Dependency ) = true
109118
119+ """
120+ RuntimeDependency(dep::Union{PackageSpec,String}; compat::String, platforms::Vector{<:AbstractPlatform})
121+
122+ Define a binary dependency that is only listed as dependency of the generated JLL package,
123+ but its artifact is not installed in the prefix during the build. The `dep` argument can be
124+ either a string with the name of the JLL package or a `Pkg.PackageSpec`.
125+
126+ The optional keyword argument `compat` can be used to specify a string for use
127+ in the `Project.toml` of the generated Julia package.
128+
129+ The optional keyword argument `platforms` is a vector of `AbstractPlatform`s which indicates
130+ for which platforms the dependency should be used. By default `platforms=[AnyPlatform()]`,
131+ to mean that the dependency is compatible with all platforms.
132+ """
133+ struct RuntimeDependency <: AbstractDependency
134+ pkg:: PkgSpec
135+ compat:: String # semver string for use in Project.toml of the JLL
136+ platforms:: Vector{<:AbstractPlatform}
137+ function RuntimeDependency (pkg:: PkgSpec ; compat:: String = " " ,
138+ platforms:: Vector{<:AbstractPlatform} = [AnyPlatform ()])
139+ if ! isempty (compat)
140+ spec = PKG_VERSIONS. semver_spec (compat) # verify compat is valid
141+ if pkg. version != PKG_VERSIONS. VersionSpec (" *" ) && ! (pkg. version in spec)
142+ throw (ArgumentError (" PackageSpec version and compat for $(pkg) are incompatible" ))
143+ end
144+ end
145+ return new (pkg, compat, platforms)
146+ end
147+ end
148+ RuntimeDependency (name:: AbstractString ; compat:: String = " " , platforms:: Vector{<:AbstractPlatform} = [AnyPlatform ()]) =
149+ RuntimeDependency (PackageSpec (; name); compat, platforms)
150+ is_host_dependency (:: RuntimeDependency ) = false
151+ is_build_dependency (:: RuntimeDependency ) = false
152+ is_runtime_dependency (:: RuntimeDependency ) = true
153+ # In some cases we may want to automatically convert a `RuntimeDependency` to a `Dependency`
154+ Base. convert (:: Type{Dependency} , dep:: RuntimeDependency ) =
155+ Dependency (dep. pkg; compat= dep. compat, platforms= dep. platforms)
156+
110157"""
111158 BuildDependency(dep::Union{PackageSpec,String}; platforms)
112159
@@ -250,7 +297,7 @@ version(d::Dependency) = __version(d.pkg.version)
250297getcompat (d:: AbstractDependency ) = " "
251298getcompat (d:: Dependency ) = d. compat
252299
253- for (type, type_descr) in ((Dependency, " dependency" ), (BuildDependency, " builddependency" ), (HostBuildDependency, " hostdependency" ))
300+ for (type, type_descr) in ((Dependency, " dependency" ), (RuntimeDependency, " runtimedependency " ), ( BuildDependency, " builddependency" ), (HostBuildDependency, " hostdependency" ))
254301 JSON. lower (d:: type ) = Dict (" type" => type_descr,
255302 " name" => d. pkg. name,
256303 " uuid" => string_or_nothing (d. pkg. uuid),
266313# dictionaries. This function converts the dictionary back to the appropriate
267314# AbstractDependency.
268315function dependencify (d:: Dict )
269- if d[" type" ] in (" dependency" , " builddependency" , " hostdependency" )
316+ if d[" type" ] in (" dependency" , " runtimedependency " , " builddependency" , " hostdependency" )
270317 uuid = isnothing (d[" uuid" ]) ? d[" uuid" ] : UUID (d[" uuid" ])
271318 compat = d[" compat" ]
272319 version = PKG_VERSIONS. VersionSpec (VersionNumber (d[" version-major" ], d[" version-minor" ], d[" version-patch" ]))
@@ -275,6 +322,8 @@ function dependencify(d::Dict)
275322 platforms = parse_platform .(d[" platforms" ])
276323 if d[" type" ] == " dependency"
277324 return Dependency (spec; compat, platforms)
325+ elseif d[" type" ] == " runtimedependency"
326+ return RuntimeDependency (spec; compat, platforms)
278327 elseif d[" type" ] == " builddependency"
279328 return BuildDependency (spec; platforms)
280329 elseif d[" type" ] == " hostdependency"
0 commit comments