Force the OSX SDK to be the one at build time:

Fixes builds with command line tools and macos 10.14.
This commit is contained in:
Axel Naumann 2018-09-26 17:00:05 +02:00 committed by sftnight
parent 2847412de4
commit c23abbc88b
4 changed files with 27 additions and 245 deletions

View File

@ -339,17 +339,9 @@ namespace {
sArguments.addArgument("-nostdinc++");
}
#if defined(__APPLE__)
if (!opts.NoBuiltinInc && !opts.SysRoot) {
std::string sysRoot;
if (platform::GetISysRoot(sysRoot, Verbose)) {
if (Verbose)
cling::log() << "Using SDK \"" << sysRoot << "\"\n";
sArguments.addArgument("-isysroot", std::move(sysRoot));
}
}
#endif // __APPLE__
#ifdef CLING_OSX_SYSROOT
sArguments.addArgument("-isysroot", CLING_OSX_SYSROOT);
#endif
#endif // _MSC_VER

View File

@ -281,38 +281,34 @@ if (UNIX)
# we need to know where is ROOT/cling STL.
set_property(GLOBAL PROPERTY ROOT_CLING_CXX_HEADERS_LOCATION "${CLING_CXX_HEADERS}")
if (CLING_CXX_PATH)
MESSAGE(STATUS "And if not found, will invoke: '${CLING_CXX_PATH}' for them.")
if (CLING_CXX_RLTV)
MESSAGE(STATUS "And then fallback to: '${CLING_CXX_RLTV}'")
# FIXME: We should use file(GENERATE) cmake command.
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
"
#define CLING_CXX_INCL \"${CLING_CXX_HEADERS}\"
#define CLING_CXX_PATH \"${CLING_CXX_PATH} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
#define CLING_CXX_RLTV \"${CLING_CXX_RLTV} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
#define CLING_INCLUDE_PATHS \"${CLING_INCLUDE_PATHS}\"
")
else()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
"
#define CLING_CXX_INCL \"${CLING_CXX_HEADERS}\"
#define CLING_CXX_PATH \"${CLING_CXX_PATH} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
#define CLING_INCLUDE_PATHS \"${CLING_INCLUDE_PATHS}\"
")
endif()
else()
MESSAGE(STATUS "And if not found, will invoke: '${CLING_CXX_RLTV}' for them.")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
# FIXME: We should use file(GENERATE) cmake command.
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
"
#define CLING_CXX_INCL \"${CLING_CXX_HEADERS}\"
#define CLING_INCLUDE_PATHS \"${CLING_INCLUDE_PATHS}\"
")
if (CMAKE_OSX_SYSROOT)
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
"
#define CLING_CXX_INCL \"${CLING_CXX_HEADERS}\"
#define CLING_CXX_RLTV \"${CLING_CXX_RLTV} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
#define CLING_INCLUDE_PATHS \"${CLING_INCLUDE_PATHS}\"
#define CLING_OSX_SYSROOT \"${CMAKE_OSX_SYSROOT}\"
")
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
"
#define CLING_CXX_PATH \"${CLING_CXX_PATH} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
")
endif()
if (CLING_CXX_RLTV)
MESSAGE(STATUS "And then fallback to: '${CLING_CXX_RLTV}'")
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
"
#define CLING_CXX_RLTV \"${CLING_CXX_RLTV} ${CMAKE_CXX_FLAGS_NO_I} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}\"
")
endif()
else()
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/cling-compiledata.h.in
"
#define CLING_INCLUDE_PATHS \"${CLING_INCLUDE_PATHS}\"
#define CLING_UCRT_VERSION \"$ENV{UCRTVersion}\"

View File

@ -28,7 +28,6 @@ add_cling_library(clingUtils OBJECT
ParserStateRAII.cpp
Output.cpp
Paths.cpp
PlatformMac.cpp
PlatformPosix.cpp
PlatformWin.cpp
SourceNormalization.cpp

View File

@ -1,205 +0,0 @@
//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// author: Roman Zulak
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
// FIXME: This should probably be handled in CMake so as not to overwrite what
// the user may have specifically requested.
// Make sure MAC_OS_X_VERSION_MAX_ALLOWED is not user defined, so that it will
// match the SDK version we are compiling with.
#ifdef MAC_OS_X_VERSION_MAX_ALLOWED
#undef MAC_OS_X_VERSION_MAX_ALLOWED
#endif
#include "cling/Utils/Platform.h"
#ifdef __APPLE__
#include "cling/Utils/Output.h"
#include "cling/Utils/Paths.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Path.h"
#include <sstream>
#include <CoreFoundation/CFBase.h> // For MAC_OS_X_VERSION_X_X macros
// gcc on Mac can only include CoreServices.h up to 10.9 SDK, which means
// we cannot use Gestalt to get the running OS version when >= 10.10
#if defined(__clang__) || !defined(MAC_OS_X_VERSION_10_10)
#include <dlfcn.h> // dlopen to avoid linking with CoreServices
#include <CoreServices/CoreServices.h>
#else
#define CLING_SWVERS_PARSE_ONLY 1
#endif
namespace cling {
namespace utils {
namespace platform {
inline namespace osx {
namespace {
static bool getISysRootVersion(const std::string& SDKs, int Major,
int Minor, std::string& SysRoot,
const char* Verbose) {
std::ostringstream os;
os << SDKs << "MacOSX" << Major << "." << Minor << ".sdk";
std::string SDKv = os.str();
if (llvm::sys::fs::is_directory(SDKv)) {
SysRoot.swap(SDKv);
if (Verbose) {
cling::errs() << "SDK version matching " << Major << "." << Minor
<< " found, this does " << Verbose << "\n";
}
return true;
}
if (Verbose)
cling::errs() << "SDK version matching " << Major << "." << Minor
<< " not found, this would " << Verbose << "\n";
return false;
}
static std::string ReadSingleLine(const char* Cmd) {
if (FILE* PF = ::popen(Cmd, "r")) {
char Buf[1024];
char* BufPtr = ::fgets(Buf, sizeof(Buf), PF);
::pclose(PF);
if (BufPtr && Buf[0]) {
const llvm::StringRef Result(Buf);
assert(Result[Result.size()-1] == '\n' && "Single line too large");
return Result.trim().str();
}
}
return "";
}
static std::pair<int, int> SplitSDKVersion(int SDKVers) {
if (SDKVers > 100000)
return std::make_pair(SDKVers/10000, (SDKVers-100000)/100);
return std::make_pair(SDKVers/100, (SDKVers-1000)/10);
}
} // anonymous namespace
bool GetISysRoot(std::string& sysRoot, bool Verbose) {
using namespace llvm::sys;
// Some versions of OS X and Server have headers installed
if (fs::is_regular_file("/usr/include/stdlib.h"))
return false;
std::string SDKs("/Applications/Xcode.app/Contents/Developer");
// Is XCode installed where it usually is?
if (!fs::is_directory(SDKs)) {
// Nope, use xcode-select -p to get the path
SDKs = ReadSingleLine("xcode-select -p");
if (SDKs.empty())
return false; // Nothing more we can do
}
SDKs.append("/Platforms/MacOSX.platform/Developer/SDKs/");
if (!fs::is_directory(SDKs))
return false;
// Try to get the SDK for whatever version of OS X is currently running
// Seems to make more sense to get the currently running SDK so headers
// and any loaded libraries will match.
int32_t majorVers = -1, minorVers = -1;
#ifndef CLING_SWVERS_PARSE_ONLY
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
if (void *core = ::dlopen(
"/System/Library/Frameworks/CoreServices.framework/CoreServices",
RTLD_LAZY)) {
typedef ::OSErr (*GestaltProc)(::OSType, ::SInt32 *);
if (GestaltProc Gestalt = (GestaltProc)::dlsym(core, "Gestalt")) {
if (Gestalt(gestaltSystemVersionMajor, &majorVers) == ::noErr) {
if (Gestalt(gestaltSystemVersionMinor, &minorVers) != ::noErr)
minorVers = -1;
} else
majorVers = -1;
}
::dlclose(core);
}
#pragma clang diagnostic pop
#endif
if (majorVers == -1 || minorVers == -1) {
const std::string SWVers = ReadSingleLine("sw_vers | grep ProductVersion"
" | awk '{print $2}'");
if (!SWVers.empty()) {
if (::sscanf(SWVers.c_str(), "%d.%d", &majorVers, &minorVers) != 2) {
majorVers = -1;
minorVers = -1;
}
}
}
if (majorVers != -1 && minorVers != -1) {
if (getISysRootVersion(SDKs, majorVers, minorVers, sysRoot,
Verbose ? "match the version of OS X running"
: nullptr)) {
return true;
}
}
// MAC_OS_X_VERSION_MAX_ALLOWED is -probably- the SDK being compiled with
const std::pair<int,int> Vers = SplitSDKVersion(MAC_OS_X_VERSION_MAX_ALLOWED);
if (Vers.first != majorVers || Vers.second != minorVers) {
if (getISysRootVersion(SDKs, Vers.first, Vers.second, sysRoot, Verbose ?
"match what cling was compiled with" : nullptr))
return true;
}
// Nothing left to do but iterate the SDKs directory
// Using a generic numerical sorting could easily break down, so we match
// against 'MacOSX10.' as this is how they are installed, and fallback to
// lexicographical sorting if things didn't work out.
if (Verbose)
cling::errs() << "Looking in '" << SDKs << "' for highest version SDK.\n";
sysRoot.clear();
int SdkVers = 0;
const std::string Match("MacOSX10.");
std::vector<std::string> LexicalSdks;
std::error_code ec;
for (fs::directory_iterator it(SDKs, ec), e; !ec && it != e;
it.increment(ec)) {
const std::string SDKName = it->path().substr(SDKs.size());
if (SDKName.find(Match) == 0) {
const int CurVer = ::atoi(SDKName.c_str() + Match.size());
if (CurVer > SdkVers) {
sysRoot = it->path();
SdkVers = CurVer;
}
} else if (sysRoot.empty())
LexicalSdks.push_back(it->path());
}
if (sysRoot.empty() && !LexicalSdks.empty()) {
if (Verbose)
cling::errs() << "Selecting SDK based on a lexical sort.\n";
std::sort(LexicalSdks.begin(), LexicalSdks.end());
sysRoot.swap(LexicalSdks.back());
}
return !sysRoot.empty();
}
} // namespace osx
} // namespace platform
} // namespace utils
} // namespace cling
#endif // __APPLE__