3 ### Build script for the TrIPE Android app
5 ### (c) 2018 Straylight/Edgeware
8 ###----- Licensing notice ---------------------------------------------------
10 ### This file is part of the Trivial IP Encryption (TrIPE) Android app.
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.
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
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/>.
25 PACKAGE = tripe-android
26 VERSION := $(shell ./auto-version)
28 .SECONDEXPANSION: #sorry
30 ###--------------------------------------------------------------------------
33 ## Where to put the object files.
38 CFLAGS = -O2 -g -Wall -pedantic -Werror
44 ## External `pkg-config' packages required.
47 ## Java development kit.
48 JDKDIR = /usr/lib/jvm/default-java
50 JNI_INCLUDES = $(JDKDIR)/include $(JDKDIR)/include/$(JDK_PLAT)
52 ## Default arguments for the Java runtime.
55 ## The Java runtime, for some reason, hardcodes its default for
56 ## `java.io.tmpdir', inviting security problems. If the user has defined a
57 ## `TMPDIR', then persuade Java to use it.
58 explicit-tmpdir-p = $(if $(filter-out undefined,$(origin TMPDIR)),t,nil)
59 ifeq ($(explicit-tmpdir-p), t)
60 JAVADEFS += -Djava.io.tmpdir=$(TMPDIR)
64 JAVAC = javac $(JAVADEFS)
69 ## Unfortunately, `fsc' is a total security disaster. On the other hand,
70 ## `scalac' is rather slow. If we're running with a custom `TMPDIR', and the
71 ## `noip' wrapper <https://git.distorted.org.uk/~mdw/preload-hacks/> is
72 ## available, then we can tame `fsc' enough that it's probably safe to run;
73 ## otherwise, it's too risky to enable by default.
74 noip-available-p := $(shell noip echo t 2>/dev/null || echo nil)
75 ifeq ($(noip-available-p), t)
78 ifeq "$(explicit-tmpdir-p),$(noip-available-p)" "t,t"
79 SCALAC = $(NOIP) fsc $(JAVADEFS)
80 SCALAC_RESET = $(SCALAC) -reset
82 SCALAC = scalac $(JAVADEFS)
85 SCALAFLAGS = -optimise -feature -deprecation -Xfatal-warnings \
86 -Xlint -Xlint:-package-object-classes \
87 -Yinline-warnings:false
88 SCALA_REPL = $(NOIP) scala $(JAVADEFS)
90 ## Silent-rules is on by default.
93 ## Allow local overrides at this point.
96 ###--------------------------------------------------------------------------
97 ### Silent-rules machinery.
99 v_tag = $(call v_tag_$V,$1)
100 v_tag_0 = @printf " %-8s %s\n" "$1" "$@";
105 ###--------------------------------------------------------------------------
106 ### External native packages.
108 PKGS_CFLAGS := $(foreach p,$(PKGS),$(shell pkg-config --cflags $p))
109 PKGS_LIBS := $(foreach p,$(PKGS),$(shell pkg-config --libs $p))
111 ALL_CFLAGS = $(CFLAGS) -fPIC \
112 $(addprefix -I,$(JNI_INCLUDES)) \
117 ###--------------------------------------------------------------------------
118 ### Various other tweaks and overrides.
120 ## Hack around https://issues.scala-lang.org/browse/SI-9689
121 SCALAFLAGS += -Yno-load-impl-class
123 ###--------------------------------------------------------------------------
124 ### And now we can start building things.
133 ###--------------------------------------------------------------------------
137 $(call v_tag,CC)mkdir -p $(OUTDIR) && \
138 $(CC) -c $(ALL_CFLAGS) -MMD -o$@ $<
141 DISTFILES += $(ALL_SOURCES)
143 objects = $(patsubst %.c,$(OUTDIR)%$2,$1)
144 CLEANFILES += $(OUTDIR)*.o $(OUTDIR)*.d
146 ###--------------------------------------------------------------------------
149 ## Java and Scala source files turn into multiple `.class' files with
150 ## unpredictable names. Rather than try to guess stable outputs for these
151 ## sources, we make artificial `timestamp' files and uses these in our
153 CLASSDIR = $(OUTDIR)cls/
154 stamps = $(patsubst %,$(OUTDIR)%.stamp,$1)
156 clean::; rm -rf $(CLASSDIR)
157 CLEANFILES += $(OUTDIR)*.stamp
159 ## Compiling actual Java code. Note that this confuses the resident Scala
160 ## compiler, so we have to reset it here.
162 $(OUTDIR)%.stamp: %.java
163 $(call v_tag,JAVAC)mkdir -p $(CLASSDIR) && \
164 $(JAVAC) -d $(CLASSDIR) -cp $(CLASSDIR) $(JAVAFLAGS) $< && \
166 $(V_AT)$(SCALAC_RESET)
168 ## Compiling Scala code.
170 $(OUTDIR)%.stamp: %.scala
171 $(call v_tag,SCALAC)mkdir -p $(CLASSDIR) && \
172 $(SCALAC) -d $(CLASSDIR) -cp $(CLASSDIR) $(SCALAFLAGS) $< && \
175 ###--------------------------------------------------------------------------
176 ### Native-code libraries.
181 shlibfile = $(patsubst %,$(OUTDIR)lib%.so,$1)
182 SHLIBFILES = $(call shlibfile,$(SHLIBS))
183 TARGETS += $(SHLIBFILES)
184 ALL_SOURCES += $(foreach l,$(SHLIBS),$($l_SOURCES))
186 $(SHLIBFILES): $(OUTDIR)lib%.so: $$(call objects,$$($$*_SOURCES),.o)
187 $(call v_tag,LD)$(LD) $(LDFLAGS.so) -o$@ $^ $(LIBS)
189 ###--------------------------------------------------------------------------
192 ## Writing things out longhand is tedious. `CLASSES' is a list of entries of
193 ## the form `SRC[:DEP,...]', saying that `SRC.ext', being a source file
194 ## capable of being built into `.class' files and setting `SRC.stamp', should
195 ## be so built, and that it depends on other similar sources named DEP having
199 CLASSES += admin:sys,util
201 CLASSES += progress:sys,util
202 CLASSES += keys:progress,tar,sys,util
203 CLASSES += terminal:progress,sys,util
206 ## Machinery for parsing the `CLASSES' list.
208 class-name = $(firstword $(subst :, ,$1))
209 class-deps = $(subst $(COMMA), ,$(word 2,$(subst :, ,$1)))
211 CLASS_NAMES = $(foreach c,$(CLASSES),$(call class-name,$c))
213 all:: $(call stamps,$(CLASS_NAMES))
215 $(foreach c,$(CLASSES),$(eval $(call stamps,$(call class-name,$c)): \
216 $(call stamps,$(call class-deps,$c))))
218 DISTFILES += $(foreach c,$(CLASSES),\
219 $(foreach e,$(CLSEXT),\
220 $(wildcard $(call class-name,$c).$e)))
222 ###--------------------------------------------------------------------------
223 ### Distribution arrangements.
226 DISTFILES += Makefile
227 DISTFILES += auto-version
229 distdir = $(PACKAGE)-$(VERSION)
230 DISTTAR = $(distdir).tar.gz
233 rm -rf $(OUTDIR)$(distdir)
234 mkdir $(OUTDIR)$(distdir)
235 echo $(VERSION) >$(OUTDIR)$(distdir)/RELEASE
236 set -e; for i in $(DISTFILES); do \
237 case $$i in */*) mkdir -p $(OUTDIR)$(distdir)/$${i%/*} ;; esac; \
238 cp $$i $(OUTDIR)$(distdir)/; \
243 set -e; cd $(OUTDIR); tar chozf ../$(DISTTAR) $(distdir)
247 ###--------------------------------------------------------------------------
248 ### Finishing touches.
252 clean::; rm -f $(CLEANFILES) $(TARGETS)
255 $(SCALA_REPL) -cp $(CLASSDIR) -Djava.library.path=$(OUTDIR)
258 -include $(call objects,$(ALL_SOURCES),.d)
260 ###----- That's all, folks --------------------------------------------------