Search code examples
androidmakefilecmakeandroid-ndkwireguard

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

  • 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