@ -21,15 +21,55 @@ TAILSCALE_COMMIT=$(shell echo $(TAILSCALE_VERSION) | cut -d - -f 2 | cut -d t -f
# Extract the version code from build.gradle.
VERSIONCODE = $( lastword $( shell grep versionCode android/build.gradle) )
VERSIONCODE_PLUSONE = $( shell expr $( VERSIONCODE) + 1)
i f e q ( $( shell uname ) , L i n u x )
ANDROID_TOOLS_URL = "https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip"
ANDROID_TOOLS_SUM = "bd1aa17c7ef10066949c88dc6c9c8d536be27f992a1f3b5a584f9bd2ba5646a0 commandlinetools-linux-9477386_latest.zip"
e l s e
ANDROID_TOOLS_URL = "https://dl.google.com/android/repository/commandlinetools-mac-9477386_latest.zip"
ANDROID_TOOLS_SUM = "2072ffce4f54cdc0e6d2074d2f381e7e579b7d63e915c220b96a7db95b2900ee commandlinetools-mac-9477386_latest.zip"
e n d i f
ANDROID_SDK_PACKAGES = 'platforms;android-31' 'extras;android;m2repository' 'ndk;23.1.7779620' 'platform-tools' 'build-tools;33.0.2'
# Attempt to find an ANDROID_SDK_ROOT / ANDROID_HOME based either from
# preexisting environment or common locations.
export ANDROID_SDK_ROOT ?= $( shell find $$ ANDROID_SDK_ROOT $$ ANDROID_HOME $$ HOME/Library/Android/sdk $$ HOME/Android/Sdk $$ HOME/AppData/Local/Android/Sdk /usr/lib/android-sdk -maxdepth 1 -type d 2>/dev/null | head -n 1)
# If ANDROID_SDK_ROOT is still unset, set it to a default location by platform.
i f e q ( $( ANDROID_SDK_ROOT ) , )
ifeq ( $( shell uname) ,Linux)
export ANDROID_SDK_ROOT = $( HOME) /Android/Sdk
else ifeq ( $( shell uname) ,Darwin)
export ANDROID_SDK_ROOT = $( HOME) /Library/Android/sdk
else ifneq ( $( WINDIR) ,) )
export ANDROID_SDK_ROOT = $( HOME) /AppData/Local/Android/sdk
else
export ANDROID_SDK_ROOT = $( PWD) /android-sdk
endif
e n d i f
export ANDROID_HOME ?= $( ANDROID_SDK_ROOT)
# Attempt to find Android Studio for Linux configuration, which does not have a
# predetermined location.
ANDROID_STUDIO_ROOT ?= $( shell find ~/android-studio /usr/local/android-studio /opt/android-studio /Applications/Android\ Studio.app $( PROGRAMFILES) /Android/Android\ Studio -type d -maxdepth 1 2>/dev/null | head -n 1)
# Set JAVA_HOME to the Android Studio bundled JDK.
export JAVA_HOME ?= $( shell find $( ANDROID_STUDIO_ROOT) /jre $( ANDROID_STUDIO_ROOT) /jbr $( ANDROID_STUDIO_ROOT) /Contents/jre/Contents/Home -maxdepth 1 -type d 2>/dev/null | head -n 1)
TOOLCHAINREV = $( shell go run tailscale.com/cmd/printdep --go)
TOOLCHAINDIR = ${ HOME } /.cache/tailscale-android-go-$( TOOLCHAINREV)
TOOLCHAINSUM = $( shell $( TOOLCHAINDIR) /go/bin/go version >/dev/null && echo "okay" || echo "bad" )
TOOLCHAINWANT = okay
export PATH := $( TOOLCHAINDIR) /go/bin:$( PATH)
# Go toolchain path, by default pulled from Tailscale prebuilts pinned to the
# version in tailscale.com/cmd/printdep.
TOOLCHAIN DIR ?= ${ HOME } /.cache/tailscale-android-go-$( shell go run tailscale.com/cmd/printdep --go )
export PATH := $( TOOLCHAINDIR) /bin:$( JAVA_HOME) /bin:$( ANDROID_HOME) /cmdline-tools/latest/bin:$( ANDROID_HOME) /platform-tools :$( PATH)
export GOROOT := # Unset
all : $( APK )
all : $( DEBUG_APK ) tailscale -fdroid .apk
env :
@echo PATH = $( PATH)
@echo ANDROID_SDK_ROOT = $( ANDROID_SDK_ROOT)
@echo ANDROID_HOME = $( ANDROID_HOME)
@echo JAVA_HOME = $( JAVA_HOME)
@echo TOOLCHAINDIR = $( TOOLCHAINDIR)
tag_release :
sed -i'.bak' 's/versionCode $(VERSIONCODE)/versionCode $(VERSIONCODE_PLUSONE)/' android/build.gradle && rm android/build.gradle.bak
@ -41,41 +81,75 @@ bumposs: toolchain
GOPROXY = direct go get tailscale.com@main
go mod tidy -compat= 1.20
toolchain :
i f n e q ( $( TOOLCHAINWANT ) , $( TOOLCHAINSUM ) )
@echo want: $( TOOLCHAINWANT)
@echo got: $( TOOLCHAINSUM)
$(TOOLCHAINDIR)/bin/go :
@if ! echo $( TOOLCHAINDIR) | grep -q 'tailscale-android-go' ; then \
echo " ERROR: TOOLCHAINDIR= $( TOOLCHAINDIR) is missing bin/go and does not appear to be a tailscale managed path " ; \
exit 1; \
fi
rm -rf ${ HOME } /.cache/tailscale-android-go-*
mkdir -p $( TOOLCHAINDIR)
curl --silent -L $( shell go run tailscale.com/cmd/printdep --go-url) | tar -C $( TOOLCHAINDIR) -zx
e n d i f
$(DEBUG_APK) : toolchain
curl --silent -L $( shell go run tailscale.com/cmd/printdep --go-url) | tar --strip-components= 1 -C $( TOOLCHAINDIR) -zx
# Get the commandline tools package, this provides (among other things) the sdkmanager binary.
$(ANDROID_HOME)/cmdline-tools/latest/bin/sdkmanager :
mkdir -p $( ANDROID_HOME) /tmp
mkdir -p $( ANDROID_HOME) /cmdline-tools
( cd $( ANDROID_HOME) /tmp && \
curl --silent -O -L $( ANDROID_TOOLS_URL) && \
echo $( ANDROID_TOOLS_SUM) | sha256sum -c && \
unzip $( shell basename $( ANDROID_TOOLS_URL) ) )
mv $( ANDROID_HOME) /tmp/cmdline-tools $( ANDROID_HOME) /cmdline-tools/latest
rm -rf $( ANDROID_HOME) /tmp
# Install the set of Android SDK packages we need.
androidsdk : $( ANDROID_HOME ) /cmdline -tools /latest /bin /sdkmanager
yes | $( ANDROID_HOME) /cmdline-tools/latest/bin/sdkmanager --licenses > /dev/null
$( ANDROID_HOME) /cmdline-tools/latest/bin/sdkmanager --update
$( ANDROID_HOME) /cmdline-tools/latest/bin/sdkmanager $( ANDROID_SDK_PACKAGES)
# Normally in make you would simply take a dependency on the task that provides
# the binaries, however users may have a decision to make as to whether they
# want to install an SDK or use the one from an Android Studio installation.
checkandroidsdk :
@$( ANDROID_HOME) /cmdline-tools/latest/bin/sdkmanager --list_installed | grep -q 'ndk' || ( \
echo -e " \n\tERROR: Android SDK not installed.\n\
\t ANDROID_HOME= $( ANDROID_HOME) \n \
\t ANDROID_SDK_ROOT= $( ANDROID_SDK_ROOT) \n \n \
See README.md for instructions on how to install the prerequisites.\n " ; exit 1)
androidpath :
@echo " export ANDROID_HOME= $( ANDROID_HOME) "
@echo " export ANDROID_SDK_ROOT= $( ANDROID_SDK_ROOT) "
@echo 'export PATH=$(ANDROID_HOME)/cmdline-tools/latest/bin:$(ANDROID_HOME)/platform-tools:$$PATH'
toolchain : $( TOOLCHAINDIR ) /bin /go
android/libs :
mkdir -p android/libs
go run gioui.org/cmd/gogio -buildmode archive -target android -appid $( APPID) -tags novulkan,tailscale_go -o $( AAR) github.com/tailscale/tailscale-android/cmd/tailscale
$(AAR) : toolchain checkandroidsdk android /libs
go run gioui.org/cmd/gogio \
-ldflags " -X tailscale.com/version.longStamp= $( VERSIONNAME) -X tailscale.com/version.shortStamp= $( VERSIONNAME_SHORT) -X tailscale.com/version.gitCommitStamp= $( TAILSCALE_COMMIT) -X tailscale.com/version.extraGitCommitStamp= $( OUR_VERSION) " \
-buildmode archive -target android -appid $( APPID) -tags novulkan,tailscale_go -o $@ github.com/tailscale/tailscale-android/cmd/tailscale
# tailscale-debug.apk builds a debuggable APK with the Google Play SDK.
$(DEBUG_APK) : $( AAR )
( cd android && ./gradlew test assemblePlayDebug)
mv android/build/outputs/apk/play/debug/android-play-debug.apk $@
rundebug : $( DEBUG_APK )
adb install -r $( DEBUG_APK)
apk : $( DEBUG_APK )
run : install
adb shell am start -n com.tailscale.ipn/com.tailscale.ipn.IPNActivity
# tailscale-fdroid.apk builds a non-Google Play SDK, without the Google bits.
# This is effectively what the F-Droid build definition produces.
# This is useful for testing on e.g. Amazon Fire Stick devices.
tailscale-fdroid.apk : toolchain
mkdir -p android/libs
go run gioui.org/cmd/gogio -buildmode archive -target android -appid $( APPID) -tags novulkan,tailscale_go -o $( AAR) github.com/tailscale/tailscale-android/cmd/tailscale
tailscale-fdroid.apk : $( AAR )
( cd android && ./gradlew test assembleFdroidDebug)
mv android/build/outputs/apk/fdroid/debug/android-fdroid-debug.apk $@
# This target is also used by the F-Droid builder.
release_aar : toolchain
release_aar :
mkdir -p android/libs
go run gioui.org/cmd/gogio -ldflags " -X tailscale.com/version.longStamp= $( VERSIONNAME) -X tailscale.com/version.shortStamp= $( VERSIONNAME_SHORT) -X tailscale.com/version.gitCommitStamp= $( TAILSCALE_COMMIT) -X tailscale.com/version.extraGitCommitStamp= $( OUR_VERSION) " -buildmode archive -target android -appid $( APPID) -tags novulkan,tailscale_go -o $( AAR) github.com/tailscale/tailscale-android/cmd/tailscale
$(RELEASE_AAB) : release_aar
$(RELEASE_AAB) : $( AAR )
( cd android && ./gradlew test bundlePlayRelease)
mv ./android/build/outputs/bundle/playRelease/android-play-release.aab $@
@ -90,6 +164,7 @@ dockershell:
docker run -v $( CURDIR) :/build/tailscale-android -it --rm tailscale-android
clean :
rm -rf android/build $( RELEASE_AAB) $( DEBUG_APK) $( AAR)
-rm -rf android/build $( DEBUG_APK) $( RELEASE_AAB) $( AAR) tailscale-fdroid.apk
-pkill -f gradle
.PHONY : all clean install $( DEBUG_APK ) $( RELEASE_AAB ) release_aar release bump_version dockershell
.PHONY : all clean install android /lib $( DEBUG_APK ) $( RELEASE_AAB ) $( AAR ) release bump_version dockershell