On Sun, 12 Jul 2026 at 18:03, René J.V. Bertin via ffmpeg-devel < [email protected]> wrote:
> On Sunday July 12 2026 15:40:01 Dennis Mungai wrote: > > Hi, > > Thanks for the detailed answer! > > > >LTO symbol resolution differently—specifically, it has a known tendency to > >prematurely discard native assembly objects if the initial pass doesn't > see > >them referenced by a standard ELF object (since it can't natively peer > into > >the bitcode without the plugin). > > Yes, this would explain this, though I do have the plugin installed (and > `nm` will find and use it). > > >Why GCC 13 Succeeded: > > I simply put that off as "designed to work with the rest of standard > toolchain" ;) > > >Rolling back to binutils 2.43.1 and using the older ld didn't fix the > issue > >because the intermediate build artifacts were already poisoned. > > Except that I *did* do a `make clean`, so I'm still not certain what > happened there. Even tried deleting the entire directory to be certain no > artifacts remained. > > > >To bypass the binutils plugin dependency entirely, you should force > >FFmpeg's configure script to use the LLVM equivalents. Run a make clean > (or git > >clean -xfd to purge all poisoned intermediate artifacts), and append these > >explicitly to your FFmpeg configure options: > > > >--ar=llvm-ar \ > >--nm=llvm-nm \ > >--ranlib=llvm-ranlib \ > >--extra-ldflags="-fuse-ld=lld" > > > >Using lld instead of GNU ld ensures seamless symbol resolution between > LLVM > >bitcode and FFmpeg's native x86 assembly optimizations. > > > > >Apply the change and retest. > > Doh, I have options in my build framework to use lld, and it never > occurred to me to try that... (but see below). > As to llvm-ar and family, I already set those (via --ar, --nm AND the AR > and NM env. variables) to the llvm versions before invoking the configure > script (the RANLIB variable i usually set to /bin/echo as in my experience > it is rarely needed and [was] more likely to cause issues). > > Adding `-fuse-ld=lld` (via LDFLAGS) doesn't solve the issue: ld.lld > complains just as much about the same symbols, it just adds the suggestion > that that is because of `--no-allow-shlib-undefined`. When I add > `--allow-shlib-undefined` to LDFLAGS the build does succeed, but you end up > with a libavcodec library that won't load because of these missing symbols. > > NB: my clang build is configured to use lld by default, so why does the > build even use `ld` instead if I don't touch the defaults? Or, why doesn't > `--enable-lto` use the entire LLVM toolchain if it detects that clang is > being used? > > > R. > _______________________________________________ > ffmpeg-devel mailing list -- [email protected] > To unsubscribe send an email to [email protected] Hi René, Thanks for the follow-up and the additional context in the email above. Your clarification actually points directly to the root cause of the issue. Since you confirmed that you wiped the directory entirely to ensure no artifacts remained, we can completely rule out lingering BFD plugin issues. The true culprit is hiding in your environment variables. The RANLIB Trap You mentioned that you usually set the RANLIB variable to /bin/echo because it is rarely needed in your experience. While it is true that standard C builds can often skip ranlib (since modern ar tools automatically generate the archive index), *LTO changes the rules of engagement completely*. When you build with --enable-lto, Clang outputs LLVM intermediate representation (IR) bitcode rather than standard machine code. If llvm-ranlib is bypassed by replacing it with /bin/echo, the static archives (like libavcodec.a) are generated without a valid symbol index for those bitcode objects. Consequently, when the linker—even ld.lld—attempts to link libavcodec.so, it scans the unindexed archive, assumes it contains nothing useful, and silently drops the assembly-backed symbols. This perfectly explains why passing --allow-shlib-undefined allows the build to finish but yields a library that refuses to load at runtime due to missing symbols. Answering Your Toolchain Questions To address the questions you raised at the end of your message: - *Why does the build use ld if Clang defaults to lld?* FFmpeg's configure script is highly conservative. It does not blindly inherit the compiler's internal default linker. Instead, it probes the host environment and typically defaults to the system ld unless --ld=lld or --extra-ldflags="-fuse-ld=lld" is strictly passed. - *Why doesn't --enable-lto use the entire LLVM toolchain if it detects Clang?* FFmpeg is designed to be compiler-agnostic. The --enable-lto flag operates across GCC, Clang, and MSVC. The configure script avoids making presumptions about your toolchain hierarchy because many environments purposefully mix toolchains (for example, using Apple's cctools alongside Clang). The Fix To resolve this, simply stop overriding RANLIB with /bin/echo. Set it to its proper LLVM equivalent (llvm-ranlib), and keep your framework configured to use lld. Let me know if restoring llvm-ranlib gets your reproducible builds back on track. <[email protected]> _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
