From c95a81f29949d3f06f6039b56d2f0b19ab87419d Mon Sep 17 00:00:00 2001 From: Tae Won Ha Date: Mon, 27 May 2024 19:56:45 +0900 Subject: [PATCH] Add workflow to build universal Neovim --- .github/workflows/build-universal-neovim.yml | 66 ++++++++++++++++++++ bin/neovim/bin/build_neovim.sh | 21 +++---- bin/neovim/bin/build_universal_neovim.sh | 47 ++++++++++++++ 3 files changed, 122 insertions(+), 12 deletions(-) create mode 100644 .github/workflows/build-universal-neovim.yml create mode 100755 bin/neovim/bin/build_universal_neovim.sh diff --git a/.github/workflows/build-universal-neovim.yml b/.github/workflows/build-universal-neovim.yml new file mode 100644 index 000000000..d69c754c6 --- /dev/null +++ b/.github/workflows/build-universal-neovim.yml @@ -0,0 +1,66 @@ +name: 'Universal Neovim' +on: + push: + tags: + # example: neovim-v0.10.0-20240601.102525 + - neovim-v[0-9]+.[0-9]+.[0-9]+-.* + +jobs: + macos: + needs: setup + strategy: + fail-fast: false + matrix: + runner: [ macos-12, macos-14 ] + include: + - runner: macos-12 + arch: x86_64 + - runner: macos-14 + arch: arm64 + runs-on: ${{ matrix.runner }} + steps: + - uses: actions/checkout@v4 + with: + # Perform a full checkout #13471 + fetch-depth: 0 + - name: Install dependencies + run: brew bundle + + - name: Build neovim + run: clean=true ./bin/neovim/bin/build_neovim.sh + + - uses: actions/upload-artifact@v4 + with: + name: nvim-macos-${{ matrix.arch }} + path: Neovim/build/nvim-macos-${{ matrix.arch }}.tar.gz + retention-days: 1 + + publish: + needs: [macos] + runs-on: macos-14 + env: + GH_REPO: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write + steps: + # Must perform checkout first, since it deletes the target directory + # before running, and would therefore delete the downloaded artifacts + - uses: actions/checkout@v4 + + - uses: actions/download-artifact@v4 + + - name: Install dependencies + run: brew-bundle + + - name: Set tag name env + run: | + TAG_NAME=${{ github.ref }} + echo "TAG_NAME=${TAG_NAME#refs/tags/}" >> $GITHUB_ENV + + - name: Create universal Neovim + run: ./bin/neovim/bin/build_universal_neovim.sh + + - name: Publish release + run: | + gh release create $TAG_NAME --title "Neovim universal build ${TAG_NAME}" --target $GITHUB_SHA nvim-macos-x86_64/nvim-macos-x86_64.tar.gz nvim-macos-arm64/nvim-macos-arm64.tar.gz nvim-macos-universal.tar.bz diff --git a/bin/neovim/bin/build_neovim.sh b/bin/neovim/bin/build_neovim.sh index 91587878d..fded59ec8 100755 --- a/bin/neovim/bin/build_neovim.sh +++ b/bin/neovim/bin/build_neovim.sh @@ -1,28 +1,27 @@ #!/bin/bash set -Eeuo pipefail +# This script builds Neovim with gettext for host's architecture, *no* universal build +# Produces /Neovim/build/neovim-macos-$arch.tar.gz + readonly clean=${clean:?"true or false"} readonly NVIM_BUILD_TYPE=${NVIM_BUILD_TYPE:-"Release"} readonly gettext_version="0.22.5" readonly gettext_url="https://ftp.gnu.org/pub/gnu/gettext/gettext-${gettext_version}.tar.gz" declare temp_dir; temp_dir="$(mktemp -d)"; readonly temp_dir -readonly gettext_install_dir="${temp_dir}/universal" +readonly gettext_install_dir="${temp_dir}/gettext" build_gettext() { - local -r -x MACOSX_DEPLOYMENT_TARGET=$1 + local -r -x MACOSX_DEPLOYMENT_TARGET="$1" pushd "${temp_dir}" >/dev/null curl -L "${gettext_url}" -o gettext.tar.gz tar -xzf gettext.tar.gz - mkdir universal + mkdir gettext pushd "./gettext-${gettext_version}" >/dev/null ./configure \ - CC="gcc -arch x86_64 -arch arm64" \ - CXX="g++ -arch x86_64 - arch arm64" \ - CPP="gcc -E" \ - CXXCPP="g++ -E" \ --prefix "${gettext_install_dir}" \ --disable-silent-rules \ --with-included-glib \ @@ -43,9 +42,9 @@ build_gettext() { } build_neovim() { - # slightly modified version of /Neovim/.github/scripts/build_universal_macos.sh + # slightly modified version of Neovim's Github workflow for release local -r -x MACOSX_DEPLOYMENT_TARGET=$1 - local -r -x SDKROOT=$(xcrun --sdk macosx --show-sdk-path) + local -x SDKROOT; SDKROOT=$(xcrun --sdk macosx --show-sdk-path); readonly SDKROOT # Brew's gettext does not get sym-linked to PATH export PATH="/opt/homebrew/opt/gettext/bin:/usr/local/opt/gettext/bin:${PATH}" @@ -53,7 +52,6 @@ build_neovim() { cmake -S cmake.deps -B .deps -G Ninja \ -D CMAKE_BUILD_TYPE="${NVIM_BUILD_TYPE}" \ -D CMAKE_OSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET}" \ - -D CMAKE_OSX_ARCHITECTURES=arm64\;x86_64 \ -D CMAKE_FIND_FRAMEWORK=NEVER cmake --build .deps @@ -62,8 +60,7 @@ build_neovim() { cmake -B build -G Ninja \ -D CMAKE_BUILD_TYPE="${NVIM_BUILD_TYPE}" \ -D CMAKE_OSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET}" \ - -D CMAKE_OSX_ARCHITECTURES=arm64\;x86_64 \ - -D CMAKE_FIND_FRAMEWORK=LAST \ + -D CMAKE_FIND_FRAMEWORK=NEVER \ -D LIBINTL_INCLUDE_DIR="${gettext_install_dir}/include" \ -D LIBINTL_LIBRARY="${gettext_install_dir}/lib/libintl.a" cmake --build build diff --git a/bin/neovim/bin/build_universal_neovim.sh b/bin/neovim/bin/build_universal_neovim.sh new file mode 100755 index 000000000..20b9b17fe --- /dev/null +++ b/bin/neovim/bin/build_universal_neovim.sh @@ -0,0 +1,47 @@ +#!/bin/bash +set -Eeuo pipefail + +# This script creates a universal build, incl. Treesitter `so`s. The Treesitter +# libs are put under the `runtime` folder instead of under `lib`. +# +# It expects to find the following files in the workspace root: +# - nvim-macos-x86_64.tar.gz +# - nvim-macos-arm64.tar.gz +# It will produce the following in the workspace root: +# - nvim-macos-universal.tar.bz +# +# To be used in the context of Github actions + +main() { + # This script is located in /bin/neovim/bin and we have to go to / + pushd "$(dirname "${BASH_SOURCE[0]}")/../../../" >/dev/null + + tar -xf nvim-macos-x86_64.tar.gz + tar -xf nvim-macos-arm64.tar.gz + + mkdir -p "nvim-macos-universal" + + local universal_folder_path; universal_folder_path="$(pwd)/nvim-macos-universal"; + readonly universal_folder_path + + mkdir -p "${universal_folder_path}/bin" + cp -r nvim-macos-arm64/share "${universal_folder_path}" + mkdir -p "${universal_folder_path}/share/nvim/runtime/parser" + + lipo -create nvim-macos-arm64/bin/nvim nvim-macos-x86_64/bin/nvim \ + -output "${universal_folder_path}/bin/nvim" + for f in nvim-macos-arm64/lib/nvim/parser/*; do + echo "${f}" + f="${f%/}" + local filename="${f##*/}" + lipo -create "nvim-macos-arm64/lib/nvim/parser/${filename}" \ + "nvim-macos-x86_64/lib/nvim/parser/${filename}" \ + -output "${universal_folder_path}/share/nvim/runtime/parser/${filename}" + done + + tar -cjf nvim-macos-universal + + popd >/dev/null +} + +main