Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
I don't expect this pull request to be merged. It makes several assumptions that are only valid in the chrome os build environment and it simply panics if it runs into any errors. Instead I'm sending this pull request as a desperate cry for help and as a sign of how bad things have gotten for at least one team (Chrome OS) that is trying to actually ship rust code as a part of a larger system.
Chrome OS builds hundreds of different software packages as part of the OS image. Rebuilding the same dependency crate 17 times for 17 different rust packages is simply not going to work for us. #1139 has been open for more than 3 years and RFC 2136 was merged more than 7 months ago but as far as I can tell no actual progress has been made towards better build system integration.
Now let me describe how this patch is supposed to work.
The Chrome OS executor is designed to work with a local, directory-based registry. We tell cargo to use this registry instead of crates.io via its
.cargo/config
. Crates with no dependencies (for example, the libc crate) are built as normal. When publishing a crate to the registry we install the crate'sCargo.toml
, the built rlib for the crate, and an emptysrc/lib.rs
file. Later when cargo tries to rebuild a crate from the local registry (as a dependency of some other crate), the chrome os executor will detect this and use the pre-built rlib instead of callingrustc
. The emptysrc/lib.rs
file is there as a backup: if we somehow do end up building the crate from source,rustc
will produce an empty crate and will cause a compile error if anything tries to use that crate.There are some additional tweaks on top of that basic usage.
Chrome OS ships both arm and x86 devices so we need to be able to cross-compile everything. Since cargo expects full sources in the registry, there is no way to detect ahead of time whether a crate is going to be used on the target machine or the build machine (maybe as part of a build.rs step). To deal with this, we build each crate twice: once for the target architecture and once for the build machine architecture. Both rlibs are installed in the registry in the appropriate directory. The chrome os executor uses the
--target
flag that cargo passes to rustc to determine which rlib to use and then provides the correct one.Cargo requires every possible dependency of the crate to exist in the registry even if they will never actually be used during the compile step. This includes things like the
winapi
crate even when building for linux. To deal with this we install empty crates in the local registry. These crates have a minimalCargo.toml
(just the name and version with no dependencies) and an emptysrc/lib.rs
file. These crates have no pre-built rlibs so if they are ever used at compile time the chrome os executor will panic because it cannot find an rlib for them.Dealing with new toolchain releases is relatively straightforward. Chrome OS uses portage as its build system. All rust packages declare a special type of dependency on the rust toolchain package so that if the toolchain version ever changes, all rust packages are rebuilt from source. This ensures that we don't use rlibs from different rustc versions in the same compile.
I'm sure that I've probably made some terrible assumptions but the fact is that cargo in its current form simply cannot provide what we need in terms of build system hooks. I'm willing to implement better integration for cargo that works for more than just chrome os. Cargo is large and complex and this is the best starting point I could find.
Please please please prioritize better build system integration for cargo.