# Myer makefile                             -*- coding: latin-1 -*-
#
# 2003 by Jonathan Yavner <jyavner@member.fsf.org>
# GPL license; see file COPYING for details.
#

# This is where you've put your development copy of gcc
GCC_BUILD=/usr/local/src/gcc-3.2

# This is where your gcc system files are.  Change this if you want to
# install Myer and get rid of the GCC_BUILD directory.
GCC_INSTALL=${GCC_BUILD}/gcc
#GCC_INSTALL=/usr/lib/gcc-lib/i386-redhat-linux/3.2

# Change this if your installed compiler is not gcc-3
CC=gcc
#CC=${GCC_BUILD}/gcc/xgcc

# Myer stuff
MYER_OBJECTS = myer.o myertoken.o myermerge.o myersum.o myercalc.o myerhtml.o myerenv.o

DEBUG=-g
#OPT = -O2

CFLAGS=${DEBUG} ${OPT} -std=gnu99 -Werror -W -Wall -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations -I${GCC_BUILD}/include

all: myer gcc_patch/cc1 myer_cc1

myer: ${MYER_OBJECTS} ${GCC_BUILD}/libiberty/libiberty.a
	${CC} ${DEBUG} -o $@ ${MYER_OBJECTS} -lm ${GCC_BUILD}/libiberty/libiberty.a

${MYER_OBJECTS}: myer.h

myer.o: CFLAGS += -DGCC_INSTALL=\"${GCC_INSTALL}/\"

myerhtml.o: myerhtml.h

# Standard command-line #defines for this host system
myerenv.c:
	${CC} ${CFLAGS} --verbose -E -o /dev/null myer.c 2>&1 \
	| fgrep cpp0 \
	| tr ' ' '\012' \
	| grep -- "^-D" \
	> myerenv.def
	echo "/* Generated file */" >$@
	echo "int myerenv_count = "`wc -l myerenv.def | cut -c1-7`";" >>$@
	echo "char *myerenv_list[] = {" >>$@
	sed 's/.*/"&",/' <myerenv.def >>$@
	echo "};" >>$@

myer_cc1:
	ln -s gcc_patch/cc1 myer_cc1

# Use the $(wildcard) operator to postpone checking the gcc_patch directory
# until after it is constructed by the next rule.
gcc_patch/cc1: gcc_patch myerparse.c $(wildcard gcc_patch/*.[ch])
	cd gcc_patch && make cc1

PATCH_FILES = $(shell \
	grep "^diff " gcc-3.2.patch \
	| sed -e "s|diff \(-[^ ]* \)*[^ ]* \./||")

# Create the gcc_patch directory, populate it with soft-links to the GCC
# base, except copy the files that will be patched.  Make the patched
# "system.h" be really old to avoid recompiling everything.
gcc_patch:
	rm -f include libiberty
	ln -s ${GCC_BUILD}/include .
	ln -s ${GCC_BUILD}/libiberty .
	mkdir $@
	ln -s ../myerparse.c gcc_patch
	ln -s ../myerparse.h gcc_patch
	(cd $@; \
	for x in ${GCC_BUILD}/gcc/*; do \
		ln -s $$x .; \
	done; \
	rm -f $(PATCH_FILES) $(PATCH_FILES:%=%.o) cc1; \
	cp $(PATCH_FILES:%=${GCC_BUILD}/gcc/%) .; \
	patch <../gcc-3.2.patch; \
	touch -t 199912312359 system.h )


# Create the example directory that README-commentary is talking about.
# Note: This rule expectedly prints lots of "No information about" messages,
# about every header in /usr/include that is not referenced by Myer.
Example_myer: myer
	rm -f *.o *.myer2
	make CC=./myer ${MYER_OBJECTS}
	./myer -o $@/ *.myer2 *.h include/*.h /usr/include/*.h

# Example of Myer output: the gcc compiler.  You'll need >180 MB of RAM+swap
# to run this phase.
Example_gcc: gcc_forexample/gcc.myer3
	./myer -v -o $@/ gcc_forexample/gcc.myer3

# Combine the analyses for each gcc file.  This rule expectedly prints lots
# of "No information about" and "File does not have same contents" messages.
# Needs >240 MB of RAM+swap!
gcc_forexample/gcc.myer3: gcc_forexample/gcc.myer2
	./myer -v -P3 -o $@ gcc_forexample/*.myer2 gcc_forexample/*.h

# Build all the .myer2 files for gcc.  We need "make -k" because the 'ar'
# commands will fail.  We delete the empty files c-common.myer2 and
# timevar.myer2 because the corresponding .c files use #include inside a
# function body, which Myer currently doesn't support.  We delete erroneous
# file tradcif.myer2, which uses a macro YYSTACK_ALLOC to select the name of
# another macro (assert) that takes arguments.
gcc_forexample/gcc.myer2: myer gcc_forexample/gcc.c
	(cd gcc_forexample; \
	make -k CC=../myer; \
	rm c-common.myer2 timevar.myer2 tradcif.myer2)

# Create the temp directory containing a copy of gcc, minus the .o files (so
# make will run Myer trying to recreate them).
gcc_forexample/gcc.c: gcc_patch
	rm -rf gcc_forexample
	mkdir -p gcc_forexample
	(cd gcc_patch; \
	 find . ! -name '*.o' -print | cpio -padm ../gcc_forexample)

# Maintainers: create a new tar archive for Myer
tar:
	tar zcvfh myer-`date --iso-8601`.tgz COPYING Makefile *.patch \
	    *.c *.h *.html README-commentary

# Maintainers: Create a new patch file
gcc-new.patch::
	-(cd gcc_patch \
	    && diff -ur --exclude="c-parse.[cy]" \
			--exclude="libgcc.mk" \
		    ${GCC_BUILD}/gcc . ) \
	  > $@

clean:
	rm -rf myer myer_cc1 myerenv.c myerenv.def *.o *.myer? \
		include libiberty gcc_patch gcc_forexample \
		Example_gcc Example_myer Myer myer_Myer
