diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt index 27e8095534a65..5cdc573ac2466 100644 --- a/clang/CMakeLists.txt +++ b/clang/CMakeLists.txt @@ -214,6 +214,44 @@ if(GCC_INSTALL_PREFIX AND NOT USE_DEPRECATED_GCC_INSTALL_PREFIX) "See https://github.com/llvm/llvm-project/pull/77537 for detail.") endif() +cmake_dependent_option(CLANG_USE_XCSELECT "Use libxcselect to find the macOS SDK." OFF "APPLE" OFF) + +if(CLANG_USE_XCSELECT) + if(DEFAULT_SYSROOT) + message(FATAL_ERROR "Setting DEFAULT_SYSROOT is incompatible with CLANG_USE_XCSELECT.") + endif() + + check_include_file(xcselect.h CLANG_HAVE_XCSELECT_H) + if(NOT CLANG_HAVE_XCSELECT_H) + message(FATAL_ERROR "CLANG_USE_XCSELECT is enabled but xcselect.h was not found.") + endif() + + include(CheckSymbolExists) + list(APPEND CMAKE_REQUIRED_LIBRARIES xcselect) + check_symbol_exists(xcselect_host_sdk_path xcselect.h CLANG_HAVE_XCSELECT_HOST_SDK_PATH) + list(REMOVE_ITEM CMAKE_REQUIRED_LIBRARIES xcselect) + + if(NOT CLANG_HAVE_XCSELECT_HOST_SDK_PATH) + message(FATAL_ERROR "CLANG_USE_XCSELECT is enabled but either libxcselect is not available " + "or it is missing xcselect_host_sdk_path.") + endif() + + set(XCSELECT_VALID_POLICIES LATEST MATCHING_ONLY MATCHING_PREFERRED) + set(CLANG_XCSELECT_HOST_SDK_POLICY "LATEST" CACHE STRING + "Policy to use for xcselect. One of: ${XCSELECT_VALID_POLICIES}") + set_property(CACHE CLANG_XCSELECT_HOST_SDK_POLICY PROPERTY STRINGS ${XCSELECT_VALID_POLICIES}) + string(TOUPPER ${CLANG_XCSELECT_HOST_SDK_POLICY} CLANG_XCSELECT_HOST_SDK_POLICY) + list(JOIN XCSELECT_VALID_POLICIES "|" XCSELECT_POLICY_REGEX) + + if(NOT CLANG_XCSELECT_HOST_SDK_POLICY MATCHES "^XCSELECT_HOST_SDK_POLICY_(${XCSELECT_POLICY_REGEX})$") + if(NOT CLANG_XCSELECT_HOST_SDK_POLICY IN_LIST XCSELECT_VALID_POLICIES) + message(FATAL_ERROR + "CLANG_XCSELECT_HOST_SDK_POLICY (${CLANG_XCSELECT_HOST_SDK_POLICY}) must be one of: ${XCSELECT_VALID_POLICIES}") + endif() + set(CLANG_XCSELECT_HOST_SDK_POLICY "XCSELECT_HOST_SDK_POLICY_${CLANG_XCSELECT_HOST_SDK_POLICY}") + endif() +endif() + set(ENABLE_LINKER_BUILD_ID OFF CACHE BOOL "pass --build-id to ld") set(ENABLE_X86_RELAX_RELOCATIONS ON CACHE BOOL diff --git a/clang/include/clang/Config/config.h.cmake b/clang/include/clang/Config/config.h.cmake index 27ed69e21562b..9ae0c6a4b9e11 100644 --- a/clang/include/clang/Config/config.h.cmake +++ b/clang/include/clang/Config/config.h.cmake @@ -86,4 +86,10 @@ /* Whether CIR is built into Clang */ #cmakedefine01 CLANG_ENABLE_CIR +/* Whether to use xcselect to find the macOS SDK */ +#cmakedefine CLANG_USE_XCSELECT + +/* Policy to use for xcselect */ +#cmakedefine CLANG_XCSELECT_HOST_SDK_POLICY ${CLANG_XCSELECT_HOST_SDK_POLICY} + #endif diff --git a/clang/lib/Driver/CMakeLists.txt b/clang/lib/Driver/CMakeLists.txt index 4fd10bf671512..299de2ef30470 100644 --- a/clang/lib/Driver/CMakeLists.txt +++ b/clang/lib/Driver/CMakeLists.txt @@ -14,6 +14,10 @@ if(WIN32) set(system_libs version) endif() +if(CLANG_USE_XCSELECT) + set(system_libs xcselect) +endif() + add_clang_library(clangDriver Action.cpp Compilation.cpp diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 87380869f6fda..ed292dfa62e10 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -29,6 +29,10 @@ #include "llvm/TargetParser/Triple.h" #include // ::getenv +#ifdef CLANG_USE_XCSELECT +#include // ::xcselect_host_sdk_path +#endif + using namespace clang::driver; using namespace clang::driver::tools; using namespace clang::driver::toolchains; @@ -2257,17 +2261,27 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { // 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)); - } + } else if (const 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)); } } +#ifdef CLANG_USE_XCSELECT + // FIXME: This should check for `getTriple().isMacOSX()`, but this breaks + // many tests. See https://github.com/llvm/llvm-project/pull/119670. + else if (getTriple().getOS() == llvm::Triple::MacOSX) { + char *p; + if (!::xcselect_host_sdk_path(CLANG_XCSELECT_HOST_SDK_POLICY, &p)) { + Args.append(Args.MakeSeparateArg( + nullptr, Opts.getOption(options::OPT_isysroot), p)); + ::free(p); + } + } +#endif // Read the SDKSettings.json file for more information, like the SDK version // that we can pass down to the compiler. diff --git a/clang/test/CMakeLists.txt b/clang/test/CMakeLists.txt index 5369dc92f69e8..78ef8bc6e690a 100644 --- a/clang/test/CMakeLists.txt +++ b/clang/test/CMakeLists.txt @@ -10,6 +10,7 @@ llvm_canonicalize_cmake_booleans( CLANG_PLUGIN_SUPPORT CLANG_SPAWN_CC1 CLANG_ENABLE_CIR + CLANG_USE_XCSELECT ENABLE_BACKTRACES LLVM_BUILD_EXAMPLES LLVM_BYE_LINK_INTO_TOOLS diff --git a/clang/test/Driver/darwin-ld-platform-version-macos-nosdk.c b/clang/test/Driver/darwin-ld-platform-version-macos-nosdk.c new file mode 100644 index 0000000000000..c5e0dd94c5925 --- /dev/null +++ b/clang/test/Driver/darwin-ld-platform-version-macos-nosdk.c @@ -0,0 +1,12 @@ +// UNSUPPORTED: xcselect +// CLANG_USE_XCSELECT will always have an SDK inferred. + +// RUN: touch %t.o + +// RUN: %clang -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 \ +// RUN: -### %t.o 2>&1 \ +// RUN: | FileCheck --check-prefix=NOSDK %s +// NOSDK: "-platform_version" "macos" "10.13.0" "10.13.0" diff --git a/clang/test/Driver/darwin-ld-platform-version-macos.c b/clang/test/Driver/darwin-ld-platform-version-macos.c index 355df8dfc1bc2..0804c850242c2 100644 --- a/clang/test/Driver/darwin-ld-platform-version-macos.c +++ b/clang/test/Driver/darwin-ld-platform-version-macos.c @@ -43,8 +43,8 @@ // RUN: %clang -target x86_64-apple-macos10.13 -mlinker-version=520 \ // RUN: -### %t.o 2>&1 \ -// RUN: | FileCheck --check-prefix=NOSDK %s +// RUN: | FileCheck --check-prefix=INFERRED-SDK %s // RUN: %clang -target x86_64-apple-darwin17 -mlinker-version=520 \ // RUN: -### %t.o 2>&1 \ -// RUN: | FileCheck --check-prefix=NOSDK %s -// NOSDK: "-platform_version" "macos" "10.13.0" "10.13.0" +// RUN: | FileCheck --check-prefix=INFERRED-SDK %s +// INFERRED-SDK: "-platform_version" "macos" "10.13.0" "{{[0-9]+(\.[0-9]+)*}}" diff --git a/clang/test/Driver/xcselect.c b/clang/test/Driver/xcselect.c new file mode 100644 index 0000000000000..01cd4aca5ec23 --- /dev/null +++ b/clang/test/Driver/xcselect.c @@ -0,0 +1,5 @@ +// REQUIRES: xcselect +// RUN: %clang -target arm64-apple-macosx -c -### %s 2> %t.log +// RUN: FileCheck %s <%t.log + +// CHECK: "-isysroot" "{{.*}}/SDKs/MacOSX{{([0-9]+(\.[0-9]+)?)?}}.sdk" diff --git a/clang/test/lit.cfg.py b/clang/test/lit.cfg.py index 7e7934d5fe0f5..aadc9f85a168b 100644 --- a/clang/test/lit.cfg.py +++ b/clang/test/lit.cfg.py @@ -338,6 +338,8 @@ def calculate_arch_features(arch_string): if config.have_llvm_driver: config.available_features.add("llvm-driver") +if config.use_xcselect: + config.available_features.add("xcselect") # Some tests perform deep recursion, which requires a larger pthread stack size # than the relatively low default of 192 KiB for 64-bit processes on AIX. The diff --git a/clang/test/lit.site.cfg.py.in b/clang/test/lit.site.cfg.py.in index 1cbd876ac5bb9..95b3a866f64b3 100644 --- a/clang/test/lit.site.cfg.py.in +++ b/clang/test/lit.site.cfg.py.in @@ -44,6 +44,7 @@ config.standalone_build = @CLANG_BUILT_STANDALONE@ config.ppc_linux_default_ieeelongdouble = @PPC_LINUX_DEFAULT_IEEELONGDOUBLE@ config.have_llvm_driver = @LLVM_TOOL_LLVM_DRIVER_BUILD@ config.substitutions.append(("%llvm-version-major", "@LLVM_VERSION_MAJOR@")) +config.use_xcselect = @CLANG_USE_XCSELECT@ import lit.llvm lit.llvm.initialize(lit_config, config)