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

[Inquiry] Inconsistent binary size with 'cargo +stable build' vs 'cargo +1.50-x86_64-pc-windows-msvc' ? #82188

Open
eddyp opened this issue Feb 16, 2021 · 7 comments
Labels
A-reproducibility Area: Reproducible / Deterministic builds C-bug Category: This is a bug. O-windows-msvc Toolchain: MSVC, Operating system: Windows T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@eddyp
Copy link
Contributor

eddyp commented Feb 16, 2021

Problem

I am not 100% sure this is a bug or expected, but while exploring #75804, I have identified this inconsistency in the size of binaries of the same sources when using +stable vs +1.50-x86_64-pc-windows-msvc:

I would have expected that since the current stable is 1.50, cargo +stable build, cargo +1.50-... build and cargo build to yield the same results, but they don't.

Unfortunately I can't share the actual tool sources, but I can share the deps list.

Steps

  1. Use a script like the one below to do multiple builds on various versions (automation in cygwin)
# RUST_DBG_FLAGS='-C debuginfo=1 -C panic=abort -C opt-level=0'
# RUST_REL_FLAGS='-C debuginfo=0 -C panic=abort -C opt-level=3'

set -e -u

BUILD=build
MAIN=parser

cargo -vV
rustc -vV

rustup toolchain list
rustup override list

mkdir -p ${BUILD}/debug
mkdir -p ${BUILD}/release
for ver in 1.{45..50} beta nightly stable; do
    echo "-- $ver"
    for variant in release debug; do

        if [ ${variant} == release ]; then
            x_opt=--release
        else
            x_opt=
        fi

        bin=${BUILD}/${variant}/${MAIN}-${ver}.exe

        cargo clean
        cargo +$ver-x86_64-pc-windows-msvc build ${x_opt}
        cp target/${variant}/${MAIN}.exe ${bin}
        size=$(stat --printf="%s" $bin)
        printf "    %s: %d\n" ${variant} $size
    done
done

echo "No params"
cargo clean
cargo build
cargo build --release

echo "release"
ls -lnG {target,build}/release/*.exe | cut -f4,8 -d ' '
echo "debug"
ls -lnG {target,build}/debug/*.exe | cut -f4,8 -d ' '
  1. Run using cygwin's bash (WSL would use Linux's cargo and I haven't checked if it happens there)

c:\tools\cygwin64\bin\bash.exe build-all.sh

  1. Note that stable and 1.50 yield different results, in spite 1.50 being the current stable.
C:\usr\perso\rust\test-size\parser>c:\tools\cygwin64\bin\bash.exe build-all.sh
cargo 1.50.0 (f04e7fab7 2021-02-04)
release: 1.50.0
commit-hash: f04e7fab73128592a4063983c302da788bdfaba5
commit-date: 2021-02-04
rustc 1.50.0 (cb75ad5db 2021-02-10)
binary: rustc
commit-hash: cb75ad5db02783e8b0222fee363c5f63f7e2cf5b
commit-date: 2021-02-10
host: x86_64-pc-windows-msvc
release: 1.50.0
stable-x86_64-pc-windows-msvc (default)
beta-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc
1.45-x86_64-pc-windows-msvc
1.46-x86_64-pc-windows-msvc
1.47-x86_64-pc-windows-msvc
1.48-x86_64-pc-windows-msvc
1.49-x86_64-pc-windows-msvc
1.50-x86_64-pc-windows-msvc
C:\usr\src\rust\sbenitez-cs140e                 nightly-2018-01-09-x86_64-pc-windows-msvc
-- 1.45
   Compiling proc-macro2 v1.0.24
   Compiling unicode-xid v0.2.1
   Compiling ucd-trie v0.1.3
   Compiling syn v1.0.60
   Compiling maplit v1.0.2
   Compiling unindent v0.1.7
   Compiling pest v2.1.3
   Compiling indoc v1.0.3
   Compiling pest_meta v2.1.3
   Compiling quote v1.0.9
   Compiling pest_generator v2.1.3
   Compiling pest_derive v2.1.0
   Compiling parser v0.1.3 (C:\usr\perso\rust\test-size\parser)
    Finished release [optimized] target(s) in 25.78s
    release: 171520
[...]
release
171520 build/release/parser-1.45.exe
172032 build/release/parser-1.46.exe
172032 build/release/parser-1.47.exe
165376 build/release/parser-1.48.exe
167424 build/release/parser-1.49.exe
169984 build/release/parser-1.50.exe
167424 build/release/parser-beta.exe
167936 build/release/parser-nightly.exe
170496 build/release/parser-stable.exe
170496 target/release/parser.exe
debug
583680 build/debug/parser-1.45.exe
577024 build/debug/parser-1.46.exe
574464 build/debug/parser-1.47.exe
573440 build/debug/parser-1.48.exe
549376 build/debug/parser-1.49.exe
546304 build/debug/parser-1.50.exe
546816 build/debug/parser-beta.exe
548864 build/debug/parser-nightly.exe
547328 build/debug/parser-stable.exe
547328 target/debug/parser.exe

Note how 1.50 versions have a different size than +stable and default on both release and debug builds.

  1. It seems that stable builds have some extra strings in them with paths to the %USERPROFILE%\.rustup\toolchains:
C:\usr\perso\rust\test-size\parser>strings build/release/parser-1.50.exe | grep '1.50.*'

C:\usr\perso\rust\test-size\parser>strings build/release/parser-1.50.exe | grep 'stable.*'

C:\usr\perso\rust\test-size\parser>strings build/release/parser-stable.exe | grep -o '1.50.*'

C:\usr\perso\rust\test-size\parser>strings build/release/parser-stable.exe | grep -o 'stable.*'
stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\alloc\src\collections\btree\map.rs
stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\std\src\io\mod.rs
stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\slice\mod.rs
stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\alloc\src\collections\btree\node.rs
stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\alloc\src\slice.rs
stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\str\pattern.rsSpan
stable-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\alloc\layout.rs

Is this expected?

Possible Solution(s)

Notes

Output of cargo version:

cargo 1.50.0 (f04e7fab7 2021-02-04)
release: 1.50.0
commit-hash: f04e7fab73128592a4063983c302da788bdfaba5
commit-date: 2021-02-04

OS and toolchain info above

@eddyp eddyp changed the title [Inquiry] Inconsistent bianry size with 'cargo +stable build' vs 'cargo +1.50-x86_64-pc-windows-msvc' ? [Inquiry] Inconsistent binary size with 'cargo +stable build' vs 'cargo +1.50-x86_64-pc-windows-msvc' ? Feb 16, 2021
@alexcrichton alexcrichton transferred this issue from rust-lang/cargo Feb 16, 2021
@alexcrichton
Copy link
Member

This is unlikely to be a Cargo issue so I've transferred this to the rust-lang/rust repository. My best guess as to what's happening is that you're monomorphizing code from the standard library which uses file!() and the value of file!() changes depending on the directory of the compiler which contains the rust-src component. I'm not certain about this, but in any case this is likely a rust-lang/rust issue rather than a Cargo one.

@eddyp
Copy link
Contributor Author

eddyp commented Feb 16, 2021

My best guess as to what's happening is that you're monomorphizing code from the standard library which uses file!() and the value of file!() changes depending on the directory of the compiler which contains the rust-src component.

How can we confirm/infirm this hypothesis?
Could it be in a directory that does not contain the version in it?

Installed components seem to be different:

C:\usr\perso\rust\test-size\parser>rustup +stable component list | grep installed
cargo-x86_64-pc-windows-msvc (installed)
clippy-x86_64-pc-windows-msvc (installed)
llvm-tools-preview-x86_64-pc-windows-msvc (installed)
rls-x86_64-pc-windows-msvc (installed)
rust-analysis-x86_64-pc-windows-msvc (installed)
rust-docs-x86_64-pc-windows-msvc (installed)
rust-src (installed)
rust-std-i686-pc-windows-msvc (installed)
rust-std-thumbv6m-none-eabi (installed)
rust-std-thumbv7em-none-eabi (installed)
rust-std-x86_64-pc-windows-gnu (installed)
rust-std-x86_64-pc-windows-msvc (installed)
rustc-x86_64-pc-windows-msvc (installed)
rustfmt-x86_64-pc-windows-msvc (installed)

C:\usr\perso\rust\test-size\parser>rustup +1.50 component list | grep installed
cargo-x86_64-pc-windows-msvc (installed)
clippy-x86_64-pc-windows-msvc (installed)
rust-docs-x86_64-pc-windows-msvc (installed)
rust-std-x86_64-pc-windows-msvc (installed)
rustc-x86_64-pc-windows-msvc (installed)
rustfmt-x86_64-pc-windows-msvc (installed)

@eddyp
Copy link
Contributor Author

eddyp commented Feb 16, 2021

I ran strings on both executables and there seem to be some differences like the ones below (but these are not the only ones).
Also, I don't know if the differences are limited only to such issues, or if there are differences in the generated code.

image

@ehuss
Copy link
Contributor

ehuss commented Feb 16, 2021

Yes, those differences appear to be due to the presence of the rust-src component. You can either remove it, or add it to the 1.50.0 install.

You may also consider experimenting with --remap-path-prefix, though YMMV, and I don't remember if that is sufficient to remove the differences.

@eddyp
Copy link
Contributor Author

eddyp commented Feb 17, 2021

@ehuss But does that mean that rustc does not make (yet) any claims WRT reproducible builds?

Context: https://reproducible-builds.org/

@ehuss
Copy link
Contributor

ehuss commented Feb 17, 2021

I don't want to speak for the compiler team (I am not on it), but AFAIK in general there is an effort to maintain reproducible builds on linux only, assuming you set up the environment correctly (such as with --remap-path-prefix flags, having the same setup and whatnot). If that regresses, then I think it is a bug (#82074 is a recent example, issues are tracked with A-reproducibility). It is not heavily tested, so regressions do happen. And it is not documented, and I think is on a "best effort" basis. Also, I think all non-linux-gnu platforms are not in a state to be completely reproducible (although my information may be out of date).

@eddyp
Copy link
Contributor Author

eddyp commented Feb 18, 2021

AFAIK in general there is an effort to maintain reproducible builds on linux only, assuming you set up the environment correctly (such as with --remap-path-prefix flags, having the same setup and whatnot)

OK, reasonable enough.

Yet I see I'm not the only one interested in reproducible builds on Windows: #71714, #66955.

I would imagine this is also relevant for the Sealed Rust effort driven by Ferrous Systems as I imagine most/many corporate setups are around Windows systems, but I guess that's something @jamesmunns and @skade can give some inputs before the community.

@camelid camelid added A-reproducibility Area: Reproducible / Deterministic builds C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Feb 26, 2021
@jieyouxu jieyouxu added T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. O-windows-msvc Toolchain: MSVC, Operating system: Windows and removed C-enhancement Category: An issue proposing an enhancement or a PR with one. labels Aug 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-reproducibility Area: Reproducible / Deterministic builds C-bug Category: This is a bug. O-windows-msvc Toolchain: MSVC, Operating system: Windows T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants