Skip to content

Commit

Permalink
Create universal builds on macos (#612)
Browse files Browse the repository at this point in the history
Update config.mak.uname and GitHub workflow to create a DMG and PKG
containing universal binaries rather than separate single-platform
packages.  Also, remove dashed versions of commands from the package to save space.
  • Loading branch information
jeffhostetler authored Nov 6, 2023
2 parents d8a31ac + 58e14eb commit dc61fa0
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 48 deletions.
57 changes: 22 additions & 35 deletions .github/macos-installer/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,17 @@ TARGET_FLAGS := -mmacosx-version-min=$(OSX_VERSION) -DMACOSX_DEPLOYMENT_TARGET=$

uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo not')

ifeq ($(uname_M),x86_64)
ARCH := x86_64
ARCH_CODE := x86_64
ARCH_FLAGS_x86_64 := -arch x86_64
CPU_VENDOR := Intel
endif
ifeq ($(uname_M),arm64)
ARCH := arm64
ARCH_CODE := arm64
ARCH_FLAGS_arm64 := -arch arm64
CPU_VENDOR := Apple Silicon
endif
ARCH_UNIV := universal
ARCH_FLAGS := -arch x86_64 -arch arm64

CFLAGS := $(TARGET_FLAGS) $(ARCH_FLAGS_${ARCH_CODE})
LDFLAGS := $(TARGET_FLAGS) $(ARCH_FLAGS_${ARCH_CODE})
CFLAGS := $(TARGET_FLAGS) $(ARCH_FLAGS)
LDFLAGS := $(TARGET_FLAGS) $(ARCH_FLAGS)

PREFIX := /usr/local
GIT_PREFIX := $(PREFIX)/git

BUILD_CODE := $(ARCH_CODE)
BUILD_DIR := $(GITHUB_WORKSPACE)/payload
DESTDIR := $(PWD)/stage/git-$(BUILD_CODE)-$(VERSION)
DESTDIR := $(PWD)/stage/git-$(ARCH_UNIV)-$(VERSION)
ARTIFACTDIR := build-artifacts
SUBMAKE := $(MAKE) C_INCLUDE_PATH="$(C_INCLUDE_PATH)" CPLUS_INCLUDE_PATH="$(CPLUS_INCLUDE_PATH)" LD_LIBRARY_PATH="$(LD_LIBRARY_PATH)" TARGET_FLAGS="$(TARGET_FLAGS)" CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" NO_GETTEXT=1 NO_DARWIN_PORTS=1 prefix=$(GIT_PREFIX) GIT_BUILT_FROM_COMMIT="$(GIT_BUILT_FROM_COMMIT)" DESTDIR=$(DESTDIR)
CORES := $(shell bash -c "sysctl hw.ncpu | awk '{print \$$2}'")
Expand All @@ -44,7 +33,7 @@ APPLE_KEYCHAIN_PROFILE =

.SECONDARY:

$(DESTDIR)$(GIT_PREFIX)/VERSION-$(VERSION)-$(BUILD_CODE):
$(DESTDIR)$(GIT_PREFIX)/VERSION-$(VERSION)-$(ARCH_UNIV):
rm -f $(BUILD_DIR)/git-$(VERSION)/osx-installed*
mkdir -p $(DESTDIR)$(GIT_PREFIX)
touch $@
Expand Down Expand Up @@ -97,22 +86,17 @@ symlinks:
ruby ../scripts/symlink-git-hardlinks.rb $(ARTIFACTDIR)
touch $@

$(BUILD_DIR)/git-$(VERSION)/osx-installed: $(DESTDIR)$(GIT_PREFIX)/VERSION-$(VERSION)-$(BUILD_CODE) $(BUILD_DIR)/git-$(VERSION)/osx-installed-man $(BUILD_DIR)/git-$(VERSION)/osx-installed-assets $(BUILD_DIR)/git-$(VERSION)/osx-installed-subtree
$(BUILD_DIR)/git-$(VERSION)/osx-installed: $(DESTDIR)$(GIT_PREFIX)/VERSION-$(VERSION)-$(ARCH_UNIV) $(BUILD_DIR)/git-$(VERSION)/osx-installed-man $(BUILD_DIR)/git-$(VERSION)/osx-installed-assets $(BUILD_DIR)/git-$(VERSION)/osx-installed-subtree
find $(DESTDIR)$(GIT_PREFIX) -type d -exec chmod ugo+rx {} \;
find $(DESTDIR)$(GIT_PREFIX) -type f -exec chmod ugo+r {} \;
touch $@

$(BUILD_DIR)/git-$(VERSION)/osx-built-assert-$(ARCH_CODE): $(BUILD_DIR)/git-$(VERSION)/osx-built
ifeq ("$(ARCH_CODE)", "universal")
$(BUILD_DIR)/git-$(VERSION)/osx-built-assert-$(ARCH_UNIV): $(BUILD_DIR)/git-$(VERSION)/osx-built
File $(BUILD_DIR)/git-$(VERSION)/git
File $(BUILD_DIR)/git-$(VERSION)/contrib/credential/osxkeychain/git-credential-osxkeychain
else
[ "$$(File $(BUILD_DIR)/git-$(VERSION)/git | cut -f 5 -d' ')" == "$(ARCH_CODE)" ]
[ "$$(File $(BUILD_DIR)/git-$(VERSION)/contrib/credential/osxkeychain/git-credential-osxkeychain | cut -f 5 -d' ')" == "$(ARCH_CODE)" ]
endif
touch $@

disk-image/VERSION-$(VERSION)-$(ARCH_CODE):
disk-image/VERSION-$(VERSION)-$(ARCH_UNIV):
rm -f disk-image/*.pkg disk-image/VERSION-* disk-image/.DS_Store
mkdir disk-image
touch "$@"
Expand All @@ -125,20 +109,23 @@ ifdef APPLE_INSTALLER_IDENTITY
pkg_cmd += --sign "$(APPLE_INSTALLER_IDENTITY)"
endif

pkg_cmd += disk-image/git-$(VERSION)-$(BUILD_CODE).pkg
disk-image/git-$(VERSION)-$(BUILD_CODE).pkg: disk-image/VERSION-$(VERSION)-$(ARCH_CODE) symlinks
pkg_cmd += disk-image/git-$(VERSION)-$(ARCH_UNIV).pkg
disk-image/git-$(VERSION)-$(ARCH_UNIV).pkg: disk-image/VERSION-$(VERSION)-$(ARCH_UNIV) symlinks
$(pkg_cmd)

git-%-$(BUILD_CODE).dmg:
hdiutil create git-$(VERSION)-$(BUILD_CODE).uncompressed.dmg -fs HFS+ -srcfolder disk-image -volname "Git $(VERSION) $(CPU_VENDOR) $(ARCH)" -ov
hdiutil convert -format UDZO -o $@ git-$(VERSION)-$(BUILD_CODE).uncompressed.dmg
rm -f git-$(VERSION)-$(BUILD_CODE).uncompressed.dmg
git-%-$(ARCH_UNIV).dmg:
hdiutil create git-$(VERSION)-$(ARCH_UNIV).uncompressed.dmg -fs HFS+ -srcfolder disk-image -volname "Git $(VERSION) $(ARCH_UNIV)" -ov 2>&1 | tee err || { \
grep "Resource busy" err && \
sleep 5 && \
hdiutil create git-$(VERSION)-$(ARCH_UNIV).uncompressed.dmg -fs HFS+ -srcfolder disk-image -volname "Git $(VERSION) $(ARCH_UNIV)" -ov; }
hdiutil convert -format UDZO -o $@ git-$(VERSION)-$(ARCH_UNIV).uncompressed.dmg
rm -f git-$(VERSION)-$(ARCH_UNIV).uncompressed.dmg

payload: $(BUILD_DIR)/git-$(VERSION)/osx-installed $(BUILD_DIR)/git-$(VERSION)/osx-built-assert-$(ARCH_CODE)
payload: $(BUILD_DIR)/git-$(VERSION)/osx-installed $(BUILD_DIR)/git-$(VERSION)/osx-built-assert-$(ARCH_UNIV)

pkg: disk-image/git-$(VERSION)-$(BUILD_CODE).pkg
pkg: disk-image/git-$(VERSION)-$(ARCH_UNIV).pkg

image: git-$(VERSION)-$(BUILD_CODE).dmg
image: git-$(VERSION)-$(ARCH_UNIV).dmg

ifdef APPLE_APP_IDENTITY
codesign:
Expand All @@ -151,6 +138,6 @@ endif
ifdef APPLE_KEYCHAIN_PROFILE
notarize:
@$(CURDIR)/../scripts/notarize.sh \
--package="disk-image/git-$(VERSION)-$(BUILD_CODE).pkg" \
--package="disk-image/git-$(VERSION)-$(ARCH_UNIV).pkg" \
--keychain-profile="$(APPLE_KEYCHAIN_PROFILE)"
endif
60 changes: 47 additions & 13 deletions .github/workflows/build-git-installers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,6 @@ jobs:
strategy:
matrix:
arch:
- name: x86_64
runner: macos-latest
- name: arm64
runner: macos-latest-xl-arm64
runs-on: ${{ matrix.arch.runner }}
Expand All @@ -323,10 +321,20 @@ jobs:

- name: Install Git dependencies
run: |
set -x
set -ex
# Install x86_64 packages
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
arch -x86_64 /usr/local/bin/brew install gettext curl
# Install arm64 packages
brew install automake asciidoc xmlto docbook
brew link --force gettext
# Make universal gettext and curl library
lipo -create -output libintl.a /usr/local/opt/gettext/lib/libintl.a /opt/homebrew/opt/gettext/lib/libintl.a
lipo -create -output libcurl.dylib /opt/homebrew/opt/curl/lib/libcurl.4.dylib /usr/local/opt/curl/lib/libcurl.4.dylib
- name: Set up signing/notarization infrastructure
env:
A1: ${{ secrets.APPLICATION_CERTIFICATE_BASE64 }}
Expand Down Expand Up @@ -383,24 +391,37 @@ jobs:
exit 1
}
# Configure the environment
# Trace execution, stop on error
set -ex
PATH=/usr/local/bin:$PATH
export CURL_LDFLAGS=$(curl-config --libs)
# Write to "version" file to force match with trigger payload version
echo "${{ needs.prereqs.outputs.tag_version }}" >>git/version
# Configure universal build
cat >git/config.mak <<EOF
# Create universal binaries. HOST_CPU is a bit of a lie and only
# used in 'git version --build-options'. We'll fix that in code.
HOST_CPU = universal
BASIC_CFLAGS += -arch arm64 -arch x86_64
EOF
# Configure the Git build to pick up gettext
homebrew_prefix="$(brew --prefix)"
cat >git/config.mak <<EOF
LDFLAGS = -L$homebrew_prefix/lib -L/usr/local/opt/gettext/lib
cat >>git/config.mak <<EOF
CFLAGS = -I$homebrew_prefix/include -I/usr/local/opt/gettext/include
LDFLAGS = -L"$(pwd)"
EOF
# On Apple Silicon, homebrew apparently does not install a `gcc` symlink
test x86_64 = '${{ matrix.arch.name }}' ||
echo 'CC = gcc-13' >>config.mak
# Configure the Git build to pick up the universal `libcurl.dylib`
cat >>git/config.mak <<EOF
CURL_LDFLAGS := -L"$(pwd)" -lcurl
CURL_CONFIG := /usr/bin/true
EOF
# Avoid even building the dashed built-ins; Those should be hard-linked
# copies of the `git` executable but would end up as actual copies instead,
# bloating the size of the `.dmg` indecently.
echo 'SKIP_DASHED_BUILT_INS = YabbaDabbaDoo' >>git/config.mak
# To make use of the catalogs...
export XML_CATALOG_FILES=$homebrew_prefix/etc/xml/catalog
Expand All @@ -416,10 +437,11 @@ jobs:
tar -xvf git/git-manpages-$VERSION.tar.gz -C manpages
# Lay out payload
cp git/config.mak payload/git-$VERSION/config.mak
make -C git/.github/macos-installer V=1 payload
# Codesign payload
cp -R stage/git-${{ matrix.arch.name }}-$VERSION/ \
cp -R stage/git-universal-$VERSION/ \
git/.github/macos-installer/build-artifacts
make -C git/.github/macos-installer V=1 codesign \
APPLE_APP_IDENTITY="$A3" || die "Creating signed payload failed"
Expand Down Expand Up @@ -584,6 +606,9 @@ jobs:
- os: macos-latest
artifact: macos-artifacts
command: git
- os: macos-latest-xl-arm64
artifact: macos-artifacts
command: git
- os: windows-latest
artifact: win-installer-x86_64
command: $PROGRAMFILES\Git\cmd\git.exe
Expand Down Expand Up @@ -616,7 +641,7 @@ jobs:
test arm64 != "$arch" ||
brew uninstall git
pkgpath=$(find ./*$arch*.pkg)
pkgpath=$(find ./*universal*.pkg)
sudo installer -pkg $pkgpath -target /
- name: Validate
Expand All @@ -625,6 +650,15 @@ jobs:
"${{ matrix.component.command }}" --version | sed 's/git version //' >actual
echo ${{ needs.prereqs.outputs.tag_version }} >expect
cmp expect actual || exit 1
- name: Validate universal binary CPU architecture
if: contains(matrix.component.os, 'macos')
shell: bash
run: |
set -ex
git version --build-options >actual
cat actual
grep "cpu: $(uname -m)" actual
# End validate installers

create-github-release:
Expand Down
16 changes: 16 additions & 0 deletions help.c
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,22 @@ const char *help_unknown_cmd(const char *cmd)
exit(1);
}

#if defined(__APPLE__)
static const char *git_host_cpu(void) {
if (!strcmp(GIT_HOST_CPU, "universal")) {
#if defined(__x86_64__)
return "x86_64";
#elif defined(__aarch64__)
return "arm64";
#endif
}

return GIT_HOST_CPU;
}
#undef GIT_HOST_CPU
#define GIT_HOST_CPU git_host_cpu()
#endif

void get_version_info(struct strbuf *buf, int show_build_options)
{
/*
Expand Down

0 comments on commit dc61fa0

Please sign in to comment.