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

Add universal prebuilt Mac package (x86_64 + arm64) #3958

Merged
merged 2 commits into from
Apr 26, 2022
Merged
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
50 changes: 50 additions & 0 deletions .azure-pipelines/4a-mac_ios.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Cross-compiles the iOS default libraries, copies them to the install dir and
# extends ldc2.conf.
#
# Required env vars:
# - ARCH
# - IOS_DEPLOYMENT_TARGET
# - PARALLEL_JOBS

steps:
- script: |
set -ex
cd ..
export PATH="$PWD/ninja:$PATH"
triple="$ARCH-apple-ios$IOS_DEPLOYMENT_TARGET"
if [[ "$ARCH" == "arm64" ]]; then
sysroot="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk"
else
sysroot="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk"
fi
# use bootstrap-ldc, which is guaranteed to be native
bootstrap-ldc/bin/ldc-build-runtime --ninja -j $PARALLEL_JOBS \
--buildDir=build-libs-ios \
--dFlags="-mtriple=$triple" \
--ldcSrcDir=$BUILD_SOURCESDIRECTORY \
CMAKE_SYSTEM_NAME=iOS \
CMAKE_OSX_SYSROOT="$sysroot" \
CMAKE_OSX_ARCHITECTURES=$ARCH \
CMAKE_OSX_DEPLOYMENT_TARGET=$IOS_DEPLOYMENT_TARGET \
BUILD_LTO_LIBS=ON
mkdir installed/lib-ios-$ARCH
cp -a build-libs-ios/lib/*.{a,dylib,o} installed/lib-ios-$ARCH
section="
\"$ARCH-apple-ios\":
{
switches = [
\"-defaultlib=phobos2-ldc,druntime-ldc\",
\"-Xcc=-target\",
\"-Xcc=$triple\",
\"-Xcc=-miphoneos-version-min=$IOS_DEPLOYMENT_TARGET\",
\"-Xcc=-isysroot\",
\"-Xcc=$sysroot\",
];
lib-dirs = [
\"%%ldcbinarypath%%/../lib-ios-$ARCH\",
];
rpath = \"%%ldcbinarypath%%/../lib-ios-$ARCH\";
};"
echo "$section" >> installed/etc/ldc2.conf
cat installed/etc/ldc2.conf
displayName: 'Cross-compile iOS default libraries, copy to install dir and extend ldc2.conf'
93 changes: 0 additions & 93 deletions .azure-pipelines/4a-mac_x64.yml

This file was deleted.

142 changes: 142 additions & 0 deletions .azure-pipelines/mac-merge.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# Each step starts in the checked-out source directory,
# environment variables aren't persisted across steps.
#
# Required env vars:
# - CI_OS
# - IOS_DEPLOYMENT_TARGET

steps:

- checkout: self
submodules: false
fetchDepth: 50

# Download x86_64 and arm64 artifacts
- task: DownloadPipelineArtifact@2
inputs:
artifactName: $(CI_OS)-x86_64
targetPath: artifacts
displayName: Download x86_64 artifact
- task: DownloadPipelineArtifact@2
inputs:
artifactName: $(CI_OS)-arm64
targetPath: artifacts
displayName: Download arm64 artifact

# Extract & merge
- script: |
set -ex

mkdir ldc2-{x86_64,arm64}
tar -xf artifacts/ldc2-*-x86_64.tar.xz --strip 1 -C ldc2-x86_64
tar -xf artifacts/ldc2-*-arm64.tar.xz --strip 1 -C ldc2-arm64

cp -R ldc2-x86_64 ldc2-universal
cd ldc2-universal

# rename/copy lib dirs
mv lib lib-x86_64
cp -R ../ldc2-arm64/lib lib-arm64
cp -R ../ldc2-arm64/lib-ios-arm64 .

# merge executables to universal ones
for exe in bin/*; do
rm $exe
lipo -create -output $exe ../ldc2-x86_64/$exe ../ldc2-arm64/$exe
done

# ldc2.conf: replace the default section and add extra sections
sections="
default:
{
// default switches injected before all explicit command-line switches
switches = [
\"-defaultlib=phobos2-ldc,druntime-ldc\",
];
// default switches appended after all explicit command-line switches
post-switches = [
\"-I%%ldcbinarypath%%/../import\",
];
// default directories to be searched for libraries when linking
lib-dirs = [];
// default rpath when linking against the shared default libs
rpath = \"\";
};

\"x86_64-apple-\":
{
switches = [
\"-defaultlib=phobos2-ldc,druntime-ldc\",
\"-Xcc=-target\",
\"-Xcc=x86_64-apple-macos\",
];
lib-dirs = [
\"%%ldcbinarypath%%/../lib-x86_64\",
];
rpath = \"%%ldcbinarypath%%/../lib-x86_64\";
};

\"arm64-apple-\":
{
switches = [
\"-defaultlib=phobos2-ldc,druntime-ldc\",
\"-Xcc=-target\",
\"-Xcc=arm64-apple-macos\",
];
lib-dirs = [
\"%%ldcbinarypath%%/../lib-arm64\",
];
rpath = \"%%ldcbinarypath%%/../lib-arm64\";
};

\"arm64-apple-ios\":
{
switches = [
\"-defaultlib=phobos2-ldc,druntime-ldc\",
\"-Xcc=-target\",
\"-Xcc=arm64-apple-ios$IOS_DEPLOYMENT_TARGET\",
\"-Xcc=-miphoneos-version-min=$IOS_DEPLOYMENT_TARGET\",
\"-Xcc=-isysroot\",
\"-Xcc=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk\",
];
lib-dirs = [
\"%%ldcbinarypath%%/../lib-ios-arm64\",
];
rpath = \"%%ldcbinarypath%%/../lib-ios-arm64\";
};"

perl -0777 -pi -e "s|\\ndefault:\\n.+?\\n\\};|$sections|s" etc/ldc2.conf
cat etc/ldc2.conf
cd ..
displayName: Extract & merge artifacts

# Smoke tests
- script: |
set -ex
echo 'void main() { import std.stdio; writefln("Hello world, %d bits", size_t.sizeof * 8); }' > hello.d
for os in macos ios$IOS_DEPLOYMENT_TARGET; do
for arch in x86_64 arm64; do
triple="$arch-apple-$os"
ldc2-universal/bin/ldc2 -mtriple="$triple" hello.d
ldc2-universal/bin/ldc2 -mtriple="$triple" hello.d -link-defaultlib-shared
done
done
displayName: Run x86_64/arm64 macOS/iOS cross-compilation smoke tests

# Pack & publish artifact
- script: |
set -ex
mkdir newArtifacts
if [ "${BUILD_SOURCEBRANCH:0:10}" = "refs/tags/" ]; then
artifactID=${BUILD_SOURCEBRANCH:11}
else
artifactID=${BUILD_SOURCEVERSION:0:8}
fi
artifactName=ldc2-$artifactID-$CI_OS-universal
mv ldc2-universal $artifactName
chmod -R go=rX $artifactName
sudo chown -R root:wheel $artifactName
tar -cJf newArtifacts/$artifactName.tar.xz --options='compression-level=9' $artifactName
displayName: Pack
- publish: newArtifacts
artifact: $(CI_OS)-universal
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@
- For the Mac package, the minimum supported macOS version has been raised to v10.12.
- The minimum D version for bootstrapping has been raised to v2.079 (for GDC: v9.4), in line with DMD. (#3956)
- The minimum LLVM version has been raised to v9.0. (#3960)
- New prebuilt *universal* macOS package, runnable on both x86_64 and arm64, and enabling x86_64/arm64 macOS/iOS cross-compilation targets out of the box (`-mtriple={x86_64,arm64}-apple-{macos,ios12.0}`). The x86_64 package doesn't bundle any arm64 libs anymore; the arm64 package newly bundles iOS libs (arm64). (#3958)
Copy link
Member Author

@kinke kinke Apr 10, 2022

Choose a reason for hiding this comment

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

This seems like less trouble than anticipated; according to CI, it's fine on x86_64 hosts. Some quick smoke tests on actual Apple Silicon (cross-compiling & -linking to all 4 targets) would be appreciated; if you have time, maybe also checking the arm64 package and that it can target iOS too. Pinging @p0nce, @dnadlinger, @schveiguy.

CI artifact(s) downloadable from https://dev.azure.com/ldc-developers/ldc/_build/results?buildId=3437&view=artifacts&pathAsName=false&type=publishedArtifacts.

Copy link
Member

Choose a reason for hiding this comment

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

Seems to work fine for building a Phobos Hello World on 12.2.1/arm64, for both arm64 and x86_64 targets (with the 1.29.0-git-788b8ef binaries from your comment).

Copy link
Contributor

@p0nce p0nce Apr 10, 2022

Choose a reason for hiding this comment

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

All tests on macOS Monterey 12.0.1, Xcode 13.0, M1
what I haven't tested = the Universal package on x86_64 host.

I'm testing intel-intrinsics in unitest-release mode, to avoid the -g bug in Monterey.

(Reference run with LDC 1.28 x86_64
dub test -a x86_64-apple-macos -b unittest-release => OK
dub test -a arm64-apple-macos -b unittest-release => OK)

LDC is Universal Binary

dub test -a x86_64-apple-macos -b unittest-release --compiler /Users/guill/Desktop/compilers/test/ldc2-788b8ef0-osx-universal/bin/ldc2 => OK

dub test -a arm64-apple-macos -b unittest-release --compiler /Users/guill/Desktop/compilers/test/ldc2-788b8ef0-osx-universal/bin/ldc2 => OK

dub test -a x86_64-apple-ios -b release --compiler /Users/guill/Desktop/compilers/test/ldc2-788b8ef0-osx-universal/bin/ldc2 => OK, successfully link and runs, crash the with dyld[1918]: DYLD_ROOT_PATH not set for simulator program which sounds alright.

dub test -a arm64-apple-ios -b release --compiler /Users/guill/Desktop/compilers/test/ldc2-788b8ef0-osx-universal/bin/ldc2 => OK, successfully link and crash the unittests with error code 9, probably my fault

So yeah I guess it can become the one and only LDC on macOS :)
Also tests the now obsolete packages:

LDC arm64 package

dub test -a x86_64-apple-macos -b unittest-release --compiler /Users/guill/Desktop/compilers/test/ldc2-788b8ef0-osx-arm64/bin/ldc2 => OK, link failure as expected, as arm64 LDC doesn't have x86_64 target.

dub test -a arm64-apple-macos -b unittest-release --compiler /Users/guill/Desktop/compilers/test/ldc2-788b8ef0-osx-arm64/bin/ldc2
=> link failure, not sure why, not a concern if universal supersedes that

ld: warning: ignoring file /Users/guill/Desktop/compilers/test/ldc2-788b8ef0-osx-arm64/lib/libphobos2-ldc.a, building for macOS-x86_64 but attempting to link with file built for unknown-arm64
ld: warning: ignoring file /Users/guill/Desktop/compilers/test/ldc2-788b8ef0-osx-arm64/lib/libdruntime-ldc.a, building for macOS-x86_64 but attempting to link with file built for unknown-arm64
ld: warning: ignoring file .dub/build/intel-intrinsics-test-library-unittest-release-posix.osx.darwin-aarch64.arm_hardfloat-ldc_v1.29.0-git-788b8ef-6D0F504A78D2DED12452D86E33078DC9/intel-intrinsics-test-library.o, building for macOS-x86_64 but attempting to link with file built for unknown-arm64
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: /usr/bin/cc failed with status: 1

LDC is x86_64

dub test -a x86_64-apple-macos -b unittest-release --compiler /Users/guill/Desktop/compilers/test/ldc2-788b8ef0-osx-x86_84/bin/ldc2 => OK

dub test -a arm64-apple-macos -b unittest-release --compiler /Users/guill/Desktop/compilers/test/ldc2-788b8ef0-osx-x86_84/bin/ldc2 => OK, link failure, but expected since x86_64 package can't target arm64 anymore.

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, this isn't working for me on OSX 12.3.1. Specifically, the -g flag doesn't work still (get linker errors).

Note also, with a previous LDC, if I set the environment variable: MACOSX_DEPLOYMENT_TARGET=11 it worked. In this version, that workaround doesn't work. So I would not be able to use this binary.

The specific error is:

steves@MacBook-Pro testd % ~/Downloads/osx-universal/ldc2-788b8ef0-osx-universal/bin/ldc2 -g testbadlink.d
ld: warning: pointer not aligned at address 0x100008032 (anon + 50 from testbadlink.o)
ld: unaligned pointer(s) for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: /usr/bin/cc failed with status: 1

See #3864 for more details.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thx for testing. - This doesn't affect/fix #3864 at all; if there are changes compared to before, that's either because of LLVM 14 or some further Xcode changes or whatever.

Copy link
Contributor

Choose a reason for hiding this comment

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

@jacob-carlborg any insights here? You were the one I think who figured out the workaround last time.

Copy link
Member Author

Choose a reason for hiding this comment

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

Off-topic, but there is another change for this CI artifact here compared to the latest releases - the macOS image for building LDC, druntime and Phobos was bumped from 10.15 to 11.x, and so the Xcode SDK version with it.

MACOSX_DEPLOYMENT_TARGET during the build was raised from 10.9 to 10.12 for the x86_64 package; still at 11.0 for the arm64 package.

One workaround is adding -preserve-dwarf-line-section=false to the cmdline / ldc2.conf file, implying no file/line infos in druntime exception backtraces. A debugger would presumably still offer those infos.

Copy link
Contributor

Choose a reason for hiding this comment

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

10.12 as target is more than OK, because once notarized a lot of software doesn't launch on 10.11 anyway except if you use a special flag.

Copy link
Contributor

Choose a reason for hiding this comment

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

any insights here? You were the one I think who figured out the workaround last time.

Unfortunately no. I think the best way forward, assuming the -preserve-dwarf-line-section=false flag works, is to read the debug info from the object files instead of the executable, that's what the debugger is doing. Debug info can also be compiled to its own .dSYM file for distribution. The best would be if all three methods were supported by druntime. @Geod24 is working on this, IIRC.


#### Platform support
- Supports LLVM 9.0 - 14.0.
31 changes: 21 additions & 10 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -117,18 +117,15 @@ jobs:
- template: .azure-pipelines/2-posix-build_native.yml
- template: .azure-pipelines/3-posix-test.yml
- template: .azure-pipelines/4-install.yml
- template: .azure-pipelines/4a-mac_x64.yml
- template: .azure-pipelines/4a-mac_ios.yml
- template: .azure-pipelines/5-integration_test.yml
- script: |
set -ex
cd ..
installed/bin/ldc2 -mtriple="arm64-apple-macos" hello.d -of=hello_arm64
installed/bin/ldc2 -mtriple="arm64-apple-macos" hello.d -of=hello_arm64_shared -link-defaultlib-shared
installed/bin/ldc2 -mtriple="arm64-apple-ios$IOS_DEPLOYMENT_TARGET" hello.d -of=hello_ios_arm64
installed/bin/ldc2 -mtriple="arm64-apple-ios$IOS_DEPLOYMENT_TARGET" hello.d -of=hello_ios_arm64_shared -link-defaultlib-shared
installed/bin/ldc2 -mtriple="x86_64-apple-ios$IOS_DEPLOYMENT_TARGET" hello.d -of=hello_ios_x86_64
installed/bin/ldc2 -mtriple="x86_64-apple-ios$IOS_DEPLOYMENT_TARGET" hello.d -of=hello_ios_x86_64_shared -link-defaultlib-shared
displayName: 'Cross-compile & -link hello-world for arm64 and iOS'
triple="x86_64-apple-ios$IOS_DEPLOYMENT_TARGET"
installed/bin/ldc2 -mtriple="$triple" hello.d -of=hello_ios
installed/bin/ldc2 -mtriple="$triple" hello.d -of=hello_ios_shared -link-defaultlib-shared
displayName: 'Run iOS cross-compilation integration test'
- template: .azure-pipelines/6-package.yml

- job: macOS_arm64
@@ -150,8 +147,23 @@ jobs:
- template: .azure-pipelines/1-posix-setup.yml
- template: .azure-pipelines/2-posix-build_cross_mac.yml
- template: .azure-pipelines/4-install.yml
- template: .azure-pipelines/4a-mac_ios.yml
- template: .azure-pipelines/6-package.yml

# Merges the x64 and arm64 macOS packages to a universal package.
- job: macOS_universal
timeoutInMinutes: 30
pool:
vmImage: 'macOS-11'
variables:
CI_OS: osx
IOS_DEPLOYMENT_TARGET: 12.0
dependsOn:
- macOS_x64
- macOS_arm64
steps:
- template: .azure-pipelines/mac-merge.yml

- job: Android
timeoutInMinutes: 120
pool:
@@ -194,8 +206,7 @@ jobs:
dependsOn:
- Windows_multilib
- Linux_multilib
- macOS_x64
- macOS_arm64
- macOS_universal
- Android
# Only run for commits on the master branch and tags.
condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), startsWith(variables['Build.SourceBranch'], 'refs/tags/')))