calebzulawski updated this revision to Diff 490698.
calebzulawski added a comment.
This revision is basically the same as before, but with two changes:
- `darwin` targets (e.g. `x86_64-apple-darwin`) do not automatically detect the
SDK. There is another bug where these targets don't seem to properly pass the
target version (e.g. `x86_64-apple-darwin9`) whenever an SDK is provided.
- A new flag `--no-detect-xcode` disables this detection.
Fingers crossed, this passes all tests for me locally.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D136315/new/
https://reviews.llvm.org/D136315
Files:
clang/docs/UsersManual.rst
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Darwin.cpp
clang/test/Driver/darwin-ld-platform-version-macos.c
clang/test/Driver/darwin-sdk-detect.c
Index: clang/test/Driver/darwin-sdk-detect.c
===================================================================
--- /dev/null
+++ clang/test/Driver/darwin-sdk-detect.c
@@ -0,0 +1,20 @@
+// REQUIRES: system-darwin
+
+// Check that we default to running `xcrun --show-sdk-path` if there is no
+// SDKROOT defined in the environment.
+//
+// RUN: env -u SDKROOT %clang -target x86_64-apple-macos -c %s -### 2> %t.log
+// RUN: FileCheck --check-prefix=CHECK-XC < %t.log %s
+//
+// CHECK-XC: clang
+// CHECK-XC: "-cc1"
+// CHECK-XC: "-isysroot" "{{.*MacOSX[0-9\.]*\.sdk}}"
+
+// Check once again that we default to running `xcrun`, this time with another target.
+//
+// RUN: env -u SDKROOT %clang -target arm64-apple-ios -c %s -### 2> %t.log
+// RUN: FileCheck --check-prefix=CHECK-XC-IOS < %t.log %s
+//
+// CHECK-XC-IOS: clang
+// CHECK-XC-IOS: "-cc1"
+// CHECK-XC-IOS: "-isysroot" "{{.*iPhoneOS[0-9\.]*\.sdk}}"
Index: clang/test/Driver/darwin-ld-platform-version-macos.c
===================================================================
--- clang/test/Driver/darwin-ld-platform-version-macos.c
+++ clang/test/Driver/darwin-ld-platform-version-macos.c
@@ -41,7 +41,7 @@
// ARM64_NEW_1: "-platform_version" "macos" "11.1.0" "10.14"
// ARM64_OLD: "-macosx_version_min" "11.0.0"
-// RUN: %clang -target x86_64-apple-macos10.13 -mlinker-version=520 \
+// RUN: %clang --no-detect-xcode -target x86_64-apple-macos10.13 -mlinker-version=520 \
// RUN: -### %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=NOSDK %s
// RUN: %clang -target x86_64-apple-darwin17 -mlinker-version=520 \
Index: clang/lib/Driver/ToolChains/Darwin.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Darwin.cpp
+++ clang/lib/Driver/ToolChains/Darwin.cpp
@@ -18,15 +18,22 @@
#include "clang/Driver/DriverDiagnostic.h"
#include "clang/Driver/Options.h"
#include "clang/Driver/SanitizerArgs.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Option/ArgList.h"
#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/VirtualFileSystem.h"
#include <cstdlib> // ::getenv
+#include <memory> // std::unique_ptr
using namespace clang::driver;
using namespace clang::driver::tools;
@@ -2078,21 +2085,90 @@
void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
const OptTable &Opts = getDriver().getOpts();
- // Support allowing the SDKROOT environment variable used by xcrun and other
- // Xcode tools to define the default sysroot, by making it the default for
- // isysroot.
+ // On Apple platforms, standard headers and libraries are not provided with
+ // the base system (e.g. in /usr/{include,lib}). Instead, they are provided
+ // in various SDKs for the different Apple platforms. Clang needs to know
+ // where that SDK lives, and there are a couple ways this can be achieved:
+ //
+ // (1) If `-isysroot <path-to-SDK>` is passed explicitly, use that.
if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
// Warn if the path does not exist.
if (!getVFS().exists(A->getValue()))
getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
- } else {
- if (char *env = ::getenv("SDKROOT")) {
- // We only use this value as the default if it is an absolute path,
- // exists, and it is not the root path.
- if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
- StringRef(env) != "/") {
- Args.append(Args.MakeSeparateArg(
- nullptr, Opts.getOption(options::OPT_isysroot), env));
+ }
+
+ // (2) If the SDKROOT environment variable is defined and points to a valid
+ // path, use that. $SDKROOT is set by `xcrun` and other Xcode tools, so
+ // running `xcrun clang` will work by going through this path.
+ else if (char *env = ::getenv("SDKROOT")) {
+ // We only use this value as the default if it is an absolute path,
+ // exists, and it is not the root path.
+ if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
+ StringRef(env) != "/") {
+ Args.append(Args.MakeSeparateArg(
+ nullptr, Opts.getOption(options::OPT_isysroot), env));
+ }
+ }
+
+ // (3) Otherwise, we try to guess the path of the default SDK by running
+ // `xcrun --show-sdk-path`. This won't always be correct, but if the
+ // user wants to use the non-default SDK, they should specify it
+ // explicitly with methods (1) or (2) above.
+ else if (!Args.hasArg(options::OPT_no_detect_xcode)) {
+ llvm::SmallString<64> OutputFile;
+ llvm::sys::fs::createTemporaryFile("print-sdk-path", "" /* No Suffix */,
+ OutputFile);
+ llvm::FileRemover OutputRemover(OutputFile.c_str());
+ std::optional<llvm::StringRef> Redirects[] = {{""}, OutputFile.str(), {""}};
+
+ Optional<StringRef> SDKName = std::nullopt;
+ switch (getTriple().getOS()) {
+ case llvm::Triple::OSType::WatchOS:
+ if (getTriple().isSimulatorEnvironment())
+ SDKName = "watchsimulator";
+ else
+ SDKName = "watchos";
+ break;
+ case llvm::Triple::OSType::TvOS:
+ if (getTriple().isSimulatorEnvironment())
+ SDKName = "appletvsimulator";
+ else
+ SDKName = "appletvos";
+ break;
+ case llvm::Triple::OSType::IOS:
+ if (getTriple().isSimulatorEnvironment())
+ SDKName = "iphonesimulator";
+ else
+ SDKName = "iphoneos";
+ break;
+ case llvm::Triple::OSType::MacOSX:
+ SDKName = "macosx";
+ break;
+ case llvm::Triple::OSType::DriverKit:
+ SDKName = "driverkit";
+ break;
+ case llvm::Triple::OSType::Darwin:
+ break;
+ default:
+ llvm_unreachable("unknown kind of Darwin platform");
+ }
+
+ if (SDKName) {
+ int Result = llvm::sys::ExecuteAndWait(
+ "/usr/bin/xcrun",
+ {"/usr/bin/xcrun", "--sdk", *SDKName, "--show-sdk-path"},
+ /* Inherit environment from parent process */ std::nullopt, Redirects,
+ /* SecondsToWait */ 0, /*MemoryLimit*/ 0);
+ if (Result == 0) {
+ llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> OutputBuf =
+ llvm::MemoryBuffer::getFile(OutputFile.c_str(), /* IsText */ true);
+ if (OutputBuf) {
+ llvm::StringRef SdkPath = (*OutputBuf)->getBuffer().trim();
+ if (getVFS().exists(SdkPath)) {
+ Args.append(Args.MakeSeparateArg(
+ nullptr, Opts.getOption(options::OPT_isysroot), SdkPath));
+ }
+ }
}
}
}
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -4091,6 +4091,8 @@
def no_integrated_cpp : Flag<["-", "--"], "no-integrated-cpp">, Flags<[NoXarchOption]>;
def no_pedantic : Flag<["-", "--"], "no-pedantic">, Group<pedantic_Group>;
def no__dead__strip__inits__and__terms : Flag<["-"], "no_dead_strip_inits_and_terms">;
+def no_detect_xcode : Flag<["--"], "no-detect-xcode">,
+ Flags<[NoXarchOption]>, HelpText<"Disable detection of the Xcode SDK">;
def nobuiltininc : Flag<["-"], "nobuiltininc">, Flags<[CC1Option, CoreOption]>,
HelpText<"Disable builtin #include directories">,
MarshallingInfoNegativeFlag<HeaderSearchOpts<"UseBuiltinIncludes">>;
Index: clang/docs/UsersManual.rst
===================================================================
--- clang/docs/UsersManual.rst
+++ clang/docs/UsersManual.rst
@@ -3824,6 +3824,20 @@
Operating System Features and Limitations
-----------------------------------------
+Apple
+^^^^^
+
+On Apple platforms, the standard headers and libraries are not provided by
+the base system and are instead part of the Xcode SDK application. The location
+of the SDK is determined any of the following ways:
+
+- If passed to Clang, the ``-isysroot`` option specifies the path to the SDK.
+
+- If the sysroot isn't provided, the ``SDKROOT`` environment variable is checked.
+ This variable is set by various Xcode tools.
+
+- Otherwise, Clang uses Xcode's ``xcrun`` tool to find the SDK.
+
Windows
^^^^^^^
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits