mhjacobson created this revision. mhjacobson added a reviewer: dylanmckay. mhjacobson added a project: clang. Herald added a subscriber: Jim. mhjacobson requested review of this revision. Herald added a subscriber: cfe-commits.
The way the GNU linker deals with static archives is that it only loads objects from the archive that are needed by *previously seen objects*. That is, in this case, if libm or libc depend on symbols from libgcc, they might be out of luck. As it happens, it's common for avr-libc to depend on symbols (specifically, the deduplicated function prologue/epilogue) from libgcc. The linker, as invoked by clang currently, fails to link the program in this case because of the argument ordering. In general, libraries should be supplied to the linker in a dependents-then- dependencies order. However, to more perfectly match GCC's behavior here--and since we don't control the libraries in question--simply use `--start-group` and `--end-group`. These flags tell the linker to repeatedly search all the intervening libraries until no new undefined symbol references are created. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D106854 Files: clang/lib/Driver/ToolChains/AVR.cpp Index: clang/lib/Driver/ToolChains/AVR.cpp =================================================================== --- clang/lib/Driver/ToolChains/AVR.cpp +++ clang/lib/Driver/ToolChains/AVR.cpp @@ -414,6 +414,8 @@ if (LinkStdlib) { assert(!CPU.empty() && "CPU name must be known in order to link stdlibs"); + CmdArgs.push_back("--start-group"); + // Add the object file for the CRT. std::string CrtFileName = std::string("-l:crt") + CPU + std::string(".o"); CmdArgs.push_back(Args.MakeArgString(CrtFileName)); @@ -425,6 +427,8 @@ // Add the link library specific to the MCU. CmdArgs.push_back(Args.MakeArgString(std::string("-l") + CPU)); + CmdArgs.push_back("--end-group"); + // Specify the family name as the emulation mode to use. // This is almost always required because otherwise avr-ld // will assume 'avr2' and warn about the program being larger
Index: clang/lib/Driver/ToolChains/AVR.cpp =================================================================== --- clang/lib/Driver/ToolChains/AVR.cpp +++ clang/lib/Driver/ToolChains/AVR.cpp @@ -414,6 +414,8 @@ if (LinkStdlib) { assert(!CPU.empty() && "CPU name must be known in order to link stdlibs"); + CmdArgs.push_back("--start-group"); + // Add the object file for the CRT. std::string CrtFileName = std::string("-l:crt") + CPU + std::string(".o"); CmdArgs.push_back(Args.MakeArgString(CrtFileName)); @@ -425,6 +427,8 @@ // Add the link library specific to the MCU. CmdArgs.push_back(Args.MakeArgString(std::string("-l") + CPU)); + CmdArgs.push_back("--end-group"); + // Specify the family name as the emulation mode to use. // This is almost always required because otherwise avr-ld // will assume 'avr2' and warn about the program being larger
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits