chiark / gitweb /
1e747137fc2882566c8c0e24dcdb46e8bc086967
[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 ## Where to put the object files.
34 OUTDIR                   = out/
35
36 ## Native C compiler.
37 CC                       = gcc
38 CFLAGS                   = -O2 -g -Wall -pedantic -Werror
39
40 ## Native linker.
41 LD                       = gcc
42 LDFLAGS.so               = -shared
43
44 ## External `pkg-config' packages required.
45 PKGS                     = mLib catacomb
46
47 ## Java development kit.
48 JDKDIR                   = /usr/lib/jvm/default-java
49 JDK_PLAT                 = linux
50 JNI_INCLUDES             = $(JDKDIR)/include $(JDKDIR)/include/$(JDK_PLAT)
51
52 ## Default arguments for the Java runtime.
53 JAVADEFS                 =
54
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)
61 endif
62
63 ## Java compiler.
64 JAVAC                    = javac $(JAVADEFS)
65 JAVAFLAGS                =
66
67 ## Scala compiler.
68 ##
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)
76   NOIP                   = noip
77 endif
78 ifeq "$(explicit-tmpdir-p),$(noip-available-p)" "t,t"
79   SCALAC                 = $(NOIP) fsc $(JAVADEFS)
80   SCALAC_RESET           = $(SCALAC) -reset
81 else
82   SCALAC                 = scalac $(JAVADEFS)
83   SCALAC_RESET           =
84 endif
85 SCALAFLAGS               = -optimise -Xlint -Xlint:-package-object-classes \
86                                 -Yinline-warnings:false
87 SCALA_REPL               = $(NOIP) scala $(JAVADEFS)
88
89 ## Silent-rules is on by default.
90 V                        = 0
91
92 ## Allow local overrides at this point.
93 -include local.mk
94
95 ###--------------------------------------------------------------------------
96 ### Silent-rules machinery.
97
98 v_tag                    = $(call v_tag_$V,$1)
99 v_tag_0                  = @printf "  %-8s %s\n" "$1" "$@";
100
101 V_AT                     = $(V_AT_$V)
102 V_AT_0                   = @
103
104 ###--------------------------------------------------------------------------
105 ### External native packages.
106
107 PKGS_CFLAGS             := $(foreach p,$(PKGS),$(shell pkg-config --cflags $p))
108 PKGS_LIBS               := $(foreach p,$(PKGS),$(shell pkg-config --libs $p))
109
110 ALL_CFLAGS               = $(CFLAGS) -fPIC \
111                                 $(addprefix -I,$(JNI_INCLUDES)) \
112                                 $(PKGS_CFLAGS)
113
114 LIBS                     = $(PKGS_LIBS)
115
116 ###--------------------------------------------------------------------------
117 ### Various other tweaks and overrides.
118
119 ## Hack around https://issues.scala-lang.org/browse/SI-9689
120 SCALAFLAGS              += -Yno-load-impl-class
121
122 ###--------------------------------------------------------------------------
123 ### And now we can start building things.
124
125 all::
126 .PHONY: all
127
128 CLEANFILES               =
129 clean::
130 .PHONY: clean
131
132 ###--------------------------------------------------------------------------
133 ### Native C code.
134
135 out/%.o: %.c
136         $(call v_tag,CC)mkdir -p $(OUTDIR) && \
137                 $(CC) -c $(ALL_CFLAGS) -MMD -o$@ $<
138
139 ALL_SOURCES              =
140 DISTFILES               += $(ALL_SOURCES)
141
142 objects                  = $(patsubst %.c,$(OUTDIR)%$2,$1)
143 CLEANFILES              += $(OUTDIR)*.o $(OUTDIR)*.d
144
145 ###--------------------------------------------------------------------------
146 ### Java classes.
147
148 ## Java and Scala source files turn into multiple `.class' files with
149 ## unpredictable names.  Rather than try to guess stable outputs for these
150 ## sources, we make artificial `timestamp' files and uses these in our
151 ## dependencies.
152 CLASSDIR                 = $(OUTDIR)cls/
153 stamps                   = $(patsubst %,$(OUTDIR)%.stamp,$1)
154
155 clean::; rm -rf $(CLASSDIR)
156 CLEANFILES              += $(OUTDIR)*.stamp
157
158 ## Compiling actual Java code.  Note that this confuses the resident Scala
159 ## compiler, so we have to reset it here.
160 CLSISH                  += java
161 $(OUTDIR)%.stamp: %.java
162         $(call v_tag,JAVAC)mkdir -p $(CLASSDIR) && \
163                 $(JAVAC) -d $(CLASSDIR) -cp $(CLASSDIR) $(JAVAFLAGS) $< && \
164                 echo built >$@
165         $(V_AT)$(SCALAC_RESET)
166
167 ## Compiling Scala code.
168 CLSEXT                  += scala
169 $(OUTDIR)%.stamp: %.scala
170         $(call v_tag,SCALAC)mkdir -p $(CLASSDIR) && \
171                 $(SCALAC) -d $(CLASSDIR) -cp $(CLASSDIR) $(SCALAFLAGS) $< && \
172                 echo built >$@
173
174 ###--------------------------------------------------------------------------
175 ### Native-code libraries.
176
177 SHLIBS                  += toy
178 toy_SOURCES              = jni.c
179
180 shlibfile                = $(patsubst %,$(OUTDIR)lib%.so,$1)
181 SHLIBFILES               = $(call shlibfile,$(SHLIBS))
182 TARGETS                 += $(SHLIBFILES)
183 ALL_SOURCES             += $(foreach l,$(SHLIBS),$($l_SOURCES))
184
185 $(SHLIBFILES): $(OUTDIR)lib%.so: $$(call objects,$$($$*_SOURCES),.o)
186         $(call v_tag,LD)$(LD) $(LDFLAGS.so) -o$@ $^ $(LIBS)
187
188 ###--------------------------------------------------------------------------
189 ### Java classes.
190
191 ## Writing things out longhand is tedious.  `CLASSES' is a list of entries of
192 ## the form `SRC[:DEP,...]', saying that `SRC.ext', being a source file
193 ## capable of being built into `.class' files and setting `SRC.stamp', should
194 ## be so built, and that it depends on other similar sources named DEP having
195 ## been so built.
196 CLASSES                 += util
197 CLASSES                 += sys:util
198 CLASSES                 += admin:sys,util
199 CLASSES                 += tar:util
200 CLASSES                 += keys:tar,sys,util
201 CLASSES                 += main:sys
202
203 ## Machinery for parsing the `CLASSES' list.
204 COMMA                    = ,
205 class-name               = $(firstword $(subst :, ,$1))
206 class-deps               = $(subst $(COMMA), ,$(word 2,$(subst :, ,$1)))
207
208 CLASS_NAMES              = $(foreach c,$(CLASSES),$(call class-name,$c))
209
210 all:: $(call stamps,$(CLASS_NAMES))
211
212 $(foreach c,$(CLASSES),$(eval $(call stamps,$(call class-name,$c)): \
213         $(call stamps,$(call class-deps,$c))))
214
215 DISTFILES               += $(foreach c,$(CLASSES),\
216                                 $(foreach e,$(CLSEXT),\
217                                   $(wildcard $(call class-name,$c).$e)))
218
219 ###--------------------------------------------------------------------------
220 ### Distribution arrangements.
221
222 DISTFILES               += COPYING
223 DISTFILES               += Makefile
224 DISTFILES               += auto-version
225
226 distdir                  = $(PACKAGE)-$(VERSION)
227 DISTTAR                  = $(distdir).tar.gz
228
229 distdir:
230         rm -rf $(OUTDIR)$(distdir)
231         mkdir $(OUTDIR)$(distdir)
232         echo $(VERSION) >$(OUTDIR)$(distdir)/RELEASE
233         set -e; for i in $(DISTFILES); do \
234           case $$i in */*) mkdir -p $(OUTDIR)$(distdir)/$${i%/*} ;; esac; \
235           cp $$i $(OUTDIR)$(distdir)/; \
236         done
237 .PHONY: distdir
238
239 dist: distdir
240         set -e; cd $(OUTDIR); tar chozf ../$(DISTTAR) $(distdir)
241         rm -rf $(distdir)
242 .PHONY: dist
243
244 ###--------------------------------------------------------------------------
245 ### Finishing touches.
246
247 all:: $(TARGETS)
248
249 clean::; rm -f $(CLEANFILES) $(TARGETS)
250
251 repl: $(TARGETS)
252         $(SCALA_REPL) -cp $(CLASSDIR) -Djava.library.path=$(OUTDIR)
253 .PHONY: repl
254
255 -include $(call objects,$(ALL_SOURCES),.d)
256
257 ###----- That's all, folks --------------------------------------------------