### -*-makefile-*-
###
### Build script for the TrIPE Android app
###
### (c) 2018 Straylight/Edgeware
###
###----- Licensing notice ---------------------------------------------------
###
### This file is part of the Trivial IP Encryption (TrIPE) Android app.
###
### TrIPE is free software: you can redistribute it and/or modify it under
### the terms of the GNU General Public License as published by the Free
### Software Foundation; either version 3 of the License, or (at your
### option) any later version.
###
### TrIPE is distributed in the hope that it will be useful, but WITHOUT
### ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
### FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
### for more details.
###
### You should have received a copy of the GNU General Public License
### along with TrIPE. If not, see .
PACKAGE = tripe-android
VERSION := $(shell ./auto-version)
VSN = 1
.SECONDEXPANSION: #sorry
###--------------------------------------------------------------------------
### Preliminary magic.
empty =
space = $(empty) $(empty)
comma = ,
definedp = $(filter-out undefined,$(origin $1))
defaulting = $(if $(call definedp,$1),$($1),$2)
all::
###--------------------------------------------------------------------------
### Build parameters.
abs_srcdir := $(abspath .)
hostos := $(shell uname -s | tr A-Z a-z)
hostcpu := $(shell uname -m | tr A-Z a-z)
## Of course we have `ccache'.
CCACHE := $(shell \
if ccache --version >/dev/null 2>&1; then echo ccache; fi)
## Where to put the object files.
OUTDIR = out
CONFIGDIR = $(OUTDIR)/config-$(hostcpu)
## The Java runtime, for some reason, hardcodes its default for
## `java.io.tmpdir', inviting security problems. If the user has defined a
## `TMPDIR', then persuade Java to use it.
explicit-tmpdir-p = $(if $(call definedp,TMPDIR),t,nil)
ifeq ($(explicit-tmpdir-p), t)
JAVADEFS += -Djava.io.tmpdir=$(TMPDIR)
endif
## Java compiler.
JAVAC = javac $(addprefix -J,$(JAVADEFS))
JAVAFLAGS = -source 1.6 -target 1.6
## Scala compiler.
##
## Unfortunately, `fsc' is a total security disaster. On the other hand,
## `scalac' is rather slow. If we're running with a custom `TMPDIR', and the
## `noip' wrapper is
## available, then we can tame `fsc' enough that it's probably safe to run;
## otherwise, it's too risky to enable by default.
noip-available-p := $(shell noip echo t 2>/dev/null || echo nil)
ifeq ($(noip-available-p), t)
NOIP = noip
endif
ifeq "$(explicit-tmpdir-p),$(noip-available-p)" "t,t"
SCALAC = noip fsc $(JAVADEFS)
SCALA = noip scala $(JAVADEFS)
SCALAC_RESET = $(SCALAC) -reset
else
SCALAC = scalac $(JAVADEFS)
SCALA = scala $(JAVADEFS) -nc
SCALAC_RESET =
endif
SCALAFLAGS = -optimise -feature -deprecation -Xfatal-warnings \
-Xlint -Xlint:-package-object-classes \
-Yinline-warnings:false -target:jvm-1.6 \
-Yno-load-impl-class
## Basic C toolchain flags.
CFLAGS = -O2 -g -Wall
LDFLAGS = -Wl,-z,defs
## Host toolchain.
FLAVOURS += host-$(hostcpu)
ENV.host-$(hostcpu) =
CC.host-$(hostcpu) = gcc
CFLAGS.host-$(hostcpu) = $(CFLAGS) -fPIC
LD.host-$(hostcpu) = $(CC.host-$(hostcpu))
LDFLAGS.host-$(hostcpu) = $(LDFLAGS)
CONFIG.host-$(hostcpu) =
## Host JNI machinery.
$(CONFIGDIR)/jdkdir.mk:
$(V_AT)mkdir -p $(dir $@)
$(call v_tag,CONFIG)java -XshowSettings:properties 2>&1 | \
sed -n 's:^ *java\.home *= *\(.*\)/jre$$:JDKDIR = \1:p' >$@.new
$(V_AT)mv $@.new $@
REALCLEANFILES += $(CONFIGDIR)/jdkdir.mk
include $(CONFIGDIR)/jdkdir.mk
JDKPLAT := $(shell \
case $(hostos) in \
(darwin) echo macosx ;; \
(*) echo $(hostos) ;; \
esac)
CFLAGS.host-$(hostcpu) += -I$(JDKDIR)/include -I$(JDKDIR)/include/$(JDKPLAT)
## Android SDK location.
ANDROID_SDKDIR = /usr/local/android/sdk
MINAPI = 15
TARGETAPI = 23
TOOLVERSION = 4.9
## Android ABI definitions. We don't bother with `armeabi-v7a': we'll use
## fancy CPU features if we detect that they're available at runtime anyway.
ANDROID_ABIS += armeabi
GNUARCH.armeabi = arm-linux-androideabi
PLATARCH.armeabi = arm
CFLAGS.ndk-armeabi =
ANDROID_ABIS += arm64-v8a
GNUARCH.arm64-v8a = aarch64-linux-android
PLATARCH.arm64-v8a = arm64
MINAPI.arm64-v8a = 21
ANDROID_ABIS += x86
TOOLCHAINDIR.x86 = x86
GNUARCH.x86 = i686-linux-android
PLATARCH.x86 = x86
ANDROID_ABIS += x86_64
TOOLCHAINDIR.x86_64 = x86_64
GNUARCH.x86_64 = x86_64-linux-android
PLATARCH.x86_64 = x86_64
MINAPI.x86_64 = 21
FLAVOURS += $(ANDROID_ABIS)
## Build variants.
VARIANTS += debug
AAPTFLAGS.debug = --debug-mode \
--rename-manifest-package uk.org.distorted.tripe.debug
KEYSTORE.debug = debug.keystore
JARSIGNERFLAGS.debug = -storepass public -keypass public
VARIANTS += release
KEYSTORE.release = release.keystore
JARSIGNERFLAGS.release =
## Android NDK location.
ANDROID_NDKDIR = $(ANDROID_SDKDIR)/ndk-bundle
NDK_HOSTARCH = $(hostos)-$(hostcpu)
## Android NDK toolchains.
ndk-sysroot = \
$(ANDROID_NDKDIR)/platforms/android-$(call defaulting,MINAPI.$1,$(MINAPI))/arch-$(PLATARCH.$1)
ndk-toolchain-bin = \
$(ANDROID_NDKDIR)/toolchains/$(call defaulting,TOOLCHAINDIR.$1,$(GNUARCH.$1))-$(TOOLVERSION)/prebuilt/$(NDK_HOSTARCH)/bin
ENV.ndk = env PATH=$(call ndk-toolchain-bin,$1):$$PATH
CC.ndk = $(GNUARCH.$1)-gcc
LD.ndk = $(CC.ndk)
CFLAGS.ndk = $(CFLAGS) -fPIC $(CFLAGS.ndk-$1) \
-D__ANDROID_API__=$(call defaulting,MINAPI.$1,$(MINAPI)) \
--sysroot=$(call ndk-sysroot,$1) \
-isystem $(ANDROID_NDKDIR)/sysroot/usr/include \
-isystem $(ANDROID_NDKDIR)/sysroot/usr/include/$(GNUARCH.$1)
LDFLAGS.ndk = $(LDFLAGS) -pie \
--sysroot=$(call ndk-sysroot,$1)
CONFIG.ndk = --host=$(GNUARCH.$1)
## Flavour options.
tool = $(call defaulting,$2.$1,$(call $2.ndk,$1))
## Subject name for debug key.
DEBUGDN = CN=Straylight/Edgeware, L=Cambridge, C=GB
## Android libraries.
ANDROID_JAR = \
$(ANDROID_SDKDIR)/platforms/android-$(MINAPI)/android.jar
## Scala libraries.
$(CONFIGDIR)/scaladir.mk:
$(V_AT)mkdir -p $(dir $@)
$(call v_tag,CONFIG)$(SCALA) -J-XshowSettings:properties -help 2>&1 | \
sed -n 's:^ *scala\.home *= *:SCALADIR = :p' >$@.new
$(V_AT)mv $@.new $@
include $(CONFIGDIR)/scaladir.mk
REALCLEANFILES += $(CONFIGDIR)/scaladir.mk
SCALA_LIB = $(SCALADIR)/lib/scala-library.jar
## Silent-rules is on by default.
V = 0
## Allow local overrides at this point.
-include local.mk
###--------------------------------------------------------------------------
### Silent-rules machinery.
v_tag = $(call v_tag_$V,$1)
v_tag_0 = @printf " %-8s %s\n" "$1" "$@";
V_AT = $(V_AT_$V)
V_AT_0 = @
###--------------------------------------------------------------------------
### Other handy functions.
join-paths = $(if $(filter /%,$2),$2,$1/$2)
## Datestamp files.
STAMPDIR = $(OUTDIR)/stamp
stamps = $(patsubst %,$(STAMPDIR)/%.$1-stamp,$2)
stamp-base = $(patsubst $(STAMPDIR)/%-stamp,%,$1)
stamp-name = $(basename $(call stamp-base,$1))
stamp-type = $(patsubst .%,%,$(suffix $(call stamp-base,$1)))
###--------------------------------------------------------------------------
### And now we can start building things.
all::
.PHONY: all
clean::
.PHONY: clean
realclean:: clean
.PHONY: realclean
distclean:: realclean
.PHONY: distclean
###--------------------------------------------------------------------------
### External native packages.
## Definitions.
EXTERNALS += adns
adns_CONFIG = --disable-dynamic
EXTERNALS += mLib
mLib_DEPS = adns
mLib_CONFIG = --enable-static --disable-shared --with-adns
EXTERNALS += catacomb
catacomb_DEPS = mLib
catacomb_CONFIG = --enable-static --disable-shared
EXTERNALS += tripe
tripe_DEPS = mLib catacomb
tripe_CONFIG = --without-wireshark --with-adns --with-tunnel=slip
## Machinery.
ext-stamps = $(foreach f,$2,$(call stamps,$f,$1))
ext-srcdir = $(call defaulting,$1_SRCDIR,../$1)
ext-builddir = $(OUTDIR)/build.$1/$2
ext-prefix = $(OUTDIR)/inst.$1
ext-absprefix = $(abs_srcdir)/$(call ext-prefix,$1)
ext-stamp-srcdir = $(call ext-srcdir,$(call stamp-name,$1))
ext-stamp-builddir = \
$(call ext-builddir,$(call stamp-type,$1),$(call stamp-name,$1))
ext-stamp-absprefix = $(call ext-absprefix,$(call stamp-type,$1))
ext-stamp-tool = $(call tool,$(call stamp-type,$1),$2)
$(foreach e,$(EXTERNALS),\
$(eval $e_VERSION := $$(shell cd $$(call ext-srcdir,$e) && $$(abs_srcdir)/auto-version)))
EXTSTAMPS = $(call ext-stamps,$(EXTERNALS),$(FLAVOURS))
$(EXTSTAMPS): \
$(STAMPDIR)/%-stamp: \
$$(call ext-stamps, \
$$($$(call stamp-name,$$@)_DEPS), \
$$(call stamp-type,$$@))
$(V_AT)mkdir -p $(STAMPDIR)
$(V_AT)rm -rf $(call ext-stamp-builddir,$@)
$(V_AT)mkdir -p $(call ext-stamp-builddir,$@)
cd $(call ext-stamp-builddir,$@) && \
$(call ext-stamp-tool,$@,ENV) \
$(call join-paths,../../..,$(call ext-stamp-srcdir,$@))/configure \
--prefix=$(call ext-stamp-absprefix,$@) \
$(call ext-stamp-tool,$@,CONFIG) \
$($(call stamp-name,$@)_CONFIG) \
CC="$(CCACHE) $(call ext-stamp-tool,$@,CC)" \
CFLAGS="$(call ext-stamp-tool,$@,CFLAGS) -I$(call ext-stamp-absprefix,$@)/include" \
LD="$(call ext-stamp-tool,$@,LD)" \
LDFLAGS="$(call ext-stamp-tool,$@,LDFLAGS) -L$(call ext-stamp-absprefix,$@)/lib" \
PKG_CONFIG="pkg-config --static" \
PKG_CONFIG_LIBDIR=$(call ext-stamp-absprefix,$@)/lib/pkgconfig
$(call ext-stamp-tool,$@,ENV) \
$(MAKE) -C$(call ext-stamp-builddir,$@)
$(call ext-stamp-tool,$@,ENV) \
$(MAKE) -C$(call ext-stamp-builddir,$@) install
$(V_AT)touch $@
$(foreach f,$(FLAVOURS),$(foreach e,$(EXTERNALS),clean-$e.$f)): clean-%:
rm -f $(STAMPDIR)/$*-stamp
rm -rf $(call ext-stamp-builddir,$*)
.PHONY: $(foreach f,$(FLAVOURS),$(foreach e,$(EXTERNALS),clean-$e.$f))
$(foreach e,$(EXTERNALS),clean-$e): clean-%: $(foreach f,$(FLAVOURS),clean-%.$f)
$(foreach f,$(FLAVOURS),clean-inst.$f): clean-inst.%:
rm -rf $(call ext-prefix,$*)
.PHONY: $(foreach f,$(FLAVOURS),clean-inst.$f)
$(foreach f,$(FLAVOURS),realclean-$f): realclean-%: \
$$(foreach e,$$(EXTERNALS),clean-$$e.$$*) \
clean-inst.$$*
realclean:: $(foreach f,$(FLAVOURS),realclean-$f)
###--------------------------------------------------------------------------
### Our own native programs.
## Fetching package configuration.
PKG_CONFIG = pkg-config --static
PKGS = catacomb mLib
PCOPT.CFLAGS = --cflags
PCOPT.LIBS = --libs
pkg-config = $(shell \
env PKG_CONFIG_LIBDIR=$(call ext-prefix,$1)/lib/pkgconfig \
$(PKG_CONFIG) $(PCOPT.$3) $2)
## Definitions.
APKLIBS += libtripe.so
libtripe.so_SRCS = jni.c
libtripe.so_EXTS = mLib catacomb tripe
libtripe.so_CFLAGS = -I$(call ext-prefix,$1)/include \
-I$(call ext-srcdir,tripe)/common \
-I$(call ext-srcdir,tripe)/priv \
-I$(call ext-srcdir,tripe)/server \
-I$(call ext-builddir,$1,tripe)/config \
$(call pkg-config,$1,mLib,CFLAGS) \
$(call pkg-config,$1,catacomb,CFLAGS)
libtripe.so_LIBS = $(call ext-builddir,$1,tripe)/server/libtripe.a \
$(call ext-builddir,$1,tripe)/priv/libpriv.a \
$(call ext-builddir,$1,tripe)/common/libcommon.a \
-L$(call ext-prefix,$1)/lib \
$(call pkg-config,$1,catacomb,LIBS) \
$(call pkg-config,$1,mLib,LIBS) \
-ladns
## Machinery for compiling.
objdir = $(OUTDIR)/obj.$1
objects = $(patsubst %.c,$(call objdir,$1)/%$3,$2)
apklib-objects = $(call objects,$1,$($2_SRCS),$3)
obj-base = $(patsubst $(OUTDIR)/obj.%.o,%,$1)
obj-type = $(patsubst %/,%,$(dir $(call obj-base,$1)))
obj-name = $(notdir $(call obj-base,$1))
obj-tool = $(call tool,$(call obj-type,$1),$2)
define obj-rule
$1_OBJS := $$(foreach f,$$(FLAVOURS),\
$$(call objects,$$f,$$($1_SRCS),.o))
DEPFILES += $$(foreach f,$$(FLAVOURS),\
$$(call objects,$$f,$$($1_SRCS),.d))
$$($1_OBJS): $$(OUTDIR)/obj.%.o: \
$$$$(call obj-name,$$$$@).c \
$$$$(call stamps,$$$$(call obj-type,$$$$@),$$$$($1_EXTS))
$$(V_AT)mkdir -p $$(dir $$@)
$$(call v_tag,CC)$$(call obj-tool,$$@,ENV) \
$$(call obj-tool,$$@,CC) -c -o$$@ -MD \
$$(call obj-tool,$$@,CFLAGS) \
$$(call $1_CFLAGS,$$(call obj-type,$$@)) \
$$<
endef
$(foreach a,$(APKLIBS), $(eval $(call obj-rule,$a)))
CLEANFILES += $(OUTDIR)/obj.*/*.o $(OUTDIR)/obj.*/*.d
## Machinery for linking.
JNIDIR.host-$(hostcpu) = $(OUTDIR)/lib.host-$(hostcpu)
JNIDIR.ndk = $(OUTDIR)/pkg/lib/$1
define apklib-rule
INSTFILES += $$(call tool,$1,JNIDIR)/$2
$$(call tool,$1,JNIDIR)/$2: $$(call objects,$$f,$$($2_SRCS),.o)
$$(V_AT)mkdir -p $$(dir $$@)
$$(call v_tag,LD)$$(call tool,$1,ENV) \
$$(call tool,$1,LD) -o$$@ \
$$(call tool,$1,LDFLAGS) -shared \
$$^ \
$$(call $2_LIBS,$1)
endef
$(foreach f,$(FLAVOURS), \
$(foreach a,$(APKLIBS), \
$(eval $(call apklib-rule,$f,$a))))
CLEANFILES += $(OUTDIR)/pkg/lib/*/lib*.so
CLEANFILES += $(OUTDIR)/lib.host-$(hostcpu)/lib*.so
###--------------------------------------------------------------------------
### Android string resource generation.
GENSTRINGS += package=PACKAGE
GENSTRINGS += version=VERSION
GENSTRINGS += vsn=VSN
$(foreach e,$(EXTERNALS),\
$(eval GENSTRINGS += $e_version=$e_VERSION))
BUILD := $(shell uuid -v4)
GENSTRINGS += build_uuid=BUILD
genstring-name = $(firstword $(subst =, ,$1))
genstring-value = $($(word 2,$(subst =, ,$1)))
define gen-strings
$(V_AT)mkdir -p $(dir $1)
$(call v_tag,GEN)set -e; rm -f $1.new; exec >$1.new; \
echo ""; \
echo ""; \
$(foreach g,$(GENSTRINGS), \
echo " $(call genstring-value,$g)";) \
echo ""
$(V_AT)mv $1.new $1
endef
$(OUTDIR)/res.dummy/values/auto.xml: Makefile
$(call gen-strings,$@)
###--------------------------------------------------------------------------
### Java and Scala building.
JARDIR = $(OUTDIR)/jar
CLASSDIR = $(OUTDIR)/cls
## External libraries we need to adopt. Grab them and feed them to `dx'
## separately, because they take aaaaages and we don't want to have to do
## this on every incremental build.
JARS = $(SCALA_LIB)
DEXJARS =
define jar-rule
DEXJARS += $$(JARDIR)/$$(notdir $1)
$$(JARDIR)/$$(notdir $1): $1
$$(V_AT)mkdir -p $$(JARDIR)/
$$(V_AT)rm -f $$@ $$(basename $$@)-new.jar
$$(call v_tag,DX)dx --dex --output=$$(basename $$@)-new.jar $1
$$(V_AT)mv $$(basename $$@)-new.jar $$@
endef
$(foreach j,$(JARS), $(eval $(call jar-rule,$j)))
REALCLEANFILES += $(JARDIR)/*.jar
## Writing things out longhand is tedious. `CLASSES' is a list of entries of
## the form `SRC[:DEP,...]', saying that `SRC.ext', being a source file
## capable of being built into `.class' files and setting `SRC.class-stamp',
## should be so built, and that it depends on other similar sources named DEP
## having been so built.
CLASSES += util
CLASSES += sys:util
CLASSES += admin:sys,util
CLASSES += tar:util
CLASSES += dep:util
CLASSES += progress:sys,util
CLASSES += keys:progress,tar,sys,util
CLASSES += terminal:progress,sys,util
CLASSES += R
CLASSES += app:R
CLASSES += toy-activity:app,R
## Building class files.
$(STAMPDIR)/%.class-stamp: %.java
$(V_AT)mkdir -p $(CLASSDIR)/
$(call v_tag,JAVAC)$(JAVAC) $(JAVAFLAGS) \
-bootclasspath $(ANDROID_JAR) \
-d $(CLASSDIR) -cp $(CLASSDIR) \
$<
$(V_AT)$(SCALAC_RESET)
$(V_AT)touch $@
$(STAMPDIR)/%.class-stamp: %.scala
$(V_AT)mkdir -p $(CLASSDIR)/
$(call v_tag,SCALAC)$(SCALAC) $(SCALAFLAGS) \
-javabootclasspath $(ANDROID_JAR) \
-bootclasspath $(SCALA_LIB) \
-d $(CLASSDIR) -cp $(CLASSDIR) \
$<
$(V_AT)touch $@
## Machinery for parsing the `CLASSES' list.
class-name = $(firstword $(subst :, ,$1))
class-deps = $(subst $(comma), ,$(word 2,$(subst :, ,$1)))
CLASSNAMES = $(foreach c,$(CLASSES),$(call class-name,$c))
CLASSSTAMPS = $(call stamps,class,$(CLASSNAMES))
$(foreach c,$(CLASSES), \
$(eval $(call stamps,class,$(call class-name,$c)): \
$(call stamps,class,$(call class-deps,$c))))
CLEANFILES += $(CLASSSTAMPS)
clean::; rm -rf $(OUTDIR)/cls
###--------------------------------------------------------------------------
### Android building machinery.
VPATH += $(OUTDIR)/src
CLEANFILES += $(OUTDIR)/*.apk
AAPTFLAGS = \
--min-sdk-version $(MINAPI) --target-sdk-version $(TARGETAPI) \
--version-name "$(VERSION)" --version-code $(VSN) --auto-add-overlay
$(OUTDIR)/src/R.java: AndroidManifest.xml $(OUTDIR)/res.dummy/values/auto.xml
$(V_AT)mkdir -p $(dir $@)
$(call v_tag,AAPT)aapt package $(AAPTFLAGS) \
-M AndroidManifest.xml -S res/ -S $(OUTDIR)/res.dummy/ \
-I $(ANDROID_JAR) \
-J $(dir $@) --generate-dependencies
CLEANFILES += $(OUTDIR)/src/R.java $(OUTDIR)/src/R.java.d
-include $(OUTDIR)/src/R.java.d
BINS = catsign key pathmtu
CLEANFILES += $(INSTFILES)
define bin-rule
INSTFILES += $$(OUTDIR)/pkg/assets/bin/$1/$2
$$(OUTDIR)/pkg/assets/bin/$1/$2: $$$$(call ext-stamps,$$$$(EXTERNALS),$1)
$$(V_AT)mkdir -p $$(dir $$@)
$$(call v_tag,CP)cp $$(call ext-prefix,$1)/bin/$2 $$@
endef
$(foreach f,$(ANDROID_ABIS), \
$(foreach b,$(BINS), \
$(eval $(call bin-rule,$f,$b))))
DISTCLEANFILES += debug.keystore
debug.keystore:
$(call v_tag,KEYTOOL)keytool -genkeypair -alias debug \
-keyalg RSA -keysize 3072 \
-dname "$(DEBUGDN)" -validity 10000 \
-keystore $@ -storetype PKCS12 \
-storepass public -keypass public
INSTFILES += $(OUTDIR)/pkg/classes.dex
$(OUTDIR)/pkg/classes.dex: $(CLASSSTAMPS) $(DEXJARS)
$(V_AT)mkdir -p $(dir $@)
$(call v_tag,DX)dx --dex --output=$@ $(CLASSDIR) $(JARDIR)
$(OUTDIR)/res.volatile/values/auto.xml: $(INSTFILES)
$(call gen-strings,$@)
$(foreach v,$(VARIANTS),$(OUTDIR)/tripe-$v.unsigned.apk): \
$(OUTDIR)/tripe-%.unsigned.apk: $(INSTFILES) $(OUTDIR)/res.volatile/values/auto.xml
$(call v_tag,AAPT)aapt package -f $(AAPTFLAGS) $(AAPTFLAGS.$*) \
-M AndroidManifest.xml -S res/ -S $(OUTDIR)/res.volatile/ \
-I $(ANDROID_JAR) -F $@ $(OUTDIR)/pkg/
$(foreach v,$(VARIANTS),$(OUTDIR)/tripe-$v.signed.apk): \
$(OUTDIR)/tripe-%.signed.apk: $(OUTDIR)/tripe-%.unsigned.apk $$(KEYSTORE.$$*)
$(call v_tag,JARSIGN)jarsigner -keystore $(KEYSTORE.$*) \
$(JARSIGNERFLAGS.$*) \
-signedjar $@ $< $(call defaulting,KEYALIAS.$*,$*)
$(foreach v,$(VARIANTS),$(OUTDIR)/tripe-$v.apk): \
$(OUTDIR)/tripe-%.apk: $(OUTDIR)/tripe-%.signed.apk
$(call v_tag,ZIPALGN)zipalign $(ZIPALIGNFLAGS.$*) -f 4 $< $@
$(VARIANTS): %: $(OUTDIR)/tripe-%.apk
.PHONY: $(VARIANTS)
###--------------------------------------------------------------------------
### Finishing touches.
all:: debug
clean::; rm -f $(CLEANFILES)
realclean::; rm -f $(REALCLEANFILES)
repl: $(CLASSSTAMPS) $(foreach a,$(APKLIBS),$(JNIDIR.host-$(hostcpu))/$a)
$(SCALA) -cp $(CLASSDIR) -Yno-load-impl-class \
-Djava.library.path=$(JNIDIR.host-$(hostcpu)) \
t:; : $(show)
.PHONY: t
-include $(DEPFILES)
###----- That's all, folks --------------------------------------------------