11name : Universal package
22description : Create universal Homebrew package which contains x86_64 and arm64
3+
4+ # Instead of using the default binary installed by Homebrew, we need to build our own because third-party libraries are
5+ # statically linked in MacVim, and need to be built against MACOSX_DEPLOYMENT_TARGET to ensure the built binary will
6+ # work on supported macOS versions. Another reason for building our own custom package is to build a unviersal binary
7+ # that has both x86_64 and arm64 arch, as Homebrew's distributed bottles are thin binaries with only one arch.
8+ #
9+ # We still use Homebrew to manage the library because their formulas are up to date and have correct build instructions
10+ # that will work. This way we don't have to manually configuring and building and updating the package info.
11+
312inputs :
413 formula :
514 description : Formura name
1827 set -o pipefail
1928 formula=${{ inputs.formula }}
2029
21- # Patch the official Homebrew formula to explicitly build for min deployment target
30+ # Need to make sure we get the latest before patching. Otherwise Homebrew may later try to get the latest
31+ # version and stomp what we have here.
32+ brew update
33+
34+ # Patch the official Homebrew formula to explicitly build for min deployment target and a universal binary. We
35+ # also need to explicitly use system Clang because Homebrew's bundled clang script tries to inject -march
36+ # compiler flags that will cause universal builds to fail as Clang does not like that.
2237 brew cat ${formula} | \
23- sed '/^[[:blank:]]*def install$/a\'$'\n ENV["MACOSX_DEPLOYMENT_TARGET"] = "'${MACOSX_DEPLOYMENT_TARGET}$'"\n' >${formula}.rb
38+ sed '/^[[:blank:]]*def install$/a\'$'\n ENV["MACOSX_DEPLOYMENT_TARGET"] = "'${MACOSX_DEPLOYMENT_TARGET}$'"\n' | \
39+ sed '/^[[:blank:]]*def install$/a\'$'\n ENV["CC"] = "/usr/bin/clang"\n' | \
40+ sed '/^[[:blank:]]*def install$/a\'$'\n ENV["CFLAGS"] = "-arch x86_64 -arch arm64"\n' | \
41+ sed '/^[[:blank:]]*def install$/a\'$'\n ENV["LDFLAGS"] = "-arch x86_64 -arch arm64"\n' >${formula}.rb
2442
2543 # Uninstall the already installed formula because we want to build our own
2644 brew uninstall --ignore-dependencies ${formula} || true
3654 uses : actions/cache@v3
3755 with :
3856 path : /usr/local/Cellar/${{ inputs.formula }}
39- key : ${{ inputs.formula }}-homebrew-cache-patched -unified-xcode${{ steps.setup-formula.outputs.xcode_version }}-${{ hashFiles(format('{0}.rb', inputs.formula)) }}
57+ key : ${{ inputs.formula }}-homebrew-cache-custom -unified-xcode${{ steps.setup-formula.outputs.xcode_version }}-${{ hashFiles(format('{0}.rb', inputs.formula)) }}
4058
4159 - name : Install formula
4260 shell : bash
@@ -51,38 +69,16 @@ runs:
5169 brew unlink ${formula} && brew link ${formula}
5270 echo '::endgroup::'
5371
54- - name : Create universal binaries with arm64 bottle
55- if : steps.cache-keg.outputs.cache-hit != 'true'
56- shell : bash
57- run : |
58- echo '::group::Create universal binaries with arm64 bottle'
59- set -o verbose
60- formula=${{ inputs.formula }}
72+ echo '::group::Verify built version'
6173 contents=($(IFS=,; for x in ${{ inputs.contents }}; do echo ${x}; done))
6274
63- # Manually download and extract a bottle for arm64
64- source /dev/stdin <<<"$(brew info --json ${formula} | \
65- jq -r '.[0] | "bottle_url=\(.bottle.stable.files.arm64_big_sur.url)", "formula_ver=\(.versions.stable)", "formula_rev=\(.revision)"')"
66- if [[ ${formula_rev} -ne 0 ]]; then
67- formula_ver=${formula_ver}_${formula_rev}
68- fi
69-
70- workdir=${formula}_download
71- mkdir ${workdir}
72- cd ${workdir}
73- wget --no-verbose --header 'Authorization: Bearer QQ==' -O ${formula}.tar.gz ${bottle_url}
74- tar xf ${formula}.tar.gz
75-
7675 for content in "${contents[@]}"; do
77- # Just for diagnostics, print out the old archs. This should be a thin binary (x86_64)
78- lipo -info /usr/local/${content}
79-
80- # Create a universal binary by patching the custom built x86_64 one with the downloaded arm64 one.
81- # Modify the actual binaries in /usr/local/Cellar instead of the symlinks to allow caching to work.
82- lipo -create -output /usr/local/Cellar/${formula}/${formula_ver}/${content} \
83- /usr/local/Cellar/${formula}/${formula_ver}/${content} ./${formula}/${formula_ver}/${content}
84-
85- # Print out the new archs and verify they are universal with 2 archs.
76+ # Print out the archs and verify they are universal fat binary.
8677 lipo -info /usr/local/${content} | grep 'x86_64 arm64'
78+
79+ # Make sure deployment target is correct. Later macOS versions have a different binary format (just search for
80+ # "minos") but for 10.13 we need to look for LC_VERSION_MIN_MACOSX.
81+ otool -l /usr/local/${content} | grep -A 2 LC_VERSION_MIN_MACOSX | tail -1 | grep "${MACOSX_DEPLOYMENT_TARGET}"
8782 done
83+
8884 echo '::endgroup::'
0 commit comments