Build a govips application for Windows on Linux using Docker, MinGW and MSYSY2. Binaries running native on Windows without WSL.
Setup inspired by:
Build a govips application for Windows on Linux using Docker, MinGW and MSYSY2. Binaries running native on Windows without WSL.
Setup inspired by:
| FROM golang:1.16-alpine as builder-linux | |
| RUN apk add \ | |
| vips-dev \ | |
| gcc \ | |
| musl-dev | |
| RUN mkdir /go/pkg \ | |
| && mkdir /tmp/go-cache \ | |
| && chmod ugo=rwX /go/pkg /tmp/go-cache | |
| ENV GOCACHE=/tmp/go-cache | |
| VOLUME /go/pkg | |
| VOLUME /tmp/go-cache | |
| FROM builder-linux as builder-windows | |
| RUN apk add \ | |
| mingw-w64-gcc \ | |
| pacman | |
| RUN mkdir /usr/share/pacman/keyrings/ \ | |
| && wget "https://raw.githubusercontent.com/msys2/MSYS2-keyring/master/msys2-revoked" -O /usr/share/pacman/keyrings/msys2-revoked \ | |
| && wget "https://raw.githubusercontent.com/msys2/MSYS2-keyring/master/msys2-trusted" -O /usr/share/pacman/keyrings/msys2-trusted \ | |
| && wget "https://raw.githubusercontent.com/msys2/MSYS2-keyring/master/msys2.gpg" -O /usr/share/pacman/keyrings/msys2.gpg \ | |
| && pacman-key --init \ | |
| && pacman-key --populate msys2 | |
| RUN echo -e "## msys2.org\\nServer = http://repo.msys2.org/mingw/x86_64\\nServer = https://downloads.sourceforge.net/project/msys2/REPOS/MINGW/x86_64" \ | |
| > /etc/pacman.d/mirrorlist.mingw64 | |
| RUN echo -e "\\n\\n[mingw64]\\nInclude = /etc/pacman.d/mirrorlist.mingw64" \ | |
| >> /etc/pacman.conf | |
| RUN pacman --noconfirm -Sy mingw-w64-x86_64-libvips \ | |
| && pacman --noconfirm -Sc | |
| COPY objcopy.sh /usr/local/bin/ | |
| ENV GOOS=windows | |
| ENV GOARCH=amd64 | |
| ENV CGO_ENABLED=1 | |
| ENV CC=x86_64-w64-mingw32-gcc | |
| ENV CXX=x86_64-w64-mingw32-g++ | |
| ENV PKG_CONFIG_PATH=/mingw64/lib/pkgconfig |
| #!/bin/bash | |
| set -euo pipefail | |
| src="${1:-}" | |
| dst="${2:-}" | |
| if [[ -z "${src}" ]] || [[ ! -f "${src}" ]] || [[ ! -d "${dst}" ]]; then | |
| echo "Usage $0 [object file] [destination]" | |
| echo "Script to copy dynamically linked windows binary with their import dependencies" | |
| exit 1 | |
| fi | |
| deps=( ) | |
| stack=( "${src}" ) | |
| analyzed=( ) | |
| ignore=( | |
| "KERNEL32.dll" | |
| "msvcrt.dll" | |
| "ADVAPI32.dll" | |
| "SHELL32.dll" | |
| "USER32.dll" | |
| "WS2_32.dll" | |
| "ole32.dll" | |
| "GDI32.dll" | |
| "MSIMG32.dll" | |
| "DNSAPI.dll" | |
| "IPHLPAPI.DLL" | |
| "SHLWAPI.dll" | |
| "USERENV.dll" | |
| "RPCRT4.dll" | |
| "USP10.dll" | |
| "gdiplus.dll" | |
| ) | |
| paths=( | |
| "." | |
| "/mingw64/bin/" | |
| ) | |
| while [[ ${#stack[@]} -gt 0 ]]; do | |
| dep="${stack[0]}" | |
| analyzed+=( "${dep}" ) | |
| found=false | |
| for p in "${paths[@]}"; do | |
| if [[ -f "${p}/${dep}" ]]; then | |
| dep="$( readlink -f "${p}/${dep}" )" | |
| found=true | |
| break | |
| fi | |
| done | |
| if ! $found; then | |
| echo "Error: Could not locate dependency \"${dep}\"." | |
| exit 2 | |
| fi | |
| echo "Analyze \"${dep}\"" | |
| while IFS='' read -r line; do stack+=("${line}"); done < \ | |
| <( comm -13 \ | |
| <( printf "%s\n" "${ignore[@]}" "${analyzed[@]}" "${stack[@]}" | uniq | sort ) \ | |
| <( objdump --private-headers "${dep}" \ | |
| | sed -n 's/^\s*DLL Name: \(.*\.dll\)$/\1/Ip' \ | |
| | uniq | sort ) ) | |
| deps+=( "${dep}" ) | |
| stack=( "${stack[@]:1}" ) | |
| done | |
| cp -uv "${deps[@]}" "${dst}" | |
| echo -e "\nCopied ${#deps[@]} dependencies" |