X-Git-Url: https://git.distorted.org.uk/~mdw/tripe-android/blobdiff_plain/ba445867a9ffcfd3f0c21e2f4f7a2c0a8d822476..3bb2303d42adb3f37420f168b009ecfe64f888cd:/Makefile?ds=sidebyside
diff --git a/Makefile b/Makefile
index c6391a1..5edb29a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,60 +1,317 @@
### -*-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)
+
+.SECONDEXPANSION: #sorry
+
+###--------------------------------------------------------------------------
+### Build parameters.
+
+abs_builddir := $(shell pwd)
+
+## Where to put the object files.
+OUTDIR = out
+
+## Native C compiler.
+CC = gcc
+CFLAGS = -O2 -g -Wall -pedantic -Werror
+
+## Native linker.
+LD = gcc -Wl,-z,defs
+LDFLAGS.so = -shared
+
+## External `pkg-config' packages required.
+PKGS = mLib catacomb
+
+## Java development kit.
+JDKDIR = /usr/lib/jvm/default-java
+JDK_PLAT = linux
+JNI_INCLUDES = $(JDKDIR)/include $(JDKDIR)/include/$(JDK_PLAT)
+
+## Default arguments for the Java runtime.
+JAVADEFS =
+
+## 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 $(filter-out undefined,$(origin TMPDIR)),t,nil)
+ifeq ($(explicit-tmpdir-p), t)
+ JAVADEFS += -Djava.io.tmpdir=$(TMPDIR)
+endif
+
+## Java compiler.
+JAVAC = javac $(JAVADEFS)
+JAVAFLAGS =
+
+## 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)
+ SCALAC_RESET = $(SCALAC) -reset
+else
+ SCALAC = scalac $(JAVADEFS)
+ SCALAC_RESET =
+endif
+SCALAFLAGS = -optimise -feature -deprecation -Xfatal-warnings \
+ -Xlint -Xlint:-package-object-classes \
+ -Yinline-warnings:false
+SCALA_REPL = $(NOIP) scala $(JAVADEFS)
+
+## 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 = @
-JDK = /usr/lib/jvm/default-java
-JDK_PLAT = linux
-INCLUDES = $(JDK)/include $(JDK)/include/$(JDK_PLAT)
+###--------------------------------------------------------------------------
+### External native packages.
-CC = gcc
-CFLAGS = -O0 -g -Wall -fPIC $(addprefix -I,$(INCLUDES))
+EXTPREFIX = $(abs_builddir)/$(OUTDIR)/inst
-LD = gcc
-LDFLAGS.so = -shared
+join-paths = $(if $(filter /%,$2),$2,$1/$2)
+ext-srcdir = $(or $($1_SRCDIR),../$1)
-JAVAC = javac
-JAVAFLAGS =
+PKG_CONFIG = PKG_CONFIG_LIBDIR=$(OUTDIR)/inst/lib/pkgconfig \
+ pkg-config --static
+
+PKGS_CFLAGS := $(foreach p,$(PKGS),$(shell $(PKG_CONFIG) --cflags $p))
+PKGS_LIBS := $(foreach p,$(PKGS),$(shell $(PKG_CONFIG) --libs $p))
+
+ALL_CFLAGS = $(CFLAGS) -fPIC \
+ $(addprefix -I,$(JNI_INCLUDES)) \
+ -I$(OUTDIR)/inst/include \
+ -I$(call ext-srcdir,tripe)/common \
+ -I$(call ext-srcdir,tripe)/priv \
+ -I$(call ext-srcdir,tripe)/server \
+ -I$(OUTDIR)/build/tripe/config \
+ $(PKGS_CFLAGS)
-SCALAC = fsc
-SCALAFLAGS = -optimise
+LIBS = $(OUTDIR)/build/tripe/server/libtripe.a \
+ $(OUTDIR)/build/tripe/priv/libpriv.a \
+ $(OUTDIR)/build/tripe/common/libcommon.a \
+ -L$(OUTDIR)/inst/lib $(PKGS_LIBS)
+
+###--------------------------------------------------------------------------
+### Various other tweaks and overrides.
+
+## Hack around https://issues.scala-lang.org/browse/SI-9689
+SCALAFLAGS += -Yno-load-impl-class
+
+###--------------------------------------------------------------------------
+### And now we can start building things.
all::
.PHONY: all
-%.o: %.c
- $(call v_tag,CC)$(CC) -c $(CFLAGS) -MMD -o$@ $<
-CLEANFILES += *.o *.d
+CLEANFILES =
+clean::
+.PHONY: clean
-%.stamp: %.java
- $(call v_tag,JAVAC)$(JAVAC) -d . $(JAVAFLAGS) $< && echo built >$@
-%.stamp: %.scala
- $(call v_tag,SCALAC)$(SCALAC) -d . $(SCALAFLAGS) $< && echo built >$@
-CLEANFILES += *.stamp
-clean::; rm -rf uk/
+###--------------------------------------------------------------------------
+### Native C code.
-objects = $(patsubst %.c,%$2,$1)
+out/%.o: %.c
+ $(call v_tag,CC)mkdir -p $(OUTDIR)/ && \
+ $(CC) -c $(ALL_CFLAGS) -MMD -o$@ $<
-TARGETS += libtoy.so
-libtoy.so_SOURCES = jni.c
-libtoy.so: $(call objects,$(libtoy.so_SOURCES),.o)
- $(call v_tag,LD)$(LD) $(LDFLAGS.so) -o$@ $^
+ALL_SOURCES =
+DISTFILES += $(ALL_SOURCES)
-TARGETS += jni.stamp
+objects = $(patsubst %.c,$(OUTDIR)/%$2,$1)
+CLEANFILES += $(OUTDIR)/*.o $(OUTDIR)/*.d
-TARGETS += sock.stamp
-sock.stamp: jni.stamp
+###--------------------------------------------------------------------------
+### Java classes.
-TARGETS += main.stamp
-main.stamp: jni.stamp sock.stamp
+## Java and Scala source files turn into multiple `.class' files with
+## unpredictable names. Rather than try to guess stable outputs for these
+## sources, we make artificial `timestamp' files and uses these in our
+## dependencies.
+CLASSDIR = $(OUTDIR)/cls
+stamps = $(patsubst %,$(OUTDIR)/%.$1-stamp,$2)
+
+clean::; rm -rf $(CLASSDIR)
+CLEANFILES += $(OUTDIR)/*.class-stamp
+
+## Compiling actual Java code. Note that this confuses the resident Scala
+## compiler, so we have to reset it here.
+CLSISH += java
+$(OUTDIR)/%.class-stamp: %.java
+ $(call v_tag,JAVAC)mkdir -p $(CLASSDIR)/ && \
+ $(JAVAC) -d $(CLASSDIR) -cp $(CLASSDIR) $(JAVAFLAGS) $< && \
+ echo built >$@
+ $(V_AT)$(SCALAC_RESET)
+
+## Compiling Scala code.
+CLSEXT += scala
+$(OUTDIR)/%.class-stamp: %.scala
+ $(call v_tag,SCALAC)mkdir -p $(CLASSDIR)/ && \
+ $(SCALAC) -d $(CLASSDIR) -cp $(CLASSDIR) $(SCALAFLAGS) $< && \
+ echo built >$@
+
+###--------------------------------------------------------------------------
+### Native-code libraries.
+
+SHLIBS += tripe
+tripe_SOURCES = jni.c
+
+shlibfile = $(patsubst %,$(OUTDIR)/lib%.so,$1)
+SHLIBFILES = $(call shlibfile,$(SHLIBS))
+TARGETS += $(SHLIBFILES)
+ALL_SOURCES += $(foreach l,$(SHLIBS),$($l_SOURCES))
+
+$(call objects,$(tripe_SOURCES),.o): $(call stamps,ext,tripe)
+
+$(SHLIBFILES): $(OUTDIR)/lib%.so: $$(call objects,$$($$*_SOURCES),.o)
+ $(call v_tag,LD)$(LD) $(LDFLAGS.so) -o$@ $^ $(LIBS)
+
+###--------------------------------------------------------------------------
+### Java classes.
+
+## 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.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 += progress:sys,util
+CLASSES += keys:progress,tar,sys,util
+CLASSES += terminal:progress,sys,util
+
+## Machinery for parsing the `CLASSES' list.
+COMMA = ,
+class-name = $(firstword $(subst :, ,$1))
+class-deps = $(subst $(COMMA), ,$(word 2,$(subst :, ,$1)))
+
+CLASS_NAMES = $(foreach c,$(CLASSES),$(call class-name,$c))
+
+all:: $(call stamps,class,$(CLASS_NAMES))
+
+$(foreach c,$(CLASSES),$(eval $(call stamps,class,$(call class-name,$c)): \
+ $(call stamps,class,$(call class-deps,$c))))
+
+DISTFILES += $(foreach c,$(CLASSES),\
+ $(foreach e,$(CLSEXT),\
+ $(wildcard $(call class-name,$c).$e)))
+
+###--------------------------------------------------------------------------
+### External packages.
+
+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
+
+all:: $(call stamps,ext,$(EXTERNALS))
+CLEANFILES += $(OUTDIR)/*.ext-stamp
+clean::; rm -rf $(OUTDIR)/inst $(OUTDIR)/build
+
+$(call stamps,ext,$(EXTERNALS)): \
+ $(OUTDIR)/%.ext-stamp: $$(call stamps,ext,$$($$*_DEPS))
+ $(V_AT)rm -rf $(OUTDIR)/build/$*/
+ $(V_AT)mkdir -p $(OUTDIR)/build/$*/
+ cd $(OUTDIR)/build/$*/ && \
+ $(call join-paths,../../..,$(call ext-srcdir,$*))/configure \
+ --prefix=$(EXTPREFIX) \
+ $($*_CONFIG) \
+ CFLAGS="-O2 -g -fPIC -Wall -I$(EXTPREFIX)/include" \
+ LDFLAGS="-L$(EXTPREFIX)/lib" \
+ PKG_CONFIG="pkg-config --static" \
+ PKG_CONFIG_LIBDIR=$(EXTPREFIX)/lib/pkgconfig
+ $(MAKE) -C$(OUTDIR)/build/$*/
+ $(MAKE) -C$(OUTDIR)/build/$*/ -s install
+ $(V_AT)echo done >$@
+
+###--------------------------------------------------------------------------
+### Distribution arrangements.
+
+DISTFILES += COPYING
+DISTFILES += Makefile
+DISTFILES += auto-version
+
+distdir = $(PACKAGE)-$(VERSION)
+DISTTAR = $(distdir).tar.gz
+
+distdir:
+ rm -rf $(OUTDIR)/$(distdir)
+ mkdir $(OUTDIR)/$(distdir)/
+ echo $(VERSION) >$(OUTDIR)/$(distdir)/RELEASE
+ set -e; for i in $(DISTFILES); do \
+ case $$i in */*) mkdir -p $(OUTDIR)/$(distdir)/$${i%/*}/ ;; esac; \
+ cp $$i $(OUTDIR)/$(distdir)/; \
+ done
+.PHONY: distdir
+
+dist: distdir
+ set -e; cd $(OUTDIR)/; tar chozf ../$(DISTTAR) $(distdir)
+ rm -rf $(distdir)
+.PHONY: dist
+
+###--------------------------------------------------------------------------
+### Finishing touches.
all:: $(TARGETS)
-ALLSOURCES += $(foreach t,$(TARGETS),$($t_SOURCES))
clean::; rm -f $(CLEANFILES) $(TARGETS)
-.PHONY: clean
--include $(call objects,$(ALLSOURCES),.d)
+repl: all
+ $(SCALA_REPL) -cp $(CLASSDIR) -Djava.library.path=$(OUTDIR)
+.PHONY: repl
+
+-include $(call objects,$(ALL_SOURCES),.d)
+
+###----- That's all, folks --------------------------------------------------