'How do I get Wireguard-Android make file to function on Windows?

I'm trying to build the wireguard-android sources on my windows machine, fixing the problems step by step with trial and error.

I have CMake and Make installed, the first problem I encountered was the 'bad' value reported by uname (mingw64), not matching with the golang filenames hosted by Google.

I've edited (hacked) the make file to point to the real filename of the windows version (amd64). The problem is the windows version has a .zip extension instead of .tar.gzand the result from zip doesn't seem compatible with the piped command.

Original command:

curl "https://dl.google.com/go/go$(DESIRED_GO_VERSION).$(shell uname -s | tr '[:upper:]' '[:lower:]')-$(NDK_GO_ARCH_MAP_$(shell uname -m)).tar.gz" | tar -C "$(dir $@)" --strip-components=1 -xzf -

My attempted changes: (uses an if-else because it still needs to run on mac too)

ifeq "msys" "$(shell uname -o | tr '[:upper:]' '[:lower:]')"
    # Note: when enclosed in the ifeq, the ARCH_MAP part no longer worked
    # Note: using tar with the zip fails, because we cant untar a zip (signal 13)
    # Note: using unzip with the zip fails with confusing paths
    curl "https://dl.google.com/go/go$(DESIRED_GO_VERSION).windows-amd64.zip" | unzip -C "$(dir $@)" --strip-components=1 -xzf -
else
    curl "https://dl.google.com/go/go$(DESIRED_GO_VERSION).$(shell uname -s | tr '[:upper:]' '[:lower:]')-$(NDK_GO_ARCH_MAP_$(shell uname -m)).tar.gz" | tar -C "$(dir $@)" --strip-components=1 -xzf -
endif

Resulting error if using unzip:

unzip: cannot find or open C:\wireguard-android\app\build\intermediates\cmake\debug\obj\armeabi-v7a/../generated-src/go-1.13.7/, C:\wireguard-android\app\build\intermediates\cmake\debug\obj\armeabi-v7a/../generated-src/go-1.13.7/.zip or C:\wireguard-android\app\build\intermediates\cmake\debug\obj\armeabi-v7a/../generated-src/go-1.13.7/.ZIP.

% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0 0 127M 0 5419 0 0 26694 0 1:23:47 --:--:-- 1:23:47 26694

curl: (23) Failed writing body (34 != 1357)

make: *** [C:\wireguard-android\app\build\intermediates\cmake\debug\obj\armeabi-v7a/../generated-src/go-1.13.7/.prepared] Error 9

Resulting error if using tar:

curl "https://dl.google.com/go/go1.13.7.windows-amd64.zip" | tar -C "C:\wireguard-android\app\build\intermediates\cmake\debug\obj\armeabi-v7a/../generated-src/go-1.13.7/" --strip-components=1 -xzf -

% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed

0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0gzip: stdin has more than one entry--rest ignored tar: Child died with signal 13 tar: Error is not recoverable: exiting now

0 127M 0 108k 0 0 248k 0 0:08:47 --:--:-- 0:08:47 248k

curl: (23) Failed writing body (738 != 1357)

make: *** [C:\wireguard-android\app\build\intermediates\cmake\debug\obj\armeabi-v7a/../generated-src/go-1.13.7/.prepared] Error 2


  • How should I get this command working? (With either tar or zip/unzip)
  • Somebody pointed out to me, that maybe I need the Android distro, not the Windows one. In that case I would assume I need armeabi-v7a, but I can only see ARMv6 and ARMv8 packages. What distribution should I use?


Solution 1:[1]

I've managed to solve this, I'm answering my own question rather than deleting because I think this will eventually help another developer.

First some clarifications:

  • It may seem like you should be including the target-platform Go libs (i.e. ARM for Android), but if you try this, you will get an error that the file is not executable when building. (So the build platform is the version to match, i.e. Windows here)
  • Because Google provides the Windows libs as a Zip (vs tar.gz for other platforms), you cannot use the tar command.
    • Because zip's cannot be read from a curl stream (the index is at the end of the file), you need to download the file and then unzip. Some people have suggested to use the jar command, however this did not work successfully with cmake/make
    • The zip file will be extracted into a subdirectory 'go' inside of whichever path you choose. For this reason you need to modify the paths
  • Some of the commands on Windows would not accept .. as the middle of a path, so I had to modify the CMakeLists file to use an absolute path

The changed end of the Makefile: (from after the .prepared/mkdir statements)

# Warning the (lack-of) indentation here is critical https://stackoverflow.com/a/4483467/984830
# Note: I've hardcoded the windows filename below, so you'll need to do an `if` (like in my question) if you want to support other platforms as well

    curl -o "$(BUILDDIR)/go-$(DESIRED_GO_VERSION)/gofile.zip" "https://dl.google.com/go/go$(DESIRED_GO_VERSION).windows-amd64.zip"
    unzip -o "$(BUILDDIR)/go-$(DESIRED_GO_VERSION)/gofile.zip" -d "$(dir $@)"
    rm -f "$(BUILDDIR)/go-$(DESIRED_GO_VERSION)/gofile.zip"

    patch -p1 -f -N -r- -d "$(dir $@)go/" < goruntime-boottime-over-monotonic.diff
    touch "$@"

$(DESTDIR)/libwg-go.so: export PATH := $(BUILDDIR)/go-$(DESIRED_GO_VERSION)/go/bin/:$(PATH)
$(DESTDIR)/libwg-go.so: $(BUILDDIR)/go-$(DESIRED_GO_VERSION)/.prepared go.mod
    go build -tags linux -ldflags="-X golang.zx2c4.com/wireguard/ipc.socketDirectory=/data/data/$(ANDROID_PACKAGE_NAME)/cache/wireguard" -v -trimpath -o "$@" -buildmode c-shared

The changed end of the CMakeLists file: (replacing the add_custom_target section)

# added a new variable to get the parent dir without using .. in the path
get_filename_component(destdirparent "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/.." ABSOLUTE)

# referred to the variable on the last line of this statment
add_custom_target(libwg-go.so WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/libwg-go" COMMENT "Building wireguard-go" VERBATIM COMMAND make
    ANDROID_ARCH_NAME=${ANDROID_ARCH_NAME}
    ANDROID_C_COMPILER=${ANDROID_C_COMPILER}
    ANDROID_TOOLCHAIN_ROOT=${ANDROID_TOOLCHAIN_ROOT}
    ANDROID_LLVM_TRIPLE=${ANDROID_LLVM_TRIPLE}
    ANDROID_SYSROOT=${ANDROID_SYSROOT}
    ANDROID_PACKAGE_NAME=${ANDROID_PACKAGE_NAME}
    CFLAGS=${CMAKE_C_FLAGS}\ -Wno-unused-command-line-argument
    LDFLAGS=${CMAKE_SHARED_LINKER_FLAGS}\ -fuse-ld=gold
    DESTDIR=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
    BUILDDIR=${destdirparent}/generated-src
    )

For reference the original files are here: Makefile & CMakeLists and are mirrored on Github

Solution 2:[2]

Thanks for @Nick Cardoso's answer. After repeated modification and debugging, I successfully worked out the makefile and CMakeLists.txt available on the Windows platform.

When using, you only need to modify these three variables: GIT_BIN_PATH, DESIRED_GO_VERSION, MAKE_PATH. Notes:

  1. No spaces are allowed in the project path! Otherwise the path of CURDIR will be truncated
  2. Don't install Cygwin! All you need is Git and the NDK, because Git contains the required commands: unzip.exe, patch.exe and touch.exe
tunnel/tools/libwg-go/Makefile
# SPDX-License-Identifier: Apache-2.0
#
# Copyright © 2017-2019 WireGuard LLC. All Rights Reserved.
BUILDDIR ?= $(CURDIR)/build
DESTDIR ?= $(CURDIR)/out

NDK_GO_ARCH_MAP_x86 := 386
NDK_GO_ARCH_MAP_x86_64 := amd64
NDK_GO_ARCH_MAP_arm := arm
NDK_GO_ARCH_MAP_arm64 := arm64
NDK_GO_ARCH_MAP_mips := mipsx
NDK_GO_ARCH_MAP_mips64 := mips64x

CLANG_FLAGS := --target=$(ANDROID_LLVM_TRIPLE) --gcc-toolchain=$(ANDROID_TOOLCHAIN_ROOT) --sysroot=$(ANDROID_SYSROOT)
export CGO_CFLAGS := $(CLANG_FLAGS) $(CFLAGS)
export CGO_LDFLAGS := $(CLANG_FLAGS) $(LDFLAGS) -Wl,-soname=libwg-go.so
export CC := $(ANDROID_C_COMPILER)
export GOARCH := $(NDK_GO_ARCH_MAP_$(ANDROID_ARCH_NAME))
export GOOS := android
export CGO_ENABLED := 1

default: $(DESTDIR)/libwg-go.so

GIT_BIN_PATH := "D:\Program Files\Git\usr\bin"
UNZIP_PATH := $(GIT_BIN_PATH)\unzip.exe
PATCH_PATH := $(GIT_BIN_PATH)\patch.exe
TOUCH_PATH := $(GIT_BIN_PATH)\touch.exe
DESIRED_GO_VERSION := 1.16.3
$(BUILDDIR)/go-$(DESIRED_GO_VERSION)/.prepared:
    if not exist "$(dir $@)" mkdir "$(dir $@)"
    curl -o "$(BUILDDIR)\go-$(DESIRED_GO_VERSION)\gofile.zip" "https://dl.google.com/go/go$(DESIRED_GO_VERSION).windows-amd64.zip"
    $(UNZIP_PATH) -o "$(BUILDDIR)\go-$(DESIRED_GO_VERSION)\gofile.zip" -d "$(dir $@)"
    del /f "$(BUILDDIR)\go-$(DESIRED_GO_VERSION)\gofile.zip"

    $(PATCH_PATH) -p1 -f -N -r- -d "$(dir $@)go/" < goruntime-boottime-over-monotonic.diff
    $(TOUCH_PATH) "$@"

$(DESTDIR)/libwg-go.so: export PATH := $(BUILDDIR)/go-$(DESIRED_GO_VERSION)/go/bin/:$(PATH)
$(DESTDIR)/libwg-go.so: $(BUILDDIR)/go-$(DESIRED_GO_VERSION)/.prepared go.mod
    go build -tags linux -ldflags="-X golang.zx2c4.com/wireguard/ipc.socketDirectory=/data/data/$(ANDROID_PACKAGE_NAME)/cache/wireguard" -v -trimpath -o "$@" -buildmode c-shared

.DELETE_ON_ERROR:
/tunnel/tools/CMakeLists.txt
# SPDX-License-Identifier: Apache-2.0
#
# Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.

cmake_minimum_required(VERSION 3.4.1)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}")

# Work around https://github.com/android-ndk/ndk/issues/602
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")


file(GLOB WG_SOURCES wireguard-tools/src/*.c ndk-compat/compat.c)
add_executable(libwg.so ${WG_SOURCES})
target_include_directories(libwg.so PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/wireguard-tools/src/uapi/linux/" "${CMAKE_CURRENT_SOURCE_DIR}/wireguard-tools/src/")
target_compile_options(libwg.so PUBLIC -O3 -std=gnu11 -D_GNU_SOURCE -include ${CMAKE_CURRENT_SOURCE_DIR}/ndk-compat/compat.h -DHAVE_VISIBILITY_HIDDEN -DRUNSTATEDIR=\"/data/data/${ANDROID_PACKAGE_NAME}/cache\")

get_filename_component(destdirparent "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/.." ABSOLUTE)
set(MAKE_PATH "D:/AndroidSDK/ndk/21.1.6352462/prebuilt/windows-x86_64/bin/make.exe")
# referred to the variable on the last line of this statment
add_custom_target(libwg-go.so WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/libwg-go" COMMENT "Building wireguard-go" VERBATIM COMMAND ${MAKE_PATH}
        ANDROID_ARCH_NAME=${ANDROID_ARCH_NAME}
        ANDROID_C_COMPILER=${ANDROID_C_COMPILER}
        ANDROID_TOOLCHAIN_ROOT=${ANDROID_TOOLCHAIN_ROOT}
        ANDROID_LLVM_TRIPLE=${ANDROID_LLVM_TRIPLE}
        ANDROID_SYSROOT=${ANDROID_SYSROOT}
        ANDROID_PACKAGE_NAME=${ANDROID_PACKAGE_NAME}
        CFLAGS=${CMAKE_C_FLAGS}\ -Wno-unused-command-line-argument
        LDFLAGS=${CMAKE_SHARED_LINKER_FLAGS}\ -fuse-ld=gold
        DESTDIR=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}
        BUILDDIR=${destdirparent}/generated-src
        )

# Hack to make it actually build as part of the default target
add_dependencies(libwg.so libwg-go.so)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Nick Cardoso
Solution 2 Zhou Hongbo