# Following symlinks when computing default sysroot

**URL:** <https://internals.rust-lang.org/t/following-symlinks-when-computing-default-sysroot/4249>\
**Category:** compiler\
**Created:** [October 21, 2016, 11:10am UTC](https://internals.rust-lang.org/t/following-symlinks-when-computing-default-sysroot/4249 "2016-10-21T11:10:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![pmatos](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pmatos/32/1894_2.png) [@pmatos](https://internals.rust-lang.org/u/pmatos)\
**Post date:** [October 21, 2016, 11:10am UTC](https://internals.rust-lang.org/t/following-symlinks-when-computing-default-sysroot/4249/1 "2016-10-21T11:10:17Z")

</div>

I had a problem with `std` crate not being found. I opened a [request](https://users.rust-lang.org/t/again-the-old-cant-find-std-crate-issue/7707) for help in the users list and headed over to IRC as well.

For context I installed rust 1.12 from the tarball (and tried using rustup as well) into `/usr/local/` I just found with the help of some of the guys in the #rust-beginners channel that the reason `std` could not be found was because my sysroot as output by `rustc --print sysroot` was `/usr/local/stow/yabar/`. I also noticed that if I set the sysroot manually in the rustc command line all was fine and the `std` crate would have been found. With this I started scratching my head and went to dig for an answer in the rustc source code.

It turns out that if no sysroot is defined, rustc will try to find a default sysroot.

This is the function that does the job (in `src/librustc/session/filesearch.rs`):

```rust
pub fn get_or_default_sysroot() -> PathBuf {
    // Follow symlinks. If the resolved path is relative, make it absolute.
    fn canonicalize(path: Option<PathBuf>) -> Option<PathBuf> {
        path.and_then(|path| {
            match fs::canonicalize(&path) {
                // See comments on this target function, but the gist is that
                // gcc chokes on verbatim paths which fs::canonicalize generates
                // so we try to avoid those kinds of paths.
                Ok(canon) => Some(rustcfs::fix_windows_verbatim_for_gcc(&canon)),
                Err(e) => bug!("failed to get realpath: {}", e),
            }
        })
    }

    match canonicalize(env::current_exe().ok()) {
        Some(mut p) => { p.pop(); p.pop(); p }
        None => bug!("can't determine value for sysroot")
    }
}

```

As soon as I saw the function it hit me what the problem was. I installed in my new machine firstly `yabar` using `GNU stow`. Since `/usr/local/bin` didn’t exist, `stow` installed `yabar` to `/usr/local/stow/yabar` and symlinked `/usr/local/bin` to `/usr/local/stow/yabar/bin`. When I installed rust, the executables were installed to `/usr/local/bin`. When this function computes sysroot, it follows the symlinks and determines that rustc resides in `/usr/local/stow/yabar/bin/rustc`. And then returns as sysroot `/usr/local/stow/yabar`. This is obviously wrong since sysroot should be `/usr/local/`. Now, if the function hadn’t followed symlinks I would have had no error at all.

So, my question is, what is the reason for following symlinks when determining the sysroot?

---

<div class="post-metadata">

**Author:** ![KillTheMule](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/killthemule/32/2579_2.png) [@KillTheMule](https://internals.rust-lang.org/u/KillTheMule)\
**Post date:** [October 21, 2016, 11:29am UTC](https://internals.rust-lang.org/t/following-symlinks-when-computing-default-sysroot/4249/2 "2016-10-21T11:29:17Z")

</div>

I use `stow` as well, it’s awesome. I think rust was right here, when the executables were instaleld in `/usr/local/bin`, they effectively landed in `/usr/local/stow/yabar/bin`, so rust was right to determine that as the location of `rustc`, and therefore the sysroot. Following symlinks probably wasn’t involved…

What you should do is make `stow` not symlink `/usr/local/bin` to `/usr/local/stow/yabar/bin`, but have it make symlinks in `/usr/local/bin` that point to targets that live in `/usr/local/stow/yabar/bin`. That would result in rustc being installed in to `/usr/local/bin`, and therefore a correct path.

---

<div class="post-metadata">

**Author:** ![pmatos](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/pmatos/32/1894_2.png) [@pmatos](https://internals.rust-lang.org/u/pmatos)\
**Post date:** [October 21, 2016, 11:42am UTC](https://internals.rust-lang.org/t/following-symlinks-when-computing-default-sysroot/4249/3 "2016-10-21T11:42:40Z")

</div>

While I understand with `stow` I still don’t agree it has nothing to do with symlinks. `which rustc` reported it at `/usr/local/bin` so `env::current_exe()` would have been `/usr/local/bin/rustc` however the symlink following would have then transformed this into `/usr/local/stow/yabar/bin/rustc`.

I am in no way saying this is incorrect. In the end, it’s my fault due to my usage of `stow` but I am still intrigued why we are following symlinks here. What’s the use case?

---

<div class="post-metadata">

**Author:** ![KillTheMule](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/killthemule/32/2579_2.png) [@KillTheMule](https://internals.rust-lang.org/u/KillTheMule)\
**Post date:** [October 21, 2016, 11:51am UTC](https://internals.rust-lang.org/t/following-symlinks-when-computing-default-sysroot/4249/4 "2016-10-21T11:51:25Z")

</div>

Ok, yeah, I see. Your `PATH` says that the rustc to use is the one at `/usr/local/bin/rustc`, nevermind that it is a symlink to `/usr/local/stow/yabar/bin/rustc`, and the first env args passed to rustc should actually read `/usr/local/bin/rustc`, not that-other-thing. So I revise my opinion and think that in this case the sysroot should have been `/usr/local/bin`.

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [October 21, 2016, 4:25pm UTC](https://internals.rust-lang.org/t/following-symlinks-when-computing-default-sysroot/4249/5 "2016-10-21T16:25:00Z")

</div>

Whatever resolution rule rustc uses needs to work for downloaded rust snapshot tarballs, too.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:12am UTC](https://internals.rust-lang.org/t/following-symlinks-when-computing-default-sysroot/4249/6 "2019-03-25T08:12:41Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
