| 1 | ### -*-makefile-*- |
| 2 | ### |
| 3 | ### Build script for the TrIPE Android app |
| 4 | ### |
| 5 | ### (c) 2018 Straylight/Edgeware |
| 6 | ### |
| 7 | |
| 8 | ###----- Licensing notice --------------------------------------------------- |
| 9 | ### |
| 10 | ### This file is part of the Trivial IP Encryption (TrIPE) Android app. |
| 11 | ### |
| 12 | ### TrIPE is free software: you can redistribute it and/or modify it under |
| 13 | ### the terms of the GNU General Public License as published by the Free |
| 14 | ### Software Foundation; either version 3 of the License, or (at your |
| 15 | ### option) any later version. |
| 16 | ### |
| 17 | ### TrIPE is distributed in the hope that it will be useful, but WITHOUT |
| 18 | ### ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 19 | ### FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 20 | ### for more details. |
| 21 | ### |
| 22 | ### You should have received a copy of the GNU General Public License |
| 23 | ### along with TrIPE. If not, see <https://www.gnu.org/licenses/>. |
| 24 | |
| 25 | PACKAGE = tripe-android |
| 26 | VERSION := $(shell ./auto-version) |
| 27 | VSN = 1 |
| 28 | |
| 29 | .SECONDEXPANSION: #sorry |
| 30 | |
| 31 | ###-------------------------------------------------------------------------- |
| 32 | ### Preliminary magic. |
| 33 | |
| 34 | empty = |
| 35 | space = $(empty) $(empty) |
| 36 | comma = , |
| 37 | |
| 38 | definedp = $(filter-out undefined,$(origin $1)) |
| 39 | defaulting = $(if $(call definedp,$1),$($1),$2) |
| 40 | |
| 41 | all:: |
| 42 | |
| 43 | ###-------------------------------------------------------------------------- |
| 44 | ### Build parameters. |
| 45 | |
| 46 | abs_srcdir := $(abspath .) |
| 47 | hostos := $(shell uname -s | tr A-Z a-z) |
| 48 | hostcpu := $(shell uname -m | tr A-Z a-z) |
| 49 | |
| 50 | ## Of course we have `ccache'. |
| 51 | CCACHE := $(shell \ |
| 52 | if ccache --version >/dev/null 2>&1; then echo ccache; fi) |
| 53 | |
| 54 | ## Where to put the object files. |
| 55 | OUTDIR = out |
| 56 | CONFIGDIR = $(OUTDIR)/config |
| 57 | |
| 58 | ## The Java runtime, for some reason, hardcodes its default for |
| 59 | ## `java.io.tmpdir', inviting security problems. If the user has defined a |
| 60 | ## `TMPDIR', then persuade Java to use it. |
| 61 | explicit-tmpdir-p = $(if $(call definedp,TMPDIR),t,nil) |
| 62 | ifeq ($(explicit-tmpdir-p), t) |
| 63 | JAVADEFS += -Djava.io.tmpdir=$(TMPDIR) |
| 64 | endif |
| 65 | |
| 66 | ## Java compiler. |
| 67 | JAVAC = javac $(addprefix -J,$(JAVADEFS)) |
| 68 | JAVAFLAGS = -source 1.6 -target 1.6 |
| 69 | |
| 70 | ## Scala compiler. |
| 71 | ## |
| 72 | ## Unfortunately, `fsc' is a total security disaster. On the other hand, |
| 73 | ## `scalac' is rather slow. If we're running with a custom `TMPDIR', and the |
| 74 | ## `noip' wrapper <https://git.distorted.org.uk/~mdw/preload-hacks/> is |
| 75 | ## available, then we can tame `fsc' enough that it's probably safe to run; |
| 76 | ## otherwise, it's too risky to enable by default. |
| 77 | noip-available-p := $(shell noip echo t 2>/dev/null || echo nil) |
| 78 | ifeq ($(noip-available-p), t) |
| 79 | NOIP = noip |
| 80 | endif |
| 81 | ifeq "$(explicit-tmpdir-p),$(noip-available-p)" "t,t" |
| 82 | SCALAC = noip fsc $(JAVADEFS) |
| 83 | SCALA = noip scala $(JAVADEFS) |
| 84 | SCALAC_RESET = $(SCALAC) -reset |
| 85 | else |
| 86 | SCALAC = scalac $(JAVADEFS) |
| 87 | SCALA = scala $(JAVADEFS) -nc |
| 88 | SCALAC_RESET = |
| 89 | endif |
| 90 | SCALAFLAGS = -optimise -feature -deprecation -Xfatal-warnings \ |
| 91 | -Xlint -Xlint:-package-object-classes \ |
| 92 | -Yinline-warnings:false -target:jvm-1.6 \ |
| 93 | -Yno-load-impl-class |
| 94 | |
| 95 | ## Basic C toolchain flags. |
| 96 | CFLAGS = -O2 -g -Wall |
| 97 | LDFLAGS = -Wl,-z,defs |
| 98 | |
| 99 | ## Host toolchain. |
| 100 | FLAVOURS += host |
| 101 | ENV.host = |
| 102 | CC.host = gcc |
| 103 | CFLAGS.host = $(CFLAGS) -fPIC |
| 104 | LD.host = $(CC.host) |
| 105 | LDFLAGS.host = $(LDFLAGS) |
| 106 | CONFIG.host = |
| 107 | |
| 108 | ## Host JNI machinery. |
| 109 | $(CONFIGDIR)/jdkdir.mk: |
| 110 | $(V_AT)mkdir -p $(dir $@) |
| 111 | $(call v_tag,CONFIG)java -XshowSettings:properties 2>&1 | \ |
| 112 | sed -n 's:^ *java\.home *= *\(.*\)/jre$$:JDKDIR = \1:p' >$@.new |
| 113 | $(V_AT)mv $@.new $@ |
| 114 | REALCLEANFILES += $(CONFIGDIR)/jdkdir.mk |
| 115 | include $(CONFIGDIR)/jdkdir.mk |
| 116 | |
| 117 | JDKPLAT := $(shell \ |
| 118 | case $(hostos) in \ |
| 119 | (darwin) echo macosx ;; \ |
| 120 | (*) echo $(hostos) ;; \ |
| 121 | esac) |
| 122 | CFLAGS.host += -I$(JDKDIR)/include -I$(JDKDIR)/include/$(JDKPLAT) |
| 123 | |
| 124 | ## Android SDK location. |
| 125 | ANDROID_SDKDIR = /usr/local/android/sdk |
| 126 | MINAPI = 15 |
| 127 | TARGETAPI = 23 |
| 128 | TOOLVERSION = 4.9 |
| 129 | |
| 130 | ## Android ABI definitions. |
| 131 | ANDROID_ABIS += armeabi |
| 132 | GNUARCH.armeabi = arm-linux-androideabi |
| 133 | PLATARCH.armeabi = arm |
| 134 | CFLAGS.ndk-armeabi = |
| 135 | |
| 136 | ANDROID_ABIS.inhibit += armeabi-v7a |
| 137 | GNUARCH.armeabi-v7a = arm-linux-androideabi |
| 138 | PLATARCH.armeabi-v7a = arm |
| 139 | CFLAGS.ndk-armeabi-v7a = |
| 140 | |
| 141 | ANDROID_ABIS.inhibit += arm64-v8a |
| 142 | GNUARCH.arm64-v8a = aarch64-linux-android |
| 143 | PLATARCH.arm64-v8a = arm64 |
| 144 | MINAPI.arm64-v8a = 21 |
| 145 | |
| 146 | ANDROID_ABIS += x86 |
| 147 | TOOLCHAINDIR.x86 = x86 |
| 148 | GNUARCH.x86 = i686-linux-android |
| 149 | PLATARCH.x86 = x86 |
| 150 | |
| 151 | ANDROID_ABIS.inhibit += x86_64 |
| 152 | TOOLCHAINDIR.x86_64 = x86_64 |
| 153 | GNUARCH.x86_64 = x86_64-linux-android |
| 154 | PLATARCH.x86_64 = x86_64 |
| 155 | MINAPI.x86_64 = 21 |
| 156 | |
| 157 | FLAVOURS += $(ANDROID_ABIS) |
| 158 | |
| 159 | ## Build variants. |
| 160 | VARIANTS += debug |
| 161 | AAPTFLAGS.debug = --debug-mode \ |
| 162 | --rename-manifest-package uk.org.distorted.tripe-debug |
| 163 | KEYSTORE.debug = debug.keystore |
| 164 | JARSIGNERFLAGS.debug = -storepass public -keypass public |
| 165 | |
| 166 | VARIANTS += release |
| 167 | KEYSTORE.release = release.keystore |
| 168 | JARSIGNERFLAGS.release = |
| 169 | |
| 170 | ## Android NDK location. |
| 171 | ANDROID_NDKDIR = $(ANDROID_SDKDIR)/ndk-bundle |
| 172 | NDK_HOSTARCH = $(hostos)-$(hostcpu) |
| 173 | |
| 174 | ## Android NDK toolchains. |
| 175 | ndk-sysroot = \ |
| 176 | $(ANDROID_NDKDIR)/platforms/android-$(call defaulting,MINAPI.$1,$(MINAPI))/arch-$(PLATARCH.$1) |
| 177 | ndk-toolchain-bin = \ |
| 178 | $(ANDROID_NDKDIR)/toolchains/$(call defaulting,TOOLCHAINDIR.$1,$(GNUARCH.$1))-$(TOOLVERSION)/prebuilt/$(NDK_HOSTARCH)/bin |
| 179 | ENV.ndk = env PATH=$(call ndk-toolchain-bin,$1):$$PATH |
| 180 | CC.ndk = $(GNUARCH.$1)-gcc |
| 181 | LD.ndk = $(CC.ndk) |
| 182 | CFLAGS.ndk = $(CFLAGS) -fPIC -D__ANDROID_API__=$(MINAPI) \ |
| 183 | $(CFLAGS.ndk-$1) \ |
| 184 | --sysroot=$(call ndk-sysroot,$1) \ |
| 185 | -isystem $(ANDROID_NDKDIR)/sysroot/usr/include \ |
| 186 | -isystem $(ANDROID_NDKDIR)/sysroot/usr/include/$(GNUARCH.$1) |
| 187 | LDFLAGS.ndk = $(LDFLAGS) -pie \ |
| 188 | --sysroot=$(call ndk-sysroot,$1) |
| 189 | CONFIG.ndk = --host=$(GNUARCH.$1) |
| 190 | |
| 191 | ## Flavour options. |
| 192 | tool = $(call defaulting,$2.$1,$(call $2.ndk,$1)) |
| 193 | |
| 194 | ## Subject name for debug key. |
| 195 | DEBUGDN = CN=Straylight/Edgeware, L=Cambridge, C=GB |
| 196 | |
| 197 | ## Android libraries. |
| 198 | ANDROID_JAR = \ |
| 199 | $(ANDROID_SDKDIR)/platforms/android-$(MINAPI)/android.jar |
| 200 | |
| 201 | ## Scala libraries. |
| 202 | $(CONFIGDIR)/scaladir.mk: |
| 203 | $(V_AT)mkdir -p $(dir $@) |
| 204 | $(call v_tag,CONFIG)$(SCALA) -J-XshowSettings:properties -help 2>&1 | \ |
| 205 | sed -n 's:^ *scala\.home *= *:SCALADIR = :p' >$@.new |
| 206 | $(V_AT)mv $@.new $@ |
| 207 | include $(CONFIGDIR)/scaladir.mk |
| 208 | REALCLEANFILES += $(CONFIGDIR)/scaladir.mk |
| 209 | SCALA_LIB = $(SCALADIR)/lib/scala-library.jar |
| 210 | |
| 211 | ## Silent-rules is on by default. |
| 212 | V = 0 |
| 213 | |
| 214 | ## Allow local overrides at this point. |
| 215 | -include local.mk |
| 216 | |
| 217 | ###-------------------------------------------------------------------------- |
| 218 | ### Silent-rules machinery. |
| 219 | |
| 220 | v_tag = $(call v_tag_$V,$1) |
| 221 | v_tag_0 = @printf " %-8s %s\n" "$1" "$@"; |
| 222 | |
| 223 | V_AT = $(V_AT_$V) |
| 224 | V_AT_0 = @ |
| 225 | |
| 226 | ###-------------------------------------------------------------------------- |
| 227 | ### Other handy functions. |
| 228 | |
| 229 | join-paths = $(if $(filter /%,$2),$2,$1/$2) |
| 230 | |
| 231 | ## Datestamp files. |
| 232 | STAMPDIR = $(OUTDIR)/stamp |
| 233 | stamps = $(patsubst %,$(STAMPDIR)/%.$1-stamp,$2) |
| 234 | stamp-base = $(patsubst $(STAMPDIR)/%-stamp,%,$1) |
| 235 | stamp-name = $(basename $(call stamp-base,$1)) |
| 236 | stamp-type = $(patsubst .%,%,$(suffix $(call stamp-base,$1))) |
| 237 | |
| 238 | ###-------------------------------------------------------------------------- |
| 239 | ### And now we can start building things. |
| 240 | |
| 241 | all:: |
| 242 | .PHONY: all |
| 243 | |
| 244 | clean:: |
| 245 | .PHONY: clean |
| 246 | |
| 247 | realclean:: clean |
| 248 | .PHONY: realclean |
| 249 | |
| 250 | distclean:: realclean |
| 251 | .PHONY: distclean |
| 252 | |
| 253 | ###-------------------------------------------------------------------------- |
| 254 | ### External native packages. |
| 255 | |
| 256 | ## Definitions. |
| 257 | EXTERNALS += adns |
| 258 | adns_CONFIG = --disable-dynamic |
| 259 | |
| 260 | EXTERNALS += mLib |
| 261 | mLib_DEPS = adns |
| 262 | mLib_CONFIG = --enable-static --disable-shared --with-adns |
| 263 | |
| 264 | EXTERNALS += catacomb |
| 265 | catacomb_DEPS = mLib |
| 266 | catacomb_CONFIG = --enable-static --disable-shared |
| 267 | |
| 268 | EXTERNALS += tripe |
| 269 | tripe_DEPS = mLib catacomb |
| 270 | tripe_CONFIG = --without-wireshark --with-adns --with-tunnel=slip |
| 271 | |
| 272 | ## Machinery. |
| 273 | ext-stamps = $(foreach f,$2,$(call stamps,$f,$1)) |
| 274 | |
| 275 | ext-srcdir = $(call defaulting,$1_SRCDIR,../$1) |
| 276 | ext-builddir = $(OUTDIR)/build.$1/$2 |
| 277 | ext-prefix = $(OUTDIR)/inst.$1 |
| 278 | ext-absprefix = $(abs_srcdir)/$(call ext-prefix,$1) |
| 279 | |
| 280 | ext-stamp-srcdir = $(call ext-srcdir,$(call stamp-name,$1)) |
| 281 | ext-stamp-builddir = \ |
| 282 | $(call ext-builddir,$(call stamp-type,$1),$(call stamp-name,$1)) |
| 283 | ext-stamp-absprefix = $(call ext-absprefix,$(call stamp-type,$1)) |
| 284 | ext-stamp-tool = $(call tool,$(call stamp-type,$1),$2) |
| 285 | |
| 286 | EXTSTAMPS = $(call ext-stamps,$(EXTERNALS),$(FLAVOURS)) |
| 287 | |
| 288 | $(EXTSTAMPS): \ |
| 289 | $(STAMPDIR)/%-stamp: \ |
| 290 | $$(call ext-stamps, \ |
| 291 | $$($$(call stamp-name,$$@)_DEPS), \ |
| 292 | $$(call stamp-type,$$@)) |
| 293 | $(V_AT)mkdir -p $(STAMPDIR) |
| 294 | $(V_AT)rm -rf $(call ext-stamp-builddir,$@) |
| 295 | $(V_AT)mkdir -p $(call ext-stamp-builddir,$@) |
| 296 | cd $(call ext-stamp-builddir,$@) && \ |
| 297 | $(call ext-stamp-tool,$@,ENV) \ |
| 298 | $(call join-paths,../../..,$(call ext-stamp-srcdir,$@))/configure \ |
| 299 | --prefix=$(call ext-stamp-absprefix,$@) \ |
| 300 | $(call ext-stamp-tool,$@,CONFIG) \ |
| 301 | $($(call stamp-name,$@)_CONFIG) \ |
| 302 | CC="$(CCACHE) $(call ext-stamp-tool,$@,CC)" \ |
| 303 | CFLAGS="$(call ext-stamp-tool,$@,CFLAGS) -I$(call ext-stamp-absprefix,$@)/include" \ |
| 304 | LD="$(call ext-stamp-tool,$@,LD)" \ |
| 305 | LDFLAGS="$(call ext-stamp-tool,$@,LDFLAGS) -L$(call ext-stamp-absprefix,$@)/lib" \ |
| 306 | PKG_CONFIG="pkg-config --static" \ |
| 307 | PKG_CONFIG_LIBDIR=$(call ext-stamp-absprefix,$@)/lib/pkgconfig |
| 308 | $(call ext-stamp-tool,$@,ENV) \ |
| 309 | $(MAKE) -C$(call ext-stamp-builddir,$@) |
| 310 | $(call ext-stamp-tool,$@,ENV) \ |
| 311 | $(MAKE) -C$(call ext-stamp-builddir,$@) install |
| 312 | $(V_AT)touch $@ |
| 313 | |
| 314 | $(foreach f,$(FLAVOURS),$(foreach e,$(EXTERNALS),clean-$e.$f)): clean-%: |
| 315 | rm -f $(STAMPDIR)/$*-stamp |
| 316 | rm -rf $(call ext-stamp-builddir,$*) |
| 317 | .PHONY: $(foreach f,$(FLAVOURS),$(foreach e,$(EXTERNALS),clean-$e.$f)) |
| 318 | $(foreach f,$(FLAVOURS),clean-inst.$f): clean-inst.%: |
| 319 | rm -rf $(call ext-prefix,$*) |
| 320 | .PHONY: $(foreach f,$(FLAVOURS),clean-inst.$f) |
| 321 | |
| 322 | $(foreach f,$(FLAVOURS),realclean-$f): realclean-%: \ |
| 323 | $$(foreach e,$$(EXTERNALS),clean-$$e.$$*) \ |
| 324 | clean-inst.$$* |
| 325 | realclean:: $(foreach f,$(FLAVOURS),realclean-$f) |
| 326 | |
| 327 | ###-------------------------------------------------------------------------- |
| 328 | ### Our own native programs. |
| 329 | |
| 330 | ## Fetching package configuration. |
| 331 | PKG_CONFIG = pkg-config --static |
| 332 | PKGS = catacomb mLib |
| 333 | |
| 334 | PCOPT.CFLAGS = --cflags |
| 335 | PCOPT.LIBS = --libs |
| 336 | |
| 337 | pkg-config = $(shell \ |
| 338 | env PKG_CONFIG_LIBDIR=$(call ext-prefix,$1)/lib/pkgconfig \ |
| 339 | $(PKG_CONFIG) $(PCOPT.$3) $2) |
| 340 | |
| 341 | ## Definitions. |
| 342 | APKLIBS += libtripe.so |
| 343 | libtripe.so_SRCS = jni.c |
| 344 | libtripe.so_EXTS = mLib catacomb tripe |
| 345 | libtripe.so_CFLAGS = -I$(call ext-prefix,$1)/include \ |
| 346 | -I$(call ext-srcdir,tripe)/common \ |
| 347 | -I$(call ext-srcdir,tripe)/priv \ |
| 348 | -I$(call ext-srcdir,tripe)/server \ |
| 349 | -I$(call ext-builddir,$1,tripe)/config \ |
| 350 | $(call pkg-config,$1,mLib,CFLAGS) \ |
| 351 | $(call pkg-config,$1,catacomb,CFLAGS) |
| 352 | libtripe.so_LIBS = $(call ext-builddir,$1,tripe)/server/libtripe.a \ |
| 353 | $(call ext-builddir,$1,tripe)/priv/libpriv.a \ |
| 354 | $(call ext-builddir,$1,tripe)/common/libcommon.a \ |
| 355 | -L$(call ext-prefix,$1)/lib \ |
| 356 | $(call pkg-config,$1,catacomb,LIBS) \ |
| 357 | $(call pkg-config,$1,mLib,LIBS) |
| 358 | |
| 359 | ## Machinery for compiling. |
| 360 | objdir = $(OUTDIR)/obj.$1 |
| 361 | objects = $(patsubst %.c,$(call objdir,$1)/%$3,$2) |
| 362 | |
| 363 | apklib-objects = $(call objects,$1,$($2_SRCS),$3) |
| 364 | obj-base = $(patsubst $(OUTDIR)/obj.%.o,%,$1) |
| 365 | obj-type = $(patsubst %/,%,$(dir $(call obj-base,$1))) |
| 366 | obj-name = $(notdir $(call obj-base,$1)) |
| 367 | obj-tool = $(call tool,$(call obj-type,$1),$2) |
| 368 | |
| 369 | define obj-rule |
| 370 | $1_OBJS := $$(foreach f,$$(FLAVOURS),\ |
| 371 | $$(call objects,$$f,$$($1_SRCS),.o)) |
| 372 | DEPFILES += $$(foreach f,$$(FLAVOURS),\ |
| 373 | $$(call objects,$$f,$$($1_SRCS),.d)) |
| 374 | $$($1_OBJS): $$(OUTDIR)/obj.%.o: \ |
| 375 | $$$$(call obj-name,$$$$@).c \ |
| 376 | $$$$(call stamps,$$$$(call obj-type,$$$$@),$$$$($1_EXTS)) |
| 377 | $$(V_AT)mkdir -p $$(dir $$@) |
| 378 | $$(call v_tag,CC)$$(call obj-tool,$$@,ENV) \ |
| 379 | $$(call obj-tool,$$@,CC) -c -o$$@ -MD \ |
| 380 | $$(call obj-tool,$$@,CFLAGS) \ |
| 381 | $$(call $1_CFLAGS,$$(call obj-type,$$@)) \ |
| 382 | $$< |
| 383 | endef |
| 384 | $(foreach a,$(APKLIBS), $(eval $(call obj-rule,$a))) |
| 385 | |
| 386 | CLEANFILES += $(OUTDIR)/obj.*/*.o $(OUTDIR)/obj.*/*.d |
| 387 | |
| 388 | ## Machinery for linking. |
| 389 | JNIDIR.host = $(OUTDIR) |
| 390 | JNIDIR.ndk = $(OUTDIR)/pkg/lib/$1 |
| 391 | |
| 392 | define apklib-rule |
| 393 | INSTFILES += $$(call tool,$1,JNIDIR)/$2 |
| 394 | $$(call tool,$1,JNIDIR)/$2: $$(call objects,$$f,$$($2_SRCS),.o) |
| 395 | $$(V_AT)mkdir -p $$(dir $$@) |
| 396 | $$(call v_tag,LD)$$(call tool,$1,ENV) \ |
| 397 | $$(call tool,$1,LD) -o$$@ \ |
| 398 | $$(call tool,$1,LDFLAGS) -shared \ |
| 399 | $$^ \ |
| 400 | $$(call $2_LIBS,$1) |
| 401 | endef |
| 402 | |
| 403 | $(foreach f,$(FLAVOURS), \ |
| 404 | $(foreach a,$(APKLIBS), \ |
| 405 | $(eval $(call apklib-rule,$f,$a)))) |
| 406 | |
| 407 | CLEANFILES += $(OUTDIR)/pkg/lib/*/lib*.so $(OUTDIR)/lib*.so |
| 408 | |
| 409 | ###-------------------------------------------------------------------------- |
| 410 | ### Java and Scala building. |
| 411 | |
| 412 | JARDIR = $(OUTDIR)/jar |
| 413 | CLASSDIR = $(OUTDIR)/cls |
| 414 | |
| 415 | ## External libraries we need to adopt. Grab them and feed them to `dx' |
| 416 | ## separately, because they take aaaaages and we don't want to have to do |
| 417 | ## this on every incremental build. |
| 418 | JARS = $(SCALA_LIB) |
| 419 | |
| 420 | DEXJARS = |
| 421 | define jar-rule |
| 422 | DEXJARS += $$(JARDIR)/$$(notdir $1) |
| 423 | $$(JARDIR)/$$(notdir $1): $1 |
| 424 | $$(V_AT)mkdir -p $$(JARDIR)/ |
| 425 | $$(V_AT)rm -f $$@ $$(basename $$@)-new.jar |
| 426 | $$(call v_tag,DX)dx --dex --output=$$(basename $$@)-new.jar $1 |
| 427 | $$(V_AT)mv $$(basename $$@)-new.jar $$@ |
| 428 | endef |
| 429 | $(foreach j,$(JARS), $(eval $(call jar-rule,$j))) |
| 430 | |
| 431 | REALCLEANFILES += $(JARDIR)/*.jar |
| 432 | |
| 433 | ## Writing things out longhand is tedious. `CLASSES' is a list of entries of |
| 434 | ## the form `SRC[:DEP,...]', saying that `SRC.ext', being a source file |
| 435 | ## capable of being built into `.class' files and setting `SRC.class-stamp', |
| 436 | ## should be so built, and that it depends on other similar sources named DEP |
| 437 | ## having been so built. |
| 438 | CLASSES += util |
| 439 | CLASSES += sys:util |
| 440 | CLASSES += admin:sys,util |
| 441 | CLASSES += tar:util |
| 442 | CLASSES += progress:sys,util |
| 443 | CLASSES += keys:progress,tar,sys,util |
| 444 | CLASSES += terminal:progress,sys,util |
| 445 | CLASSES += R |
| 446 | CLASSES += toy-activity:R |
| 447 | |
| 448 | ## Building class files. |
| 449 | $(STAMPDIR)/%.class-stamp: %.java |
| 450 | $(V_AT)mkdir -p $(CLASSDIR)/ |
| 451 | $(call v_tag,JAVAC)$(JAVAC) $(JAVAFLAGS) \ |
| 452 | -bootclasspath $(ANDROID_JAR) \ |
| 453 | -d $(CLASSDIR) -cp $(CLASSDIR) \ |
| 454 | $< |
| 455 | $(V_AT)$(SCALAC_RESET) |
| 456 | $(V_AT)touch $@ |
| 457 | $(STAMPDIR)/%.class-stamp: %.scala |
| 458 | $(V_AT)mkdir -p $(CLASSDIR)/ |
| 459 | $(call v_tag,SCALAC)$(SCALAC) $(SCALAFLAGS) \ |
| 460 | -javabootclasspath $(ANDROID_JAR) \ |
| 461 | -bootclasspath $(SCALA_LIB) \ |
| 462 | -d $(CLASSDIR) -cp $(CLASSDIR) \ |
| 463 | $< |
| 464 | $(V_AT)touch $@ |
| 465 | |
| 466 | ## Machinery for parsing the `CLASSES' list. |
| 467 | class-name = $(firstword $(subst :, ,$1)) |
| 468 | class-deps = $(subst $(comma), ,$(word 2,$(subst :, ,$1))) |
| 469 | |
| 470 | CLASSNAMES = $(foreach c,$(CLASSES),$(call class-name,$c)) |
| 471 | CLASSSTAMPS = $(call stamps,class,$(CLASSNAMES)) |
| 472 | |
| 473 | $(foreach c,$(CLASSES), \ |
| 474 | $(eval $(call stamps,class,$(call class-name,$c)): \ |
| 475 | $(call stamps,class,$(call class-deps,$c)))) |
| 476 | |
| 477 | CLEANFILES += $(CLASSSTAMPS) |
| 478 | clean::; rm -rf $(OUTDIR)/cls |
| 479 | |
| 480 | ###-------------------------------------------------------------------------- |
| 481 | ### Android building machinery. |
| 482 | |
| 483 | VPATH += $(OUTDIR)/src |
| 484 | CLEANFILES += $(OUTDIR)/*.apk |
| 485 | |
| 486 | AAPTFLAGS = \ |
| 487 | --min-sdk-version $(MINAPI) --target-sdk-version $(TARGETAPI) \ |
| 488 | --version-name "$(VERSION)" --version-code $(VSN) |
| 489 | |
| 490 | $(OUTDIR)/src/R.java: AndroidManifest.xml |
| 491 | $(V_AT)mkdir -p $(dir $@) |
| 492 | $(call v_tag,AAPT)aapt package $(AAPTFLAGS) \ |
| 493 | -M AndroidManifest.xml -S res/ -I $(ANDROID_JAR) \ |
| 494 | -J $(dir $@) --generate-dependencies |
| 495 | CLEANFILES += $(OUTDIR)/src/R.java $(OUTDIR)/src/R.java.d |
| 496 | -include $(OUTDIR)/src/R.java.d |
| 497 | |
| 498 | BINS = catsign key pathmtu |
| 499 | CLEANFILES += $(INSTFILES) |
| 500 | define bin-rule |
| 501 | INSTFILES += $$(OUTDIR)/pkg/assets/bin/$1/$2 |
| 502 | $$(OUTDIR)/pkg/assets/bin/$1/$2: $$$$(call ext-stamps,$$$$(EXTERNALS),$1) |
| 503 | $$(V_AT)mkdir -p $$(dir $$@) |
| 504 | $$(call v_tag,CP)cp $$(call ext-prefix,$1)/bin/$2 $$@ |
| 505 | endef |
| 506 | $(foreach f,$(FLAVOURS), \ |
| 507 | $(foreach b,$(BINS), \ |
| 508 | $(eval $(call bin-rule,$f,$b)))) |
| 509 | |
| 510 | DISTCLEANFILES += debug.keystore |
| 511 | debug.keystore: |
| 512 | $(call v_tag,KEYTOOL)keytool -genkeypair -alias debug \ |
| 513 | -keyalg RSA -keysize 3072 \ |
| 514 | -dname "$(DEBUGDN)" -validity 10000 \ |
| 515 | -keystore $@ -storetype PKCS12 \ |
| 516 | -storepass public -keypass public |
| 517 | |
| 518 | INSTFILES += $(OUTDIR)/pkg/classes.dex |
| 519 | $(OUTDIR)/pkg/classes.dex: $(CLASSSTAMPS) $(DEXJARS) |
| 520 | $(V_AT)mkdir -p $(dir $@) |
| 521 | $(call v_tag,DX)dx --dex --output=$@ $(CLASSDIR) $(JARDIR) |
| 522 | |
| 523 | $(foreach v,$(VARIANTS),$(OUTDIR)/tripe-$v.unsigned.apk): \ |
| 524 | $(OUTDIR)/tripe-%.unsigned.apk: $(INSTFILES) |
| 525 | $(call v_tag,AAPT)aapt package -f $(AAPTFLAGS) $(AAPTFLAGS.$*) \ |
| 526 | -M AndroidManifest.xml -S res/ -I $(ANDROID_JAR) \ |
| 527 | -F $@ $(OUTDIR)/pkg/ |
| 528 | |
| 529 | $(foreach v,$(VARIANTS),$(OUTDIR)/tripe-$v.signed.apk): \ |
| 530 | $(OUTDIR)/tripe-%.signed.apk: $(OUTDIR)/tripe-%.unsigned.apk $$(KEYSTORE.$$*) |
| 531 | $(call v_tag,JARSIGN)jarsigner -keystore $(KEYSTORE.$*) \ |
| 532 | $(JARSIGNERFLAGS.$*) \ |
| 533 | -signedjar $@ $< $(call defaulting,KEYALIAS.$*,$*) |
| 534 | |
| 535 | $(foreach v,$(VARIANTS),$(OUTDIR)/tripe-$v.apk): \ |
| 536 | $(OUTDIR)/tripe-%.apk: $(OUTDIR)/tripe-%.signed.apk |
| 537 | $(call v_tag,ZIPALGN)zipalign $(ZIPALIGNFLAGS.$*) -f 4 $< $@ |
| 538 | |
| 539 | $(VARIANTS): %: $(OUTDIR)/tripe-%.apk |
| 540 | .PHONY: $(VARIANTS) |
| 541 | |
| 542 | ###-------------------------------------------------------------------------- |
| 543 | ### Finishing touches. |
| 544 | |
| 545 | all:: debug |
| 546 | |
| 547 | clean::; rm -f $(CLEANFILES) |
| 548 | realclean::; rm -f $(REALCLEANFILES) |
| 549 | |
| 550 | t:; : $(show) |
| 551 | .PHONY: t |
| 552 | |
| 553 | -include $(DEPFILES) |
| 554 | |
| 555 | ###----- That's all, folks -------------------------------------------------- |