More progress. More work.
[tripe-android] / Makefile
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
28 .SECONDEXPANSION: #sorry
29
30 ###--------------------------------------------------------------------------
31 ### Build parameters.
32
33 abs_builddir := $(shell pwd)
34
35 ## Where to put the object files.
36 OUTDIR = out
37
38 ## Native C compiler.
39 CC = gcc
40 CFLAGS = -O2 -g -Wall -pedantic -Werror
41
42 ## Native linker.
43 LD = gcc
44 LDFLAGS.so = -shared
45
46 ## External `pkg-config' packages required.
47 PKGS = mLib catacomb
48
49 ## Java development kit.
50 JDKDIR = /usr/lib/jvm/default-java
51 JDK_PLAT = linux
52 JNI_INCLUDES = $(JDKDIR)/include $(JDKDIR)/include/$(JDK_PLAT)
53
54 ## Default arguments for the Java runtime.
55 JAVADEFS =
56
57 ## The Java runtime, for some reason, hardcodes its default for
58 ## `java.io.tmpdir', inviting security problems. If the user has defined a
59 ## `TMPDIR', then persuade Java to use it.
60 explicit-tmpdir-p = $(if $(filter-out undefined,$(origin TMPDIR)),t,nil)
61 ifeq ($(explicit-tmpdir-p), t)
62 JAVADEFS += -Djava.io.tmpdir=$(TMPDIR)
63 endif
64
65 ## Java compiler.
66 JAVAC = javac $(JAVADEFS)
67 JAVAFLAGS =
68
69 ## Scala compiler.
70 ##
71 ## Unfortunately, `fsc' is a total security disaster. On the other hand,
72 ## `scalac' is rather slow. If we're running with a custom `TMPDIR', and the
73 ## `noip' wrapper <https://git.distorted.org.uk/~mdw/preload-hacks/> is
74 ## available, then we can tame `fsc' enough that it's probably safe to run;
75 ## otherwise, it's too risky to enable by default.
76 noip-available-p := $(shell noip echo t 2>/dev/null || echo nil)
77 ifeq ($(noip-available-p), t)
78 NOIP = noip
79 endif
80 ifeq "$(explicit-tmpdir-p),$(noip-available-p)" "t,t"
81 SCALAC = $(NOIP) fsc $(JAVADEFS)
82 SCALAC_RESET = $(SCALAC) -reset
83 else
84 SCALAC = scalac $(JAVADEFS)
85 SCALAC_RESET =
86 endif
87 SCALAFLAGS = -optimise -feature -deprecation -Xfatal-warnings \
88 -Xlint -Xlint:-package-object-classes \
89 -Yinline-warnings:false
90 SCALA_REPL = $(NOIP) scala $(JAVADEFS)
91
92 ## Silent-rules is on by default.
93 V = 0
94
95 ## Allow local overrides at this point.
96 -include local.mk
97
98 ###--------------------------------------------------------------------------
99 ### Silent-rules machinery.
100
101 v_tag = $(call v_tag_$V,$1)
102 v_tag_0 = @printf " %-8s %s\n" "$1" "$@";
103
104 V_AT = $(V_AT_$V)
105 V_AT_0 = @
106
107 ###--------------------------------------------------------------------------
108 ### External native packages.
109
110 PKGS_CFLAGS := $(foreach p,$(PKGS),$(shell pkg-config --cflags $p))
111 PKGS_LIBS := $(foreach p,$(PKGS),$(shell pkg-config --libs $p))
112
113 ALL_CFLAGS = $(CFLAGS) -fPIC \
114 $(addprefix -I,$(JNI_INCLUDES)) \
115 $(PKGS_CFLAGS)
116
117 LIBS = $(PKGS_LIBS)
118
119 ###--------------------------------------------------------------------------
120 ### Various other tweaks and overrides.
121
122 ## Hack around https://issues.scala-lang.org/browse/SI-9689
123 SCALAFLAGS += -Yno-load-impl-class
124
125 ###--------------------------------------------------------------------------
126 ### And now we can start building things.
127
128 all::
129 .PHONY: all
130
131 CLEANFILES =
132 clean::
133 .PHONY: clean
134
135 ###--------------------------------------------------------------------------
136 ### Native C code.
137
138 out/%.o: %.c
139 $(call v_tag,CC)mkdir -p $(OUTDIR)/ && \
140 $(CC) -c $(ALL_CFLAGS) -MMD -o$@ $<
141
142 ALL_SOURCES =
143 DISTFILES += $(ALL_SOURCES)
144
145 objects = $(patsubst %.c,$(OUTDIR)/%$2,$1)
146 CLEANFILES += $(OUTDIR)/*.o $(OUTDIR)/*.d
147
148 ###--------------------------------------------------------------------------
149 ### Java classes.
150
151 ## Java and Scala source files turn into multiple `.class' files with
152 ## unpredictable names. Rather than try to guess stable outputs for these
153 ## sources, we make artificial `timestamp' files and uses these in our
154 ## dependencies.
155 CLASSDIR = $(OUTDIR)/cls
156 stamps = $(patsubst %,$(OUTDIR)/%.$1-stamp,$2)
157
158 clean::; rm -rf $(CLASSDIR)
159 CLEANFILES += $(OUTDIR)/*.class-stamp
160
161 ## Compiling actual Java code. Note that this confuses the resident Scala
162 ## compiler, so we have to reset it here.
163 CLSISH += java
164 $(OUTDIR)/%.class-stamp: %.java
165 $(call v_tag,JAVAC)mkdir -p $(CLASSDIR)/ && \
166 $(JAVAC) -d $(CLASSDIR) -cp $(CLASSDIR) $(JAVAFLAGS) $< && \
167 echo built >$@
168 $(V_AT)$(SCALAC_RESET)
169
170 ## Compiling Scala code.
171 CLSEXT += scala
172 $(OUTDIR)/%.class-stamp: %.scala
173 $(call v_tag,SCALAC)mkdir -p $(CLASSDIR)/ && \
174 $(SCALAC) -d $(CLASSDIR) -cp $(CLASSDIR) $(SCALAFLAGS) $< && \
175 echo built >$@
176
177 ###--------------------------------------------------------------------------
178 ### Native-code libraries.
179
180 SHLIBS += toy
181 toy_SOURCES = jni.c
182
183 shlibfile = $(patsubst %,$(OUTDIR)/lib%.so,$1)
184 SHLIBFILES = $(call shlibfile,$(SHLIBS))
185 TARGETS += $(SHLIBFILES)
186 ALL_SOURCES += $(foreach l,$(SHLIBS),$($l_SOURCES))
187
188 $(SHLIBFILES): $(OUTDIR)/lib%.so: $$(call objects,$$($$*_SOURCES),.o)
189 $(call v_tag,LD)$(LD) $(LDFLAGS.so) -o$@ $^ $(LIBS)
190
191 ###--------------------------------------------------------------------------
192 ### Java classes.
193
194 ## Writing things out longhand is tedious. `CLASSES' is a list of entries of
195 ## the form `SRC[:DEP,...]', saying that `SRC.ext', being a source file
196 ## capable of being built into `.class' files and setting `SRC.stamp', should
197 ## be so built, and that it depends on other similar sources named DEP having
198 ## been so built.
199 CLASSES += util
200 CLASSES += sys:util
201 CLASSES += admin:sys,util
202 CLASSES += tar:util
203 CLASSES += progress:sys,util
204 CLASSES += keys:progress,tar,sys,util
205 CLASSES += terminal:progress,sys,util
206 CLASSES += main:sys
207
208 ## Machinery for parsing the `CLASSES' list.
209 COMMA = ,
210 class-name = $(firstword $(subst :, ,$1))
211 class-deps = $(subst $(COMMA), ,$(word 2,$(subst :, ,$1)))
212
213 CLASS_NAMES = $(foreach c,$(CLASSES),$(call class-name,$c))
214
215 all:: $(call stamps,class,$(CLASS_NAMES))
216
217 $(foreach c,$(CLASSES),$(eval $(call stamps,class,$(call class-name,$c)): \
218 $(call stamps,class,$(call class-deps,$c))))
219
220 DISTFILES += $(foreach c,$(CLASSES),\
221 $(foreach e,$(CLSEXT),\
222 $(wildcard $(call class-name,$c).$e)))
223
224 ###--------------------------------------------------------------------------
225 ### External packages.
226
227 EXTPREFIX = $(abs_builddir)/$(OUTDIR)/inst
228
229 join-paths = $(if $(filter /%,$2),$2,$1/$2)
230 ext-srcdir = $(or $($1_SRCDIR),../$1)
231
232 EXTERNALS += adns
233 adns_CONFIG = --disable-dynamic
234
235 EXTERNALS += mLib
236 mLib_DEPS = adns
237 mLib_CONFIG = --enable-static --disable-shared --with-adns
238
239 EXTERNALS += catacomb
240 catacomb_DEPS = mLib
241 catacomb_CONFIG = --enable-static --disable-shared
242
243 EXTERNALS += tripe
244 tripe_DEPS = mLib catacomb
245 tripe_CONFIG = --without-wireshark --with-adns --with-tunnel=slip
246
247 all:: $(call stamps,ext,$(EXTERNALS))
248 CLEANFILES += $(OUTDIR)/*.ext-stamp
249 clean::; rm -rf $(OUTDIR)/inst $(OUTDIR)/build
250
251 $(call stamps,ext,$(EXTERNALS)): \
252 $(OUTDIR)/%.ext-stamp: $$(call stamps,ext,$$($$*_DEPS))
253 $(V_AT)rm -rf $(OUTDIR)/build/$*/
254 $(V_AT)mkdir -p $(OUTDIR)/build/$*/
255 cd $(OUTDIR)/build/$*/ && \
256 $(call join-paths,../../..,$(call ext-srcdir,$*))/configure \
257 --prefix=$(EXTPREFIX) \
258 $($*_CONFIG) \
259 CFLAGS="-O2 -g -fPIC -Wall -I$(EXTPREFIX)/include" \
260 LDFLAGS="-L$(EXTPREFIX)/lib" \
261 PKG_CONFIG="pkg-config --static" \
262 PKG_CONFIG_LIBDIR=$(EXTPREFIX)/lib/pkgconfig
263 $(MAKE) -C$(OUTDIR)/build/$*/
264 $(MAKE) -C$(OUTDIR)/build/$*/ -s install
265 $(V_AT)echo done >$@
266
267 ###--------------------------------------------------------------------------
268 ### Distribution arrangements.
269
270 DISTFILES += COPYING
271 DISTFILES += Makefile
272 DISTFILES += auto-version
273
274 distdir = $(PACKAGE)-$(VERSION)
275 DISTTAR = $(distdir).tar.gz
276
277 distdir:
278 rm -rf $(OUTDIR)/$(distdir)
279 mkdir $(OUTDIR)/$(distdir)/
280 echo $(VERSION) >$(OUTDIR)/$(distdir)/RELEASE
281 set -e; for i in $(DISTFILES); do \
282 case $$i in */*) mkdir -p $(OUTDIR)/$(distdir)/$${i%/*}/ ;; esac; \
283 cp $$i $(OUTDIR)/$(distdir)/; \
284 done
285 .PHONY: distdir
286
287 dist: distdir
288 set -e; cd $(OUTDIR)/; tar chozf ../$(DISTTAR) $(distdir)
289 rm -rf $(distdir)
290 .PHONY: dist
291
292 ###--------------------------------------------------------------------------
293 ### Finishing touches.
294
295 all:: $(TARGETS)
296
297 clean::; rm -f $(CLEANFILES) $(TARGETS)
298
299 repl: all
300 $(SCALA_REPL) -cp $(CLASSDIR) -Djava.library.path=$(OUTDIR)
301 .PHONY: repl
302
303 -include $(call objects,$(ALL_SOURCES),.d)
304
305 ###----- That's all, folks --------------------------------------------------