Determining installed target list when rustup is not in use

When rustup is in use, it is trivial to learn what targets are actually installed:

$ rustup target list | sed -ne 's/ *(installed)$//p'
aarch64-unknown-linux-gnu

However, if the toolchain was installed some other way, it's not nearly so easy. rustc --print target-list prints the much longer list of target tuples that the compiler could in principle generate code for, with no indication of which will actually work. I have two candidates for workarounds:

$ rustc --print target-list | while read target; do
    libdir="$(rustc --target $target --print target-libdir 2> /dev/null)"
    libstd="$(shopt -s nullglob && echo $libdir/libstd-*.rlib)"
    if [ -n "$libstd" ]; then echo $target; fi
  done
aarch64-unknown-linux-gnu

This one is painfully slow, taking fifty seconds to complete on this computer. I am also nervous that "a file named libstd-[hash].rlib exists in the target-libdir for target X" might not be a sufficient condition for rustc --target X ... to actually work.

$ find $(rustc --print sysroot) -name 'libstd-*.rlib' |
     sed -ne 's:^.*/\([^/]*\)/lib/libstd-[^/]*.rlib:\1:p'
aarch64-unknown-linux-gnu

This is much better speed-wise, but again it's checking for the existence of libstd-[hash].rlib which might not be a sufficient condition, and also now I don't know if all of the target-libdirs are guaranteed to be inside the sysroot. Moreover, when the toolchain is installed via the OS package manager, the sysroot is often /usr, which potentially contains an enormous amount of unrelated stuff that it's, again, a waste of time to search through.

Is there a better (esp. faster or more precise) way to get the list of installed targets when rustup is not available?


P.S. Please take my word for it that I cannot "just use rustup".

under $sysroot/lib/rustlib, there should be an directory named after the target triplet for each installed target, including the native target of the host toolchain.

also, on my installation, there's a components file at $sysroot/lib/rustlib, but I'm not sure if this file is generated by rustup, but you can check your installation. if you find it, look for the rust-std-<triplet> lines. rust-std is the component being installed when you run rustup target add <triplet>, even it's an no_std target. maybe it should be named something like rust-core, but that's what is is called today.

Looking for target-tuple directories in $sysroot/lib/rustlib works great, thanks. Also, I can confirm that the components file only exists when $sysroot/lib/rustlib was created by rustup.