From 24ae144af80277e6de5ee06ecc8e9780510fc00e Mon Sep 17 00:00:00 2001
From: viktorstrate <viktorstrate@gmail.com>
Date: Mon, 15 Feb 2021 23:17:37 +0100
Subject: [PATCH] Cross compile go-face with docker

---
 .github/workflows/tests.yml |   2 +-
 Dockerfile                  |  27 +++++++---
 docker_go_wrapper.sh        | 104 ++++++++++++++++++++++++++++++++++++
 3 files changed, 124 insertions(+), 9 deletions(-)
 create mode 100644 docker_go_wrapper.sh

diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 36e231c..57aaf8f 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -26,7 +26,7 @@ jobs:
         uses: actions/checkout@v2
 
       - name: Get C dependencies
-        run: apt-get install -y libdlib-dev libblas-dev liblapack-dev libjpeg62-turbo-dev
+        run: sudo apt-get install -y libdlib-dev libblas-dev liblapack-dev libjpeg62-turbo-dev
 
       - name: Get GO dependencies
         run: |
diff --git a/Dockerfile b/Dockerfile
index 815a226..3e2d2df 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -22,14 +22,25 @@ RUN npm run build -- --public-url $UI_PUBLIC_URL
 ### Build API ###
 FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.15-buster AS api
 
-# Install GCC cross compilers
+# Install G++/GCC cross compilers
+RUN dpkg --add-architecture arm64
+RUN dpkg --add-architecture armhf
 RUN apt-get update
-RUN apt-get install -y gcc-aarch64-linux-gnu libc6-dev-arm64-cross gcc-arm-linux-gnueabihf libc6-dev-armhf-cross
+RUN apt-get install -y g++-aarch64-linux-gnu libc6-dev-arm64-cross g++-arm-linux-gnueabihf libc6-dev-armhf-cross
 
 # Install go-face dependencies
-RUN apt-get install -y libdlib-dev libblas-dev liblapack-dev libjpeg62-turbo-dev
+RUN apt-get install -y \
+  libdlib-dev libdlib-dev:arm64 libdlib-dev:armhf \
+  libblas-dev libblas-dev:arm64 libblas-dev:armhf \
+  liblapack-dev liblapack-dev:arm64 liblapack-dev:armhf \
+  libjpeg62-turbo-dev libjpeg62-turbo-dev:arm64 libjpeg62-turbo-dev:armhf
 
-COPY --from=tonistiigi/xx:golang / /
+RUN echo $PATH
+
+COPY docker_go_wrapper.sh /go/bin/go
+RUN chmod +x /go/bin/go
+
+ENV CGO_ENABLED 1
 
 ARG TARGETPLATFORM
 RUN go env
@@ -41,13 +52,13 @@ WORKDIR /app
 COPY api/go.mod api/go.sum /app/
 RUN go mod download
 
-# Build go-sqlite3 dependency with CGO
-ENV CGO_ENABLED 1
-RUN go install github.com/mattn/go-sqlite3
-
 # Build go-face
+RUN sed -i 's/-march=native//g' /go/pkg/mod/github.com/!kagami/go-face*/face.go
 RUN go install github.com/Kagami/go-face
 
+# Build go-sqlite3 dependency with CGO
+RUN go install github.com/mattn/go-sqlite3
+
 # Copy api source
 COPY api /app
 
diff --git a/docker_go_wrapper.sh b/docker_go_wrapper.sh
new file mode 100644
index 0000000..fc81dd6
--- /dev/null
+++ b/docker_go_wrapper.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+: ${TARGETPLATFORM=}
+: ${TARGETOS=}
+: ${TARGETARCH=}
+: ${TARGETVARIANT=}
+: ${CGO_ENABLED=}
+: ${GOARCH=}
+: ${GOOS=}
+: ${GOARM=}
+: ${GOBIN=}
+
+set -eu
+
+if [ ! -z "$TARGETPLATFORM" ]; then
+  os="$(echo $TARGETPLATFORM | cut -d"/" -f1)"
+  arch="$(echo $TARGETPLATFORM | cut -d"/" -f2)"
+  if [ ! -z "$os" ] && [ ! -z "$arch" ]; then
+    export GOOS="$os"
+    export GOARCH="$arch"
+    if [ "$arch" = "arm" ]; then
+      case "$(echo $TARGETPLATFORM | cut -d"/" -f3)" in
+      "v5")
+        export GOARM="5"
+        ;;
+      "v6")
+        export GOARM="6"
+        ;;
+      *)
+        export GOARM="7"
+        ;;
+      esac
+    fi
+  fi
+fi
+
+if [ ! -z "$TARGETOS" ]; then
+  export GOOS="$TARGETOS"
+fi
+
+if [ ! -z "$TARGETARCH" ]; then
+  export GOARCH="$TARGETARCH"
+fi
+
+if [ "$TARGETARCH" = "arm" ]; then
+  if [ ! -z "$TARGETVARIANT" ]; then
+    case "$TARGETVARIANT" in
+    "v5")
+      export GOARM="5"
+      ;;
+    "v6")
+      export GOARM="6"
+      ;;
+    *)
+      export GOARM="7"
+      ;;
+    esac
+  else
+    export GOARM="7"
+  fi
+fi
+
+if [ "$CGO_ENABLED" = "1" ]; then
+  case "$GOARCH" in
+  "amd64")
+    export CC="x86_64-linux-gnu-gcc"
+    export CXX="x86_64-linux-gnu-g++"
+    ;;
+  "ppc64le")
+    export CC="powerpc64le-linux-gnu-gcc"
+    export CXX="powerpc64le-linux-gnu-g++"
+    ;;
+  "s390x")
+    export CC="s390x-linux-gnu-gcc"
+    export CXX="s390x-linux-gnu-g++"
+    ;;
+  "arm64")
+    export CC="aarch64-linux-gnu-gcc"
+    export CXX="aarch64-linux-gnu-g++"
+    ;;
+  "arm")
+    case "$GOARM" in
+    "5")
+      export CC="arm-linux-gnueabi-gcc"
+      export CXX="arm-linux-gnueabi-g++"
+      ;;
+    *)
+      export CC="arm-linux-gnueabihf-gcc"
+      export CXX="arm-linux-gnueabihf-g++"
+      ;;
+    esac
+    ;;
+  esac
+fi
+
+if [ "$GOOS" = "wasi" ]; then
+  export GOOS="js"
+fi
+
+if [ -z "$GOBIN" ] && [ -n "$GOPATH" ] && [ -n "$GOARCH" ] && [ -n "$GOOS" ]; then
+  export PATH=${GOPATH}/bin/${GOOS}_${GOARCH}:${PATH}
+fi
+
+exec /usr/local/go/bin/go "$@"
