JuliaPackaging / BinaryBuilder.jl

Binary Dependency Builder for Julia
https://binarybuilder.org
Other
391 stars 100 forks source link

Add a way to "inherit" default platform list from another JLL #957

Open fingolfin opened 3 years ago

fingolfin commented 3 years ago

Sometimes platform limitations for JLLs come from portability restrictions in the software being packaged up.

But in other cases, the restrictions come only from other JLLs being used. For example, anything which requires libjulia_jll won't work on 32bit musl libc systems. And anything using libcxxwrap_julia_jll necessarily must inherit its currently rather peculiar set of platforms (or a subset thereof).

It would be nice if there was a way to specify that the (initial) set of "supported platforms" should be derived from the supported platforms of one or more other JLLs which are dependencies of the currently being built JLL.

At first I though that one could even change the default list of supported platforms to "the intersection of all JLL dependencies". However, in general this would probably be too restrictive, as some JLLs might be "optional" dependencies, so there would have to be a way to exclude those. Also, this is further complicated by the fact that some dependencies might be using expand_cxxstring_abis, other are not using it, and some (like libcxxwrap_julia_jll right now) might even use some platforms with manually expanded cxxstrings abi specification.

So, I'd already be happy if there was a command like supported_platforms_of_jll("Some_jll") which returns the supported platforms of "Some_jll". That would already simplify a bunch of JLLs, and more importantly, make it clearer in those packages where their platform restrictions come from, and also make it easier to keep those packages in sync with their "template" package. E.g. hopefully soon libcxxwrap_julia_jll will support many more platforms; afterwards the ca. 10 other JLLs using it ought to be adapted to use a similar list of supported platforms.

giordano commented 3 years ago

I think you should be able to achieve this by defining a fancy toy which parses another build_tarballs.jl script, similarly to what recursively_regenerate_jlls.jl does

fingolfin commented 3 years ago

Yeah, that sounds good. Presumably the common code then should be moved into a single place (into fancy_toys.jl)?

No promises, but I might look into this, it sounds doable.

Here's my rough idea how one would use it: first, you define the dependencies; then the platforms you can support maximally (so if you know this package can never run on Windows, you filter it out; if you need to expand the C++ string ABI, you do it, etc.). Finally, you call a function which filters the platform list based on the dependencies). So e.g. like this:

dependencies = [ ...]

platforms = supported_platforms()
filter!(!Sys.iswindows, platforms) # no Windows, even if the dependencies support it
platforms = expand_cxxstring_abis(platforms) 

platforms = restrict_platforms(platforms, dependencies)

Unfortunately that leaves the difficult problem of finding a better name for restrict_platforms :joy:

fingolfin commented 3 years ago

There's an issue with the above approach when the dependencies involve JLLs like libjulia_jll or libcxxwrap_julia_jll (which are my primary usecases): those JLLs come in multiple co-existing versions, and I need to specify "the right one", as different versions may support different platforms. For libjulia_jll, I still think we can do it because we have separate build_tarballs.jl for each of the supported "branches" (1.3, 1.4, 1.5, ...); but for libcxxwrap_julia_jll, there is only one build_tarballs.jl. Perhaps the fix then is to split the latter (again into variants for Julia 1.3, 1.5, 1.5, ...).

Another issue is this: by parsing build_tarballs.jl, we get the list of supported platforms at the time we parse it, not at the time the JLL was rebuilt last -- and those can differ. E.g. one day I assume aarch64-darwin will get enabled; but not all JLLs will be rebuilt immediately. If we then e.g. parse the build_tarballs.jl for libjulia_jll it would list that platform as "supported" even though it actually is not.

Which makes me wonder: shouldn't BinaryBuilder have all required information already anyway? Basically, when it tries to build for a given platform, it installs all its (build) dependencies. What we'd now need is to iterate over all the JLLs among those, and check if the JLL is really available (i.e. an artifact was installed). If not, mark that platform as "unsupported" resp. "skip" it (granted, I am sure it's more tricky than that in practice).