diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/mock-libcxx/lib/libc++.dylib b/clang-tools-extra/test/clang-tidy/infrastructure/Inputs/mock-libcxx/lib/libc++.dylib new file mode 100644 diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -410,6 +410,32 @@ Args.AddAllArgs(CmdArgs, options::OPT_sub__library); Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella); + // If the toolchain contains libc++.dylib (in + // /bin/../lib/libc++.dylib), use that instead of the + // sysroot-provided one. This matches what we do for determining which libc++ + // headers to use. + llvm::SmallString<128> InstallBinPath = + llvm::StringRef(D.getInstalledDir()); // /bin + llvm::SmallString<128> LibCxxHeadersPath = InstallBinPath; + llvm::sys::path::append(LibCxxHeadersPath, "..", "include", "c++", + "v1"); // /bin/../include/c++/v1 + llvm::SmallString<128> LibCxxDylibDirPath = InstallBinPath; + llvm::sys::path::append(LibCxxDylibDirPath, "..", + "lib"); // /bin/../lib + llvm::SmallString<128> LibCxxDylibPath = LibCxxDylibDirPath; + llvm::sys::path::append(LibCxxDylibPath, + "libc++.dylib"); // /bin/../lib/libc++.dylib + // Checking the absence -nostdinc, -nostdinc++ or -nostdlib arguments + // arguments and the validity of paths to both the libc++ headers and + // libc++.dylib in the toolchain. + if ((!Args.hasArg(options::OPT_nostdinc, options::OPT_nostdlibinc, + options::OPT_nostdincxx)) && + D.getVFS().exists(LibCxxDylibPath) && + D.getVFS().exists(LibCxxHeadersPath)) { + CmdArgs.push_back("-L"); + CmdArgs.push_back(C.getArgs().MakeArgString(LibCxxDylibDirPath)); + } + // Give --sysroot= preference, over the Apple specific behavior to also use // --isysroot as the syslibroot. StringRef sysroot = C.getSysRoot(); @@ -2442,8 +2468,14 @@ // parent_path. llvm::SmallString<128> InstallBin = llvm::StringRef(getDriver().getInstalledDir()); // /bin + llvm::SmallString<128> LibCxxDylibPath = InstallBin; + llvm::sys::path::append( + LibCxxDylibPath, "..", "lib", + "libc++.dylib"); // /bin/../lib/libc++.dylib llvm::sys::path::append(InstallBin, "..", "include", "c++", "v1"); - if (getVFS().exists(InstallBin)) { + // Checking if paths to both the libc++ headers and libc++.dylib in the + // toolchain are valid. + if (getVFS().exists(InstallBin) && getVFS().exists(LibCxxDylibPath)) { addSystemInclude(DriverArgs, CC1Args, InstallBin); return; } else if (DriverArgs.hasArg(options::OPT_v)) { diff --git a/clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++.dylib b/clang/test/Driver/Inputs/basic_darwin_toolchain/usr/lib/libc++.dylib new file mode 100644 diff --git a/clang/test/Driver/darwin-header-search-libcxx.cpp b/clang/test/Driver/darwin-header-search-libcxx.cpp --- a/clang/test/Driver/darwin-header-search-libcxx.cpp +++ b/clang/test/Driver/darwin-header-search-libcxx.cpp @@ -116,7 +116,7 @@ // RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: -stdlib=platform \ // RUN: -nostdinc++ \ -// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \ +// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ // RUN: --check-prefix=CHECK-LIBCXX-NOSTDINCXX %s // CHECK-LIBCXX-NOSTDINCXX: "-cc1" diff --git a/clang/test/Driver/darwin-header-search-libcxx.cpp b/clang/test/Driver/darwin-link-libcxx-from-toolchain.cpp copy from clang/test/Driver/darwin-header-search-libcxx.cpp copy to clang/test/Driver/darwin-link-libcxx-from-toolchain.cpp --- a/clang/test/Driver/darwin-header-search-libcxx.cpp +++ b/clang/test/Driver/darwin-link-libcxx-from-toolchain.cpp @@ -1,63 +1,49 @@ // UNSUPPORTED: system-windows -// General tests that the header search paths for libc++ detected by the driver -// and passed to CC1 are correct on Darwin platforms. +// Tests to check that we pass -L /bin/../lib/libc++.dylib to link with the toolchain's libc++.dylib +// whenever we are including the toolchain's libc++ headers // Check without a sysroot and without headers alongside the installation -// (no include path should be added, and no warning or error). // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin \ // RUN: -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \ -// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-NONE %s -// CHECK-LIBCXX-NONE: "-cc1" +// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-2 %s // Check with only headers alongside the installation (those should be used). // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin \ // RUN: -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ // RUN: --sysroot="" \ // RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ -// RUN: --check-prefix=CHECK-LIBCXX-TOOLCHAIN-1 %s -// CHECK-LIBCXX-TOOLCHAIN-1: "-cc1" -// CHECK-LIBCXX-TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" -// CHECK-LIBCXX-TOOLCHAIN-1-NOT: "-internal-isystem" "/usr/include/c++/v1" +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-1 %s // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin \ // RUN: -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ // RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \ // RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ // RUN: -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \ -// RUN: --check-prefix=CHECK-LIBCXX-TOOLCHAIN-2 %s -// CHECK-LIBCXX-TOOLCHAIN-2: "-cc1" -// CHECK-LIBCXX-TOOLCHAIN-2: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" -// CHECK-LIBCXX-TOOLCHAIN-2-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-1 %s // Check with only headers in the sysroot (those should be used). // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin \ // RUN: -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \ // RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \ -// RUN: --check-prefix=CHECK-LIBCXX-SYSROOT-1 %s -// CHECK-LIBCXX-SYSROOT-1: "-cc1" -// CHECK-LIBCXX-SYSROOT-1: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" -// CHECK-LIBCXX-SYSROOT-1-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-2 %s // Check with both headers in the sysroot and headers alongside the installation -// (the headers in the toolchain should be preferred over the headers). -// Ensure that both -isysroot and --sysroot work, and that isysroot has precedence -// over --sysroot. // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin \ // RUN: -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ @@ -65,9 +51,9 @@ // RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ -// RUN: --check-prefix=CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1 %s +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-1 %s // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin \ // RUN: -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ @@ -75,9 +61,9 @@ // RUN: --sysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ -// RUN: --check-prefix=CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1 %s +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-1 %s // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin \ // RUN: -stdlib=libc++ \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ @@ -86,16 +72,13 @@ // RUN: --sysroot %S/Inputs/basic_darwin_sdk_no_libcxx \ // RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ -// RUN: --check-prefix=CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1 %s +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-1 %s // -// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-cc1" -// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" -// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" // Make sure that using -nostdinc, -nostdinc++ or -nostdlib will drop both the toolchain -// C++ include path and the sysroot one. +// C++ include path and the sysroot one and thus not link with toolchain's libc++.dylib // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin16 \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ @@ -104,26 +87,20 @@ // RUN: -nostdinc \ // RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ -// RUN: --check-prefix=CHECK-LIBCXX-NOSTDLIBINC %s -// CHECK-LIBCXX-NOSTDINC: "-cc1" -// CHECK-LIBCXX-NOSTDINC-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" -// CHECK-LIBCXX-NOSTDINC-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-2 %s // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin16 \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ // RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: -stdlib=platform \ // RUN: -nostdinc++ \ -// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \ +// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ -// RUN: --check-prefix=CHECK-LIBCXX-NOSTDINCXX %s -// CHECK-LIBCXX-NOSTDINCXX: "-cc1" -// CHECK-LIBCXX-NOSTDINCXX-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" -// CHECK-LIBCXX-NOSTDINCXX-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-2 %s // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin16 \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir \ @@ -132,43 +109,41 @@ // RUN: -nostdlibinc \ // RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \ -// RUN: --check-prefix=CHECK-LIBCXX-NOSTDLIBINC %s -// CHECK-LIBCXX-NOSTDLIBINC: "-cc1" -// CHECK-LIBCXX-NOSTDLIBINC-NOT: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" -// CHECK-LIBCXX-NOSTDLIBINC-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-2 %s -// Make sure we explain that we considered a path but didn't add it when it -// doesn't exist. +// Make sure we explain that we do not link with toolchain's libc++ when the paths to +// toolchain's libc++ headers doesn't exist. // -// RUN: %clang %s -fsyntax-only -v 2>&1 \ +// RUN: %clang -### %s -v 2>&1 \ // RUN: --target=x86_64-apple-darwin \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \ // RUN: -isysroot %S/Inputs/basic_darwin_sdk \ // RUN: -stdlib=libc++ \ // RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \ -// RUN: --check-prefix=CHECK-LIBCXX-MISSING-TOOLCHAIN %s -// CHECK-LIBCXX-MISSING-TOOLCHAIN: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-2 %s // -// RUN: %clang %s -fsyntax-only -v 2>&1 \ +// RUN: %clang -### %s -v 2>&1 \ // RUN: --target=x86_64-apple-darwin \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \ // RUN: -isysroot %S/Inputs/basic_darwin_sdk_no_libcxx \ // RUN: -stdlib=libc++ \ // RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_no_libcxx \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \ -// RUN: --check-prefix=CHECK-LIBCXX-MISSING-BOTH %s -// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[TOOLCHAIN]]/usr/bin/../include/c++/v1" -// CHECK-LIBCXX-MISSING-BOTH: ignoring nonexistent directory "[[SYSROOT]]/usr/include/c++/v1" +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-2 %s // Make sure that on Darwin, we use libc++ header search paths by default even when -// -stdlib= isn't passed. +// -stdlib= isn't passed and do not link to toolchain's libc++.dylib in this case. // -// RUN: %clang -### %s -fsyntax-only 2>&1 \ +// RUN: %clang -### %s 2>&1 \ // RUN: --target=x86_64-apple-darwin \ // RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \ // RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \ // RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \ -// RUN: --check-prefix=CHECK-LIBCXX-STDLIB-UNSPECIFIED %s -// CHECK-LIBCXX-STDLIB-UNSPECIFIED: "-cc1" -// CHECK-LIBCXX-STDLIB-UNSPECIFIED: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1" +// RUN: --check-prefix=CHECK-TOOLCHAIN-LIBCXX-LINKING-2 %s + +// CHECK-TOOLCHAIN-LIBCXX-LINKING-1: "/usr/bin/ld" +// CHECK-TOOLCHAIN-LIBCXX-LINKING-1: "-L" "[[TOOLCHAIN]]/usr/bin/../lib" + +// CHECK-TOOLCHAIN-LIBCXX-LINKING-2: "/usr/bin/ld" +// CHECK-TOOLCHAIN-LIBCXX-LINKING-2-NOT: "-L" "[[TOOLCHAIN]]/usr/bin/../lib"