# Based on Guardian Project's tor-android repo. Copied from:
# https://github.com/guardianproject/tor-android/blob/7e6cffd6adc5b0d62b104029148bc42694761926/external/Makefile
# Copyright (c) 2009-2010, Nathan Freitas, The Guardian Project
# Licensed under 3-clause BSD license

EXTERNAL_ROOT := $(shell pwd)

DEBUG ?= 0

MAKE ?= make -j`nproc`

# Android now has 64-bit and 32-bit versions of the NDK for GNU/Linux.  We
# assume that the build platform uses the appropriate version, otherwise the
# user building this will have to manually set NDK_PROCESSOR or NDK_TOOLCHAIN.
CPU := $(shell uname -m)
ifeq ($(CPU),x86_64)
 NDK_PROCESSOR=x86_64
else
 NDK_PROCESSOR=x86
endif

ifeq ($(APP_ABI), )
 $(error APP_ABI must be set to an NDK-supported ABI/arch for this to run!)
endif

# matching NDK revisions are required for reproducible builds
NDK_REVISION := $(shell sed -n 's,^Pkg.Revision *= *\([^ ]*\),\1,p' $(ANDROID_NDK_HOME)/source.properties)
NDK_REQUIRED_REVISION := 21.4.7075529
MIN_NDK_VERSION := 19
ifeq ($(shell test $(MIN_NDK_VERSION) -gt $(firstword $(subst ., ,$(NDK_REVISION))); echo $$?),0)
 $(error NDK r$(MIN_NDK_VERSION) or newer required! r$(NDK_REVISION) is installed at $(ANDROID_NDK_HOME).)
endif
ifneq ($(NDK_REQUIRED_REVISION), $(NDK_REVISION))
 $(warning WARNING: NDK $(NDK_REQUIRED_REVISION) required for reproducible builds, $(NDK_REVISION) is installed.)
endif

ifneq ($(filter arm64-v8a, $(APP_ABI)),)
 HOST := aarch64-linux-android
 ALTHOST := $(HOST)
 GREP_CHECK := aarch64
 NDK_ABI := arm64
 NDK_BIT := 64
 NDK_PLATFORM_LEVEL := 21
 NDK_TOOLCHAIN := $(HOST)-$(NDK_TOOLCHAIN_VERSION)
endif
ifneq ($(filter armeabi-v7a, $(APP_ABI)),)
 HOST := armv7a-linux-androideabi
 ALTHOST := arm-linux-androideabi
 GREP_CHECK := EABI5
 NDK_ABI := arm
 NDK_BIT := 32
 NDK_PLATFORM_LEVEL := 18
 NDK_TOOLCHAIN := $(HOST)-$(NDK_TOOLCHAIN_VERSION)
endif
ifneq ($(filter x86, $(APP_ABI)),)
 HOST := i686-linux-android
 ALTHOST := $(HOST)
 GREP_CHECK := 80386
 NDK_ABI := x86
 NDK_BIT := 32
 NDK_PLATFORM_LEVEL := 18
 NDK_TOOLCHAIN := $(NDK_ABI)-$(NDK_TOOLCHAIN_VERSION)
endif
ifneq ($(filter x86_64, $(APP_ABI)),)
 HOST := x86_64-linux-android
 ALTHOST := $(HOST)
 GREP_CHECK := x86-64
 NDK_ABI := x86_64
 NDK_BIT := 64
 NDK_PLATFORM_LEVEL := 21
 NDK_TOOLCHAIN := $(NDK_ABI)-$(NDK_TOOLCHAIN_VERSION)
endif

NDK_SYSROOT=$(ANDROID_NDK_HOME)/platforms/android-$(NDK_PLATFORM_LEVEL)/arch-$(NDK_ABI)
NDK_UNAME := $(shell uname -s | tr '[A-Z]' '[a-z]')
NDK_TOOLCHAIN_BASE=$(ANDROID_NDK_HOME)/toolchains/llvm/prebuilt/$(NDK_UNAME)-$(NDK_PROCESSOR)

export CC := $(NDK_TOOLCHAIN_BASE)/bin/$(HOST)$(NDK_PLATFORM_LEVEL)-clang


export TZ := UTC
export LC_ALL := C.UTF-8
export SOURCE_DATE_EPOCH := 1234567890

REPRODUCIBLE_CFLAGS := \
  -fbuild-session-timestamp=$(SOURCE_DATE_EPOCH) \
  -fdebug-compilation-dir . \
  -no-canonical-prefixes \


ALL_CFLAGS := $(REPRODUCIBLE_CFLAGS) $(CFLAGS) -Os
export CFLAGS := $(ALL_CFLAGS)


OUTPUT_FILE := $(EXTERNAL_ROOT)/tor/src/app/tor
INSTALL_DIR := $(EXTERNAL_ROOT)/lib/$(APP_ABI)

.PHONY = clean showsetup \
	openssl-clean \
	libevent-clean \
	lzma-clean \
	tor tor-clean

all: test-setup tor

test-setup:
	test -d $(NDK_SYSROOT)
	test -x $(CC)
	printf 'int main() {return 0;}\n' > .test.c
	$(CC) $(CFLAGS) .test.c
	rm -f .test.c a.out


#------------------------------------------------------------------------------#
# openssl
#
# not all of openssl is needed, only the parts that Tor needs
# https://trac.torproject.org/projects/tor/ticket/32200
# https://gitweb.torproject.org/tor.git/tree/src/lib/tls/ciphers.inc
# https://wiki.openssl.org/index.php/Compilation_and_Installation

PATH := $(ANDROID_NDK_HOME)/toolchains/llvm/prebuilt/linux-x86_64/bin:$(PATH)


openssl/Makefile: openssl/Configure $(wildcard openssl/Configurations/*.*)
	cd openssl && PATH=$(PATH) \
		./Configure \
			no-comp no-dtls no-ec2m no-psk no-srp no-ssl2 no-ssl3 \
			no-camellia no-idea no-md2 no-md4 no-mdc2 no-rc2 no-rc4 no-rc5 no-rmd160 no-whirlpool \
			no-dso no-hw no-ui-console \
			no-shared no-unit-test \
			android-$(NDK_ABI) \
			-D__ANDROID_API__=$(NDK_PLATFORM_LEVEL) \
			--prefix=/ \
			--openssldir=/

openssl-build-stamp: openssl/Makefile
ifeq ($(V), 0)
	PATH=$(PATH) $(MAKE) --silent -C openssl install_dev DESTDIR=$(EXTERNAL_ROOT) ECHO=':'
else
	PATH=$(PATH) $(MAKE) -C openssl install_dev DESTDIR=$(EXTERNAL_ROOT)
endif
	touch $@

openssl-clean:
	-rm -f openssl-build-stamp
	-rm -f lib/libcrypto.a
	-rm -f lib/libssl.a
	-$(MAKE) -C openssl uninstall_dev > /dev/null
	-$(MAKE) -C openssl clean
	-cd openssl && \
		git clean -fdx > /dev/null


#------------------------------------------------------------------------------#
# libevent

libevent/Makefile: libevent/Makefile.am libevent/configure.ac
	cd libevent && ./autogen.sh
	cd libevent && ./configure \
				LDFLAGS="-L../lib" \
				CFLAGS="-I../include" \
				--host=$(ALTHOST) \
				--disable-libevent-regress \
				--disable-samples \
				--disable-shared \
					--prefix=/

libevent-build-stamp: openssl-build-stamp libevent/Makefile
	$(MAKE) -C libevent install DESTDIR=$(EXTERNAL_ROOT)
	touch $@

libevent-clean:
	-rm -f lib/libevent.a
	-rm -f libevent-build-stamp
	-$(MAKE) -C libevent uninstall DESTDIR=$(EXTERNAL_ROOT)
	-$(MAKE) -C libevent clean
	-cd libevent && \
		git clean -fdx > /dev/null


#------------------------------------------------------------------------------#
# lzma

xz/Makefile: xz/configure.ac xz/Makefile.am
	cd xz && ./autogen.sh
	cd xz && ./configure \
			--host=$(HOST) \
			--enable-static \
			--disable-doc \
			--disable-lzma-links \
			--disable-lzmadec \
			--disable-lzmainfo \
			--disable-scripts \
			--disable-shared \
			--disable-xz \
			--disable-xzdec \
			--prefix=/

lzma-build-stamp: xz/Makefile
	$(MAKE) -C xz install DESTDIR=$(EXTERNAL_ROOT)
	touch $@

lzma-clean:
	-$(MAKE) -C xz uninstall DESTDIR=$(EXTERNAL_ROOT)
	-$(MAKE) -C xz clean
	-rm -rf include/lzma
	-rm -f include/lzma.h
	-rm -f lib/liblzma.a
	-rm -f lib/liblzma.la
	-rm -f lzma-build-stamp
	-cd xz && \
		git clean -fdx > /dev/null

#------------------------------------------------------------------------------#
# tor

tor/Makefile: tor/configure.ac tor/Makefile.am
	@which pkg-config || (echo "ERROR: pkg-config is required! apt-get install pkg-config"; exit 1)
	cd tor && ./autogen.sh
	cd tor && \
			./configure \
				--host=$(ALTHOST) \
				--enable-android \
				--enable-lzma \
				--enable-pic \
				--enable-static-libevent --with-libevent-dir=$(EXTERNAL_ROOT) \
				--enable-static-openssl --with-openssl-dir=$(EXTERNAL_ROOT) \
				--disable-module-dirauth \
				--disable-module-relay \
				--disable-unittests \
				--disable-asciidoc \
				--disable-html-manual \
				--disable-manpage \
				--disable-system-torrc \
				--disable-tool-name-check \
				--disable-systemd \
				--prefix=$(EXTERNAL_ROOT)

tor-build-stamp: tor/Makefile
	$(MAKE) -C tor
	$(NDK_TOOLCHAIN_BASE)/bin/$(ALTHOST)-strip -D $(OUTPUT_FILE)
	touch $@

tor: lzma-build-stamp libevent-build-stamp openssl-build-stamp tor-build-stamp

tor-clean:
	-rm -f $(OUTPUT_FILE)
	-rm -f tor-build-stamp
	-cd tor && \
		git clean -fdx > /dev/null


#------------------------------------------------------------------------------#
# cleanup, cleanup, put the toys away

clean: openssl-clean libevent-clean lzma-clean tor-clean


#------------------------------------------------------------------------------#
# debugging stuff

showsetup:
	@echo "ALL_CFLAGS: $(ALL_CFLAGS)"
	@echo "APP_ABI: $(APP_ABI)"
	@echo "CC: $$CC"
	@echo "CFLAGS: $$CFLAGS"
	@echo "HOST: $(HOST)"
	@echo "NDK_ABI: $(NDK_ABI)"
	@echo "NDK_BIT: $(NDK_BIT)"
	@echo "NDK_PLATFORM_LEVEL: $(NDK_PLATFORM_LEVEL)"
	@echo "NDK_SYSROOT: $(NDK_SYSROOT)"
	@echo "NDK_TOOLCHAIN: $(NDK_TOOLCHAIN)"
	@echo "PATH: $$PATH"
	@echo "REPRODUCIBLE_CFLAGS: $(REPRODUCIBLE_CFLAGS)"
	@echo "SOURCE_DATE_EPOCH: $$SOURCE_DATE_EPOCH"
	@echo "TZ: $$TZ"
