-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate multiple packages with the a single builder #778
Comments
maybe also a jll for the original source directory such that we can download it automatically in the debugger if necessary. |
I agree that this is desirable. I'm not entirely sure that the right way to do it is to create multiple JLL packages; or at least, not necessarily the user-facing way. Here are my thoughts:
First and foremost, for this to work nicely, I think we're going to need to break up API overviewI envision having a function meta = BuildMetadata()
build_binaries!(meta, ARGS, sources, script, platforms, dependencies) This # This would be defined by default, but just explicitly make it for illustration's sake
everything_extractor = raw"""
mv ${srcdir}/* ${prefix}/
"""
build_jll!(meta, name, version, platforms, dependencies, everything_extractor) What this enablesThis gives us the flexibility to do an awful lot:
meta = BuildMetadata()
build_binaries!(meta, ARGS, sources, script, filter(p -> !Sys.iswindows(p), platforms), dependencies)
build_binaries!(meta, ARGS, win_sources, win_script, filter(p -> Sys.iswindows(p), platforms), dependencies)
build_jll!(meta, name, version, platforms, dependencies, everything_extractor) Note that if we're going through the trouble of rewriting this stuff, we can probably get rid of
meta = BuildMetadata()
build_binaries!(meta, ARGS, sources, script, platforms, dependencies)
LibLLVM_extractor = raw"""
# Copy over `llvm-config`, `libLLVM` and `include`, specifically.
mkdir -p ${prefix}/include ${prefix}/tools ${libdir} ${prefix}/lib
mv -v ${srcdir}/include/llvm* ${prefix}/include/
mv -v ${srcdir}/tools/llvm-config* ${prefix}/tools/
mv -v ${srcdir}/$(basename ${libdir})/*LLVM*.${dlext}* ${libdir}/
mv -v ${srcdir}/lib/*LLVM*.a ${prefix}/lib
"""
build_jll!(meta, "LibLLVM_jll", version, platforms, dependencies, LibLLVM_extractor)
Clang_extractor = raw"""
...
"""
build_jll!(meta, "Clang_jll", version, platforms, dependencies, Clang_extractor)
...
# Build once with `-O2` and extract it into a default variant, as well as a "build" variant:
meta = BuildMetadata()
build_binaries!(meta, ARGS, sources, script, platforms, dependencies)
base_extractor = raw"""
for f in $(find_binary_objects ${srcdir}); do
rp=$(relpath ${srcdir} ${f})
mkdir -p $(dirname ${rp})
mv ${f} ${prefix}/${rp}
done
"""
build_jll!(meta, name, version, platforms, dependencies, base_extractor)
build_jll!(meta, "$(name)+build", version, platforms, dependencies, everything_extractor)
# Build once with `-O1 -g` and bundle it into the "debug" variant:
debug_meta = BuildMetadata()
build_binaries!(debug_meta, ARGS, sources, debug_script, platforms, dependencies)
build_jll!(meta, "$(name)+debug", version, platforms, dependencies, everything_extractor) The "variants" would all be put into the same JLL release as artifacts with names that have the What do you guys think? |
That sounds fantastic! I would call them |
Intelligent building and serving of debug symbolsIf we had "partial artifact" download support, we could simplify this a bit, in that we could generate only a single tarball that has everything: binaries, headers, and separate debug files. We could then work some Pkg server magic to allow requesting a union of subtrees rather than always the entire content tree. This would allow us to, for instance, request the union of subtrees that corresponds to just the shared libraries within To strip out debug symbols into external files, we can use the following tools:
Assuming we are able to work our PkgServer magic above, we will be able to stream down content trees where these files exist on-disk side-by-side, which makes the whole thing much easier. If we must keep the files separate, this becomes more difficult, we'd probably have to modify files on-disk to get relative pathing correct, or force debuggers to do the searching themselves (this is easier if we embed build ids, see below).
Note that we probably want to start adding Doing this magically via compiler wrappers/BB magicWe can force |
Oh, I also just thought to myself it would be cool to switch between e.g. debug and non-debug versions through |
Thinking about this again, it would also be really sweet for debug versions of JLLs to include all source files referenced by the DWARF files, stored in a predictable place (like We can add a post-processing step that inspects all DWARF files, finds all referenced source files (even autogenerated ones) and stores them in the appropriate location within a |
I think most of our compiler support split dwarf info? https://gcc.gnu.org/wiki/DebugFissionDWP |
In the last few weeks I've been thinking about this issue again, and coming up with beautiful ideas like using Another idea that just came to my mind is to have dev/debug tarballs as lazy artifacts of the same JLL package, instead of their own packages, but Elliot anticipated me again:
I like this idea! In particular, I'm thinking about splitting also the logs into their own tarballs. A nice benefit is that this could make the runtime tarball reproducible across multiple identical rebuilds. One additional thing to mention is that now that we have |
Just wanted to add that for JLLs which link against libjulia, it would be nice to have debug variants which link against libjulia-debug (this is orthogonal to the question of debug symbols and how to handle them). Right now, I am debugging a Julia package (Oscar.jl) involving four JLLs linking against libjulia (libcxxwrap-julia, libsingular-julia, libpolymake-julia, GAP) and it isn't exactly fun. So perhaps there could be another "variant marker" indicating "download this instead of the default if this is a Julia debug build" |
I just came across |
Long term plan is still to do JuliaPackaging#778, but that's a lot of work, and we have little time at the moment. Simply splitting the logs into a separate tarball, instead, is a simpler short-term solution which has some very important bonuses: - the git tree hash of the main tarball should be reproducible (as long as you use the same toolchain) - which means we can start testing reproducibility of builds - rebuilding a package without changing its content won't create a new artifact: less strain on the Package Storage Server.
* [AutoBuild] Split log files into a separate tarball Long term plan is still to do #778, but that's a lot of work, and we have little time at the moment. Simply splitting the logs into a separate tarball, instead, is a simpler short-term solution which has some very important bonuses: - the git tree hash of the main tarball should be reproducible (as long as you use the same toolchain) - which means we can start testing reproducibility of builds - rebuilding a package without changing its content won't create a new artifact: less strain on the Package Storage Server. * [AutoBuild] Filter out logs tarball when rebuilding the package
From time to time I look to the package managers of Linux distributions to see if we can pick up some interesting ideas. One thing that I think would be really cool to have here is to be able to generate multiple JLL packages with a single builder: the result of a build doesn't go into a single tarball, but it might be split into many of them.
One fancy application is to be able to generated:
Libfoo_jll
: contains onlybin/
andlib/
, this is the runtime part, what the Julia packages will use;Libfoo_dev_jll
: containsinclude/
, header files are generally useless for Julia packages and they mostly clutter~/.julia/artifacts/
with dozens of small filess. Ideally, this would be automatically installed, if available, whenLibfoo_jll
is used as dependency in a build;Libfoo_dbg_jll
: contains the debug symbols of the shared library, that users can optionally install to get more useful debug information about crashes or errors. Based on an idea by @Keno.Also, I think that
LLVM_full_jll
is currently "wrong": IMO it should simply be an empty metapackage binding all the other pieces. Instead now it's a monster package containing the same data as its pieces, which means that if we use bothLLVM_full_jl
andlibLLVM_jll
in a build, they would step onto each other's toes. Having a single builder that produces all other subpackages would probably make @vchuravy happy, too.The text was updated successfully, but these errors were encountered: