From d0644fa9bfc3fa3abdd886d2ef13533778317154 Mon Sep 17 00:00:00 2001 From: Carlo Cabrera <30379873+carlocab@users.noreply.github.com> Date: Fri, 24 Jun 2022 23:48:17 +0800 Subject: [PATCH] ci(release): build a universal binary on macOS After some tweaks to our dep builds, we can now build a universal binary for macOS by using `CMAKE_OSX_ARCHITECTURES`. So, let's do that. This requires a number of additional changes: 1. We need to build on macOS 11, since earlier versions do not support building universal (M1 + Intel) binaries. 2. We need to provision a universal `libintl`. The linker will look for an ARM64 version of this library when linking the `nvim` binary. While we're here: 1. Link statically to `libintl`. This allows to to avoid having to do any install name rewriting or codesigning to package Neovim. 2. Bump the `MACOSX_DEPLOYMENT_TARGET` to `11`. We're already using a `libintl` built by Homebrew (through the pre-installed version of `gettext`), and that is built for macOS 11. In order to ensure we link to `libintl.a` instead of `libintl.dylib`, we have to make sure that CMake can't find the latter. This ideally should be a matter of doing `brew unlink gettext`. However, CMake is too adept at finding things that Homebrew has installed (even when not linked), so we have to do a bit more than that. This appears in the additional step ensuring static linkage to `libintl`. We end up breaking some Homebrew-installed software in the process, and some of these software is called during our build (e.g. curl, git, wget). To avoid any adverse effects, let's just uninstall them. --- .github/workflows/notes.md | 2 +- .github/workflows/release.yml | 43 +++++++++++++++++++++-------------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/.github/workflows/notes.md b/.github/workflows/notes.md index 3bd6c739a5..86f9e8e618 100644 --- a/.github/workflows/notes.md +++ b/.github/workflows/notes.md @@ -22,7 +22,7 @@ ${NVIM_VERSION} 1. Download **nvim-macos.tar.gz** 2. Extract: `tar xzvf nvim-macos.tar.gz` -3. Run `./nvim-osx64/bin/nvim` +3. Run `./nvim-macos/bin/nvim` ### Linux (x64) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index aad76d0979..1c6e62abbb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -78,7 +78,7 @@ jobs: retention-days: 1 macOS: - runs-on: macos-10.15 + runs-on: macos-11 steps: - uses: actions/checkout@v3 with: @@ -91,27 +91,36 @@ jobs: run: printf 'NVIM_BUILD_TYPE=Release\n' >> $GITHUB_ENV - if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.tag_name == 'nightly') run: printf 'NVIM_BUILD_TYPE=RelWithDebInfo\n' >> $GITHUB_ENV + - name: Provision universal `libintl` + run: | + GETTEXT_PREFIX="$(brew --prefix gettext)" + printf 'GETTEXT_PREFIX=%s\n' "$GETTEXT_PREFIX" >> $GITHUB_ENV + bottle_tag="arm64_big_sur" + brew fetch --bottle-tag="$bottle_tag" gettext + cd "$(mktemp -d)" + tar xf "$(brew --cache)"/**/*gettext*${bottle_tag}*.tar.gz + lipo gettext/*/lib/libintl.a "${GETTEXT_PREFIX}/lib/libintl.a" -create -output libintl.a + mv -f libintl.a /usr/local/lib/ + - name: Ensure static linkage to `libintl` + run: | + # We're about to mangle `gettext`, so let's remove any potentially broken + # installs (e.g. curl, git) as those could interfere with our build. + brew uninstall $(brew uses --installed --recursive gettext) + brew unlink gettext + ln -sf "$(brew --prefix)/opt/$(readlink "${GETTEXT_PREFIX}")/bin"/* /usr/local/bin/ + rm -f "$GETTEXT_PREFIX" - name: Build release run: | - make CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH= -DCMAKE_OSX_DEPLOYMENT_TARGET=10.11" - make DESTDIR="$GITHUB_WORKSPACE/build/release/nvim-osx64" install + export MACOSX_DEPLOYMENT_TARGET="$(sw_vers -productVersion | cut -f1 -d.)" + OSX_FLAGS="-DCMAKE_OSX_DEPLOYMENT_TARGET=${MACOSX_DEPLOYMENT_TARGET} -DCMAKE_OSX_ARCHITECTURES=arm64\;x86_64" + make CMAKE_BUILD_TYPE=${NVIM_BUILD_TYPE} \ + CMAKE_EXTRA_FLAGS="-DCMAKE_INSTALL_PREFIX:PATH= $OSX_FLAGS" \ + DEPS_CMAKE_FLAGS="$OSX_FLAGS" + make DESTDIR="$GITHUB_WORKSPACE/build/release/nvim-macos" install - name: Create package run: | cd "$GITHUB_WORKSPACE/build/release" - mkdir -p nvim-osx64/libs - libs=($(otool -L nvim-osx64/bin/nvim | sed 1d | sed -E -e 's|^[[:space:]]*||' -e 's| .*||')) - echo "libs:" - for lib in "${libs[@]}"; do - if echo "$lib" | grep -q -E 'libSystem|CoreServices' 2>/dev/null; then - echo " [skipped] $lib" - else - echo " $lib" - relname="libs/${lib##*/}" - cp -L "$lib" "nvim-osx64/$relname" - install_name_tool -change "$lib" "@executable_path/../$relname" nvim-osx64/bin/nvim - fi - done - tar cfz nvim-macos.tar.gz nvim-osx64 + tar cfz nvim-macos.tar.gz nvim-macos - uses: actions/upload-artifact@v3 with: name: nvim-macos