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

Experimental Zig support for cross-compiling #32626

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
3 changes: 3 additions & 0 deletions .github/workflows/release-nightly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ jobs:
with:
go-version-file: go.mod
check-latest: true
- uses: mlugg/setup-zig@v1
with:
version: 0.12.1
- uses: actions/setup-node@v4
with:
node-version: 22
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/release-tag-rc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ jobs:
with:
go-version-file: go.mod
check-latest: true
- uses: mlugg/setup-zig@v1
with:
version: 0.12.1
- uses: actions/setup-node@v4
with:
node-version: 22
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/release-tag-version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ jobs:
with:
go-version-file: go.mod
check-latest: true
- uses: mlugg/setup-zig@v1
with:
version: 0.12.1
- uses: actions/setup-node@v4
with:
node-version: 22
Expand Down
111 changes: 102 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,6 @@ endif

LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)"

LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64

GO_TEST_PACKAGES ?= $(filter-out $(shell $(GO) list code.gitea.io/gitea/models/migrations/...) code.gitea.io/gitea/tests/integration/migration-test code.gitea.io/gitea/tests code.gitea.io/gitea/tests/integration code.gitea.io/gitea/tests/e2e,$(shell $(GO) list ./... | grep -v /vendor/))
MIGRATE_TEST_PACKAGES ?= $(shell $(GO) list code.gitea.io/gitea/models/migrations/...)

Expand Down Expand Up @@ -805,15 +803,13 @@ $(DIST_DIRS):
mkdir -p $(DIST_DIRS)

.PHONY: release-windows
release-windows: | $(DIST_DIRS)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION) .
ifeq (,$(findstring gogit,$(TAGS)))
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -buildmode exe -dest $(DIST)/binaries -tags 'osusergo gogit $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'windows/*' -out gitea-$(VERSION)-gogit .
endif
release-windows: | $(DIST_DIRS) zig-release-windows-amd64 zig-release-windows-arm64 zig-release-windows-amd64-gogit zig-release-windows-arm64-gogit
@echo "Windows binaries built"

.PHONY: release-linux
release-linux: | $(DIST_DIRS)
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets '$(LINUX_ARCHS)' -out gitea-$(VERSION) .
release-linux: | $(DIST_DIRS) zig-release-linux-amd64 zig-release-linux-arm64 zig-release-linux-arm6 zig-release-linux-linux-386
CGO_CFLAGS="$(CGO_CFLAGS)" $(GO) run $(XGO_PACKAGE) -go $(XGO_VERSION) -dest $(DIST)/binaries -tags 'netgo osusergo $(TAGS)' -ldflags '-linkmode external -extldflags "-static" $(LDFLAGS)' -targets 'linux/arm-5' -out gitea-$(VERSION) .
echo "Linux binaries built"

.PHONY: release-darwin
release-darwin: | $(DIST_DIRS)
Expand Down Expand Up @@ -986,6 +982,103 @@ docker:
docker build --disable-content-trust=false -t $(DOCKER_REF) .
# support also build args docker build --build-arg GITEA_VERSION=v1.2.3 --build-arg TAGS="bindata sqlite sqlite_unlock_notify" .

## Experimental Zig-based cross-compiling

# Platform definitions
LINUX_PLATFORMS := linux-amd64 linux-arm64 linux-386 linux-arm6
WINDOWS_PLATFORMS := windows-amd64 windows-arm64 windows-386
DARWIN_PLATFORMS := darwin-amd64 darwin-arm64

PLATFORMS := $(LINUX_PLATFORMS) $(WINDOWS_PLATFORMS) $(DARWIN_PLATFORMS)

# Zig target mappings
ZIG_TARGET.linux-amd64 := x86_64-linux-musl
ZIG_TARGET.linux-arm64 := aarch64-linux-musl
ZIG_TARGET.linux-386 := x86-linux-musl
ZIG_TARGET.linux-arm6 := arm-linux-musleabihf
ZIG_TARGET.windows-amd64 := x86_64-windows-gnu
ZIG_TARGET.windows-arm64 := aarch64-windows-gnu
ZIG_TARGET.windows-386 := x86-windows-gnu
ZIG_TARGET.darwin-amd64 := x86_64-macos
ZIG_TARGET.darwin-arm64 := aarch64-macos
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

according to https://ziglang.org/devlog/2024/#2024-11-19, maybe it should be aarch64-macos-none?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You were reading wrong article. That article is about zip-bootstrap which is used to "bootstrap" the zig compiler, but not for zip compiler itself.


# Output filename components
DARWIN_VERSION := 10.12
WINDOWS_VERSION := 4.0

# Function to get OS, ARCH from platform
OS = $(word 1,$(subst -, ,$1))
ARCH = $(word 2,$(subst -, ,$1))

# Function to generate output filename
define GET_FILENAME
$(strip \
$(if $(findstring windows,$1), \
gitea-$(VERSION)-$(if $2,gogit-)windows-$(WINDOWS_VERSION)-$(call ARCH,$1).exe, \
$(if $(findstring darwin,$1), \
gitea-$(VERSION)-darwin-$(DARWIN_VERSION)-$(call ARCH,$1), \
$(if $(filter %arm6,$(1)), \
gitea-$(VERSION)-linux-arm-6, \
gitea-$(VERSION)-linux-$(call ARCH,$1)) \
) \
) \
)
endef

# Common build flags
COMMON_TAGS := netgo osusergo $(TAGS)

# Platform-specific flags
CGO_FLAGS.linux := $(CGO_CFLAGS)
CGO_FLAGS.windows := $(CGO_CFLAGS)
CGO_FLAGS.darwin := $(CGO_CFLAGS)

# Platform-specific linker flags
EXTRA_LDFLAGS.linux := -static
# EXTRA_LDFLAGS.darwin := -dead_strip

GOARCH.linux-arm6 := arm

define GET_GOARCH
$(or $(GOARCH.$1),$(call ARCH,$1))
endef

# For ARM builds, we need to specify additional compiler flags
ZIG_ARM_FLAGS.linux-arm6 := -mcpu=arm1176jzf_s

# Generic release target
define RELEASE_template
zig-release-$(1)$(if $(2),-gogit): $$(DIST_DIRS)
CC="zig cc -target $$(ZIG_TARGET.$(1)) $$(ZIG_ARM_FLAGS.$(1))" \
CXX="zig c++ -target $$(ZIG_TARGET.$(1)) $$(ZIG_ARM_FLAGS.$(1))" \
CGO_ENABLED=1 \
CGO_CFLAGS="$$(CGO_FLAGS.$$(call OS,$(1)))" \
GOOS=$$(call OS,$(1)) \
GOARCH=$$(call GET_GOARCH,$(1)) \
$(if $(filter %arm6,$(1)),GOARM=6,) \
$$(GO) build $$(GOFLAGS) -tags '$$(COMMON_TAGS)$(if $(2), gogit,)' \
-ldflags '-s -w $(if $(findstring darwin,$(1)),,-linkmode external) -extldflags "$$(EXTRA_LDFLAGS.$$(call OS,$(1)))" $$(LDFLAGS)' \
-o $$(DIST)/binaries/$$(call GET_FILENAME,$(1),$(2)) .
endef

# Generate release targets for all platforms
$(foreach platform,$(PLATFORMS),$(eval $(call RELEASE_template,$(platform),)))

# Generate additional gogit targets for Windows
$(foreach platform,$(WINDOWS_PLATFORMS),$(eval $(call RELEASE_template,$(platform),1)))

# Target to build all platforms
zig-release-all: $(foreach platform,$(PLATFORMS),zig-release-$(platform)) \
$(foreach platform,$(WINDOWS_PLATFORMS),zig-release-$(platform)-gogit)

# Helper to list all available targets
.PHONY: list-targets
zig-list-targets:
@echo "Available targets:"
@echo "Linux targets: $(addprefix zig-release-,$(LINUX_PLATFORMS))"
@echo "Windows targets: $(addprefix zig-release-,$(WINDOWS_PLATFORMS)) $(addprefix zig-release-,$(addsuffix -gogit,$(WINDOWS_PLATFORMS)))"
@echo "Darwin targets: $(addprefix zig-release-,$(DARWIN_PLATFORMS))"

# This endif closes the if at the top of the file
endif

Expand Down
Loading