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".