# Makefile for the GAP package GUAVA.
#
# Generated from Makefile.in by ./configure; requires GNU make.
# All executables are put into $(BINDIR).

GAPPATH = /usr/lib64/gap
GAPARCH = x86_64-suse-linux-gnu-default64-kv11
GAP ?= $(GAPPATH)/gap
GAP_ARGS = -q --quitonbreak --packagedirs $(abspath .)

LEONDIR = src/leon/src
CJDIR   = src/ctjhai
OBJDIR  = obj
BINDIR  = bin/$(GAPARCH)

CC ?= gcc
CFLAGS ?= -O2 -g

EXTRA_CFLAGS += -Wall
# Leon's code is from the early 1990s and warns about style throughout;
# silence the categories that say nothing about correctness.
EXTRA_CFLAGS += -Wno-char-subscripts -Wno-unused-variable \
	-Wno-unused-but-set-variable -Wno-unused-function

ALL_CFLAGS = $(CFLAGS) $(EXTRA_CFLAGS) -MMD -MP

#
# Leon's 13 programs, plus the two others. The GAP code runs desauto,
# leonconv, minimum-weight and wtdist; the rest are usable standalone.
#
LEON_PROGS = cent cjrndper commut compgrp desauto fndelt generate inter \
	orbdes orblist randobj setstab wtdist
PROGS = $(LEON_PROGS) leonconv minimum-weight

# cputime.c is an alternative timer for machines whose clock() is unusable.
# It needs a TICK its headers never define, and group.h falls back to clock(),
# so no build has ever compiled it.
LEON_SRCS = $(filter-out $(LEONDIR)/cputime.c,$(wildcard $(LEONDIR)/*.c))

# every Leon source without a main() belongs to the library the programs share
LEON_OBJS = $(patsubst $(LEONDIR)/%.c,$(OBJDIR)/leon/%.o,$(LEON_SRCS))
LEON_LIBOBJS = $(filter-out $(patsubst %,$(OBJDIR)/leon/%.o,$(LEON_PROGS)),$(LEON_OBJS))
CJ_OBJS = $(patsubst $(CJDIR)/%.c,$(OBJDIR)/ctjhai/%.o,$(wildcard $(CJDIR)/*.c))

all: $(addprefix $(BINDIR)/,$(PROGS))

#
# how to build them
#
$(addprefix $(BINDIR)/,$(LEON_PROGS)): $(BINDIR)/%: $(OBJDIR)/leon/%.o $(OBJDIR)/libleon.a | $(BINDIR)
	$(CC) $(EXTRA_CFLAGS) $(LDFLAGS) -o $@ $^

$(BINDIR)/minimum-weight: $(CJ_OBJS) | $(BINDIR)
	$(CC) $(EXTRA_CFLAGS) $(LDFLAGS) -o $@ $^ -lm

$(BINDIR)/leonconv: $(OBJDIR)/leonconv.o | $(BINDIR)
	$(CC) $(EXTRA_CFLAGS) $(LDFLAGS) -o $@ $^

$(OBJDIR)/libleon.a: $(LEON_LIBOBJS)
	$(AR) cr $@ $^
	if which ranlib > /dev/null 2> /dev/null; then ranlib $@; fi

# minimum-weight is a brute-force search over codewords, so keep the -O3
# the old build system gave it
$(CJ_OBJS): EXTRA_CFLAGS += -O3

$(OBJDIR)/leon/%.o: $(LEONDIR)/%.c | $(OBJDIR)/leon
	$(CC) $(ALL_CFLAGS) -c -o $@ $<

$(OBJDIR)/ctjhai/%.o: $(CJDIR)/%.c | $(OBJDIR)/ctjhai
	$(CC) $(ALL_CFLAGS) -I$(CJDIR) -c -o $@ $<

$(OBJDIR)/%.o: src/%.c | $(OBJDIR)
	$(CC) $(ALL_CFLAGS) -c -o $@ $<

$(BINDIR) $(OBJDIR) $(OBJDIR)/leon $(OBJDIR)/ctjhai:
	mkdir -p $@

-include $(wildcard $(OBJDIR)/*.d $(OBJDIR)/*/*.d)

#
# other targets
#
doc:
	$(GAP) $(GAP_ARGS) makedoc.g

html:
	NOPDF=1 $(GAP) $(GAP_ARGS) makedoc.g

check test:
	$(GAP) $(GAP_ARGS) tst/testall.g

run:
	$(GAP) $(GAP_ARGS) -c 'LoadPackage("guava");'

# exercises minimum-weight on inputs the GAP code never produces: a code
# longer than the 16-bit types it used to count with, and malformed files
check-programs: all
	@set -e; tmp=`mktemp -d`; trap "rm -rf $$tmp" EXIT; \
	awk 'BEGIN { n = 65536; printf "3 %d 2\n", n+3; \
	             for (r = 1; r <= 3; r++) { \
	                 for (i = 1; i <= n; i++) printf "1 "; \
	                 for (i = 1; i <= 3; i++) printf "%d ", (i == r); \
	                 printf "\n" } }' > $$tmp/long; \
	echo "== a [65539,3] code, minimum weight 2"; \
	$(BINDIR)/minimum-weight $$tmp/long | grep -q '^Minimum weight: 2$$'; \
	echo "== malformed input is rejected, not crashed on"; \
	printf 'garbage\n'   > $$tmp/bad;   ! $(BINDIR)/minimum-weight $$tmp/bad;   \
	printf '0 10 2\n'    > $$tmp/zero;  ! $(BINDIR)/minimum-weight $$tmp/zero;  \
	printf '2 5 2\n1 0 1\n' > $$tmp/trunc; ! $(BINDIR)/minimum-weight $$tmp/trunc; \
	echo "== ok"

clean:
	rm -rf $(OBJDIR)

distclean: clean
	rm -rf bin
	rm -f Makefile

Makefile: configure Makefile.in $(GAPPATH)/sysinfo.gap
	./configure $(GAPPATH)

.PHONY: all check check-programs test clean distclean doc html run
