Skip to content

Contrib docs: note how to run a binary directly#6823

Open
matthewhughes934 wants to merge 1 commit intorust-lang:mainfrom
matthewhughes934:document-running-binary-directly
Open

Contrib docs: note how to run a binary directly#6823
matthewhughes934 wants to merge 1 commit intorust-lang:mainfrom
matthewhughes934:document-running-binary-directly

Conversation

@matthewhughes934
Copy link

Because it took me a moment to figure this out when I was wanting to run rustfmt through a debugger.

Setting LD_LIBRARY_PATH uses some Bash parameter expansion, specifically the form ${parameter:+word}[1], to avoid potentially adding an empty element to LD_LIBRARY_PATH that could be a security issue (see[2])

Some history: there used to be a note in README.md about setting this variable, but that was removed with
2e75f23. However, with the addition of rustc_driver with d7fa2ee (original upstream[3]) this is required again.

Link: https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html [1]
Link: #2923 [2]
Link: rust-lang/rust@8c000a6 [3]

Because it took me a moment to figure this out when I was wanting to run
`rustfmt` through a debugger.

Setting `LD_LIBRARY_PATH` uses some Bash parameter expansion,
specifically the form `${parameter:+word}`[1], to avoid potentially adding
an empty element to `LD_LIBRARY_PATH` that could be a security issue
(see[2])

Some history: there used to be a note in `README.md` about setting this
variable, but that was removed with
2e75f23. However, with the addition of
`rustc_driver` with d7fa2ee (original
upstream[3]) this is required again.

Link: https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html [1]
Link: rust-lang#2923 [2]
Link: rust-lang/rust@8c000a6 [3]
@rustbot rustbot added the S-waiting-on-review Status: awaiting review from the assignee but also interested parties. label Mar 11, 2026
Comment on lines +119 to +142
#### Running a binary directly

You may want to run one of the built binaries directly, for example to connect
it to a debugger. Since `rustfmt` uses `rustc_driver` it needs to be linked
against the version of that library for the current toolchain, without
configuring anything you are likely to run into errors like:

$ ./target/debug/rustfmt
./target/debug/rustfmt: error while loading shared libraries: librustc_driver-63b8deb6c23747dd.so: cannot open shared object file: No such file or directory

This library will be in the sysroot of the current toolchain, so we can fix this
by telling the linker to look there. For example on Linux with Bash:

LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" ./target/debug/rustfmt

Equivalently, you could set the variable for the current environment:

$ export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
$ ./target/debug/rustfm

Then, you can invoke a debugger like `rust-gdb`:

LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" rust-gdb --args ./target/debug/rustfmt --check some_file.rs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We encourage user to run with cargo because cargo sets the necessary environment variables for you. Also note that LD_LIBRARY_PATH is only relevant on linux. windows and macos use different environment variables and that should be called out.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We encourage user to run with cargo because cargo sets the necessary environment variables for you.

👍 I don't want this change to suggest otherwise, the use case I was looking at was attaching a debugger. This can be done when running under cargo, but it's a bit clunky (extra lines start with # inserted by me):

Reading symbols from cargo...
# symbols loaded for 'cargo' but not 'rustfmt' (yet), need to run until we start rustfmt to read those
(No debugging symbols found in cargo)
(gdb) b src/bin/main.rs:31
❌️ No symbol table is loaded.  Use the "file" command.
Make breakpoint pending on future shared library load? (y or [n]) y
Breakpoint 1 (src/bin/main.rs:31) pending.

Compared to running directly:

$ LD_LIBRARY_PATH="$(rustc --print sysroot)/lib" rust-gdb --quiet --args ./target/debug/rustfmt file.rs
Reading symbols from ./target/debug/rustfmt...
# symbols already loaded, can tab-complete file names, inspect functions etc. before running
(gdb) b src/bin/main.rs:31
Breakpoint 1 at 0x2d53ba: src/bin/main.rs:31. (2 locations)

Also note that LD_LIBRARY_PATH is only relevant on linux. windows and macos use different environment variables and that should be called out.

Indeed, I tried to make it clear before using LD_LIBRARY_PATH that the example was for Linux only. I'd be happy to go and see how to make it work on MacOS + Windows too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to include examples for MacOS + Windows too.

Copy link
Contributor

@ytmimi ytmimi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's wrap code blocks in code fences and remove leading $ in code examples. It would also be great to include examples for MacOS + Windows.

View changes since this review

Comment on lines +126 to +127
$ ./target/debug/rustfmt
./target/debug/rustfmt: error while loading shared libraries: librustc_driver-63b8deb6c23747dd.so: cannot open shared object file: No such file or directory
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's wrap this in a code fence to make the code block clearer. Also, probably enough to just show the example error message:

Suggested change
$ ./target/debug/rustfmt
./target/debug/rustfmt: error while loading shared libraries: librustc_driver-63b8deb6c23747dd.so: cannot open shared object file: No such file or directory
```
./target/debug/rustfmt: error while loading shared libraries: librustc_driver-63b8deb6c23747dd.so: cannot open shared object file: No such file or directory
```

This library will be in the sysroot of the current toolchain, so we can fix this
by telling the linker to look there. For example on Linux with Bash:

LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" ./target/debug/rustfmt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I'd prefer we wrap this in a code fence.

Suggested change
LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" ./target/debug/rustfmt
```
LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" ./target/debug/rustfmt
```

Comment on lines +136 to +137
$ export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
$ ./target/debug/rustfm
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrap in code fence and drop the leading $ since those will also get copied when using the copy feature on GitHub code blocks:

Image
Suggested change
$ export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
$ ./target/debug/rustfm
```
export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
./target/debug/rustfm
```


Then, you can invoke a debugger like `rust-gdb`:

LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" rust-gdb --args ./target/debug/rustfmt --check some_file.rs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" rust-gdb --args ./target/debug/rustfmt --check some_file.rs
```
LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" rust-gdb --args ./target/debug/rustfmt --check some_file.rs
```

Comment on lines +119 to +142
#### Running a binary directly

You may want to run one of the built binaries directly, for example to connect
it to a debugger. Since `rustfmt` uses `rustc_driver` it needs to be linked
against the version of that library for the current toolchain, without
configuring anything you are likely to run into errors like:

$ ./target/debug/rustfmt
./target/debug/rustfmt: error while loading shared libraries: librustc_driver-63b8deb6c23747dd.so: cannot open shared object file: No such file or directory

This library will be in the sysroot of the current toolchain, so we can fix this
by telling the linker to look there. For example on Linux with Bash:

LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" ./target/debug/rustfmt

Equivalently, you could set the variable for the current environment:

$ export LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
$ ./target/debug/rustfm

Then, you can invoke a debugger like `rust-gdb`:

LD_LIBRARY_PATH="$(rustc --print sysroot)/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}" rust-gdb --args ./target/debug/rustfmt --check some_file.rs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to include examples for MacOS + Windows too.

@rustbot rustbot added S-waiting-on-author Status: awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: awaiting review from the assignee but also interested parties. labels Mar 12, 2026
@rustbot
Copy link
Collaborator

rustbot commented Mar 12, 2026

Reminder, once the PR becomes ready for a review, use @rustbot ready.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: awaiting some action (such as code changes or more information) from the author.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants