diff --git a/interpreter/cling/lib/Interpreter/CIFactory.cpp b/interpreter/cling/lib/Interpreter/CIFactory.cpp index 0d015ef24f277..a4a7f3ad40e8d 100644 --- a/interpreter/cling/lib/Interpreter/CIFactory.cpp +++ b/interpreter/cling/lib/Interpreter/CIFactory.cpp @@ -365,9 +365,50 @@ 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)) { + auto env = std::getenv("SDKROOT"); + if (!env || !*env) { + 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