Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustfmt 1.5.2 runtime failure #5675

Open
chenrui333 opened this issue Jan 26, 2023 · 6 comments
Open

rustfmt 1.5.2 runtime failure #5675

chenrui333 opened this issue Jan 26, 2023 · 6 comments
Labels
blocked Blocked on rustc, an RFC, etc.

Comments

@chenrui333
Copy link

👋 trying to build the latest release, but run into some build issue. The error log is as below:

runtime issue
==> rustfmt --check ./src/main.rs
Last 15 lines from /Users/rui/Library/Logs/Homebrew/rustfmt/test.02.rustfmt:
2023-01-26 10:32:30 -0500

rustfmt
--check
./src/main.rs

dyld[52306]: Library not loaded: @rpath/librustc_driver-f64ac9ee9a3f0eb4.dylib
  Referenced from: <2CCD3F33-AAEE-3ADE-A78C-AC78D489E170> /opt/homebrew/Cellar/rustfmt/1.5.2/bin/rustfmt
  Reason: tried: '/System/Volumes/Preboot/Cryptexes/OS@rpath/librustc_driver-f64ac9ee9a3f0eb4.dylib' (no such file), '/usr/local/lib/librustc_driver-f64ac9ee9a3f0eb4.dylib' (no such file), '/usr/lib/librustc_driver-f64ac9ee9a3f0eb4.dylib' (no such file, not in dyld cache)
Error: rustfmt: failed

full build log, https://github.com/Homebrew/homebrew-core/actions/runs/4001984607/jobs/6868829982
relates to Homebrew/homebrew-core#121441

@carlocab
Copy link

This isn't really a build failure. It looks like the just-built rustfmt has a runtime dependency on an existing Rust toolchain.

On the one hand, that seems like a reasonable requirement. On the other, it wasn't there before, and seems to make rustfmt slightly less portable given that it has to know where to look for some libraries.

@calebcartwright calebcartwright changed the title rustfmt 1.5.2 build failure rustfmt 1.5.2 runtime failure Jan 27, 2023
@calebcartwright
Copy link
Member

calebcartwright commented Jan 27, 2023

Thanks for the report.

This ultimately stems from some upstream changes that we're reliant upon. I don't think there's a clear path on how it will be resolved yet, nor how long such a resolution could take, so in the interim I'd recommend either using the version of rustfmt that ships with a toolchain, or if you need to continue to build from source to do so with the prior v1.5.1 version

@calebcartwright
Copy link
Member

calebcartwright commented Jan 28, 2023

Looks like the best workaround available if you are building rustfmt from source is going to be to set LD_LIBRARY_PATH

LD_LIBRARY_PATH=$(rustc --print sysroot)/lib ./path/to/your/built/rustfmt

It looks like the just-built rustfmt has a runtime dependency on an existing Rust toolchain.

On the one hand, that seems like a reasonable requirement. On the other, it wasn't there before, and seems to make rustfmt slightly less portable given that it has to know where to look for some libraries.

fwiw I think this has already been the case for several years, certainly since we had to switch to consuming the rustc internals from the sysroot. I haven't confirmed, but my assumption is that even with an older version of rustfmt you would still get the same runtime error if you nuked the associated toolchain + sysroot.

What's really changed here is that some upstream changes have resulted in no longer being able to find/determine the correct sysroot.


I'm going to mark this as blocked for now because I suspect it will need, or at least will hopefully receive, an upstream resolution, and I don't think there's much that we can/should attempt to do on our end just yet.

@calebcartwright calebcartwright added the blocked Blocked on rustc, an RFC, etc. label Jan 28, 2023
@chenrui333
Copy link
Author

What's really changed here is that some upstream changes have resulted in no longer being able to find/determine the correct sysroot.

I actually think this might be the same cause for pyoxidizer 0.24.0 cc @messense

@carlocab
Copy link

carlocab commented Feb 1, 2023

Looks like the best workaround available if you are building rustfmt from source is going to be to set LD_LIBRARY_PATH

LD_LIBRARY_PATH=$(rustc --print sysroot)/lib ./path/to/your/built/rustfmt

This works on Linux, but will not work on macOS. macOS does have DYLD_LIBRARY_PATH, but this does not behave the same way because of Apple's System Integrity Protection (Apple really wants to avoid dylib highjacking).

Relying on DYLD_LIBRARY_PATH when using /usr/bin/make, for example, will not work. (Not without awful kludges, at least.)

fwiw I think this has already been the case for several years, certainly since we had to switch to consuming the rustc internals from the sysroot. I haven't confirmed, but my assumption is that even with an older version of rustfmt you would still get the same runtime error if you nuked the associated toolchain + sysroot.

What's really changed here is that some upstream changes have resulted in no longer being able to find/determine the correct sysroot.

I don't think this is correct. At Homebrew, we build and distribute a rustfmt binary that can function even if you do not have a toolchain installed on your system. This was the case in 1.5.1, so something significant has changed between now and then.

We can see this by looking at the libraries linked to rustfmt. In 1.5.1:

❯ otool -L rustfmt
rustfmt:
        /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1311.100.3)
        /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)

In 1.5.2:

❯ otool -L rustfmt
rustfmt:
        @rpath/librustc_driver-f64ac9ee9a3f0eb4.dylib (compatibility version 0.0.0, current version 0.0.0)
        @rpath/libstd-bb11981be80e035b.dylib (compatibility version 0.0.0, current version 0.0.0)
        /usr/lib/libiconv.2.dylib (compatibility version 7.0.0, current version 7.0.0)
        /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.11)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 905.6.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1292.100.5)

We can see that the linkage to the Rust toolchain is new in 1.5.2. (otool -L is Darwin for ldd, roughly speaking.)

@calebcartwright
Copy link
Member

This works on Linux, but will not work on macOS. macOS does have DYLD_LIBRARY_PATH, but this does not behave the same way because of Apple's System Integrity Protection (Apple really wants to avoid dylib highjacking).

Does DYLD_FALLBACK_LIBRARY_PATH not work? I'd be a little surprised if there was no way to specify this on Mac

I don't think this is correct. At Homebrew, we build and distribute a rustfmt binary that can function even if you do not have a toolchain installed on your system. This was the case in 1.5.1, so something significant has changed between now and then.

I appreciate the extra info, but I don't really think there's much to be gained from any debate in this issue.

As I stated previously, this comes from upstream changes that are outside of our control (and yes there's a resultant dynamic linking that's now happening on rustc_driver as part of those changes, so I was indeed wrong on that part). There's references to the upstream issues providing greater detail on those changes, why those changes were made, and the benefits those changes provide in the greater context.

I'm not sure why you folks are building your own rustfmt binary, and while we don't directly support those types of scenarios, all I can tell you is that if you want to use the newer version of rustfmt then you're going to have to pivot to either:

  • providing the dynamic lib path at runtime with the associated sysroot components being available from a compatible toolchain (I recognize this is likely the least palatable option for you)
  • you could use e.g. rpath at build time similar to what's done for the toolchain builds (though this carries some of the same cons as the prior option)
  • you could adjust your build process to statically link those libs

Ultimately this remains blocked. We're not going to attempt to change anything on our end, build process or otherwise, while we wait to see how things shake out upstream. Similarly, I do not anticipate we'll attempt to support nor even document things beyond what I've shared here; we simply don't have the bandwidth for it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked Blocked on rustc, an RFC, etc.
Projects
None yet
Development

No branches or pull requests

3 participants