Skip to content

Commit 141b1cf

Browse files
authored
Makefile: make unstripped libtailscale and debug symbols (#619)
- Added Makefile targets to build an unstripped version of the libtailscale AAR. - Extracted the native .so (libgojni.so) from the unstripped AAR. - Generated a debug symbols file (libgojni.so.debug) using llvm-objcopy with --only-keep-debug. - Stripped the native library (libgojni.so.stripped) with --strip-debug and repackaged the final AAR. This allows the build chain to produce a stripped AAR for the app and a separate debug symbols file that can be uploaded to Google Play for crash deobfuscation. Signed-off-by: kari-ts <[email protected]> Updates tailscale/tailscale#15210
1 parent 189de89 commit 141b1cf

File tree

2 files changed

+153
-81
lines changed

2 files changed

+153
-81
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@ tailscale.jks
3535
.vscode
3636
.idea
3737

38+
# Native libraries
39+
*.stripped
40+
*.unstripped
41+
42+
# Debug symbols
43+
*.debug
44+
3845
libtailscale.aar
3946
libtailscale-sources.jar
4047
.DS_Store

Makefile

Lines changed: 146 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -10,38 +10,57 @@
1010
# with this name, it will be used.
1111
#
1212
# The convention here is tailscale-android-build-amd64-<date>
13-
DOCKER_IMAGE=tailscale-android-build-amd64-191124
13+
DOCKER_IMAGE := tailscale-android-build-amd64-191124
1414
export TS_USE_TOOLCHAIN=1
1515

16-
DEBUG_APK=tailscale-debug.apk
17-
RELEASE_AAB=tailscale-release.aab
18-
RELEASE_TV_AAB=tailscale-tv-release.aab
19-
LIBTAILSCALE=android/libs/libtailscale.aar
20-
# Extract the version code from build.gradle.
16+
# Auto-select an NDK from ANDROID_HOME (choose highest version available)
17+
NDK_ROOT ?= $(shell ls -1d $(ANDROID_HOME)/ndk/* 2>/dev/null | sort -V | tail -n 1)
18+
19+
HOST_OS := $(shell uname | tr A-Z a-z)
20+
ifeq ($(HOST_OS),linux)
21+
STRIP_TOOL := $(NDK_ROOT)/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-objcopy
22+
else ifeq ($(HOST_OS),darwin)
23+
STRIP_TOOL := $(NDK_ROOT)/toolchains/llvm/prebuilt/darwin-x86_64/bin/llvm-objcopy
24+
endif
25+
26+
$(info Using NDK_ROOT: $(NDK_ROOT))
27+
$(info Using STRIP_TOOL: $(STRIP_TOOL))
28+
29+
DEBUG_APK := tailscale-debug.apk
30+
RELEASE_AAB := tailscale-release.aab
31+
RELEASE_TV_AAB := tailscale-tv-release.aab
32+
33+
# Define output filenames.
34+
LIBTAILSCALE_AAR := android/libs/libtailscale.aar
35+
UNSTRIPPED_AAR := android/libs/libtailscale_unstripped.aar
36+
ARM64_SO_PATH := jni/arm64-v8a/libgojni.so
37+
38+
# Compute an absolute path for the unstripped AAR.
39+
ABS_UNSTRIPPED_AAR := $(shell pwd)/$(UNSTRIPPED_AAR)
40+
41+
# Android SDK & Tools settings.
2142
ifeq ($(shell uname),Linux)
22-
ANDROID_TOOLS_URL="https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip"
23-
ANDROID_TOOLS_SUM="bd1aa17c7ef10066949c88dc6c9c8d536be27f992a1f3b5a584f9bd2ba5646a0 commandlinetools-linux-9477386_latest.zip"
43+
ANDROID_TOOLS_URL := "https://dl.google.com/android/repository/commandlinetools-linux-9477386_latest.zip"
44+
ANDROID_TOOLS_SUM := "bd1aa17c7ef10066949c88dc6c9c8d536be27f992a1f3b5a584f9bd2ba5646a0 commandlinetools-linux-9477386_latest.zip"
2445
else
25-
ANDROID_TOOLS_URL="https://dl.google.com/android/repository/commandlinetools-mac-9477386_latest.zip"
26-
ANDROID_TOOLS_SUM="2072ffce4f54cdc0e6d2074d2f381e7e579b7d63e915c220b96a7db95b2900ee commandlinetools-mac-9477386_latest.zip"
46+
ANDROID_TOOLS_URL := "https://dl.google.com/android/repository/commandlinetools-mac-9477386_latest.zip"
47+
ANDROID_TOOLS_SUM := "2072ffce4f54cdc0e6d2074d2f381e7e579b7d63e915c220b96a7db95b2900ee commandlinetools-mac-9477386_latest.zip"
2748
endif
28-
ANDROID_SDK_PACKAGES='platforms;android-31' 'extras;android;m2repository' 'ndk;23.1.7779620' 'platform-tools' 'build-tools;33.0.2'
49+
ANDROID_SDK_PACKAGES := 'platforms;android-31' 'extras;android;m2repository' 'ndk;23.1.7779620' 'platform-tools' 'build-tools;33.0.2'
2950

3051
# Attempt to find an ANDROID_SDK_ROOT / ANDROID_HOME based either from
3152
# preexisting environment or common locations.
3253
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)
33-
34-
# If ANDROID_SDK_ROOT is still unset, set it to a default location by platform.
3554
ifeq ($(ANDROID_SDK_ROOT),)
36-
ifeq ($(shell uname),Linux)
37-
export ANDROID_SDK_ROOT=$(HOME)/Android/Sdk
38-
else ifeq ($(shell uname),Darwin)
39-
export ANDROID_SDK_ROOT=$(HOME)/Library/Android/sdk
40-
else ifneq ($(WINDIR),))
41-
export ANDROID_SDK_ROOT=$(HOME)/AppData/Local/Android/sdk
42-
else
43-
export ANDROID_SDK_ROOT=$(PWD)/android-sdk
44-
endif
55+
ifeq ($(shell uname),Linux)
56+
export ANDROID_SDK_ROOT := $(HOME)/Android/Sdk
57+
else ifeq ($(shell uname),Darwin)
58+
export ANDROID_SDK_ROOT := $(HOME)/Library/Android/sdk
59+
else ifneq ($(WINDIR),)
60+
export ANDROID_SDK_ROOT := $(HOME)/AppData/Local/Android/sdk
61+
else
62+
export ANDROID_SDK_ROOT := $(PWD)/android-sdk
63+
endif
4564
endif
4665
export ANDROID_HOME ?= $(ANDROID_SDK_ROOT)
4766

@@ -51,67 +70,71 @@ ANDROID_STUDIO_ROOT ?= $(shell find ~/android-studio /usr/local/android-studio /
5170

5271
# Set JAVA_HOME to the Android Studio bundled JDK.
5372
export JAVA_HOME ?= $(shell find "$(ANDROID_STUDIO_ROOT)/jbr" "$(ANDROID_STUDIO_ROOT)/jre" "$(ANDROID_STUDIO_ROOT)/Contents/jbr/Contents/Home" "$(ANDROID_STUDIO_ROOT)/Contents/jre/Contents/Home" -maxdepth 1 -type d 2>/dev/null | head -n 1)
54-
# If JAVA_HOME is still unset, remove it, because SDK tools go into a CPU spin if it is set and empty.
5573
ifeq ($(JAVA_HOME),)
56-
unexport JAVA_HOME
74+
unexport JAVA_HOME
5775
else
58-
export PATH := $(JAVA_HOME)/bin:$(PATH)
76+
export PATH := $(JAVA_HOME)/bin:$(PATH)
5977
endif
6078

6179
AVD_BASE_IMAGE := "system-images;android-33;google_apis;"
62-
export HOST_ARCH=$(shell uname -m)
80+
export HOST_ARCH := $(shell uname -m)
6381
ifeq ($(HOST_ARCH),aarch64)
64-
AVD_IMAGE := "$(AVD_BASE_IMAGE)arm64-v8a"
82+
AVD_IMAGE := "$(AVD_BASE_IMAGE)arm64-v8a"
6583
else ifeq ($(HOST_ARCH),arm64)
66-
AVD_IMAGE := "$(AVD_BASE_IMAGE)arm64-v8a"
84+
AVD_IMAGE := "$(AVD_BASE_IMAGE)arm64-v8a"
6785
else
68-
AVD_IMAGE := "$(AVD_BASE_IMAGE)x86_64"
86+
AVD_IMAGE := "$(AVD_BASE_IMAGE)x86_64"
6987
endif
7088
AVD ?= tailscale-$(HOST_ARCH)
7189
export AVD_IMAGE
7290
export AVD
7391

7492
# Use our toolchain or the one that is specified, do not perform dynamic toolchain switching.
75-
GOTOOLCHAIN=local
93+
GOTOOLCHAIN := local
7694
export GOTOOLCHAIN
7795

78-
# TOOLCHAINDIR is set by fdoid CI and used by tool/* scripts.
7996
TOOLCHAINDIR ?=
8097
export TOOLCHAINDIR
8198

82-
GOBIN ?= $(PWD)/android/build/go/bin
99+
GOBIN := $(PWD)/android/build/go/bin
83100
export GOBIN
84101

85102
export PATH := $(PWD)/tool:$(GOBIN):$(ANDROID_HOME)/cmdline-tools/latest/bin:$(ANDROID_HOME)/platform-tools:$(PATH)
86103
export GOROOT := # Unset
87104

88-
#
89-
# Android Builds:
90-
#
105+
# ------------------------------------------------------------------------------
106+
# Android Build Targets
107+
# ------------------------------------------------------------------------------
108+
109+
110+
.PHONY: debug-unstripped
111+
debug-unstripped: build-unstripped-aar
112+
@echo "Listing contents of $(ABS_UNSTRIPPED_AAR):"
113+
unzip -l $(ABS_UNSTRIPPED_AAR)
91114

92115
.PHONY: apk
93-
apk: $(DEBUG_APK) ## Build the debug APK
116+
apk: $(DEBUG_APK)
94117

95118
.PHONY: tailscale-debug
96-
tailscale-debug: $(DEBUG_APK) ## Build the debug APK
119+
tailscale-debug: $(DEBUG_APK)
120+
121+
$(DEBUG_APK): libtailscale debug-symbols version gradle-dependencies build-unstripped-aar
122+
(cd android && ./gradlew test assembleDebug)
123+
install -C android/build/outputs/apk/debug/android-debug.apk $@
97124

98125
# Builds the release AAB and signs it (phone/tablet/chromeOS variant)
99126
.PHONY: release
100-
release: jarsign-env $(RELEASE_AAB) ## Build the release AAB
127+
release: jarsign-env $(RELEASE_AAB)
101128
@jarsigner -sigalg SHA256withRSA -digestalg SHA-256 -keystore $(JKS_PATH) -storepass $(JKS_PASSWORD) $(RELEASE_AAB) tailscale
102129

103130
# Builds the release AAB and signs it (androidTV variant)
104131
.PHONY: release-tv
105-
release-tv: jarsign-env $(RELEASE_TV_AAB) ## Build the release AAB
132+
release-tv: jarsign-env $(RELEASE_TV_AAB)
106133
@jarsigner -sigalg SHA256withRSA -digestalg SHA-256 -keystore $(JKS_PATH) -storepass $(JKS_PASSWORD) $(RELEASE_TV_AAB) tailscale
107134

108135
# gradle-dependencies groups together the android sources and libtailscale needed to assemble tests/debug/release builds.
109136
.PHONY: gradle-dependencies
110-
gradle-dependencies: $(shell find android -type f -not -path "android/build/*" -not -path '*/.*') $(LIBTAILSCALE) tailscale.version
111-
112-
$(DEBUG_APK): version gradle-dependencies
113-
(cd android && ./gradlew test assembleDebug)
114-
install -C android/build/outputs/apk/debug/android-debug.apk $@
137+
gradle-dependencies: $(shell find android -type f -not -path "android/build/*" -not -path '*/.*') $(LIBTAILSCALE_AAR) tailscale.version
115138

116139
$(RELEASE_AAB): version gradle-dependencies
117140
@echo "Building release AAB"
@@ -128,50 +151,93 @@ tailscale-test.apk: version gradle-dependencies
128151
install -C ./android/build/outputs/apk/androidTest/applicationTest/android-applicationTest-androidTest.apk $@
129152

130153
tailscale.version: go.mod go.sum $(wildcard .git/HEAD)
131-
$(shell ./tool/go run tailscale.com/cmd/mkversion > tailscale.version)
154+
@bash -c "./tool/go run tailscale.com/cmd/mkversion > tailscale.version"
132155

133156
.PHONY: version
134-
version: tailscale.version ## print the current version information
135-
cat tailscale.version
157+
version: tailscale.version
158+
@cat tailscale.version
136159

137-
#
138-
# Go Builds:
139-
#
160+
# ------------------------------------------------------------------------------
161+
# Go Build Targets (Unstripped AAR, Debug Symbols, Stripped SO, Packaging)
162+
# ------------------------------------------------------------------------------
140163

141164
android/libs:
142165
mkdir -p android/libs
143166

144-
$(GOBIN)/gomobile: $(GOBIN)/gobind go.mod go.sum
167+
$(GOBIN):
168+
mkdir -p $(GOBIN)
169+
170+
$(GOBIN)/gomobile: $(GOBIN)/gobind go.mod go.sum | $(GOBIN)
145171
./tool/go install golang.org/x/mobile/cmd/gomobile
146172

147173
$(GOBIN)/gobind: go.mod go.sum
148174
./tool/go install golang.org/x/mobile/cmd/gobind
149175

150-
$(LIBTAILSCALE): Makefile android/libs $(shell find libtailscale -name *.go) go.mod go.sum $(GOBIN)/gomobile tailscale.version
176+
.PHONY: build-unstripped-aar
177+
build-unstripped-aar: tailscale.version $(GOBIN)/gomobile
178+
@echo "Running gomobile bind to generate unstripped AAR..."
179+
@echo "Output file: $(ABS_UNSTRIPPED_AAR)"
180+
mkdir -p $(dir $(ABS_UNSTRIPPED_AAR))
181+
rm -f $(ABS_UNSTRIPPED_AAR)
151182
$(GOBIN)/gomobile bind -target android -androidapi 26 \
152183
-tags "$$(./build-tags.sh)" \
153-
-ldflags "-w $$(./version-ldflags.sh)" \
154-
-o $@ ./libtailscale
184+
-ldflags "$$(./version-ldflags.sh)" \
185+
-o $(ABS_UNSTRIPPED_AAR) ./libtailscale || { echo "gomobile bind failed"; exit 1; }
186+
@if [ ! -f $(ABS_UNSTRIPPED_AAR) ]; then \
187+
echo "Error: $(ABS_UNSTRIPPED_AAR) was not created"; exit 1; \
188+
fi
189+
@echo "Generated unstripped AAR: $(ABS_UNSTRIPPED_AAR)"
190+
191+
$(UNSTRIPPED_AAR): build-unstripped-aar
192+
193+
libgojni.so.unstripped: $(UNSTRIPPED_AAR)
194+
@echo "Extracting libgojni.so from unstripped AAR..."
195+
@if unzip -p $(ABS_UNSTRIPPED_AAR) jni/arm64-v8a/libgojni.so > libgojni.so.unstripped; then \
196+
echo "Found arm64-v8a libgojni.so"; \
197+
elif unzip -p $(ABS_UNSTRIPPED_AAR) jni/armeabi-v7a/libgojni.so > libgojni.so.unstripped; then \
198+
echo "Found armeabi-v7a libgojni.so"; \
199+
else \
200+
echo "Neither jni/arm64-v8a/libgojni.so nor jni/armeabi-v7a/libgojni.so was found."; \
201+
echo "Listing contents of $(ABS_UNSTRIPPED_AAR):"; \
202+
unzip -l $(ABS_UNSTRIPPED_AAR); exit 1; \
203+
fi
204+
205+
libgojni.so.debug: libgojni.so.unstripped
206+
@echo "Extracting debug symbols from libgojni.so..."
207+
$(STRIP_TOOL) --only-keep-debug libgojni.so.unstripped libgojni.so.debug
208+
209+
libgojni.so.stripped: libgojni.so.unstripped
210+
@echo "Stripping debug symbols from libgojni.so..."
211+
$(STRIP_TOOL) --strip-debug libgojni.so.unstripped libgojni.so.stripped
212+
213+
$(LIBTAILSCALE_AAR): libgojni.so.stripped $(UNSTRIPPED_AAR)
214+
@echo "Repackaging AAR with stripped libgojni.so..."
215+
rm -rf temp_aar
216+
mkdir temp_aar
217+
unzip $(ABS_UNSTRIPPED_AAR) -d temp_aar
218+
cp libgojni.so.stripped temp_aar/$(ARM64_SO_PATH)
219+
(cd temp_aar && zip -r ../$(LIBTAILSCALE_AAR) .)
220+
rm -rf temp_aar
155221

156222
.PHONY: libtailscale
157-
libtailscale: $(LIBTAILSCALE) ## Build the libtailscale AAR
223+
libtailscale: $(LIBTAILSCALE_AAR) ## Build the stripped libtailscale AAR
158224

159-
#
160-
# Utility tasks:
161-
#
225+
.PHONY: debug-symbols
226+
debug-symbols: libgojni.so.debug
162227

163-
.PHONY: all
164-
all: test $(DEBUG_APK) ## Build and test everything
228+
# ------------------------------------------------------------------------------
229+
# Utility Targets
230+
# ------------------------------------------------------------------------------
165231

166232
.PHONY: env
167233
env:
168-
@echo PATH=$(PATH)
169-
@echo ANDROID_SDK_ROOT=$(ANDROID_SDK_ROOT)
170-
@echo ANDROID_HOME=$(ANDROID_HOME)
171-
@echo ANDROID_STUDIO_ROOT=$(ANDROID_STUDIO_ROOT)
172-
@echo JAVA_HOME=$(JAVA_HOME)
173-
@echo TOOLCHAINDIR=$(TOOLCHAINDIR)
174-
@echo AVD_IMAGE="$(AVD_IMAGE)"
234+
@echo "PATH=$(PATH)"
235+
@echo "ANDROID_SDK_ROOT=$(ANDROID_SDK_ROOT)"
236+
@echo "ANDROID_HOME=$(ANDROID_HOME)"
237+
@echo "ANDROID_STUDIO_ROOT=$(ANDROID_STUDIO_ROOT)"
238+
@echo "JAVA_HOME=$(JAVA_HOME)"
239+
@echo "TOOLCHAINDIR=$(TOOLCHAINDIR)"
240+
@echo "AVD_IMAGE=$(AVD_IMAGE)"
175241

176242
# Ensure that JKS_PATH and JKS_PASSWORD are set before we attempt a build
177243
# that requires signing.
@@ -195,21 +261,20 @@ androidpath:
195261
@echo 'export PATH=$(ANDROID_HOME)/cmdline-tools/latest/bin:$(ANDROID_HOME)/platform-tools:$$PATH'
196262

197263
.PHONY: tag_release
198-
tag_release: tailscale.version ## Tag the current commit with the current version
264+
tag_release: debug-symbols tailscale.version ## Tag the current commit with the current version
199265
source tailscale.version && git tag -a "$${VERSION_LONG}" -m "OSS and Version updated to $${VERSION_LONG}"
200266

201-
202267
.PHONY: bumposs ## Bump to the latest oss and update the versions.
203268
bumposs: update-oss tailscale.version
204269
source tailscale.version && git commit -sm "android: bump OSS" -m "OSS and Version updated to $${VERSION_LONG}" go.toolchain.rev android/build.gradle go.mod go.sum
205270
source tailscale.version && git tag -a "$${VERSION_LONG}" -m "OSS and Version updated to $${VERSION_LONG}"
206271

207-
.PHONY: bump_version_code
208-
bump_version_code: ## Bump the version code in build.gradle
272+
.PHONY: bump_version_code ## Bump the version code in build.gradle
273+
bump_version_code:
209274
sed -i'.bak' "s/versionCode .*/versionCode $$(expr $$(awk '/versionCode ([0-9]+)/{print $$2}' android/build.gradle) + 1)/" android/build.gradle && rm android/build.gradle.bak
210275

211-
.PHONY: update-oss
212-
update-oss: ## Update the tailscale.com go module
276+
.PHONY: update-oss ## Update the tailscale.com go module
277+
update-oss:
213278
GOPROXY=direct ./tool/go get tailscale.com@main
214279
./tool/go mod tidy -compat=1.24
215280
./tool/go run tailscale.com/cmd/printdep --go > go.toolchain.rev.new
@@ -247,7 +312,7 @@ checkandroidsdk: ## Check that Android SDK is installed
247312
test: gradle-dependencies ## Run the Android tests
248313
(cd android && ./gradlew test)
249314

250-
.PHONY: emulator
315+
.PHONY: emulator
251316
emulator: ## Start an android emulator instance
252317
@echo "Checking installed SDK packages..."
253318
@if ! $(ANDROID_HOME)/cmdline-tools/latest/bin/sdkmanager --list_installed | grep -q "$(AVD_IMAGE)"; then \
@@ -262,15 +327,15 @@ emulator: ## Start an android emulator instance
262327
@echo "Starting emulator..."
263328
@$(ANDROID_HOME)/emulator/emulator -avd "$(AVD)" -logcat-output /dev/stdout -netdelay none -netspeed full
264329

265-
.PHONY: install
330+
.PHONY: install
266331
install: $(DEBUG_APK) ## Install the debug APK on a connected device
267332
adb install -r $<
268333

269334
.PHONY: run
270335
run: install ## Run the debug APK on a connected device
271336
adb shell am start -n com.tailscale.ipn/com.tailscale.ipn.MainActivity
272337

273-
.PHONY: docker-build-image
338+
.PHONY: docker-build-image
274339
docker-build-image: ## Builds the docker image for the android build environment if it does not exist
275340
@echo "Checking if docker image $(DOCKER_IMAGE) already exists..."
276341
@if ! docker images $(DOCKER_IMAGE) -q | grep -q . ; then \
@@ -279,29 +344,29 @@ docker-build-image: ## Builds the docker image for the android build environment
279344
fi
280345

281346
.PHONY: docker-run-build
282-
docker-run-build: clean jarsign-env docker-build-image ## Runs the docker image for the android build environment and builds release
347+
docker-run-build: clean jarsign-env docker-build-image ## Runs the docker image for the android build environment and builds release
283348
@docker run --rm -v $(CURDIR):/build/tailscale-android --env JKS_PASSWORD=$(JKS_PASSWORD) --env JKS_PATH=$(JKS_PATH) $(DOCKER_IMAGE)
284349

285350
.PHONY: docker-remove-build-image
286351
docker-remove-build-image: ## Removes the current docker build image
287352
docker rmi --force $(DOCKER_IMAGE)
288353

289-
.PHONY: docker-all ## Makes a fresh docker environment, builds docker and cleans up. For CI.
354+
.PHONY: docker-all ## Makes a fresh docker environment, builds docker and cleans up. For CI.
290355
docker-all: docker-build-image docker-run-build $(DOCKER_IMAGE)
291356

292357
.PHONY: docker-shell
293358
docker-shell: ## Builds a docker image with the android build env and opens a shell
294-
docker build -f docker/DockerFile.amd64-shell -t tailscale-android-shell-amd64 .
359+
docker build -f docker/DockerFile.amd64-shell -t tailscale-android-shell-amd64 .
295360
docker run --rm -v $(CURDIR):/build/tailscale-android -it tailscale-android-shell-amd64
296361

297362
.PHONY: docker-remove-shell-image
298363
docker-remove-shell-image: ## Removes all docker shell image
299364
docker rmi --force tailscale-android-shell-amd64
300365

301366
.PHONY: clean
302-
clean: ## Remove build artifacts. Does not purge docker build envs. Use dockerRemoveEnv for that.
367+
clean: ## Remove build artifacts. Does not purge docker build envs. Use dockerRemoveEnv for that.
303368
@echo "Cleaning up old build artifacts"
304-
-rm -rf android/build $(DEBUG_APK) $(RELEASE_AAB) $(RELEASE_TV_AAB) $(LIBTAILSCALE) android/libs *.apk *.aab
369+
-rm -rf android/build $(DEBUG_APK) $(RELEASE_AAB) $(RELEASE_TV_AAB) $(LIBTAILSCALE_AAR) android/libs *.apk *.aab
305370
@echo "Cleaning cached toolchain"
306371
-rm -rf $(HOME)/.cache/tailscale-go{,.extracted}
307372
-pkill -f gradle

0 commit comments

Comments
 (0)