https://github.com/ian-twilightcoder updated https://github.com/llvm/llvm-project/pull/120507
>From 3a651d6ff0b2435ee058b06a1da235b8b3bfdaed Mon Sep 17 00:00:00 2001 From: Ian Anderson <i...@apple.com> Date: Wed, 18 Dec 2024 16:31:19 -0800 Subject: [PATCH] [Darwin][Driver][clang] apple-none-macho orders the resource directory after internal-externc-isystem when nostdlibinc is used Embedded development often needs to use a different C standard library, replacing the existing one normally passed as -internal-externc-isystem. This works fine for an apple-macos target, but apple-none-macho doesn't work because the MachO driver doesn't implement AddClangSystemIncludeArgs to add the resource directory as -internal-isystem like most other drivers do. Move most of the search path logic from Darwin and DarwinClang down into an AppleMachO toolchain between the MachO and Darwin toolchains. --- clang/lib/Driver/Driver.cpp | 5 +- clang/lib/Driver/ToolChains/Darwin.cpp | 116 ++++++++++-------- clang/lib/Driver/ToolChains/Darwin.h | 73 +++++++---- clang/lib/Lex/InitHeaderSearch.cpp | 3 +- .../MacOSX15.1.sdk/embedded/usr/include/.keep | 0 .../embedded/usr/local/include/.keep | 0 .../MacOSX15.1.sdk/usr/include/c++/v1/.keep | 0 .../MacOSX15.1.sdk/usr/local/include/.keep | 0 .../Driver/darwin-embedded-search-paths.c | 43 +++++++ 9 files changed, 160 insertions(+), 80 deletions(-) create mode 100644 clang/test/Driver/Inputs/MacOSX15.1.sdk/embedded/usr/include/.keep create mode 100644 clang/test/Driver/Inputs/MacOSX15.1.sdk/embedded/usr/local/include/.keep create mode 100644 clang/test/Driver/Inputs/MacOSX15.1.sdk/usr/include/c++/v1/.keep create mode 100644 clang/test/Driver/Inputs/MacOSX15.1.sdk/usr/local/include/.keep create mode 100644 clang/test/Driver/darwin-embedded-search-paths.c diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index dc84c1b9d1cc4e..5ce69c0ffccb6a 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -6604,7 +6604,10 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, else if (Target.isOSBinFormatELF()) TC = std::make_unique<toolchains::Generic_ELF>(*this, Target, Args); else if (Target.isOSBinFormatMachO()) - TC = std::make_unique<toolchains::MachO>(*this, Target, Args); + if (Target.getVendor() == llvm::Triple::Apple) + TC = std::make_unique<toolchains::AppleMachO>(*this, Target, Args); + else + TC = std::make_unique<toolchains::MachO>(*this, Target, Args); else TC = std::make_unique<toolchains::Generic_GCC>(*this, Target, Args); } diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 4105d38d15d7d8..0da9281e5e34b6 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -961,15 +961,19 @@ void darwin::VerifyDebug::ConstructJob(Compilation &C, const JobAction &JA, } MachO::MachO(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : ToolChain(D, Triple, Args) { +: ToolChain(D, Triple, Args) { // We expect 'as', 'ld', etc. to be adjacent to our install dir. getProgramPaths().push_back(getDriver().Dir); } +AppleMachO::AppleMachO(const Driver &D, const llvm::Triple &Triple, + const ArgList &Args) + : MachO(D, Triple, Args), CudaInstallation(D, Triple, Args), + RocmInstallation(D, Triple, Args) {} + /// Darwin - Darwin tool chain for i386 and x86_64. Darwin::Darwin(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) - : MachO(D, Triple, Args), TargetInitialized(false), - CudaInstallation(D, Triple, Args), RocmInstallation(D, Triple, Args) {} + : AppleMachO(D, Triple, Args), TargetInitialized(false) {} types::ID MachO::LookupTypeForExtension(StringRef Ext) const { types::ID Ty = ToolChain::LookupTypeForExtension(Ext); @@ -1018,13 +1022,13 @@ bool Darwin::hasBlocksRuntime() const { } } -void Darwin::AddCudaIncludeArgs(const ArgList &DriverArgs, - ArgStringList &CC1Args) const { +void AppleMachO::AddCudaIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { CudaInstallation->AddCudaIncludeArgs(DriverArgs, CC1Args); } -void Darwin::AddHIPIncludeArgs(const ArgList &DriverArgs, - ArgStringList &CC1Args) const { +void AppleMachO::AddHIPIncludeArgs(const ArgList &DriverArgs, + ArgStringList &CC1Args) const { RocmInstallation->AddHIPIncludeArgs(DriverArgs, CC1Args); } @@ -2482,7 +2486,7 @@ static void AppendPlatformPrefix(SmallString<128> &Path, // Returns the effective sysroot from either -isysroot or --sysroot, plus the // platform prefix (if any). llvm::SmallString<128> -DarwinClang::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const { +AppleMachO::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const { llvm::SmallString<128> Path("/"); if (DriverArgs.hasArg(options::OPT_isysroot)) Path = DriverArgs.getLastArgValue(options::OPT_isysroot); @@ -2495,8 +2499,9 @@ DarwinClang::GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const { return Path; } -void DarwinClang::AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const { +void AppleMachO::AddClangSystemIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { const Driver &D = getDriver(); llvm::SmallString<128> Sysroot = GetEffectiveSysroot(DriverArgs); @@ -2574,7 +2579,7 @@ bool DarwinClang::AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverAr return getVFS().exists(Base); } -void DarwinClang::AddClangCXXStdlibIncludeArgs( +void AppleMachO::AddClangCXXStdlibIncludeArgs( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { // The implementation from a base class will pass through the -stdlib to @@ -2631,55 +2636,60 @@ void DarwinClang::AddClangCXXStdlibIncludeArgs( } case ToolChain::CST_Libstdcxx: - llvm::SmallString<128> UsrIncludeCxx = Sysroot; - llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++"); - - llvm::Triple::ArchType arch = getTriple().getArch(); - bool IsBaseFound = true; - switch (arch) { - default: break; - - case llvm::Triple::x86: - case llvm::Triple::x86_64: - IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, - "4.2.1", - "i686-apple-darwin10", - arch == llvm::Triple::x86_64 ? "x86_64" : ""); - IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, - "4.0.0", "i686-apple-darwin8", - ""); - break; + AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args); + break; + } +} - case llvm::Triple::arm: - case llvm::Triple::thumb: - IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, - "4.2.1", - "arm-apple-darwin10", - "v7"); - IsBaseFound |= AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, - "4.2.1", - "arm-apple-darwin10", - "v6"); - break; +void AppleMachO::AddGnuCPlusPlusIncludePaths( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const {} - case llvm::Triple::aarch64: - IsBaseFound = AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, - "4.2.1", - "arm64-apple-darwin10", - ""); - break; - } +void DarwinClang::AddGnuCPlusPlusIncludePaths( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const { + llvm::SmallString<128> UsrIncludeCxx = GetEffectiveSysroot(DriverArgs); + llvm::sys::path::append(UsrIncludeCxx, "usr", "include", "c++"); - if (!IsBaseFound) { - getDriver().Diag(diag::warn_drv_libstdcxx_not_found); - } + llvm::Triple::ArchType arch = getTriple().getArch(); + bool IsBaseFound = true; + switch (arch) { + default: + break; + + case llvm::Triple::x86: + case llvm::Triple::x86_64: + IsBaseFound = AddGnuCPlusPlusIncludePaths( + DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1", "i686-apple-darwin10", + arch == llvm::Triple::x86_64 ? "x86_64" : ""); + IsBaseFound |= AddGnuCPlusPlusIncludePaths( + DriverArgs, CC1Args, UsrIncludeCxx, "4.0.0", "i686-apple-darwin8", ""); + break; + + case llvm::Triple::arm: + case llvm::Triple::thumb: + IsBaseFound = + AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1", + "arm-apple-darwin10", "v7"); + IsBaseFound |= + AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1", + "arm-apple-darwin10", "v6"); + break; + case llvm::Triple::aarch64: + IsBaseFound = + AddGnuCPlusPlusIncludePaths(DriverArgs, CC1Args, UsrIncludeCxx, "4.2.1", + "arm64-apple-darwin10", ""); break; } + + if (!IsBaseFound) { + getDriver().Diag(diag::warn_drv_libstdcxx_not_found); + } } -void DarwinClang::AddCXXStdlibLibArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { +void AppleMachO::AddCXXStdlibLibArgs(const ArgList &Args, + ArgStringList &CmdArgs) const { CXXStdlibType Type = GetCXXStdlibType(Args); switch (Type) { @@ -3615,7 +3625,7 @@ SanitizerMask Darwin::getSupportedSanitizers() const { return Res; } -void Darwin::printVerboseInfo(raw_ostream &OS) const { +void AppleMachO::printVerboseInfo(raw_ostream &OS) const { CudaInstallation->print(OS); RocmInstallation->print(OS); } diff --git a/clang/lib/Driver/ToolChains/Darwin.h b/clang/lib/Driver/ToolChains/Darwin.h index 2e55b49682a7e9..8c7407f083a26e 100644 --- a/clang/lib/Driver/ToolChains/Darwin.h +++ b/clang/lib/Driver/ToolChains/Darwin.h @@ -290,8 +290,50 @@ class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain { /// } }; +/// Apple specific MachO extensions +class LLVM_LIBRARY_VISIBILITY AppleMachO : public MachO { +public: + AppleMachO(const Driver &D, const llvm::Triple &Triple, + const llvm::opt::ArgList &Args); + ~AppleMachO() override; + + /// } + /// @name Apple Specific ToolChain Implementation + /// { + void + AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + + void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + + void AddClangCXXStdlibIncludeArgs( + const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, + llvm::opt::ArgStringList &CmdArgs) const override; + + void printVerboseInfo(raw_ostream &OS) const override; + /// } + + LazyDetector<CudaInstallationDetector> CudaInstallation; + LazyDetector<RocmInstallationDetector> RocmInstallation; + +protected: + llvm::SmallString<128> + GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const; + +private: + virtual void + AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const; +}; + + /// Darwin - The base Darwin tool chain. -class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { +class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO { public: /// Whether the information on the target has been initialized. // @@ -329,9 +371,6 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { /// The target variant triple that was specified (if any). mutable std::optional<llvm::Triple> TargetVariantTriple; - LazyDetector<CudaInstallationDetector> CudaInstallation; - LazyDetector<RocmInstallationDetector> RocmInstallation; - private: void AddDeploymentTarget(llvm::opt::DerivedArgList &Args) const; @@ -343,7 +382,7 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { std::string ComputeEffectiveClangTriple(const llvm::opt::ArgList &Args, types::ID InputType) const override; - /// @name Apple Specific Toolchain Implementation + /// @name Darwin Specific Toolchain Implementation /// { void addMinVersionArgs(const llvm::opt::ArgList &Args, @@ -559,11 +598,6 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { ObjCRuntime getDefaultObjCRuntime(bool isNonFragile) const override; bool hasBlocksRuntime() const override; - void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; - void AddHIPIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; - bool UseObjCMixedDispatch() const override { // This is only used with the non-fragile ABI and non-legacy dispatch. @@ -594,8 +628,6 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public MachO { bool SupportsEmbeddedBitcode() const override; SanitizerMask getSupportedSanitizers() const override; - - void printVerboseInfo(raw_ostream &OS) const override; }; /// DarwinClang - The Darwin toolchain used by Clang. @@ -613,16 +645,6 @@ class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { llvm::opt::ArgStringList &CmdArgs, bool ForceLinkBuiltinRT = false) const override; - void AddClangCXXStdlibIncludeArgs( - const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; - - void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, - llvm::opt::ArgStringList &CC1Args) const override; - - void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const override; - void AddCCKextLibArgs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; @@ -647,15 +669,16 @@ class LLVM_LIBRARY_VISIBILITY DarwinClang : public Darwin { StringRef Sanitizer, bool shared = true) const; + void + AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, + llvm::opt::ArgStringList &CC1Args) const override; + bool AddGnuCPlusPlusIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, llvm::SmallString<128> Base, llvm::StringRef Version, llvm::StringRef ArchDir, llvm::StringRef BitDir) const; - - llvm::SmallString<128> - GetEffectiveSysroot(const llvm::opt::ArgList &DriverArgs) const; }; } // end namespace toolchains diff --git a/clang/lib/Lex/InitHeaderSearch.cpp b/clang/lib/Lex/InitHeaderSearch.cpp index ea02f5dfb62644..e3d44d584a053a 100644 --- a/clang/lib/Lex/InitHeaderSearch.cpp +++ b/clang/lib/Lex/InitHeaderSearch.cpp @@ -312,7 +312,8 @@ bool InitHeaderSearch::ShouldAddDefaultIncludePaths( break; case llvm::Triple::UnknownOS: - if (triple.isWasm()) + if (triple.isWasm() || ((triple.getVendor() == llvm::Triple::Apple) && + triple.isOSBinFormatMachO())) return false; break; diff --git a/clang/test/Driver/Inputs/MacOSX15.1.sdk/embedded/usr/include/.keep b/clang/test/Driver/Inputs/MacOSX15.1.sdk/embedded/usr/include/.keep new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/clang/test/Driver/Inputs/MacOSX15.1.sdk/embedded/usr/local/include/.keep b/clang/test/Driver/Inputs/MacOSX15.1.sdk/embedded/usr/local/include/.keep new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/clang/test/Driver/Inputs/MacOSX15.1.sdk/usr/include/c++/v1/.keep b/clang/test/Driver/Inputs/MacOSX15.1.sdk/usr/include/c++/v1/.keep new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/clang/test/Driver/Inputs/MacOSX15.1.sdk/usr/local/include/.keep b/clang/test/Driver/Inputs/MacOSX15.1.sdk/usr/local/include/.keep new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/clang/test/Driver/darwin-embedded-search-paths.c b/clang/test/Driver/darwin-embedded-search-paths.c new file mode 100644 index 00000000000000..2cb0fcf188d562 --- /dev/null +++ b/clang/test/Driver/darwin-embedded-search-paths.c @@ -0,0 +1,43 @@ +// UNSUPPORTED: system-windows +// Windows is unsupported because we use the Unix path separator `/` in the test. + +// Unlike the Darwin driver, the MachO driver doesn't add any framework search paths, +// only the normal header ones. +// RUN: %clang -x c -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CC1,NO-CXX,ULI,CI,UI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s + +// Unlike the Darwin driver, the MachO driver doesn't default to libc++ +// RUN: %clang -x c++ -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CC1,NO-CXX,ULI,CI,UI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s + +// However, if the user requests libc++, the MachO driver should find the search path. +// RUN: %clang -x c++ -stdlib=libc++ -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk -### -c %s 2>&1 \ +// RUN: | FileCheck --check-prefixes=CC1,CXX,ULI,CI,UI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s + +// Verify that embedded uses can swap in alternate usr/include and usr/local/include directories. +// usr/local/include is specified in the driver as -internal-isystem, however, the driver generated +// paths come before the paths in the driver arguments. In order to keep usr/local/include in the +// same position, -isystem has to be used instead of -Xclang -internal-isystem. There isn't an +// -externc-isystem, but it's ok to use -Xclang -internal-externc-isystem since the driver doesn't +// use that if -nostdlibinc or -nostdinc is passed. +// RUN: %clang -x c++ -stdlib=libc++ -target arm64-apple-none-macho -isysroot %S/Inputs/MacOSX15.1.sdk \ +// RUN: -nostdlibinc -isystem %S/Inputs/MacOSX15.1.sdk/embedded/usr/local/include \ +// RUN: -Xclang -internal-externc-isystem -Xclang %S/Inputs/MacOSX15.1.sdk/embedded/usr/include \ +// RUN: -### -c %s 2>&1 | FileCheck --check-prefixes=CC1,NO-CXX,EULI,CI,EUI,NO-FW -DSDKROOT=%S/Inputs/MacOSX15.1.sdk %s + + +// The ordering of these flags doesn't matter, and so this test is a little +// fragile. i.e. all of the -internal-isystem paths will be searched before the +// -internal-externc-isystem ones, and their order on the command line doesn't +// matter. The line order here is just the current order that the driver writes +// the cc1 arguments. + +// CC1: "-cc1" +// NO-CXX-NOT: "-internal-isystem" "[[SDKROOT]]/usr/include/c++/v1" +// CXX: "-internal-isystem" "[[SDKROOT]]/usr/include/c++/v1" +// ULI-SAME: "-internal-isystem" "[[SDKROOT]]/usr/local/include" +// EULI-SAME: "-isystem" "[[SDKROOT]]/embedded/usr/local/include" +// CI-SAME: "-internal-isystem" "{{.*}}/clang/{{[[:digit:].]*}}/include" +// UI-SAME: "-internal-externc-isystem" "[[SDKROOT]]/usr/include" +// EUI-SAME: "-internal-externc-isystem" "[[SDKROOT]]/embedded/usr/include" +// NO-FW-NOT: "-internal-iframework" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits