Currently, the builtins build will emit static libs into per-target directories that are spelled exactly as they are passed to the build (i.e. no canonicalization):
❯ find . -iname '*builtins*a'
./lib/clang/13.0.1/lib/armv7a-unknown-linux-androideabi21/libclang_rt.builtins.a
./lib/clang/13.0.1/lib/x86_64-plex-linux-musl/libclang_rt.builtins.a
./lib/clang/13.0.1/lib/aarch64-plex-linux-musl/libclang_rt.builtins.a
./lib/clang/13.0.1/lib/aarch64-unknown-linux-android21/libclang_rt.builtins.a
However, runtimes will rely on the frontend to find these paths and that fails to find some of these, for example:
❯ ./bin/clang++ --rtlib=compiler-rt -print-libgcc-file-name --target=armv7a-unknown-linux-androideabi21
(..snip..)/lib/clang/13.0.1/lib/linux/libclang_rt.builtins-arm-android.a
This is because the above will use the canonicalized form of the target triple and that eventually hits this code:
// Special case logic goes here. At this point Arch, Vendor and OS have the
// correct values for the computed components.
std::string NormalizedEnvironment;
if (Environment == Triple::Android && Components[3].startswith("androideabi")) {
StringRef AndroidVersion = Components[3].drop_front(strlen("androideabi"));
if (AndroidVersion.empty()) {
Components[3] = "android";
} else {
NormalizedEnvironment = Twine("android", AndroidVersion).str();
Components[3] = NormalizedEnvironment;
}
}
Because of this, it won’t find the builtins lib, so it falls back to the old layout/name for the lib (but that again doesn’t exist because in fact the libs were created at paths with the complete triples in them).
Dropping eabi
seems very intentional, and I guess the idea here is that armv7 on Android only exists with eabi, so spelling it out is redundant. But that breaks the runtimes build for android because of the above difference between actual and computed paths. FWIW, symlinking armv7a-unknown-linux-androideabi21
to armv7a-unknown-linux-android21
makes it output the correct path.
This situation is a bit unfortunate because the error is very confusing (users will only see that the build is looking for lib/clang/13.0.1/lib/linux/libclang_rt.builtins-arm-android.a
instead of the right path without any explanation).
I see a couple ways to improve this:
- provide a way to trace candidate paths, similarly to search paths
- try the exact triple (without canonicalization) first
- add a
--runtime-target
flag that provides the same output, but without canonicalizing the triple (i.e. the old invocation doesn’t change its behavior). This is mentioned in this topic (addressing an adjacent use-case).