[DarwinDriver] Reapply: Use -lto_library to specify the path for libLTO.dylib
Reapply r248935.
Usually, when using LTO with a clang installation newer than the
system's one, there's a libLTO.dylib version mismatch and LTO fails. One
solution to this is to make ld point to the right libLTO.dylib by
changing DYLD_LIBRARY_PATH.
However, ld64 supports specifying the complete path to the desired
libLTO.dylib through the -lto_library option. This commit adds support
for the clang driver to use this option whenever it's capable of finding
a libLTO.dylib in clang's installed library directory. This way, we
don't need to rely on DYLD_LIBRARY_PATH nor get caught by version
mismatches.
Differential Revision: http://reviews.llvm.org/D13117
rdar://problem/7363476
llvm-svn: 249143
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index 1b741ee..9321222 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -6502,15 +6502,34 @@
options::OPT_fno_application_extension, false))
CmdArgs.push_back("-application_extension");
- // If we are using LTO, then automatically create a temporary file path for
- // the linker to use, so that it's lifetime will extend past a possible
- // dsymutil step.
- if (Version[0] >= 116 && D.IsUsingLTO(Args) && NeedsTempPath(Inputs)) {
- const char *TmpPath = C.getArgs().MakeArgString(
- D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
- C.addTempFile(TmpPath);
- CmdArgs.push_back("-object_path_lto");
- CmdArgs.push_back(TmpPath);
+ if (D.IsUsingLTO(Args)) {
+ // If we are using LTO, then automatically create a temporary file path for
+ // the linker to use, so that it's lifetime will extend past a possible
+ // dsymutil step.
+ if (Version[0] >= 116 && NeedsTempPath(Inputs)) {
+ const char *TmpPath = C.getArgs().MakeArgString(
+ D.GetTemporaryPath("cc", types::getTypeTempSuffix(types::TY_Object)));
+ C.addTempFile(TmpPath);
+ CmdArgs.push_back("-object_path_lto");
+ CmdArgs.push_back(TmpPath);
+ }
+
+ // Use -lto_library option to specify the libLTO.dylib path. Try to find
+ // it in clang installed libraries. If not found, the option is not used
+ // and 'ld' will use its default mechanism to search for libLTO.dylib.
+ if (Version[0] >= 133) {
+ // Search for libLTO in <InstalledDir>/../lib/libLTO.dylib
+ StringRef P = llvm::sys::path::parent_path(D.getInstalledDir());
+ SmallString<128> LibLTOPath(P);
+ llvm::sys::path::append(LibLTOPath, "lib");
+ llvm::sys::path::append(LibLTOPath, "libLTO.dylib");
+ if (llvm::sys::fs::exists(LibLTOPath)) {
+ CmdArgs.push_back("-lto_library");
+ CmdArgs.push_back(C.getArgs().MakeArgString(LibLTOPath));
+ } else {
+ D.Diag(diag::warn_drv_lto_libpath);
+ }
+ }
}
// Derived from the "link" spec.