CC = cc
CXX = c++
FETCH = curl -fsSL --retry 5 -o

.PHONY: clean

clean:
	rm -rf bin/ build/ include/ lib/ share/ *.done

UNAME_S := $(shell uname -s)
UNAME_M := $(shell uname -m)

ifeq ($(UNAME_S),Darwin)
SHA256_CHECK = shasum -a 256 -c -
else
SHA256_CHECK = sha256sum -c -
endif

ifeq ($(UNAME_S),Darwin)
GC_SECTIONS_LDFLAG = -Wl,-dead_strip
else
GC_SECTIONS_LDFLAG = -Wl,--gc-sections
endif

ifeq ($(UNAME_S),Linux)
FORM_LIBS = -pthread
else
FORM_LIBS =
endif

ifeq ($(UNAME_S)-$(UNAME_M),Darwin-x86_64)
GMP_CONFIGURE_FLAGS = --with-pic
FLINT_CONFIGURE_FLAGS = --disable-gmp-internals --disable-mpfr-check
else
GMP_CONFIGURE_FLAGS =
FLINT_CONFIGURE_FLAGS =
endif

DIR = ${CURDIR}
DEP_CFLAGS = -I${DIR}/include -O3 -fno-omit-frame-pointer -fdata-sections -ffunction-sections ${CFLAGS}
DEP_FFLAGS = -I${DIR}/include -O3 ${FFLAGS}
DEP_LDFLAGS = -L${DIR}/lib ${GC_SECTIONS_LDFLAG} ${LDFLAGS}

MAKEOVERRIDES =

build/.dir:
	mkdir -p bin build include lib share
	date >$@

## GMP

VER_gmp = 6.3.0
SHA256_gmp = a3c2b80201b89e68616f4ad30bc66aee4927c3ce50e33929ca819d5c43538898

build/gmp-${VER_gmp}.tar.xz: build/.dir
	rm -f build/gmp*.tar.xz
	${FETCH} $@ "https://ftpmirror.gnu.org/gmp/gmp-${VER_gmp}.tar.xz" \
		|| ${FETCH} $@ "https://ftp.gnu.org/gnu/gmp/gmp-${VER_gmp}.tar.xz" \
		|| ${FETCH} $@ "https://gmplib.org/download/gmp/gmp-${VER_gmp}.tar.xz" \
		|| { rm -f $@; exit 1; }
	{ echo "${SHA256_gmp}  $@" | ${SHA256_CHECK}; } || { rm -f $@; exit 1; }

gmp.done: build/gmp-${VER_gmp}.tar.xz
	rm -rf build/gmp-*/
	cd build && tar xf gmp-${VER_gmp}.tar.xz
	cd build/gmp-*/ && mv configfsf.guess config.guess
	cd build/gmp-*/ && \
		env CC="${CC}" CXX="${CXX}" CFLAGS="-std=c11 ${DEP_CFLAGS}" CXXFLAGS="${DEP_CFLAGS}" LDFLAGS="${DEP_LDFLAGS}" \
		./configure \
		--prefix="${DIR}" --libdir="${DIR}/lib" \
		--includedir="${DIR}/include" --bindir="${DIR}/bin" \
		--enable-static --disable-shared --enable-cxx \
		${GMP_CONFIGURE_FLAGS}
	+${MAKE} -C build/gmp-*/
	+${MAKE} -C build/gmp-*/ install
	date >$@

## MPFR

VER_mpfr = 4.2.2
SHA256_mpfr = b67ba0383ef7e8a8563734e2e889ef5ec3c3b898a01d00fa0a6869ad81c6ce01

build/mpfr-${VER_mpfr}.tar.xz: build/.dir
	rm -f build/mpfr*.tar.xz
	${FETCH} $@ "https://ftpmirror.gnu.org/mpfr/mpfr-${VER_mpfr}.tar.xz" \
		|| ${FETCH} $@ "https://ftp.gnu.org/gnu/mpfr/mpfr-${VER_mpfr}.tar.xz" \
		|| ${FETCH} $@ "https://www.mpfr.org/mpfr-${VER_mpfr}/mpfr-${VER_mpfr}.tar.xz" \
		|| { rm -f $@; exit 1; }
	{ echo "${SHA256_mpfr}  $@" | ${SHA256_CHECK}; } || { rm -f $@; exit 1; }

mpfr.done: build/mpfr-${VER_mpfr}.tar.xz gmp.done
	rm -rf build/mpfr-*/
	cd build && tar xf mpfr-${VER_mpfr}.tar.xz
	cd build/mpfr-*/ && \
		env CC="${CC}" CXX="${CXX}" CFLAGS="${DEP_CFLAGS}" CXXFLAGS="${DEP_CFLAGS}" LDFLAGS="${DEP_LDFLAGS}" \
		./configure \
		--prefix="${DIR}" --libdir="${DIR}/lib" \
		--includedir="${DIR}/include" --bindir="${DIR}/bin" \
		--enable-static --disable-shared --enable-thread-safe \
		--with-gmp="${DIR}"
	+${MAKE} -C build/mpfr-*/
	+${MAKE} -C build/mpfr-*/ install
	date >$@

## Flint

VER_flint = 3.6.0
SHA256_flint = b95e2c7792f5eea4a1c8d2d42c4098434756832e57a094b295eb5dfdc9b4c36b

build/flint-${VER_flint}.tar.gz: build/.dir
	rm -f build/flint*.tar.gz
	${FETCH} $@ "https://flintlib.org/download/flint-${VER_flint}.tar.gz" \
		|| ${FETCH} $@ "https://github.com/flintlib/flint/releases/download/v${VER_flint}/flint-${VER_flint}.tar.gz" \
		|| { rm -f $@; exit 1; }
	{ echo "${SHA256_flint}  $@" | ${SHA256_CHECK}; } || { rm -f $@; exit 1; }

flint.done: build/flint-${VER_flint}.tar.gz gmp.done mpfr.done
	rm -rf build/flint-*/
	cd build && tar xf flint-${VER_flint}.tar.gz
	cd build/flint-*/ && mv config/configfsf.guess config/config.guess
	cd build/flint-*/ && \
		./configure \
		--prefix="${DIR}" --enable-static --disable-shared \
		CC="${CC}" CXX="${CXX}" CFLAGS="${DEP_CFLAGS} -Wno-deprecated-declarations -Wmissing-prototypes -Wno-stringop-overflow -Wno-stringop-overread -Werror=implicit-function-declaration -Wall -std=c11 -pedantic -O3" \
		${FLINT_CONFIGURE_FLAGS} \
		--with-gmp="${DIR}" \
		--with-mpfr="${DIR}"
	+${MAKE} -C build/flint-*/ V=1
	+${MAKE} -C build/flint-*/ install
	date >$@

## zlib

VER_zlib = 1.3.2
SHA256_zlib = bb329a0a2cd0274d05519d61c667c062e06990d72e125ee2dfa8de64f0119d16

build/zlib-${VER_zlib}.tar.gz: build/.dir
	rm -f build/zlib*.tar.gz
	${FETCH} $@ "https://zlib.net/fossils/zlib-${VER_zlib}.tar.gz" \
		|| ${FETCH} $@ "https://github.com/madler/zlib/releases/download/v${VER_zlib}/zlib-${VER_zlib}.tar.gz" \
		|| { rm -f $@; exit 1; }
	{ echo "${SHA256_zlib}  $@" | ${SHA256_CHECK}; } || { rm -f $@; exit 1; }

zlib.done: build/zlib-${VER_zlib}.tar.gz
	rm -rf build/zlib-*/
	cd build && tar xf zlib-${VER_zlib}.tar.gz
	cd build/zlib-*/ && \
		env CC="${CC}" CXX="${CXX}" CFLAGS="${DEP_CFLAGS}" \
		./configure \
		--prefix="${DIR}" --static
	+${MAKE} -C build/zlib-*/
	+${MAKE} -C build/zlib-*/ install
	date >$@

## FORM

VER_form = 5.0.0
SHA256_form = 10d22acf2f0acf831b494e6a73682828980b9054ea8ec2b5dc46677dca8d6518

build/form-${VER_form}.tar.gz: build/.dir
	rm -f build/form*.tar.gz
	${FETCH} $@ "https://github.com/form-dev/form/releases/download/v${VER_form}/form-${VER_form}.tar.gz" \
		|| { rm -f $@; exit 1; }
	{ echo "${SHA256_form}  $@" | ${SHA256_CHECK}; } || { rm -f $@; exit 1; }

form.done: build/form-${VER_form}.tar.gz flint.done gmp.done mpfr.done zlib.done zstd.done
	rm -rf build/form-*/
	cd build && tar xf form-${VER_form}.tar.gz
	cd build/form-*/ && \
		env CC="${CC}" CXX="${CXX}" CFLAGS="${DEP_CFLAGS} -g" CXXFLAGS="${DEP_CFLAGS} -g" LDFLAGS="${DEP_LDFLAGS}" LIBS="${FORM_LIBS}" \
		./configure \
		--prefix="${DIR}" --libdir="${DIR}/lib" \
		--includedir="${DIR}/include" --bindir="${DIR}/bin" \
		--enable-scalar=yes \
		--enable-threaded=yes \
		--enable-debug=no \
		--enable-parform=no \
		--enable-float=yes \
		--enable-static-link=no \
		--enable-native=no \
		--with-flint="${DIR}" \
		--with-gmp="${DIR}" \
		--with-mpfr="${DIR}" \
		--with-zlib="${DIR}" \
		--with-zstd="${DIR}"
	+${MAKE} -C build/form-*/
	+${MAKE} -C build/form-*/ install
	date >$@

## Zstd

VER_zstd = 1.5.7
SHA256_zstd = eb33e51f49a15e023950cd7825ca74a4a2b43db8354825ac24fc1b7ee09e6fa3

build/zstd-${VER_zstd}.tar.gz: build/.dir
	rm -f build/zstd*.tar.gz
	${FETCH} $@ "https://github.com/facebook/zstd/releases/download/v${VER_zstd}/zstd-${VER_zstd}.tar.gz" \
		|| { rm -f $@; exit 1; }
	{ echo "${SHA256_zstd}  $@" | ${SHA256_CHECK}; } || { rm -f $@; exit 1; }

zstd.done: build/zstd-${VER_zstd}.tar.gz zlib.done
	rm -rf build/zstd-*/
	cd build && tar xf zstd-${VER_zstd}.tar.gz
	@# build libzstd.a, libastd_zlibwrapper.a, and zstd
	+${MAKE} -C build/zstd-*/lib/ CC=${CC} CXX=${CXX} CFLAGS="${DEP_CFLAGS}" LDFLAGS="${DEP_LDFLAGS}" VERBOSE=1 libzstd.a-release-nomt
	+${MAKE} -C build/zstd-*/programs/ CC=${CC} CXX=${CXX} CFLAGS="${DEP_CFLAGS}" LDFLAGS="${DEP_LDFLAGS}" VERBOSE=1 HAVE_ZLIB=no HAVE_LZMA=no HAVE_LZ4=no zstd-nomt
	+${MAKE} -C build/zstd-*/zlibWrapper/ CC=${CC} CXX=${CXX} CFLAGS="${DEP_CFLAGS} -DZWRAP_USE_ZSTD=1" LDFLAGS="${DEP_LDFLAGS}" VERBOSE=1 zstd_zlibwrapper.o gzclose.o gzlib.o gzread.o gzwrite.o
	cd build/zstd-*/zlibWrapper/ && ${AR} rcs libzstd_zlibwrapper.a zstd_zlibwrapper.o gzclose.o gzlib.o gzread.o gzwrite.o
	@# install libzstd.a, libastd_zlibwrapper.a, zstd*.h, and zstd
	+${MAKE} -C build/zstd-*/lib/ PREFIX="${DIR}" VERBOSE=1 install-static install-includes
	+${MAKE} -C build/zstd-*/programs/ PREFIX="${DIR}" VERBOSE=1 install
	cd build/zstd-*/zlibWrapper/ && cp -a libzstd_zlibwrapper.a "${DIR}/lib/"
	cd build/zstd-*/zlibWrapper/ && cp -a zstd_zlibwrapper.h "${DIR}/include/"
	date >$@

## License files

LICENSE_STAMP_DIR = build/stamps/licenses

LICENSE_STAMPS = \
	${LICENSE_STAMP_DIR}/LICENSES_bundled.done \
	${LICENSE_STAMP_DIR}/form.done \
	${LICENSE_STAMP_DIR}/gmp.done \
	${LICENSE_STAMP_DIR}/mpfr.done \
	${LICENSE_STAMP_DIR}/flint.done \
	${LICENSE_STAMP_DIR}/zlib.done \
	${LICENSE_STAMP_DIR}/zstd.done

licenses.done: ${LICENSE_STAMPS}
	date >$@

${LICENSE_STAMP_DIR}/LICENSES_bundled.done: LICENSES_bundled.txt
	mkdir -p ${@D} build/licenses
	cp LICENSES_bundled.txt build/licenses/
	date >$@

${LICENSE_STAMP_DIR}/form.done: build/form-${VER_form}.tar.gz
	mkdir -p ${@D} build/licenses/form
	tar -xf $< -C build/licenses/form --strip-components=1 form-${VER_form}/COPYING
	date >$@

${LICENSE_STAMP_DIR}/gmp.done: build/gmp-${VER_gmp}.tar.xz
	mkdir -p ${@D} build/licenses/gmp
	tar -xf $< -C build/licenses/gmp --strip-components=1 gmp-${VER_gmp}/COPYINGv3 gmp-${VER_gmp}/COPYING.LESSERv3
	date >$@

${LICENSE_STAMP_DIR}/mpfr.done: build/mpfr-${VER_mpfr}.tar.xz
	mkdir -p ${@D} build/licenses/mpfr
	tar -xf $< -C build/licenses/mpfr --strip-components=1 mpfr-${VER_mpfr}/COPYING mpfr-${VER_mpfr}/COPYING.LESSER
	date >$@

${LICENSE_STAMP_DIR}/flint.done: build/flint-${VER_flint}.tar.gz
	mkdir -p ${@D} build/licenses/flint
	tar -xf $< -C build/licenses/flint --strip-components=1 flint-${VER_flint}/COPYING flint-${VER_flint}/COPYING.LESSER
	date >$@

${LICENSE_STAMP_DIR}/zlib.done: build/zlib-${VER_zlib}.tar.gz
	mkdir -p ${@D} build/licenses/zlib
	tar -xf $< -C build/licenses/zlib --strip-components=1 zlib-${VER_zlib}/LICENSE
	date >$@

${LICENSE_STAMP_DIR}/zstd.done: build/zstd-${VER_zstd}.tar.gz
	mkdir -p ${@D} build/licenses/zstd
	tar -xf $< -C build/licenses/zstd --strip-components=1 zstd-${VER_zstd}/LICENSE
	date >$@
