Skip to content

Commit

Permalink
Add workflow to build universal Neovim
Browse files Browse the repository at this point in the history
  • Loading branch information
qvacua committed May 27, 2024
1 parent 1bcba99 commit c95a81f
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 12 deletions.
66 changes: 66 additions & 0 deletions .github/workflows/build-universal-neovim.yml
Original file line number Diff line number Diff line change
@@ -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
21 changes: 9 additions & 12 deletions bin/neovim/bin/build_neovim.sh
Original file line number Diff line number Diff line change
@@ -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 \
Expand All @@ -43,17 +42,16 @@ 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}"

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

Expand All @@ -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
Expand Down
47 changes: 47 additions & 0 deletions bin/neovim/bin/build_universal_neovim.sh
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit c95a81f

Please sign in to comment.