@@ -426,24 +426,6 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
426426 Args.AddAllArgs (CmdArgs, options::OPT_sub__library);
427427 Args.AddAllArgs (CmdArgs, options::OPT_sub__umbrella);
428428
429- // Pass -L <toolchain-install>/bin/../lib/ to linker to prioritize the
430- // toolchain's libc++.dylib over the sysroot-provided one. This matches
431- // what we do for determining which libc++ headers to use.
432- //
433- // If the toolchain does not provide libc++.dylib, we will fall back to the
434- // normal system search paths for finding libc++.dylib (on Darwin, that would
435- // be in the SDK so we would find Apple's system libc++ instead of using
436- // LLVM's).
437- {
438- llvm::SmallString<128 > InstallBinPath =
439- llvm::StringRef (D.Dir ); // <install>/bin
440- llvm::SmallString<128 > InstallLibPath = InstallBinPath;
441- llvm::sys::path::append (InstallLibPath, " .." ,
442- " lib" ); // <install>/bin/../lib
443- CmdArgs.push_back (" -L" );
444- CmdArgs.push_back (C.getArgs ().MakeArgString (InstallLibPath));
445- }
446-
447429 // Give --sysroot= preference, over the Apple specific behavior to also use
448430 // --isysroot as the syslibroot.
449431 // We check `OPT__sysroot_EQ` directly instead of `getSysRoot` to make sure we
@@ -2864,11 +2846,49 @@ void AppleMachO::AddCXXStdlibLibArgs(const ArgList &Args,
28642846 CXXStdlibType Type = GetCXXStdlibType (Args);
28652847
28662848 switch (Type) {
2867- case ToolChain::CST_Libcxx:
2868- CmdArgs.push_back (" -lc++" );
2849+ case ToolChain::CST_Libcxx: {
2850+ // On Darwin, we prioritize a libc++ located in the toolchain to a libc++
2851+ // located in the sysroot. Unlike the driver for most other platforms, on
2852+ // Darwin we do that by explicitly passing the library path to the linker
2853+ // to avoid having to add the toolchain's `lib/` directory to the linker
2854+ // search path, which would make other libraries findable as well.
2855+ //
2856+ // Prefering the toolchain library over the sysroot library matches the
2857+ // behavior we have for headers, where we prefer headers in the toolchain
2858+ // over headers in the sysroot if there are any. Note that it's important
2859+ // for the header search path behavior to match the link-time search path
2860+ // behavior to ensure that we link the program against a library that
2861+ // matches the headers that were used to compile it.
2862+ //
2863+ // Otherwise, we end up compiling against some set of headers and then
2864+ // linking against a different library (which, confusingly, shares the same
2865+ // name) which may have been configured with different options, be at a
2866+ // different version, etc.
2867+ SmallString<128 > InstallLib = llvm::sys::path::parent_path (getDriver ().Dir );
2868+ llvm::sys::path::append (InstallLib, " lib" ); // <install>/bin/../lib
2869+ auto Link = [&](StringRef Library) {
2870+ SmallString<128 > Shared (InstallLib);
2871+ llvm::sys::path::append (Shared,
2872+ SmallString<4 >(" lib" ) + Library + " .dylib" );
2873+ SmallString<128 > Static (InstallLib);
2874+ llvm::sys::path::append (Static, SmallString<4 >(" lib" ) + Library + " .a" );
2875+ SmallString<32 > Relative (" -l" );
2876+ Relative += Library;
2877+
2878+ if (getVFS ().exists (Shared)) {
2879+ CmdArgs.push_back (Args.MakeArgString (Shared));
2880+ } else if (getVFS ().exists (Static)) {
2881+ CmdArgs.push_back (Args.MakeArgString (Static));
2882+ } else {
2883+ CmdArgs.push_back (Args.MakeArgString (Relative));
2884+ }
2885+ };
2886+
2887+ Link (" c++" );
28692888 if (Args.hasArg (options::OPT_fexperimental_library))
2870- CmdArgs. push_back ( " -lc ++experimental" );
2889+ Link ( " c ++experimental" );
28712890 break ;
2891+ }
28722892
28732893 case ToolChain::CST_Libstdcxx:
28742894 // Unfortunately, -lstdc++ doesn't always exist in the standard search path;
0 commit comments