Просмотр исходного кода

Merge pull request #145 from geebee/master

Docker build for Android Library
Rod Hynes 10 лет назад
Родитель
Сommit
3259cb9c5b
7 измененных файлов с 375 добавлено и 68 удалено
  1. 1 0
      .gitignore
  2. 93 0
      AndroidLibrary/Dockerfile
  3. 47 23
      AndroidLibrary/README.md
  4. 45 0
      AndroidLibrary/make.bash
  5. 74 33
      ConsoleClient/Dockerfile
  6. 87 3
      ConsoleClient/make.bash
  7. 28 9
      psiphon/buildinfo.go

+ 1 - 0
.gitignore

@@ -8,6 +8,7 @@ psiphon.boltdb
 # Exclude compiled tunnel core binaries
 ConsoleClient/ConsoleClient
 ConsoleClient/bin
+AndroidLibrary/psi.aar
 
 # Compiled Object files, Static and Dynamic libs (Shared Objects)
 *.o

+ 93 - 0
AndroidLibrary/Dockerfile

@@ -0,0 +1,93 @@
+# Dockerfile to build an image with the local version of psiphon-tunnel-core.
+#
+# See README.md for usage instructions.
+
+FROM ubuntu:latest
+
+# Install system-level dependencies.
+ENV DEBIAN_FRONTEND=noninteractive
+RUN apt-get update -y && apt-get install -y --no-install-recommends \
+    build-essential \
+    ca-certificates \
+    curl \
+    git \
+    openjdk-7-jdk \
+    pkg-config \
+  && apt-get clean \
+  && rm -rf /var/lib/apt/lists/*
+
+# Install Go.
+ENV GOVERSION=go1.5.3 GOROOT=/usr/local/go GOPATH=/go PATH=$PATH:/usr/local/go/bin:/go/bin CGO_ENABLED=1
+
+RUN curl -L https://storage.googleapis.com/golang/$GOVERSION.linux-amd64.tar.gz -o /tmp/go.tar.gz \
+  && tar -C /usr/local -xzf /tmp/go.tar.gz \
+  && rm /tmp/go.tar.gz \
+  && echo $GOVERSION > $GOROOT/VERSION
+
+# Setup Android Environment.
+ENV ANDROID_NDK_ROOT=/android-ndk ANDROID_HOME=/android-sdk-linux
+
+# Setup Android NDK
+RUN cd /tmp \
+  && curl -L http://dl.google.com/android/ndk/android-ndk-r10e-linux-x86_64.bin -o /tmp/android-ndk.bin \
+  && chmod a+x /tmp/android-ndk.bin \
+  && /tmp/android-ndk.bin \
+  && rm /tmp/android-ndk.bin \
+  && ln -s $(find /tmp -type d -name 'android-ndk-*') /android-ndk
+
+# Setup Android SDK.
+RUN curl -L http://dl.google.com/android/android-sdk_r24.4.1-linux.tgz -o /tmp/android-sdk.tgz \
+  && tar -C / -xzf /tmp/android-sdk.tgz \
+  && rm /tmp/android-sdk.tgz \
+  && (while true; do echo 'y'; sleep 2; done) | $ANDROID_HOME/tools/android update sdk --no-ui --filter platform,platform-tool,tool
+
+# Setup OpenSSL libray.
+ENV OPENSSL_VERSION=1.0.1p
+ENV PKG_CONFIG_PATH=/tmp/openssl/openssl-$OPENSSL_VERSION
+ENV CGO_CFLAGS="-I $PKG_CONFIG_PATH/include" CGO_LDFLAGS="-L $PKG_CONFIG_PATH -lssl -lcrypto"
+
+RUN mkdir -p /tmp/openssl \
+  && curl -L https://github.com/Psiphon-Labs/psiphon-tunnel-core/raw/master/openssl/openssl-$OPENSSL_VERSION.tar.gz -o /tmp/openssl.tar.gz \
+  && tar -C /tmp/openssl -xzf /tmp/openssl.tar.gz \
+  && rm /tmp/openssl.tar.gz \
+  && curl -L https://github.com/Psiphon-Labs/psiphon-tunnel-core/raw/master/openssl/setenv-android.sh -o /tmp/setenv-android.sh \
+  && /bin/bash -c "\
+    source /tmp/setenv-android.sh \
+    && cd /tmp/openssl/openssl-$OPENSSL_VERSION \
+    && perl -pi -e 's/install: all install_docs install_sw/install: install_docs install_sw/g' Makefile.org \
+    && ./config \
+      no-shared \
+      no-ssl2 \
+      no-ssl3 \
+      no-comp \
+      no-hw \
+      no-md2 \
+      no-md4 \
+      no-rc2 \
+      no-rc5 \
+      no-krb5 \
+      no-ripemd160 \
+      no-idea \
+      no-gost \
+      no-camellia \
+      no-seed \
+      no-3des \
+      no-heartbeats \
+      --openssldir=./ssl \
+    && perl -pi -e 's/-O3/-Os -mfloat-abi=softfp/g' Makefile \
+    && make depend \
+    && make all"
+
+# Install Pinned Gomobile
+#  - Ordered last to allow use of previously cached layers when changing revisions
+ENV GOMOBILE_PINNED_REV=52e0785361572f92c44186af9e2ccd18746adc2e
+RUN mkdir -p $GOPATH/src/golang.org/x \
+  && cd $GOPATH/src/golang.org/x \
+  && git clone https://github.com/golang/mobile \
+  && cd mobile \
+  && git checkout -b pinned $GOMOBILE_PINNED_REV \
+  && echo "master: $(git rev-parse master)\npinned: $(git rev-parse pinned)" | tee $GOROOT/MOBILE \
+  && go install golang.org/x/mobile/cmd/gomobile \
+  && gomobile init -v
+
+WORKDIR $GOPATH/src

+ 47 - 23
AndroidLibrary/README.md

@@ -1,36 +1,60 @@
-Psiphon Library for Android README
-================================================================================
+##Psiphon Android Library README
 
-Overview
---------------------------------------------------------------------------------
+###Overview
 
 Psiphon Library for Android enables you to easily embed Psiphon in your Android
 app. The Psiphon Library for Android is implemented in Go and follows the standard
 conventions for using a Go library in an Android app.
 
-Status
---------------------------------------------------------------------------------
+###Building with Docker
 
-* Pre-release
+Note that you may need to use `sudo docker` below, depending on your OS.
 
-Building From Source
---------------------------------------------------------------------------------
+#####Create the build image:
 
-Follow Go Android documentation:
-* [gomobile documentation](https://godoc.org/golang.org/x/mobile/cmd/gomobile)
-* Requires Go 1.5 or later.
-* Build command: `gomobile bind -target=android github.com/Psiphon-Labs/psiphon-tunnel-core/AndroidLibrary/psi`
-  * Record build version info, as described [here](https://github.com/Psiphon-Labs/psiphon-tunnel-core/blob/master/README.md#setup), by passing a `-ldflags` argument to `gomobile bind`.
-* Output: `psi.aar`
+  1. Run the command: `docker build --no-cache=true -t psiandroid .` (this may take some time to complete)
+  2. Once completed, verify that you see an image named `psiandroid` when running: `docker images`
 
-Using
---------------------------------------------------------------------------------
+#####Run the build:
 
-1. Build `psi.aar` from source or use the [binary release](https://github.com/Psiphon-Labs/psiphon-tunnel-core/releases)
-1. Add `psi.aar` to your Android Studio project as described in the [gomobile documentation](https://godoc.org/golang.org/x/mobile/cmd/gomobile)
-1. Example usage in [TunneledWebView sample app](../SampleApps/TunneledWebView/README.md)
+  *Ensure that the command below is run from within the `AndroidLibrary` directory*
 
-Limitations
---------------------------------------------------------------------------------
+  ```bash
+  cd .. && \
+    docker run \
+    --rm \
+    -v $(pwd):/go/src/github.com/Psiphon-Labs/psiphon-tunnel-core \
+    psiandroid \
+    /bin/bash -c 'source /tmp/setenv-android.sh && cd /go/src/github.com/Psiphon-Labs/psiphon-tunnel-core/AndroidLibrary && ./make.bash' \
+  ; cd -
+  ```
+When that command completes, the compiled `.aar` file (suitable for use in an Android Studio project) will be located in the current directory (it will likely be owned by root, so be sure to `chown` to an appropriate user).
 
-* Only supports one concurrent instance of Psiphon.
+###Building without Docker (from source)
+
+#####Prerequisites:
+
+ - The `build-essential` package (on Debian based systems - or its equivalent for your platform)
+ - Go 1.5 or later
+ - Full JDK
+ - Android NDK
+ - Android SDK
+ - OpenSSL (tested against the version [here](../openssl))
+  - Follow its [README](../openssl/README.md) to prepare the environment before you follow the steps below
+
+#####Steps:
+
+ 1. Follow Go Android documentation ([gomobile documentation](https://godoc.org/golang.org/x/mobile/cmd/gomobile))
+ - Build command: `gomobile bind -target=android github.com/Psiphon-Labs/psiphon-tunnel-core/AndroidLibrary/psi`
+  - Record build version info, as described [here](../README.md#setup), by passing a `-ldflags` argument to `gomobile bind`.
+  - Output: `psi.aar`
+
+###Using the Library
+
+ 1. Build `psi.aar` from via the docker container, from source, or use the [binary release](https://github.com/Psiphon-Labs/psiphon-tunnel-core/releases)
+ 2. Add `psi.aar` to your Android Studio project as described in the [gomobile documentation](https://godoc.org/golang.org/x/mobile/cmd/gomobile)
+ 3. Example usage in [TunneledWebView sample app](../SampleApps/TunneledWebView/README.md)
+
+#####Limitations
+
+ - Only supports one concurrent instance of Psiphon.

+ 45 - 0
AndroidLibrary/make.bash

@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+
+set -e
+
+if [ ! -f make.bash ]; then
+  echo "make.bash must be run from $GOPATH/src/github.com/Psiphon-Labs/psiphon-tunnel-core/AndroidLibrary"
+  exit 1
+fi
+
+GOOS=arm go get -d -v github.com/Psiphon-Inc/openssl
+GOOS=arm go get -d -v ./...
+if [ $? != 0 ]; then
+  echo "..'go get' failed, exiting"
+  exit $?
+fi
+
+BUILDDATE=$(date --iso-8601=seconds)
+BUILDREPO=$(git config --get remote.origin.url)
+BUILDREV=$(git rev-parse --short HEAD)
+GOVERSION=$(go version | perl -ne '/go version (.*?) / && print $1')
+GOMOBILEVERSION=$(gomobile version | perl -ne '/gomobile version (.*?) / && print $1')
+
+LDFLAGS="\
+-X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildDate=$BUILDDATE \
+-X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildRepo=$BUILDREPO \
+-X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildRev=$BUILDREV \
+-X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.goVersion=$GOVERSION \
+-X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.gomobileVersion=$GOMOBILEVERSION \
+"
+
+echo "Variables for ldflags:"
+echo " Build date: ${BUILDDATE}"
+echo " Build repo: ${BUILDREPO}"
+echo " Build revision: ${BUILDREV}"
+echo " Go version: ${GOVERSION}"
+echo " Gomobile version: ${GOMOBILEVERSION}"
+echo ""
+
+gomobile bind -v -ldflags="$LDFLAGS" github.com/Psiphon-Labs/psiphon-tunnel-core/AndroidLibrary/psi
+if [ $? != 0 ]; then
+  echo "..'gomobile bind' failed, exiting"
+  exit $?
+fi
+
+echo "Done"

+ 74 - 33
ConsoleClient/Dockerfile

@@ -2,48 +2,89 @@
 #
 # See README.md for usage instructions.
 
-FROM ubuntu:15.04
-
-ENV GOVERSION=go1.5.3
+FROM ubuntu:latest
 
 # Install system-level dependencies.
 ENV DEBIAN_FRONTEND=noninteractive
-RUN apt-get update && apt-get -y install build-essential curl git mercurial upx gcc-mingw-w64-i686 gcc-mingw-w64-x86-64 mingw-w64 gcc-multilib pkg-config
+RUN apt-get update -y && apt-get install -y --no-install-recommends \
+    build-essential \
+    ca-certificates \
+    curl \
+    gcc-mingw-w64-i686 \
+    gcc-mingw-w64-x86-64 \
+    gcc-multilib \
+    git \
+    mingw-w64 \
+    mercurial \
+    pkg-config \
+    upx \
+  && apt-get clean \
+  && rm -rf /var/lib/apt/lists/*
 
 # Install Go.
-ENV GOROOT=/usr/local/go GOPATH=/go
-ENV PATH=$PATH:$GOROOT/bin:$GOPATH/bin
-
-RUN curl -L https://storage.googleapis.com/golang/$GOVERSION.linux-amd64.tar.gz -o /tmp/go.tar.gz && \
-  tar -C /usr/local -xzf /tmp/go.tar.gz && \
-  rm /tmp/go.tar.gz && \
-  echo $GOVERSION > $GOROOT/VERSION
+ENV GOVERSION=go1.5.3 GOROOT=/usr/local/go GOPATH=/go PATH=$PATH:/usr/local/go/bin:/go/bin CGO_ENABLED=1
 
-ENV CGO_ENABLED=1
+RUN curl -L https://storage.googleapis.com/golang/$GOVERSION.linux-amd64.tar.gz -o /tmp/go.tar.gz \
+   && tar -C /usr/local -xzf /tmp/go.tar.gz \
+   && rm /tmp/go.tar.gz \
+   && echo $GOVERSION > $GOROOT/VERSION
 
-# Get go dependencies
-RUN go get github.com/mitchellh/gox && go get github.com/pwaller/goupx
+# Get external Go dependencies.
+RUN go get github.com/mitchellh/gox \
+    && go get github.com/pwaller/goupx
 
-# Setup paths for static OpenSSL libray
+# Setup OpenSSL libray.
 ENV OPENSSL_VERSION=1.0.1p
+ENV PKG_CONFIG_PATH_32=/tmp/openssl/32/openssl-$OPENSSL_VERSION PKG_CONFIG_PATH_64=/tmp/openssl/64/openssl-$OPENSSL_VERSION
+
+RUN mkdir -p /tmp/openssl/32 \
+ && mkdir -p /tmp/openssl/64 \
+ && curl -L https://github.com/Psiphon-Labs/psiphon-tunnel-core/raw/master/openssl/openssl-$OPENSSL_VERSION.tar.gz -o /tmp/openssl.tar.gz \
+ && tar -C /tmp/openssl/32 -xzf /tmp/openssl.tar.gz \
+ && tar -C /tmp/openssl/64 -xzf /tmp/openssl.tar.gz \
+ && rm /tmp/openssl.tar.gz
 
-RUN mkdir -p /tmp/openssl/32 && mkdir -p /tmp/openssl/64 && \
-      curl -L https://github.com/Psiphon-Labs/psiphon-tunnel-core/raw/master/openssl/openssl-$OPENSSL_VERSION.tar.gz -o /tmp/openssl.tar.gz && \
-      tar -C /tmp/openssl/32 -xzf /tmp/openssl.tar.gz && \
-      tar -C /tmp/openssl/64 -xzf /tmp/openssl.tar.gz
-
-ENV PKG_CONFIG_PATH_32=/tmp/openssl/32/openssl-$OPENSSL_VERSION
-RUN cd $PKG_CONFIG_PATH_32 && \
-      ./Configure --cross-compile-prefix=i686-w64-mingw32- mingw \
-      no-shared no-ssl2 no-ssl3 no-comp no-hw no-md2 no-md4 no-rc2 no-rc5 no-krb5 no-ripemd160 no-idea no-gost no-camellia no-seed no-3des no-heartbeats && \
-      make depend && \
-      make
-
-ENV PKG_CONFIG_PATH_64=/tmp/openssl/64/openssl-$OPENSSL_VERSION
-RUN cd $PKG_CONFIG_PATH_64 && \
-      ./Configure --cross-compile-prefix=x86_64-w64-mingw32- mingw64 \
-      no-shared no-ssl2 no-ssl3 no-comp no-hw no-md2 no-md4 no-rc2 no-rc5 no-krb5 no-ripemd160 no-idea no-gost no-camellia no-seed no-3des no-heartbeats && \
-      make depend && \
-      make
+RUN cd $PKG_CONFIG_PATH_32 \
+  && ./Configure --cross-compile-prefix=i686-w64-mingw32- mingw \
+    no-shared \
+    no-ssl2 \
+    no-ssl3 \
+    no-comp \
+    no-hw \
+    no-md2 \
+    no-md4 \
+    no-rc2 \
+    no-rc5 \
+    no-krb5 \
+    no-ripemd160 \
+    no-idea \
+    no-gost \
+    no-camellia \
+    no-seed \
+    no-3des \
+    no-heartbeats \
+  && make depend \
+  && make \
+  && cd $PKG_CONFIG_PATH_64 \
+  && ./Configure --cross-compile-prefix=x86_64-w64-mingw32- mingw64 \
+    no-shared \
+    no-ssl2 \
+    no-ssl3 \
+    no-comp \
+    no-hw \
+    no-md2 \
+    no-md4 \
+    no-rc2 \
+    no-rc5 \
+    no-krb5 \
+    no-ripemd160 \
+    no-idea \
+    no-gost \
+    no-camellia \
+    no-seed \
+    no-3des \
+    no-heartbeats \
+  && make depend \
+  && make
 
 WORKDIR $GOPATH/src

+ 87 - 3
ConsoleClient/make.bash

@@ -12,11 +12,13 @@ BUILDINFOFILE="${EXE_BASENAME}_buildinfo.txt"
 BUILDDATE=$(date --iso-8601=seconds)
 BUILDREPO=$(git config --get remote.origin.url)
 BUILDREV=$(git rev-parse --short HEAD)
+GOVERSION=$(go version | perl -ne '/go version (.*?) / && print $1')
 
 LDFLAGS="\
--X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildDate $BUILDDATE \
--X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildRepo $BUILDREPO \
--X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildRev $BUILDREV \
+-X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildDate=$BUILDDATE \
+-X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildRepo=$BUILDREPO \
+-X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildRev=$BUILDREV \
+-X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.goVersion=$GOVERSION \
 "
 echo -e "${BUILDDATE}\n${BUILDREPO}\n${BUILDREV}\n" > $BUILDINFOFILE
 
@@ -24,6 +26,7 @@ echo "Variables for ldflags:"
 echo " Build date: ${BUILDDATE}"
 echo " Build repo: ${BUILDREPO}"
 echo " Build revision: ${BUILDREV}"
+echo " Go version: ${GOVERSION}"
 echo ""
 
 if [ ! -d bin ]; then
@@ -33,6 +36,10 @@ fi
 build_for_windows () {
   echo "...Getting project dependencies (via go get) for Windows. Parameter is: '$1'"
   GOOS=windows go get -d -v ./...
+  if [ $? != 0 ]; then
+    echo "....'go get' failed, exiting"
+    exit $?
+  fi
 
   if [ -z $1 ] || [ "$1" == "32" ]; then
     unset PKG_CONFIG_PATH
@@ -45,6 +52,13 @@ build_for_windows () {
     CGO_LDFLAGS="-L $PKG_CONFIG_PATH -L /usr/i686-w64-mingw32/lib/ -lssl -lcrypto -lwsock32 -lcrypt32 -lgdi32" \
     CC=/usr/bin/i686-w64-mingw32-gcc \
     gox -verbose -ldflags "$LDFLAGS" -osarch windows/386 -output bin/windows/${EXE_BASENAME}-i686
+    RETVAL=$?
+    echo ".....gox completed, exit code: $?"
+    if [ $RETVAL != 0 ]; then
+      echo ".....gox failed, exiting"
+      exit $RETVAL
+    fi
+    unset RETVAL
 
     ## We are finding that UPXing the full Windows Psiphon client produces better results if psiphon-tunnel-core.exe is not already UPX'd.
     echo "....No UPX for this build"
@@ -61,6 +75,12 @@ build_for_windows () {
     CGO_LDFLAGS="-L $PKG_CONFIG_PATH -L /usr/x86_64-w64-mingw32/lib/ -lssl -lcrypto -lwsock32 -lcrypt32 -lgdi32" \
     CC=/usr/bin/x86_64-w64-mingw32-gcc \
     gox -verbose -ldflags "$LDFLAGS" -osarch windows/amd64 -output bin/windows/${EXE_BASENAME}-x86_64
+    RETVAL=$?
+    if [ $RETVAL != 0 ]; then
+      echo ".....gox failed, exiting"
+      exit $RETVAL
+    fi
+    unset RETVAL
 
     # We are finding that UPXing the full Windows Psiphon client produces better results if psiphon-tunnel-core.exe is not already UPX'd.
     echo "....No UPX for this build"
@@ -70,25 +90,59 @@ build_for_windows () {
 build_for_linux () {
   echo "Getting project dependencies (via go get) for Linux. Parameter is: '$1'"
   GOOS=linux go get -d -v ./...
+  if [ $? != 0 ]; then
+    echo "...'go get' failed, exiting"
+    exit $?
+  fi
 
   if [ -z $1 ] || [ "$1" == "32" ]; then
     echo "...Building linux-i686"
     CFLAGS=-m32 gox -verbose -ldflags "$LDFLAGS" -osarch linux/386 -output bin/linux/${EXE_BASENAME}-i686
+    RETVAL=$?
+    if [ $RETVAL != 0 ]; then
+      echo ".....gox failed, exiting"
+      exit $RETVAL
+    fi
+    unset RETVAL
+
     echo "....UPX packaging output"
     goupx --best bin/linux/${EXE_BASENAME}-i686
+    RETVAL=$?
+    if [ $RETVAL != 0 ]; then
+      echo ".....goupx failed, exiting"
+      exit $RETVAL
+    fi
+    unset RETVAL
   fi
 
   if [ -z $1 ] || [ "$1" == "64" ]; then
     echo "...Building linux-x86_64"
     gox -verbose -ldflags "$LDFLAGS" -osarch linux/amd64 -output bin/linux/${EXE_BASENAME}-x86_64
+    RETVAL=$?
+    if [ $RETVAL != 0 ]; then
+      echo "....gox failed, exiting"
+      exit $RETVAL
+    fi
+    unset RETVAL
+
     echo "....UPX packaging output"
     goupx --best bin/linux/${EXE_BASENAME}-x86_64
+    RETVAL=$?
+    if [ $RETVAL != 0 ]; then
+      echo ".....goupx failed, exiting"
+      exit $RETVAL
+    fi
+    unset RETVAL
   fi
 }
 
 build_for_osx () {
   echo "Getting project dependencies (via go get) for OSX"
   GOOS=darwin go get -d -v ./...
+  if [ $? != 0 ]; then
+    echo "..'go get' failed, exiting"
+    exit $?
+  fi
 
   echo "Building darwin-x86_64..."
   echo "..Disabling CGO for this build"
@@ -102,26 +156,56 @@ case $TARGET in
   windows)
     echo "..Building for Windows"
     build_for_windows $2
+    exit $?
+
     ;;
   linux)
     echo "..Building for Linux"
     build_for_linux $2
+    exit $?
+
     ;;
   osx)
     echo "..Building for OSX"
     build_for_osx
+    exit $?
+
     ;;
   all)
     echo "..Building all"
     build_for_windows $2
+    if [ $? != 0 ]; then
+      exit $?
+    fi
+
     build_for_linux $2
+    if [ $? != 0 ]; then
+      exit $?
+    fi
+
     build_for_osx
+    if [ $? != 0 ]; then
+      exit $?
+    fi
+
     ;;
   *)
     echo "..No selection made, building all"
     build_for_windows $2
+    if [ $? != 0 ]; then
+      exit $?
+    fi
+
     build_for_linux $2
+    if [ $? != 0 ]; then
+      exit $?
+    fi
+
     build_for_osx
+    if [ $? != 0 ]; then
+      exit $?
+    fi
+
     ;;
 
 esac

+ 28 - 9
psiphon/buildinfo.go

@@ -23,24 +23,43 @@ import "strings"
 
 /*
 These values should be filled in at build time using the `-X` option[1] to the
-Go linker (probably via `-ldflags` option to `go build` -- like `-ldflags "-X var1 abc -X var2 xyz"`).
+Go linker (probably via `-ldflags` option to `go build` -- like `-ldflags "-X var1=abc -X var2=xyz"`).
 [1]: http://golang.org/cmd/ld/
 Without those build flags, the build info in the notice will simply be empty strings.
 Suggestions for how to fill in the values will be given for each variable.
+Note that any passed value must contain no whitespace.
 */
-// -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildDate `date --iso-8601=seconds`
+// -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildDate=`date --iso-8601=seconds`
 var buildDate string
 
-// -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildRepo `git config --get remote.origin.url`
+// -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildRepo=`git config --get remote.origin.url`
 var buildRepo string
 
-// -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildRev `git rev-parse HEAD`
+// -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.buildRev=`git rev-parse --short HEAD`
 var buildRev string
 
+// -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.goVersion=`go version | perl -ne '/go version (.*?) / && print $1'`
+var goVersion string
+
+// -X github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon.gomobileVersion=`gomobile version | perl -ne '/gomobile version (.*?) / && print $1'`
+var gomobileVersion string
+
 func NoticeBuildInfo() {
-	NoticeInfo(
-		"Built: %#v from %#v at rev %#v",
-		strings.TrimSpace(buildDate),
-		strings.TrimSpace(buildRepo),
-		strings.TrimSpace(buildRev))
+
+	if len(strings.TrimSpace(gomobileVersion)) > 0 {
+		NoticeInfo(
+			"Built: %#v from %#v at rev %#v using go: %#v and gomobile: %#v",
+			strings.TrimSpace(buildDate),
+			strings.TrimSpace(buildRepo),
+			strings.TrimSpace(buildRev),
+			strings.TrimSpace(goVersion),
+			strings.TrimSpace(gomobileVersion))
+	} else {
+		NoticeInfo(
+			"Built: %#v from %#v at rev %#v using go: %#v",
+			strings.TrimSpace(buildDate),
+			strings.TrimSpace(buildRepo),
+			strings.TrimSpace(buildRev),
+			strings.TrimSpace(goVersion))
+	}
 }