From a16be21df9273f41f583e783264b77b9904f92af Mon Sep 17 00:00:00 2001 From: Danilo Piparo Date: Fri, 17 Jul 2026 14:55:38 +0200 Subject: [PATCH 1/2] [cling] Do not rely on hardcoded SDK path, but find dynamically In order of priority: - Check if the -isysroot argument is being passed - If not, honour the env variable SDKROOT - Otherwise, use xcrun to locate the SDK (cherry picked from commit 96d4abf01f253302470517a3db130741a54711aa) --- .../cling/lib/Interpreter/CIFactory.cpp | 46 +++++++++++++++++-- .../cling/lib/Interpreter/CMakeLists.txt | 19 -------- 2 files changed, 43 insertions(+), 22 deletions(-) diff --git a/interpreter/cling/lib/Interpreter/CIFactory.cpp b/interpreter/cling/lib/Interpreter/CIFactory.cpp index 0d015ef24f277..9e5c7d81cb74e 100644 --- a/interpreter/cling/lib/Interpreter/CIFactory.cpp +++ b/interpreter/cling/lib/Interpreter/CIFactory.cpp @@ -365,9 +365,49 @@ namespace { sArguments.addArgument("-nostdinc++"); } - #ifdef CLING_OSX_SYSROOT - sArguments.addArgument("-isysroot", CLING_OSX_SYSROOT); - #endif + #ifdef __APPLE__ + // + // On macOS, we try to find the SDK location through the following steps: + // - We check if the -isysroot option is specified and the directory exists + // - If not, we check for the directory specified by the SDKROOT env + // variable, which is handled by the driver internally + // - If also that is not there, we execute xcrun as a last resort + // + { + auto arvIt = std::find(args.begin(), args.end(), "-isysroot"); + std::string cling_osx_sysroot_directory; + if(arvIt != args.end() && ++arvIt != args.end()) + cling_osx_sysroot_directory = *arvIt; + if (!llvm::sys::fs::exists(cling_osx_sysroot_directory)) { + if (!::getenv("SDKROOT")) { + std::array buffer; + const auto xcrun_cmd = "xcrun --show-sdk-path"; + std::unique_ptr pipe( + ::popen(xcrun_cmd, "r"), pclose); + if (!pipe) { + cling::errs() << "The option -isyroot was not passed to cling. " + << "The command " << xcrun_cmd << " was tried to " + << "find the SDK path on the system, however, an " + << "issue with the invocation occurred.\n"; + } else { + cling_osx_sysroot_directory.clear(); + // Read the output block by block + while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { + cling_osx_sysroot_directory += buffer.data(); + } + if (!cling_osx_sysroot_directory.empty()) { + cling_osx_sysroot_directory.pop_back(); + sArguments.addArgument("-isysroot", cling_osx_sysroot_directory); + } else { + cling::errs() << "The command " << xcrun_cmd << " was tried to " + << "find the SDK path on the system, however, no " + "valid path was returned.\n"; + } + } + } + } + } + #endif // __APPLE__ #endif // _MSC_VER diff --git a/interpreter/cling/lib/Interpreter/CMakeLists.txt b/interpreter/cling/lib/Interpreter/CMakeLists.txt index 416a3b002ecd5..2786a0c88bdef 100644 --- a/interpreter/cling/lib/Interpreter/CMakeLists.txt +++ b/interpreter/cling/lib/Interpreter/CMakeLists.txt @@ -317,25 +317,6 @@ if (UNIX) #define CLING_CXX_INCL \"${CLING_CXX_HEADERS}\" #define CLING_INCLUDE_PATHS \"${CLING_INCLUDE_PATHS}\" ") - if (CMAKE_OSX_SYSROOT) - # CMAKE_OSX_SYSROOT hardcodes the concrete version of the sdk - # (eg .../MacOSX11.1.sdk) which changes after every update of XCode. We use - # the assumption that in the parent folder there is a symlink MacOSX.sdk - # which points to the current active sdk. This change allows releases - # to work when the users update their sdks. - # FIXME: That is a horrible hack and we should teach CIFactory to pick up - # the SDK directory at runtime, just as we do for the include paths to C++. - set (OSX_SYSROOT_DEFAULT_SDK ${CMAKE_OSX_SYSROOT}) - if (${OSX_SYSROOT_DEFAULT_SDK} MATCHES "MacOSX[.0-9]+\.sdk") - get_filename_component(OSX_SYSROOT_DEFAULT_SDK ${OSX_SYSROOT_DEFAULT_SDK} DIRECTORY) - set (OSX_SYSROOT_DEFAULT_SDK ${OSX_SYSROOT_DEFAULT_SDK}/MacOSX.sdk/) - endif() - - file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in - " - #define CLING_OSX_SYSROOT \"${OSX_SYSROOT_DEFAULT_SDK}\" - ") - endif() if (CLING_CXX_PATH) MESSAGE(STATUS "And if not found, will invoke: '${CLING_CXX_PATH}' for them.") file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in From 3aa38cb3f27e91f3dca5cde93497b91b0af753c9 Mon Sep 17 00:00:00 2001 From: ferdymercury Date: Wed, 14 Oct 2026 10:57:36 +0200 Subject: [PATCH 2/2] [cling] treat empty SDKROOT as unset Fixes https://github.com/root-project/root/issues/23712 Full credit goes to cxwx (cherry picked from commit 97db95a8ef3f9954fe71f22db525c582044255fe) --- interpreter/cling/lib/Interpreter/CIFactory.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interpreter/cling/lib/Interpreter/CIFactory.cpp b/interpreter/cling/lib/Interpreter/CIFactory.cpp index 9e5c7d81cb74e..a4a7f3ad40e8d 100644 --- a/interpreter/cling/lib/Interpreter/CIFactory.cpp +++ b/interpreter/cling/lib/Interpreter/CIFactory.cpp @@ -379,7 +379,8 @@ namespace { if(arvIt != args.end() && ++arvIt != args.end()) cling_osx_sysroot_directory = *arvIt; if (!llvm::sys::fs::exists(cling_osx_sysroot_directory)) { - if (!::getenv("SDKROOT")) { + auto env = std::getenv("SDKROOT"); + if (!env || !*env) { std::array buffer; const auto xcrun_cmd = "xcrun --show-sdk-path"; std::unique_ptr pipe(