## Makefile for installing the JSR 308 compiler and the Checker Framework.
# This automates the instructions that are found in the manuals, available
# from http://groups.csail.mit.edu/pag/jsr308/ .

## 3 steps to install:
# 1. Obtain this Makefile:
#   cd
#   wget -nv -N http://groups.csail.mit.edu/pag/jsr308/current/Makefile-jsr308-install
# 2. Execute the following command, which installs the "langtools" and
# "checkers" directories into JSR308_DIR (by default, ~/jsr308).
#   make -f Makefile-jsr308-install
# 3. In your shell startup file (such as ~/.bashrc), set the environment
# variables JAVA_HOME, PATH, and CLASSPATH; see the lines below that set them.
# Setting these variables will make the JSR 308 compiler your default javac;
# if you do not wish to do so, then just set the appropriate variables when
# you wish to use the JSR 308 compiler (e.g., in buildfiles and makefiles).


## Notes:
#  * This has only been tested on Linux.
#  * You should only run this script if you agree to the Sun Java SE
#    Development Kit (JDK) license.
#  * If the installation fails, please report the problem to
#     jsr308-bugs@lists.csail.mit.edu .
#    Then, follow the detailed installation instructions at
#      http://groups.csail.mit.edu/pag/jsr308/current/README-jsr308.html#installing
#      http://groups.csail.mit.edu/pag/jsr308/current/checkers-manual.html#installation
#  * Except for the default target, this Makefile should be run in
#    #${JSR308_DIR}, which defaults to ~/jsr308 .


###########################################################################
### Variables
###

## You may override these settings at the shell, e.g.:
##   export JSR308_DIR=${HOME}/jsr308

# The directory containing this file, Makefile-jsr308-install
MAKEFILE_DIR ?= ${HOME}
# The directory that will contain the "langtools" and "checkers" directories.
JSR308_DIR ?= ${HOME}/jsr308


###
### You should not need to set any variables below this line.
### (But you may override these settings in your own personalization dotfiles.)
###

# Override to obtain a development release or a test release.
JSR308_WEB ?= http://groups.csail.mit.edu/pag/jsr308/current
JSR308_BUILD := 0.7.8

# export MAKEFILE_DIR
export JSR308_DIR

export JDK_7_BIN := jdk-7-ea-bin-b35-linux-i586-11_sep_2008.bin
export MAKEFILE := ${MAKEFILE_DIR}/Makefile-jsr308-install

export JAVA_HOME := ${JSR308_DIR}/jdk1.7.0
export PATH := ${JAVA_HOME}/bin:${PATH}

export CLASSPATH := ${CLASSPATH}:${JSR308_DIR}/jdk1.7.0/lib/tools.jar:${JSR308_DIR}/checkers/checkers.jar


###########################################################################
### Rules
###


.PHONY : chdir_then_install
chdir_then_install : ${JSR308_DIR}
	$(MAKE) -C ${JSR308_DIR} -f ${MAKEFILE} install

# By default, do all downloads before any installation.
install: download .install-jdk1.7.0 test-jdk1.7.0 .install-langtools .install-checkers test-checkers

${JSR308_DIR}:
	mkdir -p ${JSR308_DIR}

###
### Cleaning up
###

.PHONY : clean
clean: clean-checkers clean-langtools 
veryclean: clean-checkers clean-langtools clean-jdk1.7.0

.PHONY : clean-checkers
clean-checkers:
	rm -rf jsr308-checkers.zip checkers .install-checkers

.PHONY : clean-langtools
clean-langtools:
	rm -rf jsr308-langtools.zip langtools .install-langtools

.PHONY : clean-jdk1.7.0
clean-jdk1.7.0:
	rm -rf jdk1.7.0 .install-jdk1.7.0

###
### Downloading
###

download: download-jdk1.7.0 download-jsr308-langtools download-jsr308-checkers

${JDK_7_BIN}:
	$(MAKE) -f ${MAKEFILE} download-jdk1.7.0
.PHONY : download-jdk1.7.0
download-jdk1.7.0:
	wget -nv -N http://www.java.net/download/jdk7/binaries/${JDK_7_BIN}

jsr308-langtools.zip:
	$(MAKE) -f ${MAKEFILE} download-jsr308-langtools
.PHONY : download-jsr308-langtools
download-jsr308-langtools:
	wget -nv -N ${JSR308_WEB}/jsr308-langtools.zip

jsr308-checkers.zip:
	$(MAKE) -f ${MAKEFILE} download-jsr308-checkers
.PHONY : download-jsr308-checkers
download-jsr308-checkers:
	wget -nv -N ${JSR308_WEB}/jsr308-checkers.zip


###
### Installation and testing
###

# Executing the binary creates a directory with an older date than the binary.
jdk1.7.0:
	$(MAKE) -f ${MAKEFILE} .install-jdk1.7.0
.install-jdk1.7.0: ${JDK_7_BIN}
	chmod +x ${JDK_7_BIN}
	yes | MORE='-1000 -l' ./${JDK_7_BIN}
	touch .install-jdk1.7.0

test-jdk1.7.0:
	@echo javac version: `javac -version 2>&1`
# The output should start with "javac 1.7.0"
	javac -version 2>&1 | grep 'javac 1.7.0'

langtools:
	$(MAKE) -f ${MAKEFILE} .install-langtools
.install-langtools: jsr308-langtools.zip
	$(MAKE) -f ${MAKEFILE} test-jdk1.7.0
	unzip -q -o jsr308-langtools.zip
	cd langtools/binary && yes | ant install
	touch .install-langtools

test-langtools:
	@echo javac version: `javac -version 2>&1`
	/usr/bin/test "`javac -version 2>&1`" = "javac 1.7.0-jsr308-${JSR308_BUILD}"

checkers:
	$(MAKE) -f ${MAKEFILE} .install-checkers
.install-checkers: jsr308-checkers.zip
	$(MAKE) -f ${MAKEFILE} test-langtools
	unzip -q -o jsr308-checkers.zip
#	perl -pi -e 's/^(compiler.lib=.*)$/\# \1\ncompiler.lib=..\/langtools\/binary\/javac.jar/g' checkers/build.properties
	touch .install-checkers

test-checkers:
	cd checkers && ant all-tests
	cd checkers && javac -typeprocessor checkers.nullness.NullnessChecker examples/NullnessExample.java
	@echo "The following command is expected to issue warnings."
	-cd checkers && javac -typeprocessor checkers.nullness.NullnessChecker examples/NullnessExampleWithWarnings.java
	@echo "The previous command was expected to issue warnings."

###
### Additional tests (most users shouldn't have to run these)
###

## Todo:  check that the compiler processes Daikon and FreePastry.