arti fails to compile with LTO cflags
When building arti with LTO CFLAGS, we get the following build failure:
$ CFLAGS="-flto -Werror=odr -Werror=lto-type-mismatch -Werror=strict-aliasing" cargo build --verbose --release -p arti-bench --target x86_64-unknown-linux-gnu
[snip]
= note: "cc" "-m64" "/tmp/rustcSmVUDu/symbols.o" "/builds/ajak/arti/target/x86_64-unknown-linux-gnu/release/deps/arti_bench-654d55f788aad115.arti_bench.a19f5557-cgu.0.rcgu.o" "-Wl,--as-needed" "-L" "/builds/ajak/arti/target/x86_64-unknown-linux-gnu/release/deps" "-L" "/builds/ajak/arti/target/release/deps" "-L" "/usr/lib/x86_64-linux-gnu" "-L" "/builds/ajak/arti/target/x86_64-unknown-linux-gnu/release/build/zstd-sys-2fc86ca4080c769c/out" "-L" "/usr/local/rustup/toolchains/1.66.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-Wl,-Bstatic" "/tmp/rustcSmVUDu/libzstd_sys-327eb6b716d5430a.rlib" "/usr/local/rustup/toolchains/1.66.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-b73e5b4656934876.rlib" "-Wl,-Bdynamic" "-lsqlite3" "-llzma" "-lssl" "-lcrypto" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-znoexecstack" "-L" "/usr/local/rustup/toolchains/1.66.0-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "/builds/ajak/arti/target/x86_64-unknown-linux-gnu/release/deps/arti_bench-654d55f788aad115" "-Wl,--gc-sections" "-pie" "-Wl,-zrelro,-znow" "-nodefaultlibs"
= note: /usr/bin/ld: /builds/ajak/arti/target/x86_64-unknown-linux-gnu/release/deps/arti_bench-654d55f788aad115.arti_bench.a19f5557-cgu.0.rcgu.o: in function `tor_dirclient::get_decoder':
arti_bench.a19f5557-cgu.0:(.text._ZN13tor_dirclient11get_decoder17hab1b7124f3e9b562E+0x7d): undefined reference to `ZSTD_createDCtx'
/usr/bin/ld: arti_bench.a19f5557-cgu.0:(.text._ZN13tor_dirclient11get_decoder17hab1b7124f3e9b562E+0x92): undefined reference to `ZSTD_initDStream'
/usr/bin/ld: arti_bench.a19f5557-cgu.0:(.text._ZN13tor_dirclient11get_decoder17hab1b7124f3e9b562E+0xa4): undefined reference to `ZSTD_DCtx_loadDictionary'
/usr/bin/ld: arti_bench.a19f5557-cgu.0:(.text._ZN13tor_dirclient11get_decoder17hab1b7124f3e9b562E+0xb0): undefined reference to `ZSTD_isError'
/usr/bin/ld: arti_bench.a19f5557-cgu.0:(.text._ZN13tor_dirclient11get_decoder17hab1b7124f3e9b562E+0x4a7): undefined reference to `ZSTD_freeDCtx'
/usr/bin/ld: /builds/ajak/arti/target/x86_64-unknown-linux-gnu/release/deps/arti_bench-654d55f788aad115.arti_bench.a19f5557-cgu.0.rcgu.o: in function `core::ptr::drop_in_place<async_compression::futures::bufread::ZstdDecoder<futures_util::io::buf_reader::BufReader<&mut tor_proto::stream::data::DataStream>>>':
arti_bench.a19f5557-cgu.0:(.text._ZN4core3ptr171drop_in_place$LT$async_compression..futures..bufread..ZstdDecoder$LT$futures_util..io..buf_reader..BufReader$LT$$RF$mut$u20$tor_proto..stream..data..DataStream$GT$$GT$$GT$17h99de4fd791ae07fbE+0x1c): undefined reference to `ZSTD_freeDCtx'
/usr/bin/ld: /builds/ajak/arti/target/x86_64-unknown-linux-gnu/release/deps/arti_bench-654d55f788aad115.arti_bench.a19f5557-cgu.0.rcgu.o: in function `<async_compression::futures::bufread::generic::decoder::Decoder<R,D> as futures_io::if_std::AsyncRead>::poll_read':
arti_bench.a19f5557-cgu.0:(.text._ZN125_$LT$async_compression..futures..bufread..generic..decoder..Decoder$LT$R$C$D$GT$$u20$as$u20$futures_io..if_std..AsyncRead$GT$9poll_read17h2b0395e6145f82bbE+0xfd): undefined reference to `ZSTD_decompressStream'
/usr/bin/ld: arti_bench.a19f5557-cgu.0:(.text._ZN125_$LT$async_compression..futures..bufread..generic..decoder..Decoder$LT$R$C$D$GT$$u20$as$u20$futures_io..if_std..AsyncRead$GT$9poll_read17h2b0395e6145f82bbE+0x109): undefined reference to `ZSTD_isError'
/usr/bin/ld: arti_bench.a19f5557-cgu.0:(.text._ZN125_$LT$async_compression..futures..bufread..generic..decoder..Decoder$LT$R$C$D$GT$$u20$as$u20$futures_io..if_std..AsyncRead$GT$9poll_read17h2b0395e6145f82bbE+0x195): undefined reference to `ZSTD_DCtx_reset'
/usr/bin/ld: arti_bench.a19f5557-cgu.0:(.text._ZN125_$LT$async_compression..futures..bufread..generic..decoder..Decoder$LT$R$C$D$GT$$u20$as$u20$futures_io..if_std..AsyncRead$GT$9poll_read17h2b0395e6145f82bbE+0x1a1): undefined reference to `ZSTD_isError'
/usr/bin/ld: /builds/ajak/arti/target/x86_64-unknown-linux-gnu/release/deps/arti_bench-654d55f788aad115.arti_bench.a19f5557-cgu.0.rcgu.o: in function `zstd::map_error_code':
arti_bench.a19f5557-cgu.0:(.text._ZN4zstd14map_error_code17h4fcc207ec2913eb8E+0xd): undefined reference to `ZSTD_getErrorName'
/usr/bin/ld: /builds/ajak/arti/target/x86_64-unknown-linux-gnu/release/deps/arti_bench-654d55f788aad115.arti_bench.a19f5557-cgu.0.rcgu.o: in function `core::ptr::drop_in_place<zstd_safe::DCtx>':
arti_bench.a19f5557-cgu.0:(.text._ZN4core3ptr36drop_in_place$LT$zstd_safe..DCtx$GT$17h79d2f4f1a5ad312fE+0x2): undefined reference to `ZSTD_freeDCtx'
collect2: error: ld returned 1 exit status
I've hacked together a reproducer via Gitlab CI here:
ajak/arti@b4f2d29a https://gitlab.torproject.org/ajak/arti/-/jobs/215718