Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create universal builds on macos #612

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading