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

Add darwin arm64 target #34

Merged
merged 15 commits into from Mar 31, 2021
2 changes: 2 additions & 0 deletions .gitignore
@@ -1 +1,3 @@
/fyne-cross
/*.dmg
/*.xip
6 changes: 6 additions & 0 deletions CHANGELOG.md
@@ -1,6 +1,12 @@
# Changelog - Fyne.io fyne-cross

## Unreleased
- Update Go to v1.16.2
- Update fyne cli to v2.0.1
- Add darwin arm64 target #33
- Add the `darwin-image` command to build the darwin docker image
- Remove darwin 386 target
- Add dedicated docker image for windows
- Fix android keystore path is not resolved correctly
- Fix some release flags are always set even if empty
- Fix appID flag should not have a default #25
Expand Down
42 changes: 32 additions & 10 deletions Makefile
@@ -1,30 +1,52 @@
tag := $(shell date +"%y.%m.%d")

build-images:
base:
@docker build -f ${CURDIR}/docker/base/Dockerfile -t fyneio/fyne-cross:base-latest .
@docker tag fyneio/fyne-cross:base-latest fyneio/fyne-cross:base-$(tag)

android: base
@docker build -f ${CURDIR}/docker/android/Dockerfile -t fyneio/fyne-cross:android-latest .

darwin: base
@docker build -f ${CURDIR}/docker/darwin/Dockerfile -t fyneio/fyne-cross:darwin-latest .

freebsd: base
@docker build -f ${CURDIR}/docker/freebsd/Dockerfile -t fyneio/fyne-cross:freebsd-latest .

linux: base
@docker build -f ${CURDIR}/docker/linux-386/Dockerfile -t fyneio/fyne-cross:linux-386-latest .
@docker tag fyneio/fyne-cross:linux-386-latest fyneio/fyne-cross:linux-386-$(tag)
@docker build -f ${CURDIR}/docker/linux-arm/Dockerfile -t fyneio/fyne-cross:linux-arm-latest .
@docker tag fyneio/fyne-cross:linux-arm-latest fyneio/fyne-cross:linux-arm-$(tag)
@docker build -f ${CURDIR}/docker/linux-arm64/Dockerfile -t fyneio/fyne-cross:linux-arm64-latest .
@docker tag fyneio/fyne-cross:linux-arm64-latest fyneio/fyne-cross:linux-arm64-$(tag)
@docker build -f ${CURDIR}/docker/android/Dockerfile -t fyneio/fyne-cross:android-latest .
@docker tag fyneio/fyne-cross:android-latest fyneio/fyne-cross:android-$(tag)
@docker build -f ${CURDIR}/docker/freebsd/Dockerfile -t fyneio/fyne-cross:freebsd-latest .

windows: base
@docker build -f ${CURDIR}/docker/windows/Dockerfile -t fyneio/fyne-cross:windows-latest .

# build all images for release. Note do not build darwin
build-images: base android freebsd linux windows
@docker tag fyneio/fyne-cross:freebsd-latest fyneio/fyne-cross:freebsd-$(tag)

push-images:
$(eval TAG := $(date +"%y.%m.%d"))
@docker push fyneio/fyne-cross:base-latest
@docker tag fyneio/fyne-cross:base-latest fyneio/fyne-cross:base-$(tag)
@docker push fyneio/fyne-cross:base-$(tag)
@docker push fyneio/fyne-cross:android-latest
@docker tag fyneio/fyne-cross:android-latest fyneio/fyne-cross:android-$(tag)
@docker push fyneio/fyne-cross:android-$(tag)
@docker push fyneio/fyne-cross:linux-386-latest
@docker tag fyneio/fyne-cross:linux-386-latest fyneio/fyne-cross:linux-386-$(tag)
@docker push fyneio/fyne-cross:linux-386-$(tag)
@docker push fyneio/fyne-cross:linux-arm-latest
@docker tag fyneio/fyne-cross:linux-arm-latest fyneio/fyne-cross:linux-arm-$(tag)
@docker push fyneio/fyne-cross:linux-arm-$(tag)
@docker push fyneio/fyne-cross:linux-arm64-latest
@docker tag fyneio/fyne-cross:linux-arm64-latest fyneio/fyne-cross:linux-arm64-$(tag)
@docker push fyneio/fyne-cross:linux-arm64-$(tag)
@docker push fyneio/fyne-cross:android-latest
@docker push fyneio/fyne-cross:android-$(tag)
@docker push fyneio/fyne-cross:freebsd-latest
@docker tag fyneio/fyne-cross:freebsd-latest fyneio/fyne-cross:freebsd-$(tag)
@docker push fyneio/fyne-cross:freebsd-$(tag)
@docker push fyneio/fyne-cross:windows-latest
@docker tag fyneio/fyne-cross:windows-latest fyneio/fyne-cross:windows-$(tag)
@docker push fyneio/fyne-cross:windows-$(tag)

embed:
go run internal/cmd/embed/main.go
33 changes: 25 additions & 8 deletions README.md
Expand Up @@ -2,13 +2,11 @@

[![CI](https://github.com/fyne-io/fyne-cross/workflows/CI/badge.svg)](https://github.com/fyne-io/fyne-cross/actions?query=workflow%3ACI) [![Go Report Card](https://goreportcard.com/badge/github.com/fyne-io/fyne-cross)](https://goreportcard.com/report/github.com/fyne-io/fyne-cross) [![GoDoc](https://godoc.org/github.com/fyne-io/fyne-cross?status.svg)](http://godoc.org/github.com/fyne-io/fyne-cross) [![version](https://img.shields.io/github/v/tag/fyne-io/fyne-cross?label=version)]()

fyne-cross is a simple tool to cross compile and create distribution packages for [Fyne](https://fyne.io) applications.

It has been inspired by [xgo](https://github.com/karalabe/xgo) and uses a [docker image](https://hub.docker.com/r/fyneio/fyne-cross) built on top of the [golang-cross](https://github.com/docker/golang-cross) image, that includes the MinGW compiler for windows, and an OSX SDK, along with the Fyne requirements.
fyne-cross is a simple tool to cross compile and create distribution packages for [Fyne](https://fyne.io) applications using docker images that include the MinGW compiler for windows, and a macOS SDK, along with the Fyne requirements.

Supported targets are:
- darwin/amd64
- darwin/386
- darwin/arm64
- freebsd/amd64
- linux/amd64
- linux/386
Expand All @@ -20,6 +18,7 @@ Supported targets are:
- ios

> Note:
> - starting from v1.1.0 the image with the OSX SDK is no more available via docker hub and has to be build manually, see the [Build the darwin image](#build_darwin_image) section below.
> - iOS compilation is supported only on darwin hosts. See [fyne pre-requisites](https://developer.fyne.io/started/#prerequisites) for details.
> - macOS packaging for public distrubution (release mode) is supported only on darwin hosts.
> - windows packaging for public distrubution (release mode) is supported only on windows hosts.
Expand Down Expand Up @@ -109,6 +108,24 @@ fyne-cross linux
fyne-cross linux -output bugs ./cmd/bugs
```

## <a name="build_darwin_image"></a>Build the docker image for OSX/Darwin/Apple builds
The docker image for the darwin image is not provided via docker hub and need to build manually since depends on the OSX SDK.

**[Please ensure you have read and understood the Xcode license
terms before continuing.](https://www.apple.com/legal/sla/docs/xcode.pdf)**

To build the image:
1. [Download Command Line Tools for Xcode](https://developer.apple.com/download/more) >= 12.4
2. Run: `fyne-cross darwin-image --xcode-path /path/to/Command_Line_Tools_for_Xcode_<version>.dmg`

The command above will:
- install the dependencies required by [osxcross](https://github.com/tpoechtrager/osxcross) to package the macOS SDK and compile the macOS cross toolchain.
- package the macOS SDK
- compile the macOS cross toolchain
- create the `fyneio/fyne-cross:darwin-latest` image that will be used by fyne-cross

> NOTE: the creation of the image may take several minutes and may require more than 25 GB of free disk space.

## Contribute

- Fork and clone the repository
Expand All @@ -119,8 +136,8 @@ fyne-cross linux -output bugs ./cmd/bugs

See [contributors](https://github.com/fyne-io/fyne-cross/graphs/contributors) page

## Legal note
## Credits

OSX/Darwin/Apple builds:
**[Please ensure you have read and understood the Xcode license
terms before continuing.](https://www.apple.com/legal/sla/docs/xcode.pdf)**
- [osxcross](https://github.com/tpoechtrager/osxcross) for the macOS Cross toolchain for Linux
- [golang-cross](https://github.com/docker/golang-cross) for the inspiration and the docker images used in the initial versions
- [xgo](https://github.com/karalabe/xgo) for the inspiration
13 changes: 7 additions & 6 deletions docker/README.md
Expand Up @@ -4,9 +4,10 @@ This folder contains the docker images used by fyne-cross to build the Fyne appl

It provides the following images:

- fyneio/fyne-cross:base
- fyneio/fyne-cross:linux-386
- fyneio/fyne-cross:linux-arm64
- fyneio/fyne-cross:linux-arm
- fyneio/fyne-cross:android
- fyneio/fyne-cross:freebsd
- fyneio/fyne-cross:base-latest
- fyneio/fyne-cross:darwin-latest
- fyneio/fyne-cross:linux-386-latest
- fyneio/fyne-cross:linux-arm64-latest
- fyneio/fyne-cross:linux-arm-latest
- fyneio/fyne-cross:android-latest
- fyneio/fyne-cross:freebsd-latest
32 changes: 11 additions & 21 deletions docker/base/Dockerfile
@@ -1,38 +1,28 @@
# docker cross 1.13.15
ARG DOCKER_CROSS_VERSION=sha256:11a04661d910f74c419623ef7880024694f9151c17578af15e86c45cdf6c8588
ARG GO_VERSION=1.16.2
# fyne stable branch
ARG FYNE_VERSION=v2.0.0
ARG FYNE_VERSION=v2.0.1

# Build the fyne command utility
FROM dockercore/golang-cross@${DOCKER_CROSS_VERSION} AS fyne
FROM golang:${GO_VERSION}-buster AS tools
ARG FYNE_VERSION
RUN GO111MODULE=on go get -ldflags="-w -s" -v "fyne.io/fyne/v2/cmd/fyne@${FYNE_VERSION}"

# Build the gowindres command utility
FROM dockercore/golang-cross@${DOCKER_CROSS_VERSION} AS gowindres
WORKDIR /app
COPY . .
RUN GO111MODULE=on go build -o /go/bin/gowindres -ldflags="-w -s" ./internal/cmd/gowindres

FROM golang:1.14.15-buster AS golang
# Install the fyne CLI tool
RUN go get -ldflags="-w -s" -v "fyne.io/fyne/v2/cmd/fyne@${FYNE_VERSION}"

# Build the fyne-cross base image
FROM dockercore/golang-cross@${DOCKER_CROSS_VERSION}
FROM golang:${GO_VERSION}-buster AS base

COPY --from=fyne /go/bin/fyne /usr/local/bin
COPY --from=gowindres /go/bin/gowindres /usr/local/bin
RUN rm -rf /usr/local/go
COPY --from=golang /usr/local/go /usr/local/go
COPY --from=tools /go/bin/fyne /usr/local/bin

RUN apt-get update -qq \
&& apt-get install -y -q --no-install-recommends \
gosu \
zip \
unzip \
# fyne deps
libgl1-mesa-dev \
libegl1-mesa-dev \
libgles2-mesa-dev \
xorg-dev \
gosu \
zip \
unzip \
# headers needed by xorg-dev
x11proto-dev \
# deps to support wayland
Expand Down
58 changes: 58 additions & 0 deletions docker/darwin/Dockerfile
@@ -0,0 +1,58 @@
ARG LLVM_VERSION=12
ARG OSX_VERSION_MIN=10.12
ARG OSX_CROSS_COMMIT="035cc170338b7b252e3f13b0e3ccbf4411bffc41"

## Install latest version of llvm and clang
FROM fyneio/fyne-cross:base-latest AS darwin-base
ARG LLVM_VERSION

RUN wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - \
&& echo "deb http://apt.llvm.org/buster/ llvm-toolchain-buster-${LLVM_VERSION} main" | tee /etc/apt/sources.list.d/llvm.list > /dev/null \
&& apt-get update \
&& apt-get install -y -q --no-install-recommends \
clang-${LLVM_VERSION} \
llvm-${LLVM_VERSION} \
&& apt-get -qy autoremove \
&& apt-get clean \
&& rm -r /var/lib/apt/lists/*;

ENV PATH=/usr/lib/llvm-${LLVM_VERSION}/bin:${PATH}

## Build osxcross toolchain
FROM darwin-base as osxcross
ARG OSX_CROSS_COMMIT
ARG OSX_VERSION_MIN

RUN apt-get update -qq && apt-get install -y -q --no-install-recommends \
bzip2 \
cmake \
cpio \
patch \
libbz2-dev \
libssl-dev \
zlib1g-dev \
liblzma-dev \
libxml2-dev \
uuid-dev \
&& rm -rf /var/lib/apt/lists/*

COPY *.dmg /tmp/command_line_tools_for_xcode.dmg

WORKDIR "/osxcross"

RUN git clone https://github.com/tpoechtrager/osxcross.git . \
&& git checkout -q "${OSX_CROSS_COMMIT}" \
&& rm -rf ./.git

RUN ./tools/gen_sdk_package_tools_dmg.sh /tmp/command_line_tools_for_xcode.dmg

RUN mv MacOSX11*.tar.bz2 tarballs

RUN UNATTENDED=yes OSX_VERSION_MIN=${OSX_VERSION_MIN} ./build.sh


## Build darwin-latest image
FROM darwin-base

COPY --from=osxcross /osxcross/target /osxcross/target
ENV PATH=/osxcross/target/bin:$PATH
20 changes: 20 additions & 0 deletions docker/windows/Dockerfile
@@ -0,0 +1,20 @@
## Build the gowindres CLI tool
FROM fyneio/fyne-cross:base-latest AS builder

WORKDIR /app
COPY . .

RUN go build -o /go/bin/gowindres -ldflags="-w -s" ./internal/cmd/gowindres

# Build the windows-base image
FROM fyneio/fyne-cross:base-latest AS windows-base

COPY --from=builder /go/bin/gowindres /usr/local/bin

RUN apt-get update \
&& apt-get install -y -q --no-install-recommends \
gcc-mingw-w64 \
parallel \
&& apt-get -qy autoremove \
&& apt-get clean \
&& rm -r /var/lib/apt/lists/*;
33 changes: 33 additions & 0 deletions internal/cmd/embed/main.go
@@ -0,0 +1,33 @@
// This file embeds resources like Dockerfiles to be used in fyne-cross
// TODO: move to go:embed once the go min version required by fyne-cross will be 1.16
package main

import (
"fmt"
"io/ioutil"
"os"
"text/template"
)

func main() {
b, err := ioutil.ReadFile("docker/darwin/Dockerfile")
if err != nil {
fmt.Printf("could not read darwin Dockerfile, please run from the project root: %s", err)
os.Exit(1)
}

f, err := os.Create("internal/resource/darwin_dockerfile.go")
if err != nil {
fmt.Printf("could not write embedded darwin Dockerfile, please run from the project root: %s", err)
os.Exit(1)
}
t := template.Must(template.New("dockerfile").Parse(tpl))
t.Execute(f, fmt.Sprintf("`%s`", b))
}

var tpl = `// auto-generated by cmd/internal/main.go DO NOT EDIT.

package resource

const DockerfileDarwin = {{.}}
`
14 changes: 9 additions & 5 deletions internal/command/darwin.go
@@ -1,6 +1,7 @@
package command

import (
"errors"
"fmt"
"os"
"path/filepath"
Expand All @@ -17,9 +18,9 @@ const (

var (
// darwinArchSupported defines the supported target architectures on darwin
darwinArchSupported = []Architecture{ArchAmd64, Arch386}
darwinArchSupported = []Architecture{ArchAmd64, ArchArm64}
// darwinImage is the fyne-cross image for the Darwin OS
darwinImage = "fyneio/fyne-cross:base-latest"
darwinImage = "fyneio/fyne-cross:darwin-latest"
)

// Darwin build and package the fyne app for the darwin OS
Expand Down Expand Up @@ -201,6 +202,9 @@ func darwinContext(flags *darwinFlags, args []string) ([]Context, error) {
if err != nil {
return ctxs, err
}
if ctx.AppID == "" {
return ctxs, errors.New("appID is mandatory")
}

ctx.Architecture = arch
ctx.OS = darwinOS
Expand All @@ -209,9 +213,9 @@ func darwinContext(flags *darwinFlags, args []string) ([]Context, error) {

switch arch {
case ArchAmd64:
ctx.Env = append(ctx.Env, "GOOS=darwin", "GOARCH=amd64", "CC=o32-clang")
case Arch386:
ctx.Env = append(ctx.Env, "GOOS=darwin", "GOARCH=386", "CC=o32-clang")
ctx.Env = append(ctx.Env, "GOOS=darwin", "GOARCH=amd64", "CC=o64-clang", "CGO_CFLAGS=-mmacosx-version-min=10.12", "CGO_LDFLAGS=-mmacosx-version-min=10.12")
case ArchArm64:
ctx.Env = append(ctx.Env, "GOOS=darwin", "GOARCH=arm64", "CC=oa64-clang", "CGO_CFLAGS=-mmacosx-version-min=11.1", "CGO_LDFLAGS=-mmacosx-version-min=11.1")
}

// set context based on command-line flags
Expand Down