Skip to content

MacOS universal build dependencies #18

MacOS universal build dependencies

MacOS universal build dependencies #18

name: MacOS universal build dependencies
on:
workflow_dispatch:
inputs:
use_macports_cache:
description: 'Use MacPorts cache'
required: false
default: true
type: boolean
use_ccache:
description: 'Use ccache'
required: false
type: boolean
schedule:
- cron: '0 3 * * 0' # run at 3 AM UTC every Sunday
repository_dispatch:
types: [mac_universal_deps]
jobs:
build:
runs-on: macos-11
strategy:
fail-fast: false
matrix:
binary_compatibility:
- "darwin_20.arm64-x86_64" # macOS 11, the earliest ARM64 version
include:
# this list is meant to be synchronized with mac_release.yml
- common_pkgs:
- brotli 1.0.9_2
- dbus 1.14.6_0
- double-conversion 3.3.0_0
- freetype 2.12.1_0
- gettext-runtime 0.21.1_0
- giflib 4.2.3_0
- glib2 2.76.3_0+x11
- graphite2 1.3.14_0
- harfbuzz 6.0.0_1
- icu 73.1_1
- jasper 4.0.0_1
- lcms2 2.15_0
- lerc 4.0.0_1
- libdeflate 1.18_0
- libedit 20221030-3.1_0
- libffi 3.4.4_0
- libiconv 1.17_0
- libjpeg-turbo 2.1.5.1_0
- libmng 2.0.3_1
- libpng 1.6.39_0
- ncurses 6.4_0
- openssl3 3.1.1_0
- pcre 8.45_0
- pcre2 10.42_0
- python39 3.9.17_0+lto+optimizations
- tcl 8.6.13_0+corefoundation+threads
- tiff 4.5.1_1
- webp 1.3.0_1
- xz 5.4.3_0
- zstd 1.5.5_0
- binary_compatibility: darwin_20.arm64-x86_64
cflags: -arch arm64 -arch x86_64
add_variants: "+universal"
dmg_postfix: "-macos11.universal"
qmake_flags: ""
pkgs:
- qt5-qtbase 5.15.10_0+openssl
- qt5-qtdeclarative 5.15.10_0
- qt5-qtimageformats 5.15.10_0
- qt5-qtscript 5.15.10_0
- qt5-qtsvg 5.15.10_0
- qt5-qttools 5.15.10_0
steps:
- name: Restore distfiles packages cache
id: cache-distfiles
uses: actions/cache/restore@v3
with:
path: distfiles
key: distfiles-${{ matrix.binary_compatibility }}-${{ github.sha }}
restore-keys: distfiles-${{ matrix.binary_compatibility }}-
- name: Fetch distfiles
run: |
mkdir -p distfiles
fetch_binpkg() {
local _compat="$1"; shift
while [ -n "$1" ]; do
local _name="$1"
local _postfix="$(echo "$2${{ matrix.add_variants}}" | sed 's/+x11+universal/+universal+x11/')"
local _url="https://packages.macports.org/$_name/$_name-$_postfix.$_compat.tbz2"
shift 2
case " $*" in *" $_name "*_) echo "$_name: Skipping as an override follows" 1>&2; continue ;; esac
_file="distfiles/$(basename "$_url")"
if [ ! -e "$_file" ]; then
echo "Fetching $_url" 1>&2
if ! curl -fsL -o "$_file" "$_url"; then
echo "Fetching $_url failed, skipping" 1>&2
rm -f "$_file"
printf '%s @%s\n' "$_name" "$_postfix"
fi
fi
done
}
_distfiles_count="$(ls distfiles | wc -l)"
_any="no"
_missing="$(fetch_binpkg ${{ matrix.binary_compatibility }} ${{ join(matrix.common_pkgs, ' ') }} ${{ join(matrix.pkgs, ' ') }})"
[ "$(ls distfiles | wc -l)" -eq "$_distfiles_count" ] || _any=yes
tee -a $GITHUB_ENV <<EOF_ENV
UPDATE_DISTFILES_CACHE=$_any
MISSING_PACKAGES<<EOF_VAR
${_missing}
EOF_VAR
EOF_ENV
- name: Fetch MacPorts cache
# Unconditionally touch the cache to prevent its autoremoval
id: cache-macports
uses: actions/cache/restore@v3
with:
path: ~/macports-cache
key: macports-${{ matrix.binary_compatibility }}-${{ github.sha }}
restore-keys: macports-${{ matrix.binary_compatibility }}-
- name: Install MacPorts
if: env.MISSING_PACKAGES != ''
run: |
wget https://raw.githubusercontent.com/GiovanniBussi/macports-ci/master/macports-ci
source ./macports-ci install
[ "${{ inputs.use_ccache || false }}" = false ] || source ./macports-ci ccache
- name: Restore MacPorts from cache
if: env.MISSING_PACKAGES != '' && inputs.use_macports_cache
run: |
echo "CACHE_TIMESTAMP=$(date '+%Y%m%d-%H%M%S')" >> $GITHUB_ENV
if [ -f ~/macports-cache/macports.tar.bz2 ]; then
# Remove fresh installation keeping only /opt/local/etc/macports/macports.conf, /opt/local/var/macports/sources
sudo cp -p /opt/local/etc/macports/macports.conf .
sudo rm -fr /opt/local/[a-uw-z]*
sudo rm -fr /opt/local/var/[a-ln-z]*
sudo rm -fr /opt/local/var/macports/[a-rt-z]* /opt/local/var/macports/software
sudo tar -C / -xjpf ~/macports-cache/macports.tar.bz2
sudo cp -p macports.conf /opt/local/etc/macports/
fi
- name: Add local ports
if: env.MISSING_PACKAGES != ''
run: |
set -x
_ports_src=$(echo /opt/local/var/macports/sources/*/macports/release/tarballs/ports)
_our_python="$(echo "${{join(matrix.common_pkgs, fromJSON('"\n"')) }}" | awk '/^python3/ { print $1 }')"
echo "OUR_PYTHON=$_our_python" >> $GITHUB_ENV
mkdir -p ports/aqua ports/devel ports/gnome ports/graphics
cd ports
# graphite2 universal patch: https://github.com/macports/macports-ports/pull/18070
cp -rp $_ports_src/graphics/graphite2 graphics/
curl -L https://github.com/macports/macports-ports/commit/c305ea5333bb4f3c3bca1dae70c74d63231e68ea.diff \
| patch -p1
# Make clang-16 a non-dependency of qt5-qttools to let us skip rebuilding it as universal
cp -rp $_ports_src/aqua/qt5 aqua/
sed -i '' 's,"port:clang-\${llvm_version}","",' \
aqua/qt5/Portfile
# Make python311 a non-dependency of qt5-qtdeclarative
sed -i '' "s/python311/$_our_python/g;s/3\\.11/3.${_our_python#python3}/g" \
aqua/qt5/Portfile
# Make python311 a non-dependency of glib2
cp -rp $_ports_src/devel/glib2 devel/
sed -i '' "s/^set py_ver .*/set py_ver 3.${_our_python#python3}/" \
devel/glib2/Portfile
# Make python311 a non-dependency of meson
cp -rp $_ports_src/devel/meson devel/
sed -i '' "s/^python\\.default_version.*/python.default_version ${_our_python#python}/" \
devel/meson/Portfile
# Make python311 a non-dependency of ninja
cp -rp $_ports_src/devel/ninja devel/
sed -i '' "s/^set py_ver .*/set py_ver 3.${_our_python#python3}/" \
devel/ninja/Portfile
# Make python311 a non-dependency of gobject-introspection
cp -rp $_ports_src/gnome/gobject-introspection gnome/
sed -i '' "s/^set py_ver .*/set py_ver 3.${_our_python#python3}/" \
gnome/gobject-introspection/Portfile
# Make python310 a non-dependency of fontconfig
cp -rp $_ports_src/graphics/fontconfig graphics/
sed -i '' "s/port:python310/port:$_our_python/" \
graphics/fontconfig/Portfile
cd ..
source ./macports-ci localports $(pwd)/ports
- name: Install missing packages except Qt
if: env.MISSING_PACKAGES != ''
run: |
set -x
# Try to install what's possible to install from binary packages
sudo port -Nkv install "$OUR_PYTHON" +universal
sudo port -Nkv install python_select python3_select
sudo port select --set python "$OUR_PYTHON"
sudo port select --set python3 "$OUR_PYTHON"
case "$MISSING_PACKAGES" in *glib2*)
sudo port -Nkv install glib2 +universal # our and cairo's dependency, needs +universal, +x11 is the default
;;
esac
case "$MISSING_PACKAGES" in *harfbuzz*)
sudo port -Nk install python310 # fontconfig seems to need it badly but -universal is ok
sudo port -Nkv install cairo -x11 +universal # skip x11 dependencies
;;
esac
_the_rest="$(echo "$MISSING_PACKAGES" | grep -v '^qt5-')"
[ -z "$_the_rest" ] || sudo port -Nkv install $_the_rest
- name: Install missing Qt packages except qt5-qttools
if: env.MISSING_PACKAGES != ''
run: |
set -x
_the_rest="$(echo "$MISSING_PACKAGES" | grep '^qt5-' | grep -v '^qt5-qttools' || true)"
[ -z "$_the_rest" ] || sudo port -Nkv install $_the_rest
- name: Install missing qt5-qttools
if: env.MISSING_PACKAGES != ''
run: |
set -x
universalize_clang_lib() {
local _lib="$1"
local _lib_path="opt/local/libexec/llvm-16/lib/$_lib"
local _current_lib_archs="$(lipo "/$_lib_path" -info | awk -F ': ' '{print $3}')"
local _other=${{ matrix.binary_compatibility }}
case "$_current_lib_archs" in
x86_64) _other="${_other%.*}.arm64" ;;
arm64) _other="${_other%.*}.x86_64" ;;
*" "*) return 0 ;; # already universal
esac
local _clang_dist_name="$(port installed | awk '$1 == "clang-16" && $3 == "(active)" {sub(/@/, "-"); sub(/\+universal/, ""); print $1 $2}').$_other.tbz2"
if [ ! -e "distfiles/$_clang_dist_name" ]; then
curl -fsL -o "distfiles/$_clang_dist_name" "https://packages.macports.org/clang-16/$_clang_dist_name"
echo "UPDATE_DISTFILES_CACHE=yes" >> "$GITHUB_ENV"
fi
tar -xjf "distfiles/$_clang_dist_name" "$_lib_path"
lipo {,/}"$_lib_path" -create -output "$_lib"
sudo install -S "$_lib" "/$_lib_path"
}
case "$MISSING_PACKAGES" in *qt5-qttools*)
# Don't build clang-16 as universal (~12 hours)
if ! port installed | grep -q clang-16; then
sudo port -Nkv install clang-16 -universal
fi
universalize_clang_lib libc++.1.0.dylib
universalize_clang_lib libc++.a
universalize_clang_lib libclang.dylib
sudo port -Nkv install qt5-qttools +universal
;;
esac
- name: Prepare distfiles cache
if: always() && env.MISSING_PACKAGES != ''
run: |
set -x
# Save any new wanted distfiles
_any=""
while read -r _package _version; do
_package_path="/opt/local/var/macports/software/$_package/$_package-${_version#@}"
[ -n "$(ls $_package_path.*.tbz2 2>/dev/null)" ] || continue
cp $_package_path.*.tbz2 distfiles/
_any=1
done <<EOF
$MISSING_PACKAGES
EOF
[ -z "$_any" ] || echo "UPDATE_DISTFILES_CACHE=yes" >> $GITHUB_ENV
- name: Prepare MacPorts cache
if: always() && env.MISSING_PACKAGES != '' && inputs.use_macports_cache
run: |
set -x
sudo rm -fr /opt/local/var/macports/{build,logs,sources}/*
rm -fr ~/macports-cache && mkdir ~/macports-cache
sudo tar -cjpf ~/macports-cache/macports.tar.bz2 /opt/local || true
- name: Save distfiles cache
if: always() && env.UPDATE_DISTFILES_CACHE == 'yes'
uses: actions/cache/save@v3
with:
path: distfiles
key: ${{ steps.cache-distfiles.outputs.cache-primary-key }}-${{ env.CACHE_TIMESTAMP }}
- name: Save MacPorts cache
if: always() && env.MISSING_PACKAGES != '' && inputs.use_macports_cache
uses: actions/cache/save@v3
with:
path: ~/macports-cache
key: macports-${{ matrix.binary_compatibility }}-${{ github.sha }}-${{ env.CACHE_TIMESTAMP }}