From 261de1051107e47e34a0afc2aed75b8173bc6856 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20P=C3=B6chtrager?= Date: Sat, 15 Aug 2020 20:07:54 +0200 Subject: [PATCH] Support ARM target --- README.md | 2 +- build.sh | 66 ++++++++++++++++------- build_compiler_rt.sh | 2 - tools/gen_sdk_package.sh | 2 +- tools/tools.sh | 17 +++++- wrapper/build_wrapper.sh | 41 +++++++++++---- wrapper/main.cpp | 4 ++ wrapper/target.cpp | 110 +++++++++++++++++++++++++++------------ wrapper/target.h | 2 +- wrapper/tools.h | 7 +-- 10 files changed, 182 insertions(+), 71 deletions(-) diff --git a/README.md b/README.md index 3afe377..cd20a9d 100644 --- a/README.md +++ b/README.md @@ -164,7 +164,7 @@ use these variants unless you know what you're doing. OSXCross. \*\* --- Xcode up to 12 Beta 4 is known to work. +-- Xcode up to 12 Beta 4 is known to work. -- Use Firefox if you have problems signing in. \*\*\* diff --git a/build.sh b/build.sh index ac0ba46..5214fa5 100755 --- a/build.sh +++ b/build.sh @@ -5,7 +5,7 @@ # This script requires the OS X SDK and the Clang/LLVM compiler. # -VERSION=1.2 +VERSION=1.3 pushd "${0%/*}" &>/dev/null @@ -29,18 +29,19 @@ esac case $SDK_VERSION in - 10.6*) TARGET=darwin10; X86_64H_SUPPORTED=0; I386_SUPPORTED=1; NEED_TAPI_SUPPORT=0; OSX_VERSION_MIN_INT=10.6; ;; - 10.7*) TARGET=darwin11; X86_64H_SUPPORTED=0; I386_SUPPORTED=1; NEED_TAPI_SUPPORT=0; OSX_VERSION_MIN_INT=10.6; ;; - 10.8*) TARGET=darwin12; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; NEED_TAPI_SUPPORT=0; OSX_VERSION_MIN_INT=10.6; ;; - 10.9*) TARGET=darwin13; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; NEED_TAPI_SUPPORT=0; OSX_VERSION_MIN_INT=10.6; ;; - 10.10*) TARGET=darwin14; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; NEED_TAPI_SUPPORT=0; OSX_VERSION_MIN_INT=10.6; ;; - 10.11*) TARGET=darwin15; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.6; ;; - 10.12*) TARGET=darwin16; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.6; ;; - 10.13*) TARGET=darwin17; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.6; ;; - 10.14*) TARGET=darwin18; X86_64H_SUPPORTED=1; I386_SUPPORTED=0; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.9; ;; - 10.15*) TARGET=darwin19; X86_64H_SUPPORTED=1; I386_SUPPORTED=0; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.9; ;; - 10.16*) TARGET=darwin20; X86_64H_SUPPORTED=1; I386_SUPPORTED=0; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.9; ;; -*) echo "Unsupported SDK"; exit 1 ;; + 10.6*) TARGET=darwin10; X86_64H_SUPPORTED=0; I386_SUPPORTED=1; ARM_SUPPORTED=0; NEED_TAPI_SUPPORT=0; OSX_VERSION_MIN_INT=10.6; ;; + 10.7*) TARGET=darwin11; X86_64H_SUPPORTED=0; I386_SUPPORTED=1; ARM_SUPPORTED=0; NEED_TAPI_SUPPORT=0; OSX_VERSION_MIN_INT=10.6; ;; + 10.8*) TARGET=darwin12; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; ARM_SUPPORTED=0; NEED_TAPI_SUPPORT=0; OSX_VERSION_MIN_INT=10.6; ;; + 10.9*) TARGET=darwin13; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; ARM_SUPPORTED=0; NEED_TAPI_SUPPORT=0; OSX_VERSION_MIN_INT=10.6; ;; + 10.10*) TARGET=darwin14; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; ARM_SUPPORTED=0; NEED_TAPI_SUPPORT=0; OSX_VERSION_MIN_INT=10.6; ;; + 10.11*) TARGET=darwin15; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; ARM_SUPPORTED=0; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.6; ;; + 10.12*) TARGET=darwin16; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; ARM_SUPPORTED=0; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.6; ;; + 10.13*) TARGET=darwin17; X86_64H_SUPPORTED=1; I386_SUPPORTED=1; ARM_SUPPORTED=0; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.6; ;; + 10.14*) TARGET=darwin18; X86_64H_SUPPORTED=1; I386_SUPPORTED=0; ARM_SUPPORTED=0; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.9; ;; + 10.15*) TARGET=darwin19; X86_64H_SUPPORTED=1; I386_SUPPORTED=0; ARM_SUPPORTED=0; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.9; ;; + 10.16*) TARGET=darwin20; X86_64H_SUPPORTED=1; I386_SUPPORTED=0; ARM_SUPPORTED=1; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.9; ;; + 11.0*) TARGET=darwin20; X86_64H_SUPPORTED=1; I386_SUPPORTED=0; ARM_SUPPORTED=1; NEED_TAPI_SUPPORT=1; OSX_VERSION_MIN_INT=10.9; ;; + *) echo "Unsupported SDK"; exit 1 ;; esac # Minimum targeted OS X version @@ -147,6 +148,16 @@ if [ $f_res -eq 1 ]; then create_symlink $CCTOOL $CCTOOL_I386 done fi + if [ $ARM_SUPPORTED -eq 1 ]; then + for CCTOOL in ${CCTOOLS[@]}; do + CCTOOL_ARM64=$(echo "$CCTOOL" | $SED 's/x86_64/arm64/g') + create_symlink $CCTOOL $CCTOOL_ARM64 + done + for CCTOOL in ${CCTOOLS[@]}; do + CCTOOL_ARM64E=$(echo "$CCTOOL" | $SED 's/x86_64/arm64e/g') + create_symlink $CCTOOL $CCTOOL_ARM64E + done + fi # For unpatched dsymutil. There is currently no way around it. create_symlink x86_64-apple-$TARGET-lipo lipo popd &>/dev/null @@ -225,6 +236,7 @@ export LIBLTO_PATH export LINKER_VERSION export X86_64H_SUPPORTED export I386_SUPPORTED +export ARM_SUPPORTED export TOP_BUILD_SCRIPT=1 $BASE_DIR/wrapper/build_wrapper.sh @@ -284,20 +296,36 @@ if [ $(osxcross-cmp $SDK_VERSION ">=" 10.7) -eq 1 ]; then popd &>/dev/null echo "" if [ $I386_SUPPORTED -eq 1 ]; then - test_compiler_cxx11 o32-clang++ $BASE_DIR/oclang/test_libcxx.cpp + test_compiler_cxx11 i386-apple-$TARGET-clang++ $BASE_DIR/oclang/test_libcxx.cpp fi - test_compiler_cxx11 o64-clang++ $BASE_DIR/oclang/test_libcxx.cpp + test_compiler_cxx11 x86_64-apple-$TARGET-clang++ $BASE_DIR/oclang/test_libcxx.cpp echo "" fi if [ $I386_SUPPORTED -eq 1 ]; then - test_compiler o32-clang $BASE_DIR/oclang/test.c - test_compiler o32-clang++ $BASE_DIR/oclang/test.cpp + test_compiler i386-apple-$TARGET-clang $BASE_DIR/oclang/test.c "required" + test_compiler i386-apple-$TARGET-clang++ $BASE_DIR/oclang/test.cpp "required" echo "" fi -test_compiler o64-clang $BASE_DIR/oclang/test.c -test_compiler o64-clang++ $BASE_DIR/oclang/test.cpp +if [ $X86_64H_SUPPORTED -eq 1 ]; then + test_compiler x86_64h-apple-$TARGET-clang $BASE_DIR/oclang/test.c + test_compiler x86_64h-apple-$TARGET-clang++ $BASE_DIR/oclang/test.cpp + echo "" +fi + +if [ $ARM_SUPPORTED -eq 1 ]; then + test_compiler arm64-apple-$TARGET-clang $BASE_DIR/oclang/test.c + test_compiler arm64-apple-$TARGET-clang++ $BASE_DIR/oclang/test.cpp + echo "" + + test_compiler arm64e-apple-$TARGET-clang $BASE_DIR/oclang/test.c + test_compiler arm64e-apple-$TARGET-clang++ $BASE_DIR/oclang/test.cpp + echo "" +fi + +test_compiler x86_64-apple-$TARGET-clang $BASE_DIR/oclang/test.c "required" +test_compiler x86_64-apple-$TARGET-clang++ $BASE_DIR/oclang/test.cpp "required" echo "" echo "Do not forget to add" diff --git a/build_compiler_rt.sh b/build_compiler_rt.sh index 3cbc45b..8fa34ea 100755 --- a/build_compiler_rt.sh +++ b/build_compiler_rt.sh @@ -92,8 +92,6 @@ if [ $f_res -eq 1 ]; then EXTRA_MAKE_FLAGS+="VERBOSE=1 " fi - export OSXCROSS_NO_X86_64H_DEPLOYMENT_TARGET_WARNING=1 - if [ $USE_CMAKE -eq 1 ]; then ### CMAKE ### diff --git a/tools/gen_sdk_package.sh b/tools/gen_sdk_package.sh index 728d34b..d716ecd 100755 --- a/tools/gen_sdk_package.sh +++ b/tools/gen_sdk_package.sh @@ -148,7 +148,7 @@ else fi fi -SDKS=$(ls | grep "^MacOSX10.*" | grep -v "Patch") +SDKS=$(ls | grep -E "^MacOSX11.*|^MacOSX10.*" | grep -v "Patch") if [ -z "$SDKS" ]; then echo "No SDK found" 1>&2 diff --git a/tools/tools.sh b/tools/tools.sh index 50128b9..2317260 100644 --- a/tools/tools.sh +++ b/tools/tools.sh @@ -433,10 +433,23 @@ function verbose_cmd() function test_compiler() { + if [ "$3" != "required" ]; then + set +e + fi + echo -ne "testing $1 ... " $1 $2 -O2 -Wall -o test - rm test - echo "works" + + if [ $? -eq 0 ]; then + rm test + echo "works" + else + echo "failed (ignored)" + fi + + if [ "$3" != "required" ]; then + set -e + fi } function test_compiler_cxx11() diff --git a/wrapper/build_wrapper.sh b/wrapper/build_wrapper.sh index f71b1a2..e8941c5 100755 --- a/wrapper/build_wrapper.sh +++ b/wrapper/build_wrapper.sh @@ -6,9 +6,7 @@ source ./tools/tools.sh popd &>/dev/null set +e -if [ -z "$VERSION" ]; then - eval $(${TARGET_DIR}/bin/osxcross-conf 2>/dev/null) - +if [ -n "$VERSION" ]; then if [ -n "$SDK_VERSION" ]; then if [ -z "$X86_64H_SUPPORTED" ]; then if [ $(osxcross-cmp $SDK_VERSION ">=" 10.8) -eq 1 ]; then @@ -24,6 +22,13 @@ if [ -z "$VERSION" ]; then I386_SUPPORTED=0 fi fi + if [ -z "$ARM_SUPPORTED" ]; then + if [ $(osxcross-cmp $SDK_VERSION ">=" 11.0) -eq 1 ]; then + ARM_SUPPORTED=1 + else + ARM_SUPPORTED=0 + fi + fi fi fi set -e @@ -36,6 +41,9 @@ if [ -z "$X86_64H_SUPPORTED" ]; then X86_64H_SUPPORTED=0 fi +if [ -z "$ARM_SUPPORTED" ]; then + ARM_SUPPORTED=0 +fi function create_wrapper_link { @@ -67,10 +75,18 @@ function create_wrapper_link verbose_cmd create_symlink "${TARGETTRIPLE}-wrapper" \ "x86_64-apple-${TARGET}-${1}" - if [ $X86_64H_SUPPORTED -eq 1 ] && - ([[ $1 != gcc* ]] && [[ $1 != g++* ]] && [[ $1 != *gstdc++ ]]); then - verbose_cmd create_symlink "${TARGETTRIPLE}-wrapper" \ - "x86_64h-apple-${TARGET}-${1}" + if ([[ $1 != gcc* ]] && [[ $1 != g++* ]] && [[ $1 != *gstdc++ ]]); then + if [ $X86_64H_SUPPORTED -eq 1 ]; then + verbose_cmd create_symlink "${TARGETTRIPLE}-wrapper" \ + "x86_64h-apple-${TARGET}-${1}" + fi + + if [ $ARM_SUPPORTED -eq 1 ]; then + verbose_cmd create_symlink "${TARGETTRIPLE}-wrapper" \ + "arm64-apple-${TARGET}-${1}" + verbose_cmd create_symlink "${TARGETTRIPLE}-wrapper" \ + "arm64e-apple-${TARGET}-${1}" + fi fi if [ $# -ge 2 ] && [ $2 -eq 2 ]; then @@ -87,6 +103,13 @@ function create_wrapper_link verbose_cmd create_symlink "${TARGETTRIPLE}-wrapper" \ "o64h-${1}" fi + + if [ $ARM_SUPPORTED -eq 1 ]; then + verbose_cmd create_symlink "${TARGETTRIPLE}-wrapper" \ + "oa64-${1}" + verbose_cmd create_symlink "${TARGETTRIPLE}-wrapper" \ + "oa64e-${1}" + fi fi } @@ -104,11 +127,9 @@ if [ -n "$BWPLATFORM" ]; then #CXX=$(xcrun -f g++) FLAGS+="-fvisibility-inlines-hidden " elif [ $PLATFORM = "FreeBSD" -a $(uname -s) != "FreeBSD" ]; then - CXX=amd64-pc-freebsd10.1-clang++ - #CXX=amd64-pc-freebsd10.1-g++ + CXX=amd64-pc-freebsd13.0-clang++ elif [ $PLATFORM = "NetBSD" -a $(uname -s) != "NetBSD" ]; then CXX=amd64-pc-netbsd6.1.3-clang++ - #CXX=amd64-pc-netbsd6.1.3-g++ fi [ -z "$BWCOMPILEONLY" ] && BWCOMPILEONLY=1 diff --git a/wrapper/main.cpp b/wrapper/main.cpp index 405fae7..cc25d2d 100644 --- a/wrapper/main.cpp +++ b/wrapper/main.cpp @@ -439,6 +439,10 @@ bool detectTarget(int argc, char **argv, Target &target) { target.arch = Arch::x86_64h; else if (!strncmp(cmd, "o64", 3)) target.arch = Arch::x86_64; + else if (!strncmp(cmd, "oa64", 4)) + target.arch = Arch::arm64; + else if (!strncmp(cmd, "oa64e", 4)) + target.arch = Arch::arm64e; else return false; diff --git a/wrapper/target.cpp b/wrapper/target.cpp index 5672e09..a89091a 100644 --- a/wrapper/target.cpp +++ b/wrapper/target.cpp @@ -72,7 +72,11 @@ OSVersion Target::getSDKOSNum() const { return OSVersion(); int n = atoi(target.c_str() + 6); - return OSVersion(10, 4 + (n - 8)); + + if (n >= 20) + return OSVersion(11, n - 20); + else + return OSVersion(10, 4 + (n - 8)); } } @@ -133,25 +137,30 @@ void Target::overrideDefaultSDKPath(const char *SDKSearchDir) { } } -bool Target::getSDKPath(std::string &path) const { +bool Target::getSDKPath(std::string &path, bool MacOSX10_16Fix) const { + OSVersion SDKVer = getSDKOSNum(); + if (SDK) { path = SDK; } else { - OSVersion SDKVer = getSDKOSNum(); - + if (MacOSX10_16Fix) + SDKVer = OSVersion(10, 16); path = execpath; path += "/../SDK/MacOSX"; path += SDKVer.shortStr(); - if (SDKVer <= OSVersion(10, 4)) path += "u"; - path += ".sdk"; } if (!dirExists(path)) { + // Some early 11.0 SDKs are misnamed as 10.16 + if (SDKVer == OSVersion(11, 0) && !MacOSX10_16Fix) + return getSDKPath(path, true); + err << "cannot find Mac OS X SDK (expected in: " << path << ")" << err.endl(); + return false; } @@ -505,35 +514,59 @@ bool Target::setup() { setCompilerPath(); - if (!OSNum.Num()) { - if (haveArch(Arch::x86_64h)) { - // Default to >= 10.8 for x86_64h - OSVersion defaultMinTarget = getDefaultMinTarget(); - OSNum = std::max(defaultMinTarget, OSVersion(10, 8)); - if (SDKOSNum < OSNum) { - err << "'" << getArchName(arch) << "' requires Mac OS X SDK " - << OSNum.shortStr() << " (or later)" << err.endl(); - return false; + constexpr struct { + Arch arch; + OSVersion SDKVer; + bool lower; + } RequiredSDKVersion[] = { + { Arch::i386, {10, 13}, true }, + { Arch::x86_64h, {10, 8} }, + { Arch::arm64, {11, 0} }, + { Arch::arm64e, {11, 0} }, + }; + + for (auto &RequiredSDK : RequiredSDKVersion) { + if (haveArch(RequiredSDK.arch)) { + + if (RequiredSDK.lower) { + if (SDKOSNum > RequiredSDK.SDKVer) { + err << "Architecture '" << getArchName(RequiredSDK.arch) << "' requires " + << "Mac OS X <= '" << RequiredSDK.SDKVer.shortStr() << "' SDK" + << err.endl(); + return false; + } + } else { + if (SDKOSNum < RequiredSDK.SDKVer) { + err << "Architecture '" << getArchName(RequiredSDK.arch) << "' requires " + << "Mac OS X >= '" << RequiredSDK.SDKVer.shortStr() << "' SDK" + << err.endl(); + return false; + } } - } else if (stdlib == StdLib::libcxx) { - // Default to >= 10.7 for libc++ - OSVersion defaultMinTarget = getDefaultMinTarget(); - OSNum = std::max(defaultMinTarget, OSVersion(10, 7)); - } else { - OSNum = getDefaultMinTarget(); + } } - if (haveArch(Arch::x86_64h) && OSNum < OSVersion(10, 8)) { - // -mmacosx-version-min= < 10.8 in combination with '-arch x86_64h' - // may cause linker errors. + if (!OSNum.Num()) { + OSVersion defaultMinTarget = getDefaultMinTarget(); - // Erroring here is really annoying, better risk linking errors instead - // of enforcing '-mmacosx-version-min= >= 10.8'. + if (haveArch(Arch::arm64) || haveArch(Arch::arm64e)) { + // Default to >= 11.0 for arm64 + OSNum = std::max(defaultMinTarget, OSVersion(11, 0)); + } - if (!getenv("OSXCROSS_NO_X86_64H_DEPLOYMENT_TARGET_WARNING")) - warn << "'-mmacosx-version-min=' should be '>= 10.8' for architecture " - << "'" << getArchName(Arch::x86_64h) << "'" << warn.endl(); + if (haveArch(Arch::x86_64h)) { + // Default to >= 10.8 for x86_64h + OSNum = std::max(OSNum, std::max(defaultMinTarget, OSVersion(10, 8))); + } + + if (stdlib == StdLib::libcxx) { + // Default to >= 10.7 for libc++ + OSNum = std::max(OSNum, std::max(defaultMinTarget, OSVersion(10, 7))); + } + + if (!OSNum.Num()) + OSNum = defaultMinTarget; } if (stdlib == StdLib::unset) { @@ -776,12 +809,18 @@ bool Target::setup() { if (OSNum.Num()) { std::string tmp; tmp = "-mmacosx-version-min="; - tmp += OSNum.Str(); + if (OSNum >= OSVersion(11, 0)) { + // Fix this once clang is able to parse 11.x + tmp += "10.16"; + } else { + tmp += OSNum.Str(); + } fargs.push_back(tmp); } for (auto arch : targetarch) { bool is32bit = false; + bool isArm = false; switch (arch) { case Arch::i386: @@ -790,10 +829,16 @@ bool Target::setup() { case Arch::i686: is32bit = true; // falls through + case Arch::arm64: + isArm = true; + // falls through + case Arch::arm64e: + isArm = true; + // falls through case Arch::x86_64: case Arch::x86_64h: if (isGCC()) { - if (arch == Arch::x86_64h) { + if (arch != Arch::x86_64 && arch != Arch::i386) { err << "gcc does not support architecture '" << getArchName(arch) << "'" << err.endl(); return false; @@ -802,7 +847,8 @@ bool Target::setup() { if (targetarch.size() > 1) break; - fargs.push_back(is32bit ? "-m32" : "-m64"); + if (!isArm) + fargs.push_back(is32bit ? "-m32" : "-m64"); } else if (isClang()) { if (usegcclibs && targetarch.size() > 1) break; diff --git a/wrapper/target.h b/wrapper/target.h index 88074f9..fc5f526 100644 --- a/wrapper/target.h +++ b/wrapper/target.h @@ -96,7 +96,7 @@ struct Target { OSVersion getSDKOSNum() const; void overrideDefaultSDKPath(const char *SDKSearchDir); - bool getSDKPath(std::string &path) const; + bool getSDKPath(std::string &path, bool MacOSX10_16Fix = false) const; bool getMacPortsDir(std::string &path) const; bool getMacPortsSysRootDir(std::string &path) const; diff --git a/wrapper/tools.h b/wrapper/tools.h index 025e62c..5136a5f 100644 --- a/wrapper/tools.h +++ b/wrapper/tools.h @@ -392,6 +392,7 @@ enum Arch { armv8, arm64, arm64v8, + arm64e, i386, i486, i586, @@ -405,9 +406,9 @@ enum Arch { constexpr const char *ArchNames[] = { "armv4t", "armv5", "armv6", "armv7", "armv7f", "armv7k", "armv7s", - "amrv6m", "armv7m", "armv7em", "armv8", "arm64", "arm64v8", "i386", - "i486", "i586", "i686", "x86_64", "x86_64h", "ppc", "ppc64", - "unknown" + "amrv6m", "armv7m", "armv7em", "armv8", "arm64", "arm64v8", "arm64e", + "i386", "i486", "i586", "i686", "x86_64", "x86_64h", "ppc", + "ppc64", "unknown" }; constexpr const char *getArchName(Arch arch) { return ArchNames[arch]; }