Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix naked DMD-style asm emission for non-Mac x86 Darwin targets & add prebuilt druntime/Phobos for iOS/x86_64 to macOS package #3478

Merged
merged 3 commits into from
Jun 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 44 additions & 12 deletions .azure-pipelines/posix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -267,35 +267,48 @@ steps:
displayName: 'Android: Cross-compile x86 libraries and copy to install dir'
condition: and(succeeded(), eq(variables['CI_OS'], 'android'))

# Mac: add iOS/arm64 libraries
# Mac: add iOS libraries (arm64 and x86_64)
- script: |
set -ex
cd ..
export PATH="$PWD/ninja:$PATH"
triple="arm64-apple-ios$IOS_DEPLOYMENT_TARGET"
# TODO: shared libs too, and look into `-fvisibility=hidden` requirement
triple_arm64="arm64-apple-ios$IOS_DEPLOYMENT_TARGET"
triple_x64="x86_64-apple-ios$IOS_DEPLOYMENT_TARGET"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not sure if it matters but Xcode does not use this triple for the simulator. I’m not currently at the computer but, IIRC, it uses iphonesimulator instead of iOS.

# TODO: build shared libs too, and look into `-fvisibility=hidden` requirement
build/bin/ldc-build-runtime --ninja -j $PARALLEL_JOBS \
--buildDir=build-libs-arm64 \
--cFlags="-target;$triple" \
--dFlags="-mtriple=$triple;-fvisibility=hidden" \
--cFlags="-target;$triple_arm64" \
--dFlags="-mtriple=$triple_arm64;-fvisibility=hidden" \
--ldcSrcDir=$BUILD_SOURCESDIRECTORY \
CMAKE_SYSTEM_NAME=iOS \
CMAKE_OSX_ARCHITECTURES=arm64 \
CMAKE_OSX_DEPLOYMENT_TARGET=$IOS_DEPLOYMENT_TARGET \
BUILD_SHARED_LIBS=OFF \
BUILD_LTO_LIBS=ON
mkdir installed/lib-ios-arm64
build/bin/ldc-build-runtime --ninja -j $PARALLEL_JOBS \
--buildDir=build-libs-x86_64 \
--cFlags="-target;$triple_x64" \
--dFlags="-mtriple=$triple_x64;-fvisibility=hidden" \
--ldcSrcDir=$BUILD_SOURCESDIRECTORY \
CMAKE_SYSTEM_NAME=iOS \
CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk \
Copy link
Contributor

@jacob-carlborg jacob-carlborg Jul 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard coding the path to the SDK should be avoided. The following command can be used retrieve the path: xcrun --show-sdk-path --sdk iphonesimulator.

CMAKE_OSX_ARCHITECTURES=x86_64 \
CMAKE_OSX_DEPLOYMENT_TARGET=$IOS_DEPLOYMENT_TARGET \
BUILD_SHARED_LIBS=OFF \
BUILD_LTO_LIBS=ON
mkdir installed/lib-ios-{arm64,x86_64}
cp build-libs-arm64/lib/*.a installed/lib-ios-arm64
rm installed/lib-ios-arm64/*-lto-debug.a
section="
cp build-libs-x86_64/lib/*.a installed/lib-ios-x86_64
rm installed/lib-ios-{arm64,x86_64}/*-lto-debug.a
sections="
\"arm64-apple-ios\":
{
switches = [
\"-defaultlib=phobos2-ldc,druntime-ldc\",
\"-link-defaultlib-shared=false\",
\"-fvisibility=hidden\",
\"-Xcc=-target\",
\"-Xcc=$triple\",
\"-Xcc=$triple_arm64\",
\"-Xcc=-miphoneos-version-min=$IOS_DEPLOYMENT_TARGET\",
\"-Xcc=-isysroot\",
\"-Xcc=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk\",
Expand All @@ -304,10 +317,28 @@ steps:
\"%%ldcbinarypath%%/../lib-ios-arm64\",
];
rpath = \"%%ldcbinarypath%%/../lib-ios-arm64\";
};

\"x86_64-apple-ios\":
{
switches = [
\"-defaultlib=phobos2-ldc,druntime-ldc\",
\"-link-defaultlib-shared=false\",
\"-fvisibility=hidden\",
\"-Xcc=-target\",
\"-Xcc=$triple_x64\",
\"-Xcc=-miphoneos-version-min=$IOS_DEPLOYMENT_TARGET\",
\"-Xcc=-isysroot\",
\"-Xcc=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk\",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to run the above mentioned command to avoid hard coding the path?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's hardcoded just like the one for the arm64 triple, and noone has complained about that so far.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know. I'm just saying it would be better if it wasn't hard coded. Not for arm64 either. If someone only installs the command line tools and not Xcode, the path to the SDKs will be different. Also, Apple may decide to change the path. Originally when I started developing on Mac, the SDK was located somewhere in /Developer.

Copy link
Member Author

@kinke kinke Jul 16, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we wanted to do this properly for the few users who might run into troubles (and aren't able to fix it themselves by adapting ldc2.conf), we would probably have to do something similar to the MSVC toolchain setup, invoking that xcrun cmdline and parsing its result to obtain the proper path, and injecting it into the linker/clang cmdline for non-Mac Apple targets. Of course none of this would be necessary (none of these -Xcc flags) if Apple just used a little preconfigured wrapper à la x86_64-apple-i{os,phonesimulator}12.0-clang like the Android NDK or most cross-gcc toolchains.

];
lib-dirs = [
\"%%ldcbinarypath%%/../lib-ios-x86_64\",
];
rpath = \"%%ldcbinarypath%%/../lib-ios-x86_64\";
};"
echo "$section" >> installed/etc/ldc2.conf
echo "$sections" >> installed/etc/ldc2.conf
cat installed/etc/ldc2.conf
displayName: 'Mac: Cross-compile iOS/arm64 libraries, copy to install dir and extend ldc2.conf'
displayName: 'Mac: Cross-compile iOS libraries (arm64 and x86_64), copy to install dir and extend ldc2.conf'
condition: and(succeeded(), eq(variables['CI_OS'], 'osx'))

# Integration tests
Expand All @@ -326,7 +357,8 @@ steps:
- script: |
set -ex
cd ..
installed/bin/ldc2 -mtriple="arm64-apple-ios$IOS_DEPLOYMENT_TARGET" hello.d -of=hello_ios
installed/bin/ldc2 -mtriple="arm64-apple-ios$IOS_DEPLOYMENT_TARGET" hello.d -of=hello_ios_arm64
installed/bin/ldc2 -mtriple="x86_64-apple-ios$IOS_DEPLOYMENT_TARGET" hello.d -of=hello_ios_x86_64
displayName: 'Mac: Cross-compile & -link hello-world for iOS'
condition: and(succeeded(), eq(variables['CI_OS'], 'osx'))
- script: |
Expand Down
27 changes: 25 additions & 2 deletions bitrise.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,30 @@ workflows:
envman add --key LDC_BINARY --value "$(pwd)/bin/ldc2"

- script@1.1.6:
title: Build Runtime
title: Cross-compile (iOS/x86_64) druntime & Phobos
deps:
brew:
- name: cmake
- name: ninja
inputs:
- content: |-
#!/bin/bash
set -ex
build/bin/ldc-build-runtime \
--buildDir="ldc-build-runtime.x86_64" \
--cFlags="-target;x86_64-apple-ios${IOS_VERSION}" \
--dFlags="-mtriple=x86_64-apple-ios${IOS_VERSION};-fvisibility=hidden" \
--ldcSrcDir=. \
--ninja \
-j 2 \
CMAKE_SYSTEM_NAME=iOS \
CMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk \
CMAKE_OSX_ARCHITECTURES=x86_64 \
CMAKE_OSX_DEPLOYMENT_TARGET="${IOS_VERSION}" \
BUILD_SHARED_LIBS=OFF

- script@1.1.6:
title: Cross-compile (iOS/arm64) druntime & Phobos, incl. debug unittest runners
deps:
brew:
- name: cmake
Expand Down Expand Up @@ -86,7 +109,7 @@ workflows:
run_if: not .IsPR

- virtual-device-testing-for-ios@0.9.10:
title: Run Tests on Device
title: Run druntime & Phobos debug unittests on iPhone
run_if: not .IsPR
inputs:
- test_devices: iphone6s,12.0,en,portrait
Expand Down
3 changes: 3 additions & 0 deletions driver/linker-gcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,9 @@ void ArgsBuilder::addCppStdlibLinkFlags(const llvm::Triple &triple) {
break;
case llvm::Triple::Darwin:
case llvm::Triple::MacOSX:
case llvm::Triple::IOS:
case llvm::Triple::WatchOS:
case llvm::Triple::TvOS:
case llvm::Triple::FreeBSD:
args.push_back("-lc++");
break;
Expand Down
52 changes: 24 additions & 28 deletions driver/targetmachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,7 @@ static const char *getLLVMArchSuffixForARM(llvm::StringRef CPU) {

static FloatABI::Type getARMFloatABI(const llvm::Triple &triple,
const char *llvmArchSuffix) {
switch (triple.getOS()) {
case llvm::Triple::Darwin:
case llvm::Triple::MacOSX:
case llvm::Triple::IOS: {
if (triple.isOSDarwin()) {
// Darwin defaults to "softfp" for v6 and v7.
if (llvm::StringRef(llvmArchSuffix).startswith("v6") ||
llvm::StringRef(llvmArchSuffix).startswith("v7")) {
Expand All @@ -260,35 +257,34 @@ static FloatABI::Type getARMFloatABI(const llvm::Triple &triple,
return FloatABI::Soft;
}

case llvm::Triple::FreeBSD:
if (triple.isOSFreeBSD()) {
// FreeBSD defaults to soft float
return FloatABI::Soft;
}

default:
if (triple.getVendorName().startswith("hardfloat"))
return FloatABI::Hard;
if (triple.getVendorName().startswith("softfloat"))
return FloatABI::SoftFP;

switch (triple.getEnvironment()) {
case llvm::Triple::GNUEABIHF:
return FloatABI::Hard;
case llvm::Triple::GNUEABI:
return FloatABI::SoftFP;
case llvm::Triple::EABI:
// EABI is always AAPCS, and if it was not marked 'hard', it's softfp
if (triple.getVendorName().startswith("hardfloat"))
return FloatABI::Hard;
if (triple.getVendorName().startswith("softfloat"))
return FloatABI::SoftFP;

switch (triple.getEnvironment()) {
case llvm::Triple::GNUEABIHF:
return FloatABI::Hard;
case llvm::Triple::GNUEABI:
return FloatABI::SoftFP;
case llvm::Triple::EABI:
// EABI is always AAPCS, and if it was not marked 'hard', it's softfp
return FloatABI::SoftFP;
case llvm::Triple::Android: {
if (llvm::StringRef(llvmArchSuffix).startswith("v7")) {
return FloatABI::SoftFP;
case llvm::Triple::Android: {
if (llvm::StringRef(llvmArchSuffix).startswith("v7")) {
return FloatABI::SoftFP;
}
return FloatABI::Soft;
}
default:
// Assume "soft".
// TODO: Warn the user we are guessing.
return FloatABI::Soft;
}
return FloatABI::Soft;
}
default:
// Assume "soft".
// TODO: Warn the user we are guessing.
return FloatABI::Soft;
}
}

Expand Down
10 changes: 5 additions & 5 deletions gen/abi-x86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
#include "ir/irfuncty.h"

struct X86TargetABI : TargetABI {
const bool isOSX;
const bool isDarwin;
const bool isMSVC;
bool returnStructsInRegs;
IntegerRewrite integerRewrite;
IndirectByvalRewrite indirectByvalRewrite;

X86TargetABI()
: isOSX(global.params.targetTriple->isMacOSX()),
: isDarwin(global.params.targetTriple->isOSDarwin()),
isMSVC(global.params.targetTriple->isWindowsMSVCEnvironment()) {
using llvm::Triple;
auto os = global.params.targetTriple->getOS();
Expand Down Expand Up @@ -206,8 +206,8 @@ struct X86TargetABI : TargetABI {

// Clang does not pass empty structs, while it seems that GCC does,
// at least on Linux x86. We don't know whether the C compiler will
// be Clang or GCC, so just assume Clang on OS X and G++ on Linux.
if (externD || !isOSX)
// be Clang or GCC, so just assume Clang on Darwin and G++ on Linux.
if (externD || !isDarwin)
return;

size_t i = 0;
Expand Down Expand Up @@ -247,7 +247,7 @@ struct X86TargetABI : TargetABI {

const char *objcMsgSendFunc(Type *ret, IrFuncTy &fty) override {
// see objc/message.h for objc_msgSend selection rules
assert(isOSX);
assert(isDarwin);
if (fty.arg_sret) {
return "objc_msgSend_stret";
}
Expand Down
7 changes: 3 additions & 4 deletions gen/asm-x86.h
Original file line number Diff line number Diff line change
Expand Up @@ -2322,11 +2322,10 @@ struct AsmProcessor {
// OSX and 32-bit Windows need an extra leading underscore when mangling a
// symbol name.
static bool prependExtraUnderscore(LINK link) {
return global.params.targetTriple->getOS() == llvm::Triple::MacOSX ||
global.params.targetTriple->getOS() == llvm::Triple::Darwin ||
const auto &triple = *global.params.targetTriple;
return triple.isOSDarwin() ||
// Win32: all symbols except for MSVC++ ones
(global.params.targetTriple->isOSWindows() &&
global.params.targetTriple->isArch32Bit() && link != LINKcpp);
(triple.isOSWindows() && triple.isArch32Bit() && link != LINKcpp);
}

void addOperand(const char *fmt, AsmArgType type, Expression *e,
Expand Down
7 changes: 3 additions & 4 deletions gen/naked.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,11 @@ void DtoDefineNakedFunction(FuncDeclaration *fd) {

const auto &triple = *global.params.targetTriple;
bool const isWin = triple.isOSWindows();
bool const isOSX = (triple.getOS() == llvm::Triple::Darwin ||
triple.getOS() == llvm::Triple::MacOSX);
bool const isDarwin = triple.isOSDarwin();

// osx is different
// also mangling has an extra underscore prefixed
if (isOSX) {
if (isDarwin) {
fullmangle += '_';
fullmangle += mangle;
mangle = fullmangle.c_str();
Expand Down Expand Up @@ -233,7 +232,7 @@ void DtoDefineNakedFunction(FuncDeclaration *fd) {

// emit size after body
// llvm does this on linux, but not on osx or Win
if (!(isWin || isOSX)) {
if (!(isWin || isDarwin)) {
asmstr << "\t.size\t" << mangle << ", .-" << mangle << std::endl
<< std::endl;
}
Expand Down