# Vona's super-ninja makefile (mostly for Java)
#
# *** DO NOT EDIT THIS FILE EXCEPT IN THE PROJECT HOME DIRECTORY ***
#
# This makefile is auto-generated by "make makefiles" in the parent package
#
# You should edit makefile.project, which is included below, to specify
# project-specific settings.
#
# You should edit makefile.package, which is also included below, to specify
# package-specific targets and variables.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the Free
# Software Foundation; either version 2 of the License, or (at your option)
# any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc., 59
# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# Copyright (c) 2014 Marsette A. Vona
# make setup ###################################################################
SHELL = /bin/bash
# platform
PLATFORM := $(shell uname -s | tr " " "_"; echo " "; uname -m | tr " " "_")
SYSTEM := $(firstword $(PLATFORM))
MACHINE := $(lastword $(PLATFORM))
PLATFORM := $(SYSTEM)_$(MACHINE)
# to show commands use "make VERBOSE=1 ..."
ifeq ("$(VERBOSE)","1")
Q :=
else
Q := @
endif
# these let $(COMMA) and $(SPACE) be lone arguments to make function calls
COMMA := ,
EMPTY :=
SPACE := $(EMPTY) $(EMPTY)
# whitespace regex
WS = [ \t]*
ifneq ($(findstring CYGWIN,$(SYSTEM)),CYGWIN)
# make cd .. follow the Physical directory structure on Unix
CD = cd -P
else
CD = cd
# always use bash on cygwin, sh doesn't have pushd, but bash slows things down
SHELL = `which bash`
endif
# command to run make without generating any extraneous output
MAKE_NPD = $(MAKE) $(if $(Q),--no-print-directory)
MAKE_SILENT = $(MAKE_NPD) $(if $(Q),--silent)
# the default target
default: package
# prevent make from always trying to remake makefiles
makefile.package makefile.project makefile: ;
# use this target as a prereq to force another target
.PHONY: FORCE
FORCE:
.PHONY: nothing
nothing: ;
# Relative path to the directory containing the root package for the project.
# For generated makefiles (in every directory other than $(PROJECT_HOME)) this
# is automatically set by "make makefiles"
PROJECT_HOME = .
# The full name of this package. For generated makefiles (in every directory
# other than $(PROJECT_HOME)) this is automatically set by "make makefiles"
PACKAGE = $(BASE_PACKAGE)
# compute short package name from fullname
PACKAGE_NAME = $(subst .,,$(suffix .$(PACKAGE)))
# compute project name (root package name) from package fullname
PROJECT = $(firstword $(subst ., ,$(PACKAGE)))
# compute the package path from the package full name
# $(PROJECT_HOME)/../$(PACKAGE_PATH) is a path to this package
PACKAGE_PATH = $(call package-to-path,$(PACKAGE))
# is this the project root package?
ifeq ($(PROJECT_HOME),.)
ROOT_PACKAGE = yes
endif
# application name
APPNAME = $(BASE_PACKAGE)
# always exclude these subdirs
EXCLUDE_SUBDIRS = . .. CVS .svn $(wildcard gen-images-*)
# figure out our subdirs
# defer expansion since makefile.{package,project} can add to EXCLUDE_SUBDIRS
PACKAGE_SUBDIRS = \
$(filter-out $(EXCLUDE_SUBDIRS),$(notdir $(shell find . -maxdepth 1 -type d \
-not -name ".*" -a -not -name ".*.tmp" -a -not -name "javadoc-*")))
# subpackage makefiles
SUBPACKAGE_MAKEFILES = $(addsuffix /makefile,$(PACKAGE_SUBDIRS))
# functions ####################################################################
# VT100 colors
vt100red = 31
vt100grn = 32
vt100yel = 33
vt100blu = 34
vt100mag = 35
vt100cyn = 36
# generate a colored vt100 message for bash echo -e
# arg1 is vt100 color code
# arg2 is message string
vt100 = "\033[0;$(vt100$(1))m$(2)\033[0m"
# warning message
wmsg = echo -e $(call vt100,red,W) $(1)
wmsg-fn = $(info $(shell $(call wmsg,$(1))))
# info message
imsg = echo -e $(call vt100,yel,I) $(1)
imsg-fn = $(info $(shell $(call imsg,$(1))))
qimsg-fn = $(if $(Q),,$(info $(shell $(call imsg,$(1)))))
# build message
bmsg = echo -e $(call vt100,grn,$(1))
# jar build message
jmsg = echo -e $(call vt100,cyn,$(1))
# directory change message
dmsg = echo -e $(call vt100,blu,$(1))
toupper = $(shell echo "$1" | tr "a-z" "A-Z")
tolower = $(shell echo "$1" | tr "A-Z" "a-z")
dash-to-underscore = $(shell echo "$1" | tr "-" "_")
# function to make a target recursively
# first argument is target to make
# second argument is "true" to continue on fail, "false" to stop on fail
recursively-make = \
$(foreach DIR, $(PACKAGE_SUBDIRS), \
[ ! -d $(DIR) ] || \
$(call dmsg,entering subdir $(PACKAGE_PATH)/$(DIR)) && \
pushd $(DIR) > /dev/null && \
( $(MAKE_NPD) $(1) || $(2) ) && \
$(call dmsg,leaving subdir $(PACKAGE_PATH)/$(DIR)) && \
popd > /dev/null && \
) true
# function to make something from $(PROJECT_HOME)
make-from-project-home = \
@echo making $(1) from $(PROJECT_HOME); \
$(CD) $(PROJECT_HOME) && $(MAKE_NPD) $(1)
# convert a package name to a path
package-to-path = $(subst .,/,$(1))
# extract package part of full class name (not including the trailing .class)
package-part = $(basename $(1))
# extract the class part of full class name (not including the trailing .class)
class-part = $(subst .,,$(suffix $(1)))
#locate the target of a possible symlink
#make's "realpath" doesn't seem to follow multiple levels of symlinks on linux
#locate-target = realpath
locate-target = $(shell \
f="$(1)"; \
while [ -L "$$f" ]; do f=`ls -l "$$f" | awk '{print $$NF}'`; done; \
[[ "$$f" == .* ]] && f=`dirname "$(1)"`/$$f; \
echo "$$f")
#try hard to find a command
#
#first arg is command name
#
#second arg (optional) is expected directory
#
#if cmd executable in directory, that is returned
#
#else if which knows where the command is, that is returned
#
#else empty string is returned
locate-cmd = $(shell \
if [[ "$(2)x" != "x" ]] && [[ -x "$(2)/$(1)" ]]; then echo "$(2)/$(1)"; else \
cmd="$(shell which "$(1)" 2>/dev/null || true)"; \
if [ -x "$$cmd" ]; then echo "$$cmd"; else echo ""; fi; \
fi)
#get the parent directory name
#
#better than the make builtin function because this also works on a directory
dirname = $(shell \
if [[ "$(1)"x != x && -e "$(1)" ]]; then dirname "$(1)"; else echo ""; fi)
#default a dir
#
#first arg is the desired dir
#
#second is the default dir
#
#returns first arg iff it's a directory, else second arg
default-dir = $(shell \
if [ ! -d "$(1)" ]; then echo "$(2)"; else echo "$(1)"; fi)
# generate commands to run RMIWrap
#
# first arg is the (simple) name of the API interface
#
# second arg is the (simple) name of the implementation class
run-rmiwrap = \
if [ ! -f $(1)Remote.java -o \
! -f $(2)Server.java -o \
! -f $(2)Client.java -o \
\( $(1).java -nt $(1)Remote.java \) -o \
\( $(2).java -nt $(2)Client.java \) -o \
\( $(2).java -nt $(2)Server.java \) ]; then \
$(call bmsg,rmiwrap $(1) from $(2) in $(PACKAGE)); \
$(JAVA) $(RUN_JAVA_FLAGS) vona.rmi.rmiwrap.RMIWrap \
$(PACKAGE).$(1) $(PACKAGE).$(2) && \
$(JAVAC) $(JAVAC_FLAGS) *.java; \
fi
# generate commands to run rmic
#
# first arg is the (simple) name of the remote class for which to generate a
# stub
RMIC_JRMP_VERSION = 1.1
run-rmic = \
if [ ! -f $(1)_Stub.class -o $(1).class -nt $(1)_Stub.class ]; then \
$(call bmsg,rmic $(PACKAGE).$(1)); \
$(RMIC) -v$(RMIC_JRMP_VERSION) -d $(PROJECT_HOME)/.. $(CLASSPATH_FLAG) \
$(PACKAGE).$(1); \
fi
# copy symlinks as symlinks by default, but ignore any that point outside tree
# separate this out so it can be individually overridden
RSYNC_LINKS = --links --safe-links
# flags for rsync, excludes the usual suspects
RSYNC_FLAGS = -rv $(RSYNC_LINKS) --progress --exclude "**~" --exclude ".\#**" --exclude CVS --exclude .svn --exclude "*.tmp"
# rsync first arg to second arg, with cvs exclude
# third arg is optional extra rsync flags
rsync = $(RSYNC) $(RSYNC_FLAGS) --cvs-exclude $(3) $(1) $(2)
# rsync a subproject
#
# symlinks are copied as symlinks, and symlinks that point outside the tree are
# not copied
#
# first arg is filename extension to include (starting with ".", or empty for
# all)
#
# second arg is the name of a subproject (i.e. the name of the base package of
# the subproject). If it ends in "." then it is copied non-recursively, else
# it is copied recursively.
#
# third arg is rsync dest, if not absolute then relative to $(PROJECT_HOME)/..
#
rsync-subproject = \
pushd $(realpath $(PROJECT_HOME)/..) > /dev/null && \
$(RSYNC) $(RSYNC_FLAGS) --links --safe-links \
--include "*/" \
--exclude "/$(BASE_PACKAGE)/$(JAVADOC_DIR_NAME)/**" \
--exclude "*.jar" \
--include $(if $(filter ".","$(suffix $(2))"),"/$(call package-to-path,$(basename $(2)))/*$(1)","/$(call package-to-path,$(2))/**$(1)") \
--exclude "*" \
$(BASE_PACKAGE) $(3) && \
popd > /dev/null
# this should have dynamic binding so that makefile.package can override
# JARFILE
JAR_DIR = .$(JARFILE).tmp
FIND_HIDDEN = find . -not -type d -a -name ".*"
COUNT_HIDDEN = $(FIND_HIDDEN) | wc -l
FIND_NOT_HIDDEN = find . -not -type d -a -not -name ".*"
COUNT_NOT_HIDDEN = $(FIND_NOT_HIDDEN) | wc -l
FIND_CLASSES = $(FIND_NOT_HIDDEN) -a -name "*.class"
COUNT_CLASSES = $(FIND_CLASSES) | wc -l
find-by-ext = \
$(FIND_NOT_HIDDEN) -a "(" -false $(foreach E,$(1),-o -name "*$(E)" ) ")"
count-by-ext = $(call find-by-ext,$(1)) | wc -l
ifneq ($(JAR_DBG),)
override JAR_DBG=v
endif
# Note: these can fail on OS X 10.9 with argument list too long
# $(JAR) cvf $(3) `$(FIND_NOT_HIDDEN)`
# $(JAR) uvf $(3) `$(FIND_CLASSES)`
# workarounds below
# make a jar
#
# Never includes hidden files (any file with name beginning ".").
#
# If .class files are included in the jar, they are always updated with later
# timestamps than other files in the jar, so that javac should not decide it
# needs to recompile things if a jar with both .java and corresp .class files
# is put on a javac classpath.
#
# arg 1: "true" to include javadoc tree, "false" otherwise
#
# arg 2: the list of external jars (none if empty)
#
# arg 3: the (versioned) name of the jarfile
#
# arg 4: the list of filename extensions to include (each beginning with ".",
# empty to include all)
#
# arg 5: list of extra files to include (pathnames relative to parent of base
# package, files must be present and must not be already included by arg 4)
#
# arg 6: includes only files in these subproject packages
#
# arg 7: the (newest) name of the jarfile
#
# arg 8: (optional) extra commands to prepare $(JAR_DIR)
#
define make-jar
@$(call bmsg,making $(3))
@$(call jmsg, cleaning $(3) and $(JAR_DIR))
$(Q)$(RM) $(3)
$(Q)$(RM) -r $(JAR_DIR)
$(Q)mkdir $(JAR_DIR)
$(Q)if [[ $(1) ]]; then \
if [[ -d "$(JAVADOC_DIR)" ]]; then \
$(call jmsg, copying javadoc from $(JAVADOC_DIR) to $(JAR_DIR)); \
$(call rsync,$(JAVADOC_DIR),$(JAR_DIR)) $(if $(JAR_DBG),,> /dev/null); \
else $(call wmsg, no javadoc found in $(JAVADOC_DIR)); fi; fi
$(Q)if [[ "$(4)"x == x ]]; then \
$(foreach P,$(6),\
$(call jmsg, copying subproject $(P) to $(JAR_DIR)) && \
$(call rsync-subproject,,$(P),\
$(call package-to-path,$(PACKAGE))/$(JAR_DIR) \
$(if $(JAR_DBG),,> /dev/null)) && ) true; \
else $(foreach E,$(4),\
$(foreach P,$(6),\
$(call jmsg, copying *$(E) from subproject $(P) to $(JAR_DIR)) && \
$(call rsync-subproject,$(E),$(P),\
$(call package-to-path,$(PACKAGE))/$(JAR_DIR) \
$(if $(JAR_DBG),,> /dev/null)) && )) true; fi
$(Q)$(foreach F,$(5),\
$(call jmsg, copying $(F) from $(PROJECT_HOME)/../$(F) to $(JAR_DIR)/$(dir $(F))) && \
cp $(addprefix $(PROJECT_HOME)/../,$(F)) \
$(JAR_DIR)/$(dir $(F)) && ) true
$(Q)$(foreach F,$(addprefix $(EXT_DIR)/,\
$(call filter-excluded-jars,$(sort $(2)))),\
if [[ -f $(F) ]]; then \
$(call jmsg, copying $(F)); \
cp $(F) $(JAR_DIR); \
else $(call wmsg, $(F) not found); fi; )
$(Q)$(8)
$(Q)$(MAKE_NPD) $(JAR_DIR)/makefile
@$(call dmsg, entering subdir $(JAR_DIR))
$(Q)$(MAKE_NPD) -C $(JAR_DIR) pack-jar \
EJ="$(call filter-excluded-jars,$(sort $(2)))" \
JF=$(3) FX="$(4)" XF="$(5)" JD=$(JAR_DBG)
@$(call dmsg, leaving subdir $(JAR_DIR))
$(Q)if [[ "$(JAR_DBG)"x == x ]]; then \
$(call jmsg, cleaning $(JAR_DIR)); \
rm -rf $(JAR_DIR); fi
$(Q)if [[ ! -a $(7) || -h $(7) ]]; then \
$(call jmsg, linking $(3) to $(7)); \
ln -s -f $(3) $(7); fi
endef
.PHONY: pack-jar
pack-jar:
$(Q)$(foreach F,$(filter-out $(JOGL_NATIVE_JARS),$(EJ)),\
if [[ -f $(F) ]]; then \
$(call jmsg, exploding $(F)); \
$(JAR) x$(JD)f $(F) $(if $(JD),,> /dev/null); \
rm $(F); fi; )
$(Q)$(foreach F,$(filter $(JOGL_NATIVE_JARS),$(EJ)),\
[[ $(F) =~ .*natives-(.*).jar ]] && D=natives/$${BASH_REMATCH[1]}; \
$(call jmsg, exploding $(F) to $$D); \
mkdir -p $$D; pushd $$D > /dev/null; \
$(JAR) x$(JD)f ../../$(F) $(if $(JD),,> /dev/null); \
popd > /dev/null; \
rm $(F); )
$(Q)rm -rf META-INF
$(Q)if [[ "$(FX)"x == x && `$(COUNT_NOT_HIDDEN)` -gt 0 ]]; then \
$(MAKE_NPD) pack-jar-all JF=$(JF) JD=$(JD); \
elif [[ `$(call count-by-ext,$(FX))` -gt 0 || "$(XF)"x != x ]]; then \
$(MAKE_NPD) pack-jar-exts JF=$(JF) FX="$(FX)" XF="$(XF)" JD=$(JD); \
else $(call jmsg, not creating jar no non-hidden input files); fi
$(Q)if [[ -f $(JF) && -f $(JAR_MF) ]]; then \
$(call jmsg, adding manifest $(JAR_MF) to $(JF)); \
$(JAR) ufm $(JF) $(JAR_MF); \
else $(call jmsg, manifest $(JAR_MF) not found); fi
$(Q)if [[ -f $(JF) && -f $(JAR_CRT) ]]; then \
$(call jmsg, signing $(JF) with $(JARKEY)); \
$(JARSIGNER) -keystore $(JAR_CRT) $(JF) $(JARKEY); \
else $(call jmsg, $(JAR_CRT) not found - not signing jar); fi
$(Q)if [[ -f $(JF) ]]; then chmod a+r $(JF); mv $(JF) ..; fi
.PHONY: pack-jar-all
pack-jar-all:
$(Q)$(call jmsg, creating $(JF))
$(Q)$(JAR) c$(JD)f $(JF) . $(if $(JD),,> /dev/null)
$(Q)if [[ -f $(JF) && `$(COUNT_HIDDEN)` -gt 0 ]]; then \
$(call jmsg, removing hidden files from $(JF)); \
$(ZIP) -d $(JF) `$(FIND_HIDDEN)`; fi
$(Q)if [[ -f $(JF) && `$(COUNT_CLASSES)` -gt 0 ]]; then \
$(call jmsg, updating class files to be newest in $(JF)); \
$(FIND_CLASSES) | xargs $(JAR) uvf $(JF) $(if $(JD),,> /dev/null); fi
.PHONY: pack-jar-exts
pack-jar-exts:
$(Q)$(call jmsg, adding $(foreach E,$(FX),*$(E))$(if $(XF), and $(XF) )to $(JF))
$(Q)$(JAR) c$(JD)f $(JF) `$(call find-by-ext,$(filter-out .class,$(FX)))` \
$(XF) $(if $(JD),,> /dev/null)
$(Q)if [[ -f $(JF) && `$(COUNT_CLASSES)` -gt 0 ]]; then \
$(call jmsg, adding class files to $(JF)); \
$(JAR) u$(JD)f $(JF) `$(call find-by-ext,$(filter .class,$(FX)))` \
$(if $(JD),,> /dev/null); fi
# template file locations
TEMPLATE_DIR = $(PROJECT_HOME)/templates
JAVA_TEMPLATE = $(TEMPLATE_DIR)/Template.java
EXCEPTION_TEMPLATE = $(TEMPLATE_DIR)/Exception.java
PACKAGE_TEMPLATE = $(TEMPLATE_DIR)/package.html
MAKEFILE_PACKAGE_TEMPLATE = $(TEMPLATE_DIR)/makefile.package
# make a boilerplate java file
template-m4-java = \
$(call bmsg,making boilerplate $(basename $(1)).java); \
m4 -P "-DYEAR=`date +%Y`" "-DPACKAGE=$(PACKAGE)" \
"-DCLASS=$(notdir $(basename $(1)))" \
$(JAVA_TEMPLATE) > $(basename $(1)).java
# function to generate a javadoc command line
#
# javadoc will be deposited in $(JAVADOC_DIR)
#
# first arg is list of base packages. Javadoc will be built for all subpackages
# of the base packages, except those specifically excluded in the next arg
#
# second arg, if any, is a list of packages to specifically exclude
javadoc = \
$(call bmsg,making javadoc for $(1) $(if $(2),excluding $(2))); \
$(JAVADOC) $(JAVADOC_FLAGS) -d $(JAVADOC_DIR) \
$(foreach P,$(1), -subpackages $(P)) $(foreach P,$(2), -exclude $(P))
# include makefile.project #####################################################
# do it here so it can set PROJECT_TOOLS_HOME if it wants
-include $(PROJECT_HOME)/makefile.project
# find stuff ###################################################################
CACHEFILE = $(PROJECT_HOME)/.makefile_cache_$(PLATFORM)
ifndef NO_CACHE
-include $(CACHEFILE)
ifdef USING_CACHE
$(call qimsg-fn,"read cachefile $(CACHEFILE)")
else
$(call qimsg-fn,"cachefile $(CACHEFILE) not readable")
endif
else
$(call qimsg-fn,"not reading cachefile $(CACHEFILE) since NO_CACHE=$(NO_CACHE)")
endif
# if we successfully loaded a cachefile then it will have defined USING_CACHE=1
ifndef USING_CACHE
# look everything up, and possibly also write a cachefile
ifndef NO_CACHE
ifndef NO_CACHE_CREATE
$(call qimsg-fn,"creating cachefile $(CACHEFILE)")
stash = $(shell echo "$(1) := $($(1))" >> $(CACHEFILE))
WRITING_CACHE := 1
endif
endif
ifndef WRITING_CACHE
$(call qimsg-fn,"not creating cachefile $(CACHEFILE) since NO_CACHE=$(NO_CACHE)")
endif
USING_CACHE := 1
$(call stash,USING_CACHE)
USING_CACHE :=
$(call stash,SYSTEM)
$(call stash,MACHINE)
$(call stash,PLATFORM)
# don't use ?= here as we want to avoid deferred expansion for speed
ifndef BASE_PACKAGE
BASE_PACKAGE := $(notdir $(shell cd $(PROJECT_HOME) && pwd))
endif
ifndef TOOLS_HOME
TOOLS_HOME := $(call default-dir,$(PROJECT_TOOLS_HOME),/usr)
endif
BIN := $(call default-dir,$(TOOLS_HOME)/bin/$(PLATFORM),/usr/bin)
SCRIPTS := $(call default-dir,$(TOOLS_HOME)/scripts,$(BIN))
ifndef JDK_BASE
JDK_BASE := $(TOOLS_HOME)/java/$(PLATFORM)
endif
ifndef JDK_VERSION
JDK_VERSION := newest
endif
ifndef JDK_BIN_SUBDIR
JDK_BIN_SUBDIR = bin
ifeq ($(SYSTEM),Darwin)
JDK_BIN_SUBDIR = Commands
endif
endif
ifndef JDK_HOME
JDK_HOME := $(call dirname,$(call dirname,$(call locate-target,$(call locate-cmd,javac,$(JDK_BASE)/$(JDK_VERSION)/$(JDK_BIN_SUBDIR)))))
endif
ifndef JDK_BIN
JDK_BIN := $(JDK_HOME)/$(JDK_BIN_SUBDIR)
endif
$(call stash,BASE_PACKAGE)
$(call stash,TOOLS_HOME)
$(call stash,BIN)
$(call stash,SCRIPTS)
$(call stash,JDK_BASE)
$(call stash,JDK_VERSION)
$(call stash,JDK_BIN_SUBDIR)
$(call stash,JDK_HOME)
$(call stash,JDK_BIN)
JDK_EXT := $(JDK_HOME)/jre/lib/ext
ifeq ($(SYSTEM),Darwin)
JDK_EXT := /System/Library/Java/Extensions
endif
ifndef TOOLS_EXT
TOOLS_EXT = $(TOOLS_HOME)/java/indep/lib
endif
# find pure java extension jars in TOOLS_EXT if present, else in JDK_EXT
#
# NOTE the classes will come in on different classloaders in the two cases,
# which can lead to subtle CNFEs
ifndef EXT_DIR
EXT_DIR := $(call default-dir,$(TOOLS_EXT),$(JDK_EXT))
endif
ifndef NATIVE_EXT_DIR
NATIVE_EXT_DIR := $(TOOLS_HOME)/java/native/lib/$(PLATFORM)
endif
$(call stash,JDK_EXT)
$(call stash,TOOLS_EXT)
$(call stash,EXT_DIR)
$(call stash,NATIVE_EXT_DIR)
# JDK executables
ifndef JAVAC
JAVAC := $(call locate-cmd,javac,$(JDK_BIN))
endif
ifndef JAVA
JAVA := $(call locate-cmd,java,$(JDK_BIN))
endif
ifndef JAVADOC
JAVADOC := $(call locate-cmd,javadoc,$(JDK_BIN))
endif
ifndef JAR
JAR := $(call locate-cmd,jar,$(JDK_BIN))
endif
ZIP := $(call locate-cmd,zip,$(JDK_BIN))
KEYTOOL := $(call locate-cmd,keytool,$(JDK_BIN))
JARSIGNER := $(call locate-cmd,jarsigner,$(JDK_BIN))
RMIC := $(call locate-cmd,rmic,$(JDK_BIN))
$(call stash,JAVAC)
$(call stash,JAVA)
$(call stash,JAVADOC)
$(call stash,JAR)
$(call stash,ZIP)
$(call stash,KEYTOOL)
$(call stash,JARSIGNER)
$(call stash,RMIC)
#other executables
#don't suggest a directory, use which to respect path
JAVACC := $(call locate-cmd,javacc)
RSYNC := $(call locate-cmd,rsync)
WWWIMAGESIZE := $(call locate-cmd,wwwimagesize)
SVNVERSION := $(call locate-cmd,svnversion)
$(call stash,JAVACC)
$(call stash,RSYNC)
$(call stash,WWWIMAGESIZE)
$(call stash,SVNVERSION)
#we sometimes need to find the JDK "tools.jar", which is a confusing alternate
#meaning for "tools" here...
TOOLS_JAR := $(JDK_HOME)/lib/tools.jar
ifeq ($(SYSTEM),Darwin)
#TOOLS_JAR := /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Classes/classes.jar
TOOLS_JAR := /Library/Java/JavaVirtualMachines/jdk$(shell $(JAVAC) -version 2>&1 | cut -f2 -d' ').jdk/Contents/Home/lib/tools.jar
endif
$(call stash,TOOLS_JAR)
# the native compileserver submit stub
JAVAC_SUBMIT := $(call locate-cmd,javac_submit,$(BIN))
# the compile server binary directory
CS_BIN := $(call dirname,$(call locate-target,$(JAVAC_SUBMIT)))
# the compile server scripts directory
CS_SCRIPTS := $(call dirname,$(call locate-target,$(call locate-cmd,CompileServer-submit,$(SCRIPTS))))
# compile server scripts
CS_ENSURE := $(call locate-cmd,CompileServer-ensure-running,$(CS_SCRIPTS))
CS_SUBMIT := $(call locate-cmd,CompileServer-submit,$(CS_SCRIPTS))
$(call stash,JAVAC_SUBMIT)
$(call stash,CS_BIN)
$(call stash,CS_SCRIPTS)
$(call stash,CS_ENSURE)
$(call stash,CS_SUBMIT)
endif # USING_CACHE
# compile server ###############################################################
JAVAC_OR_CS_SUBMIT := $(JAVAC)
# define NO_COMPILE_SERVER to disable compile server
ifndef NO_COMPILE_SERVER
ifdef JAVAC_SUBMIT
ifdef CS_SUBMIT
ifdef CS_ENSURE
ifeq ($(findstring OK,$(shell $(CS_ENSURE) nostart)),OK)
JAVAC_OR_CS_SUBMIT := $(CS_SUBMIT)
USING_COMPILE_SERVER := 1
else
CS_WHY_NOT = "CompileServer-ensure-running not OK"
endif #OK
else
CS_WHY_NOT = "CompileServer-ensure-running not found"
endif #CS_ENSURE
else
CS_WHY_NOT = "CompileServer-submit not found"
endif #CS_SUBMIT
else
CS_WHY_NOT = "javac_submit not found"
endif #JAVAC_SUBMIT
else
CS_WHY_NOT = "NO_COMPILE_SERVER set"
endif #NO_COMPILE_SERVER
# svnversion ###################################################################
SVNVERSION_FILE := SVNVERSION.txt
ifdef SVNVERSION_FILE_NOAUTO
SVNVERSION_FILE_DEP =
else
SVNVERSION_FILE_DEP := $(SVNVERSION_FILE)
endif
SVNVERSION_STRING := $(if $(wildcard $(SVNVERSION_FILE)),R$(subst $(SPACE),_,$(filter-out %die,$(subst :,die ,$(strip $(shell cat $(SVNVERSION_FILE)))))),unknown)
# jar and publish config #######################################################
# a lot of this would have already been set in makefile.project
# targets that will be built for "make jars"
PROJECT_JAR_TARGETS ?= jar jar-lite jar-xlite
# filename extensions to put in the jars, empty to include all files
JARFILE_EXTS ?=
JARFILE_LITE_EXTS ?= .class .scm .hex .txt .html .java .package .c .h .gif .png .jpg .css .inc .o .eep .elf .lss .m4 .policy
JARFILE_XLITE_EXTS ?= .class .scm .hex .txt .gif .png .jpg .o .eep .elf .lss .policy
# extra files to put in the jars (relative to parent of base package)
JAR_EXTRA ?=
JAR_LITE_EXTRA ?= $(BASE_PACKAGE)/makefile
JAR_XLITE_EXTRA ?=
# extra commands to prepare $(JAR_DIR)
JAR_EXTRA_CMDS ?=
JAR_LITE_EXTRA_CMDS ?=
JAR_XLITE_EXTRA_CMDS ?=
# the jar manifest file
JAR_MF_NAME ?= $(APPNAME).mf
JAR_MF ?= $(PROJECT_HOME)/$(JAR_MF_NAME)
# list of packages to include in jarfile
#
# all descendant subpackages of these will also be included
#
# makefile.package can override this for making sub-project jars
SUBPROJECT_PACKAGES ?= $(BASE_PACKAGE)
LITE_SUBPROJECT_PACKAGES ?= $(SUBPROJECT_PACKAGES)
XLITE_SUBPROJECT_PACKAGES ?= $(LITE_SUBPROJECT_PACKAGES)
# 3rd party jars, found in EXT_DIR, on which the whole project depends
#
# these will be folded into built jarfiles
#
# makefile.package can append to this (or override it) for making sub-project
# jars
EXT_JARS ?=
EXT_JARS_JARFILE_ONLY ?=
EXT_JARS_LITE ?=
EXT_JARS_LITE_JARFILE_ONLY ?=
EXT_JARS_XLITE ?=
EXT_JARS_XLITE_JARFILE_ONLY ?=
# for jarfiles containing natives we follow the JOGL naming conventions
ifndef JAR_OS
JAR_OS=linux
ifeq ($(findstring CYGWIN,$(SYSTEM)),CYGWIN)
JAR_OS=windows
else ifeq ($(SYSTEM),Darwin)
JAR_OS=macosx
endif
endif
ifndef JAR_ARCH
JAR_ARCH=amd64
ifneq ($(filter i386 i486 i586 i686,$(MACHINE)),)
JAR_ARCH=i586
else ifeq ($(MACHINE),armv6l)
JAR_ARCH=armv6hf
endif
endif
JAR_OS_ALL ?= linux windows macosx android solaris
JAR_ARCH_ALL ?= amd64 i586 armv6 armv6hf universal
JAR_OS_OTHER ?= $(filter-out $(JAR_OS),$(JAR_OS_ALL))
JAR_ARCH_OTHER ?= $(filter-out universal $(JAR_ARCH),$(JAR_ARCH_ALL))
JAR_OS_INCLUDE ?= $(filter-out $(JAR_OS_EXCLUDE),$(JAR_OS_ALL))
JAR_ARCH_INCLUDE ?= $(filter-out $(JAR_ARCH_EXCLUDE),$(JAR_ARCH_ALL))
ifeq ($(JAR_OS_INCLUDE),)
ifneq ($(JAR_ARCH_INCLUDE),)
override JAR_OS_INCLUDE := $(JAR_OS_ALL)
override JAR_OS_EXCLUDE :=
endif
endif
ifeq ($(JAR_ARCH_INCLUDE),)
ifneq ($(JAR_OS_INCLUDE),)
override JAR_ARCH_INCLUDE := $(JAR_ARCH_ALL)
override JAR_ARCH_EXCLUDE :=
endif
endif
ifndef JAR_OS_EXCLUDE
JAR_OS_EXCLUDE := $(filter-out $(JAR_OS_INCLUDE),$(JAR_OS_ALL))
endif
ifndef JAR_ARCH_EXCLUDE
JAR_ARCH_EXCLUDE := $(filter-out universal $(JAR_ARCH_INCLUDE),$(JAR_ARCH_ALL))
endif
ifneq ($(JAR_OS_INCLUDE),$(JAR_OS_ALL))
JAR_OS_TAG := $(subst $(SPACE),-,$(JAR_OS_INCLUDE))
JAR_OS_TAG := $(if $(JAR_OS_TAG),-$(JAR_OS_TAG))
endif
ifneq ($(JAR_ARCH_INCLUDE),$(JAR_ARCH_ALL))
JAR_ARCH_TAG := $(subst $(SPACE),-,$(JAR_ARCH_INCLUDE))
JAR_ARCH_TAG := $(if $(JAR_ARCH_TAG),-$(JAR_ARCH_TAG))
endif
ifeq ($(JAR_OS_INCLUDE)$(JAR_ARCH_INCLUDE),)
JAR_OS_TAG := -nonatives
JAR_ARCH_TAG :=
endif
# arg 1: os(s) to exclude
# arg 2: arch(s) to exclude
# arg 3: list of jarfiles
filter-native-jars = \
$(filter-out \
$(foreach os,$(JAR_OS_ALL),$(foreach arch,$(2),%-$(os)-$(arch).jar)) \
$(foreach os,$(1),$(foreach arch,$(JAR_ARCH_ALL),%-$(os)-$(arch).jar)),\
$(3))
# filter out jars for platforms other than $(JAR_OS)-$(JAR_ARCH)
filter-foreign-jars = \
$(call filter-native-jars,$(JAR_OS_OTHER),$(JAR_ARCH_OTHER),$(1))
# filter out jars for non-included platforms and/or architectures
filter-excluded-jars = \
$(call filter-native-jars,$(JAR_OS_EXCLUDE),$(JAR_ARCH_EXCLUDE),$(1))
# Java3D jars
J3D_JARS ?= vecmath.jar j3dcore.jar j3dutils.jar
J3D_LOADER_JARS ?= Loader3DS1_2.jar j3d-vrml97.jar
# JOGL jars
JOGL_JARS ?= gluegen-rt.jar jogl-all.jar
JOGL_NATIVE_JARS ?= \
gluegen-rt-natives-linux-amd64.jar \
gluegen-rt-natives-linux-armv6.jar gluegen-rt-natives-linux-armv6hf.jar \
gluegen-rt-natives-linux-i586.jar \
gluegen-rt-natives-macosx-universal.jar \
gluegen-rt-natives-solaris-amd64.jar gluegen-rt-natives-solaris-i586.jar \
gluegen-rt-natives-windows-amd64.jar gluegen-rt-natives-windows-i586.jar \
jogl-all-natives-linux-amd64.jar \
jogl-all-natives-linux-armv6.jar jogl-all-natives-linux-armv6hf.jar \
jogl-all-natives-linux-i586.jar \
jogl-all-natives-macosx-universal.jar \
jogl-all-natives-solaris-amd64.jar jogl-all-natives-solaris-i586.jar \
jogl-all-natives-windows-amd64.jar jogl-all-natives-windows-i586.jar
# jlapack and netlib-java jars
JLAPACK_JARS ?= f2jutil.jar xerbla.jar blas.jar lapack.jar
NETLIB_JAVA_JARS ?= netlib-java.jar
#arpack.jar arpack_util.jar
NETLIB_JAVA_NATIVE_JARS ?= \
netlib-java-natives-linux-i586.jar netlib-java-natives-linux-amd64.jar \
netlib-java-natives-macosx-amd64.jar
FOMMIL_NETLIB_JARS ?= jniloader.jar fommil-netlib.jar
#arpack.jar arpack_util.jar
FOMMIL_NETLIB_NATIVE_JARS ?= \
fommil-netlib-natives-linux-armv6hf.jar \
fommil-netlib-natives-linux-amd64.jar \
fommil-netlib-natives-linux-i586.jar \
fommil-netlib-natives-macosx-amd64.jar \
fommil-netlib-natives-windows-i586.jar \
fommil-netlib-natives-windows-amd64.jar
# name of key used to sign jars
#
# makefile.package can override this for making sub-project jars
#
# presence of $(JAR_CRT) triggers signing of built jarfile
#
# "make keygen" to generate the key initially, then check in the .crt file in
# the base package
JARKEY ?= mykey
JAR_CRT_NAME ?= $(JARKEY).crt
JAR_CRT ?= $(PROJECT_HOME)/$(JAR_CRT_NAME)
# the string SVNVERSION will be replaced by $(SVNVERSION_STRING) below
JARFILE ?= $(APPNAME)-SVNVERSION$(JAR_OS_TAG)$(JAR_ARCH_TAG).jar
JARFILE_LITE ?= $(APPNAME)-lite-SVNVERSION.jar
JARFILE_XLITE ?= $(APPNAME)-xlite-SVNVERSION.jar
JARFILE_PAT ?= $(subst SVNVERSION,R*,$(JARFILE))
JARFILE_LITE_PAT ?= $(subst SVNVERSION,R*,$(JARFILE_LITE))
JARFILE_XLITE_PAT ?= $(subst SVNVERSION,R*,$(JARFILE_XLITE))
JARFILE_NEWEST ?= $(subst SVNVERSION,newest,$(JARFILE))
JARFILE_LITE_NEWEST ?= $(subst SVNVERSION,newest,$(JARFILE_LITE))
JARFILE_XLITE_NEWEST ?= $(subst SVNVERSION,newest,$(JARFILE_XLITE))
JARFILE_SUBST ?= $(subst SVNVERSION,$(SVNVERSION_STRING),$(JARFILE))
JARFILE_LITE_SUBST ?= $(subst SVNVERSION,$(SVNVERSION_STRING),$(JARFILE_LITE))
JARFILE_XLITE_SUBST ?= $(subst SVNVERSION,$(SVNVERSION_STRING),$(JARFILE_XLITE))
JARFILE_PUBLISH_UNPACK_SUBST ?= $(subst SVNVERSION,$(SVNVERSION_STRING),$(JARFILE_PUBLISH_UNPACK))
# name of subdir in which javadoc is built
JAVADOC_DIR_NAME ?= javadoc-$(APPNAME)
JAVADOC_DIR ?= $(PROJECT_HOME)/$(JAVADOC_DIR_NAME)
EXCLUDE_JAVADOC_PACKAGES += $(BASE_PACKAGE).templates
# publish rsync destination
#
# empty disables publish
#
# makefile.package can override this sub-project publish
PUBLISH_DEST ?=
# jarfile to unpack at $(PUBLISH_DEST), if any
JARFILE_PUBLISH_UNPACK ?= $(JARFILE_LITE)
# include makefile.package #####################################################
# do it here so it can override settings from above
# and before building classpath so that EXT_JARS can be frobbed
-include makefile.package
# classpath and tool options ###################################################
# put the parent of project home first on the classpath
# that way if there are built checkouts of the source trees for any EXT_JARS
# then we'll pick up those classes directly from there
NINJA_CLASSPATH := $(PROJECT_HOME)/..
ifdef USING_COMPILE_SERVER
NINJA_CLASSPATH := $(shell pwd)/$(NINJA_CLASSPATH)
endif
# now put each EXT_JAR on the classpath, in order, but only if we're finding
# them in an EXT_DIR which is not the JDK installed extensions dir
ifneq ($(EXT_DIR),$(JDK_EXT))
NINJA_CLASSPATH := $(subst $(SPACE),,$(NINJA_CLASSPATH)$(foreach JAR,$(EXT_JARS),:$(EXT_DIR)/$(JAR)))
endif
# next add the JDK tools jar to the classpath
# in particular, for use by CompileServer
NINJA_CLASSPATH := $(NINJA_CLASSPATH):$(TOOLS_JAR)
# finally append the user's externally defined CLASSPATH, if any
ifdef CLASSPATH
MAKE_CLASSPATH := $(NINJA_CLASSPATH):$(CLASSPATH)
else
#trailing colon breaks java under Windows
MAKE_CLASSPATH := $(NINJA_CLASSPATH)
endif
# important: only consider for compilation sourcefiles that are found within
# this project (and e.g. not within jars on the classpath)
ifdef SOURCEPATH
MAKE_SOURCEPATH := $(PROJECT_HOME)/..:$(SOURCEPATH)
else
MAKE_SOURCEPATH := $(PROJECT_HOME)/..
endif
ifeq ($(findstring CYGWIN,$(SYSTEM)),CYGWIN)
MAKE_CLASSPATH := `cygpath -w -p "$(MAKE_CLASSPATH)"`
MAKE_SOURCEPATH := `cygpath -w -p "$(MAKE_SOURCEPATH)"`
endif
CLASSPATH_FLAG = -classpath "$(MAKE_CLASSPATH)"
SOURCEPATH_FLAG = -sourcepath "$(MAKE_SOURCEPATH)"
DEPRECATION_FLAG = -deprecation
# always exclude these source files
# this might have been set in makefile.{package,project}
EXCLUDE_SOURCE ?=
# figure out source files
PACKAGE_JAVAC_SOURCE := $(filter-out $(wildcard $(EXCLUDE_SOURCE)),$(wildcard *.java))
PACKAGE_HTML_SOURCE := $(sort $(filter-out $(wildcard $(EXCLUDE_SOURCE)),$(wildcard *.phtml *.m4 *.md *.m4d)))
PACKAGE_JAVACC_SOURCE := $(filter-out $(wildcard $(EXCLUDE_SOURCE)),$(wildcard *.jj))
# all source
SOURCE = \
$(wildcard *.java) \
$(wildcard *.scm) \
$(wildcard *.c *.cc *.h *.hh) \
$(wildcard *.mf) \
$(wildcard *.jj) \
$(wildcard *.xsd *.xml *.spp) \
$(wildcard *.txt *.tex *.html *.htm *.css README) \
$(wildcard *.properties *.conf *.xcf *.gif *.jpg *.png *.bmp *.ico) \
$(wildcard *.lws *.lwo *.wrl) \
$(wildcard *.sh *.csh *.bat *.iss) \
$(wildcard *.phtml *.m4 *.md *.m4d) \
$(wildcard *.policy) \
package.html makefile.package
SOURCE := $(sort $(SOURCE))
PACKAGE_HTML_DEPS := $(addsuffix .html,$(basename $(PACKAGE_HTML_SOURCE)))
PACKAGE_JAVACC_DEPS := $(addsuffix .class,$(basename $(PACKAGE_JAVACC_SOURCE)))
PACKAGE_JAVAC_DEPS := $(addsuffix .class,$(basename $(PACKAGE_JAVAC_SOURCE)))
PACKAGE_DEPS = \
$(if $(NO_SOURCE_GEN),,package-source-gen) \
$(if $(NO_HTML),,package-html) \
package-javac
ifdef ROOT_PACKAGE
SOURCE += makefile makefile.project
endif
# compile-time flags
JAVAC_FLAGS += $(DEPRECATION_FLAG) $(CLASSPATH_FLAG)
ifdef SOURCE_VERSION
JAVAC_FLAGS += -source $(SOURCE_VERSION)
endif
ifdef TARGET_VERSION
JAVAC_FLAGS += -target $(TARGET_VERSION)
endif
JAVAC_FLAGS += $(JAVAC_OPTIONS)
# unfortunately, -sourcepath seems buggy with compileserver
ifndef USING_COMPILE_SERVER
JAVAC_FLAGS += $(SOURCEPATH_FLAG)
endif
ifneq ($(findstring CYGWIN,$(SYSTEM)),CYGWIN)
NATIVE_EXT_PATH = /usr/lib:/usr/lib/jni
endif
ifeq ($(SYSTEM),Darwin)
NATIVE_EXT_PATH := $(JDK_EXT)
endif
ifdef LD_LIBRARY_PATH
NATIVE_EXT_PATH := $(NATIVE_EXT_PATH):$(LD_LIBRARY_PATH)
endif
ifdef NATIVE_EXT_DIR
NATIVE_EXT_PATH := $(NATIVE_EXT_DIR):$(NATIVE_EXT_PATH)
endif
ifneq ($(findstring CYGWIN,$(SYSTEM)),CYGWIN)
NATIVE_LIB_FLAG := $(if $(NATIVE_LIB_NOAUTO),,"-Djava.library.path=$(NATIVE_EXT_PATH)")
endif
MEMORY_FLAG = -Xmx$(TOTAL_HEAP_SIZE)
# runtime flags
RUN_JAVA_FLAGS += \
$(CLASSPATH_FLAG) $(MEMORY_FLAG) $(NATIVE_LIB_FLAG) $(WORKAROUND_FLAGS) \
$(JAVA_OPTIONS) -ea
# javadoc
JAVADOC_FLAGS += $(CLASSPATH_FLAG) -private -use -author -doctitle $(APPNAME) \
`[[ -r overview.html ]] && echo -overview overview.html` \
-XDignore.symbol.file
ifdef JAVADOC_SOURCE_VERSION
JAVADOC_FLAGS += -source $(JAVADOC_SOURCE_VERSION)
endif
# HTML stuff ###################################################################
# markdown files autogenerated from m4d (markdown + m4)
GEN_MD := $(filter %.m4d,$(PACKAGE_HTML_SOURCE))
GEN_MD := $(GEN_MD:.m4d=.md)
HTML_M4_EXTRA_DEPS += $(wildcard html-*.m4)
WWWROOT = $(HOME)/www
.SUFFIXES: .m4 .phtml .html .md .m4d
HTML_GEN_DEFS += "-DBUILD_DATE=`date`" "-DYEAR=`date +%Y`" "-DSVNVERSION_STRING=$(SVNVERSION_STRING)" $(if $(SUPPRESS_HTML_PARENT_PATH),"-DSUPPRESS_HTML_PARENT_PATH=true")
HTML_GEN_INC += "-I$(WWWROOT)/include"
PANDOC_HTML_OPTS += --standalone --smart --gladtex
# generate html using the C preprocessor
# first arg is input, second arg is output
html-cpp = \
gcc -E -P -traditional $(HTML_GEN_DEFS) $(HTML_GEN_INC) $(HTML_CPP_EXTRA) - \
< $(1) > $(2)
# generate html using m4
# first arg is input, second arg is output
html-m4 = m4 -P $(HTML_GEN_DEFS) $(HTML_GEN_INC) $(HTML_M4_EXTRA) $(1) > $(2)
# generate markdown using m4
# first arg is input, second arg is output
md-m4d = m4 -P $(HTML_GEN_DEFS) $(HTML_GEN_INC) $(MD_M4D_EXTRA) $(1) > $(2)
# generate html+gladtex from markdown
#
# first arg is input, second arg is output
#
# 1/22/13 pandoc on ubuntu 12.04 is converting html entities inside latex math
# workaround by splitting and tags onto their own lines
# then replace & < and > between and with &, <, >
htex-md = \
pandoc $(PANDOC_HTML_OPTS) -o $(2) $(1) && \
awk '{gsub("]*>","\n&\n");\
gsub("]*>","\n&\n");\
print}' < $(2) > $(2).tmp && \
awk '/]*>/{inmath=1}\
/<\/EQ[^>]*>/{inmath=0}\
inmath{gsub("&","\&");\
gsub("<","<");\
gsub(">",">");\
gsub("&\#39;","'\''");\
print}\
!inmath{print}' < $(2).tmp > $(2) && \
$(RM) $(2).tmp
# generate html from html+gladtex
# first arg is input, second arg is output
html-htex = \
[[ -d gen-images-$(basename $(2)) ]] || mkdir gen-images-$(basename $(2)); \
gladtex $(GLADTEX_OPTS) -d gen-images-$(basename $(2)) $(1) && \
if [[ `ls gen-images-$(basename $(2))/*.png 2> /dev/null | wc -l` == 0 ]]; \
then $(RM) -rf gen-images-$(basename $(2)); fi
# run wwwimagesize on an html file
wwwimagesize = \
if [ -x "$(WWWIMAGESIZE)" ]; then $(WWWIMAGESIZE) -MakeBackup no $(1); fi
# pattern rules ################################################################
# make java boilerplate
%.java-template: $(JAVA_TEMPLATE)
$(Q)if [ ! -f ./$(basename $@).java ] || [ ! -s ./$(basename $@).java ]; \
then $(call template-m4-java,$@); \
else echo ./$(basename $@).java exists and is non-empty, not overwriting; \
fi
# make java boilerplate for each empty file named *.java in this directory
.PHONY: java-templates
java-templates:
$(Q)$(foreach F,$(shell find . -maxdepth 1 -size 0 -name "*.java"),\
$(call template-m4-java,$F); )
# make java exception class boilerplate
%.java-exception-template: $(EXCEPTION_TEMPLATE)
$(Q)if [ ! -f ./$(basename $@).java ]; then \
$(call bmsg,making boilerplate exception class $(basename $@).java); \
cp $(EXCEPTION_TEMPLATE) ./$(basename $@).java; \
else echo ./$(basename $@).java exists, not overwriting; \
fi
# make package.html boilerplate
.PHONY: package.html-template
package.html-template: $(PACKAGE_TEMPLATE)
$(Q)if [ ! -f package.html ]; then \
$(call bmsg,making boilerplate package.html); \
cp $(PACKAGE_TEMPLATE) ./package.html; \
else echo ./package.html exists, not overwriting; \
fi
# make makefile.package boilerplate
.PHONY: makefile.package-template
makefile.package-template: $(MAKEFILE_PACKAGE_TEMPLATE)
$(Q)if [ ! -f makefile.package ]; then \
$(call bmsg,making boilerplate makefile.package); \
cp $(MAKEFILE_PACKAGE_TEMPLATE) ./makefile.package; \
else echo ./makefile.package exists, not overwriting; \
fi
# make html from m4
%.html: %.m4 $(SVNVERSION_FILE_DEP) $(HTML_M4_EXTRA_DEPS)
$(Q)$(MAKE_NPD) $@-m4-impl
%.html-m4-impl:
@$(call bmsg,making $(basename $@).html from $(basename $@).m4)
$(Q)$(call html-m4,$(basename $@).m4,$(basename $@).html)
$(Q)$(call wwwimagesize $(basename $@).html)
# make html from phtml by sending it through the C pre-processor
%.html: %.phtml $(SVNVERSION_FILE_DEP) $(HTML_PHTML_EXTRA_DEPS)
$(Q)$(MAKE_NPD) $@-phtml-impl
%.html-phtml-impl:
@$(call bmsg,making $(basename $@).html from $(basename $@).phtml)
$(Q)$(call html-cpp,$(basename $@).phtml,$(basename $@).html)
$(Q)$(call wwwimagesize $(basename $@).html)
# make md from m4d (markdown+m4)
%.md: %.m4d $(SVNVERSION_FILE_DEP) $(MD_M4D_EXTRA_DEPS)
$(Q)$(MAKE_NPD) $@-m4d-impl
%.md-m4d-impl:
@$(call bmsg,making $(basename $@).md from $(basename $@).m4d)
$(Q)$(call md-m4d,$(basename $@).m4d,$(basename $@).md)
# make htex from md (markdown+latex math)
%.htex: %.md $(SVNVERSION_FILE_DEP) $(HTEX_MD_EXTRA_DEPS)
$(Q)$(MAKE_NPD) $@-md-impl
%.htex-md-impl:
@$(call bmsg,making $(basename $@).htex from $(basename $@).md)
$(Q)$(call htex-md,$(basename $@).md,$(basename $@).htex)
# make html from htex (html+gladtex)
%.html: %.htex $(SVNVERSION_FILE_DEP) $(HTML_HTEX_EXTRA_DEPS)
$(Q)$(MAKE_NPD) $@-htex-impl
%.html-htex-impl:
@$(call bmsg,making $(basename $@).html from $(basename $@).htex)
$(Q)$(call html-htex,$(basename $@).htex,$(basename $@).html)
$(Q)$(call wwwimagesize $(basename $@).html)
# build a .class file from a .java file
export COMPILESERVER_MSG_DELIVERED = 0
ifdef CS_VERBOSE
COMPILESERVER_MSG = \
$(if $(USING_COMPILE_SERVER),\
$(call imsg,"using compile server"),\
$(call imsg,"not using compile server: $(CS_WHY_NOT)"))
endif
ifeq ($(findstring CYGWIN,$(SYSTEM)),CYGWIN)
#fix paths on cygwin. ARGH...
ifdef USING_COMPILE_SERVER
%.class: %.java
@$(COMPILESERVER_MSG)
@$(call bmsg,compiling $<)
$(Q)$(JAVAC_OR_CS_SUBMIT) $(JAVAC_FLAGS) \
"`cygpath -w "$(addprefix $(shell pwd)/,$<)"`" \
$(if $(filter $<,$(IGNORE_JAVAC_ERRORS)),> /dev/null 2>&1 || \
$(call wmsg,"compilation of $< failed (errors ignored)"))
else
%.class: %.java
@$(COMPILESERVER_MSG)
@$(call bmsg,compiling $<)
$(Q)$(JAVAC_OR_CS_SUBMIT) $(JAVAC_FLAGS) $< \
$(if $(filter $<,$(IGNORE_JAVAC_ERRORS)),> /dev/null 2>&1 || \
$(call wmsg,"compilation of $< failed (errors ignored)"))
endif
else
# not on cygwin. Phew.
%.class: %.java
@$(COMPILESERVER_MSG)
@$(call bmsg,compiling $<)
$(Q)$(JAVAC_OR_CS_SUBMIT) $(JAVAC_FLAGS) $< \
$(if $(filter $<,$(IGNORE_JAVAC_ERRORS)),> /dev/null 2>&1 || \
$(call wmsg,"compilation of $< failed (errors ignored)"))
endif
# build Java source files from a .jj grammar file
%.java: %.jj
@$(call bmsg,compiling $<)
$(Q)$(JAVACC) $<
# run a class in a specific package
$(PROJECT).%.run: $(if BUILD_BEFORE_RUN,$(PROJECT).%.class,)
@$(call bmsg,running $(basename $@))
$(Q)$(JAVA_PREFIX) $(JAVA) $(RUN_JAVA_FLAGS) $(basename $@)
# run a class in the current package with a main() function directly
%.run: $(if BUILD_BEFORE_RUN,%.class,)
@$(call bmsg,running $(PACKAGE).$(basename $@))
$(Q)$(JAVA_PREFIX) $(JAVA) $(RUN_JAVA_FLAGS) $(PACKAGE).$(basename $@)
# run a class in appletviewer (specify html filename without path or extension)
%.appletviewer:
@$(call bmsg,appletviewer $(basename $@).html)
$(Q)$(JDK_BIN)/appletviewer $(basename $@).html
# build a class in a specific package
$(PROJECT).%.class:
@$(call bmsg,compiling $(basename $@).java)
$(Q)$(CD) $(PROJECT_HOME)/../$(call package-to-path,$(call package-part,$(basename $@))) && $(MAKE_NPD) $(call class-part,$(basename $@)).class
# build a specific package
$(PROJECT).%.package-make:
@$(call bmsg,making package $(basename $@))
$(Q)$(CD) $(PROJECT_HOME)/../$(call package-to-path,$(basename $@)) && \
$(MAKE_NPD) package
# recursive build of the base package is a project build
# note the semicolon which makes this an "empty command"!!
# without it the %.recursive pattern would get called after this runs
# resulting in an infinite loop!!
$(PROJECT).package-make.recursive: project ;
# build a specific package and all descendant packages
$(PROJECT).%.package-make.recursive:
@$(call bmsg,making package $(basename $(basename $@)) and all descendants)
$(Q)$(CD) \
$(PROJECT_HOME)/../$(call package-to-path,$(basename $(basename $@))) && \
$(MAKE_NPD) package.recursive
# trick make into building the base package when asked
# if we don't do this then a spurious implicit rule gets invoked because the
# base package has no .suffix
$(PROJECT).package-make:
@$(call bmsg,making base package $(PROJECT))
$(Q)$(CD) $(PROJECT_HOME) && $(MAKE_NPD) package
# recursively make something
%.recursive:
# @$(call bmsg,recursively making $(basename $@))
$(Q)$(MAKE_NPD) $(basename $@)
$(Q)$(call recursively-make,$@,true)
%/makefile: makefile
$(Q)if [ -e $@ ] && [ `grep -c super-ninja $@ 2> /dev/null ` -eq 0 ]; \
then echo "$@ exists but is not super-ninja, skipping"; \
else $(call bmsg,(re)making $(call package-to-path,$(PACKAGE))/$@); \
$(RM) $@ && \
sed \
-e 's|^$(WS)PROJECT_HOME$(WS)=$(WS)\(.*\)$(WS)|PROJECT_HOME = ../\1|' \
-e 's/^$(WS)PACKAGE$(WS)=$(WS)\(.*\)$(WS)/PACKAGE = \1.$(subst /,,$(dir $@))/' \
-e 's/^$(WS)if-root-package$(WS)=.*/if-root-package = $$(2)/' \
makefile > $@; \
fi
# makefile utility and debug targets ###########################################
show-%:
@echo $($(call dash-to-underscore,$(call toupper,$*)))
# these are used by the run-class script
.PHONY: show-java
show-java:
@echo $(JAVA_PREFIX) $(JAVA)
.PHONY: show-run-java-flags
show-run-java-flags:
@echo $(RUN_JAVA_FLAGS)
.PHONY: show-run-java-with-flags
show-run-java-with-flags:
@echo $(JAVA_PREFIX) $(JAVA) $(RUN_JAVA_FLAGS)
.PHONY: show-run-java-with-flags-and-package
show-run-java-with-flags-and-package:
@echo $(JAVA_PREFIX) $(JAVA) $(RUN_JAVA_FLAGS) $(PACKAGE)
.PHONY: show-package
show-package:
@echo $(PACKAGE)
# package targets ##############################################################
# make the current package
.PHONY: package
package: $(EXTRA_PACKAGE_DEPS) $(PACKAGE_DEPS)
$(EXTRA_PACKAGE_CMDS)
.PHONY: package-javac
package-javac: $(PACKAGE_JAVAC_DEPS)
.PHONY: package-source-gen
package-source-gen: package-javacc
# make javacc in the current package
.PHONY: package-javacc
package-javacc: $(PACKAGE_JAVACC_DEPS)
# make html in the current package
.PHONY: package-html
package-html: $(PACKAGE_HTML_EXTRA_DEPS) $(PACKAGE_HTML_DEPS)
# this seems like a nice way to ensure that the makefile in the current package
# is up to date, but the problem is that if it does get remade that will emit a
# mesage even if -s was specified to the command line
#
# make the makefile in the current package
#ifndef ROOT_PACKAGE
#makefile: $(PROJECT_HOME)/makefile
# $(Q)@$(CD) .. && $(MAKE_NPD) $(PACKAGE_NAME)/makefile
#else
#makefile: FORCE
#endif
.PHONY: clean
clean: $(EXTRA_CLEAN_DEPS)
@echo removing all .class files in this package
$(Q)$(RM) *.class
.PHONY: c-clean
c-clean:
@echo removing all .o files in this package
$(Q)$(RM) *.o
.PHONY: javacc-clean
javacc-clean:
@echo removing javacc-generated files
$(Q)$(RM) `ls *.java | xargs grep -l "Generated By:JavaCC"`
.PHONY: rmiwrap-clean
rmiwrap-clean:
@echo removing RMIWrap-generated files
$(Q)$(RM) `ls *.java | xargs grep -l "generated by RMIWrap"`
.PHONY: svnversion-clean
svnversion-clean:
@echo removing generated $(SVNVERSION_FILE)
$(Q)$(RM) $(SVNVERSION_FILE)
.PHONY: html-clean
html-clean:
@echo removing all generated html
$(Q)$(RM) $(PACKAGE_HTML_DEPS)
$(Q)$(RM) $(GEN_MD)
$(Q)$(RM) -f gen-*.html *.htex
$(Q)$(RM) -rf gen-images-*
.PHONY: jar-clean
jar-clean:
# $(Q)$(RM) $(JARFILE_PAT) $(JARFILE_LITE_PAT) $(JARFILE_XLITE_PAT)
# $(Q)$(RM) $(JARFILE_NEWEST) $(JARFILE_LITE_NEWEST) $(JARFILE_XLITE_NEWEST)
$(Q)$(RM) $(APPNAME)-*.jar
.PHONY: javadoc-clean
javadoc-clean:
$(Q)$(RM) -r $(JAVADOC_DIR)
.PHONY: realclean
realclean: $(EXTRA_REALCLEAN_DEPS) clean rmiwrap-clean javacc-clean html-clean jar-clean javadoc-clean $(if $(SVNVERSION_FILE_NOAUTO),,svnversion-clean)
$(Q)if [ -f core ]; then $(RM) core; fi
.PHONY: show-svnversion
show-svnversion:
@echo $(SVNVERSION)
.PHONY: show-svnversion-string
show-svnversion-string:
@echo $(SVNVERSION_STRING)
.PHONY: show-svnversion-file-dep
show-svnversion-file-dep:
@echo $(SVNVERSION_FILE_DEP)
$(SVNVERSION_FILE): FORCE
@$(call bmsg,updating $@)
$(Q)$(SVNVERSION) > $@
$(Q)date +%Y-%m-%d >> $@
# project targets ##############################################################
.PHONY: project-announce
project-announce:
@echo making project
.PHONY: project
project: project-announce $(if $(NO_SOURCE_GEN),,project-source-gen)
$(Q)$(call make-from-project-home,package.recursive)
.PHONY: project-javacc
project-javacc:
$(Q)$(call make-from-project-home,package-javacc.recursive)
.PHONY: project-source-gen
project-source-gen:
$(Q)$(call make-from-project-home,package-source-gen.recursive)
.PHONY: project-html
project-html:
$(Q)$(call make-from-project-home,package-html.recursive)
.PHONY: project-javadoc
project-javadoc:
$(Q)$(call make-from-project-home,subproject-javadoc)
.PHONY: subproject-javadoc
subproject-javadoc:
$(Q)if [ "$(SUBPROJECT_PACKAGES)" ]; then \
$(call javadoc,$(SUBPROJECT_PACKAGES),$(EXCLUDE_JAVADOC_PACKAGES)); fi
.PHONY: cacheclean
cacheclean:
@$(RM) $(CACHEFILE)
.PHONY: project-clean
project-clean:
$(Q)$(call make-from-project-home,clean.recursive)
.PHONY: project-realclean
project-realclean: cacheclean
$(Q)$(call make-from-project-home,realclean.recursive)
.PHONY: project-show-svnversion
project-show-svnversion:
$(Q)$(call make-from-project-home,show-svnversion)
.PHONY: project-$(SVNVERSION_FILE)
project-SVNVERSION.txt:
$(Q)$(call make-from-project-home,$(SVNVERSION_FILE))
.PHONY: makefiles
makefiles: $(SUBPACKAGE_MAKEFILES)
$(Q)$(call recursively-make,makefiles,true)
# jar and publish targets ######################################################
# make the jar key
.PHONY: keygen
keygen:
$(Q)$(JDK_BIN)/keytool -genkey -keyalg rsa -alias $(JARKEY)
$(Q)$(JDK_BIN)/keytool -export -alias $(JARKEY) -file $(JAR_CRT)
# make the jar
#
# the jar is built containing all rsync-able files in all
# $(SUBPROJECT_PACKAGES), the subproject javadoc, and the makefile from the
# base package. Subproject packages ending in "." are copied non-recursively,
# else they are copied recursively.
#
# empty dirs will not be included in the jar
#
# all $(EXT_JARS) and $(EXT_JARS_JARFILE_ONLY), if any, are folded in to the
# generated jarfile (it's ok to include a jar in both of those lists)
#
# if $(JAR_MF) exists it is used as the jar manifest
#
# if $(JAR_CRT) exist the jar is signed with $(JARKEY)
.PHONY: jar
jar: $(SVNVERSION_FILE_DEP)
$(Q)$(MAKE_NPD) jar-impl
.PHONY: jar-impl
jar-impl:
$(Q)$(call make-jar,true,$(EXT_JARS) $(EXT_JARS_JARFILE_ONLY),$(JARFILE_SUBST),$(JARFILE_EXTS),$(JAR_EXTRA),$(SUBPROJECT_PACKAGES),$(JARFILE_NEWEST),$(JAR_EXTRA_CMDS))
# make the lite jar
#
# same as the "jar" target except uses LITE_SUBPROJECT_PACKAGES, EXT_JARS_LITE,
# EXT_JARS_LITE_JARFILE_ONLY, JARFILE_LITE_EXTS, JAR_LITE_EXTRA
.PHONY: jar-lite
jar-lite: $(SVNVERSION_FILE_DEP)
$(Q)$(MAKE_NPD) jar-lite-impl
.PHONY: jar-lite-impl
jar-lite-impl:
$(Q)$(call make-jar,true,$(EXT_JARS_LITE) $(EXT_JARS_LITE_JARFILE_ONLY),$(JARFILE_LITE_SUBST),$(JARFILE_LITE_EXTS),$(JAR_LITE_EXTRA),$(LITE_SUBPROJECT_PACKAGES),$(JARFILE_LITE_NEWEST),$(JAR_LITE_EXTRA_CMDS))
# make the xlite jar
#
# same as the "jar-lite" target except uses XLITE_SUBPROJECT_PACKAGES,
# EXT_JARS_XLITE, EXT_JARS_XLITE_JARFILE_ONLY, JARFILE_XLITE_EXTS, and
# JAR_XLITE_EXTRA
.PHONY: jar-xlite
jar-xlite: $(SVNVERSION_FILE_DEP)
$(Q)$(MAKE_NPD) jar-xlite-impl
.PHONY: jar-xlite-impl
jar-xlite-impl:
$(Q)$(call make-jar,false,$(EXT_JARS_XLITE) $(EXT_JARS_XLITE_JARFILE_ONLY),$(JARFILE_XLITE_SUBST),$(JARFILE_XLITE_EXTS),$(JAR_XLITE_EXTRA),$(XLITE_SUBPROJECT_PACKAGES),$(JARFILE_XLITE_NEWEST),$(JAR_XLITE_EXTRA_CMDS))
# make a jar for specific platforms
# e.g. jar-nonatives, jar-windows, jar-amd64, jar-windows-linux-amd64
jar-%: $(SVNVERSION_FILE_DEP)
$(Q)$(MAKE_NPD) \
JAR_OS_INCLUDE="$(filter $(JAR_OS_ALL),$(subst -,$(SPACE),$@))" \
JAR_ARCH_INCLUDE="$(filter $(JAR_ARCH_ALL),$(subst -,$(SPACE),$@))" \
jar-impl
.PHONY: jars
jars: $(PROJECT_JAR_TARGETS)
# publish to PUBLISH_DEST
#
# rsyncs $(JARFILE_SUBST) (and $(JARFILE_LITE_SUBST), and
# $(JARFILE_XLITE_SUBST), if any) there and rsync's
# $(JARFILE_PUBLISH_UNPACK_SUBST)'s contents there
.PHONY: publish
ifdef PUBLISH_DEST
publish: $(SVNVERSION_FILE_DEP)
$(Q)$(MAKE_NPD) publish-impl
.PHONY: publish-impl
publish-impl:
@echo publishing to $(PUBLISH_DEST)
$(Q)if [[ "$(JARFILE_PUBLISH_UNPACK_SUBST)"x != x ]]; then \
if [[ -f $(JARFILE_PUBLISH_UNPACK_SUBST) ]]; then \
$(call jmsg,"unpacking $(JARFILE_PUBLISH_UNPACK_SUBST) and rsyncing to $(PUBLISH_DEST)"); \
mkdir .$(JARFILE_PUBLISH_UNPACK_SUBST)-unpack.tmp; \
pushd .$(JARFILE_PUBLISH_UNPACK_SUBST)-unpack.tmp > /dev/null; \
$(JAR) x$(JAR_DBG)f ../$(JARFILE_PUBLISH_UNPACK_SUBST) $(if $(JAR_DBG),,> /dev/null) && \
$(call rsync,*,$(PUBLISH_DEST)); \
popd > /dev/null; \
rm -rf .$(JARFILE_PUBLISH_UNPACK_SUBST)-unpack.tmp; \
else $(call wmsg,"not unpacking $(JARFILE_PUBLISH_UNPACK_SUBST) - file not found"); fi; fi
$(Q)$(foreach j,$(wildcard $(APPNAME)*newest*.jar),\
$(call jmsg,"rsyncing $(realpath $(j)) to $(PUBLISH_DEST)"); \
$(call rsync,$(realpath $(j)),$(PUBLISH_DEST),--copy-links); \
$(call jmsg,"rsyncing $(j) to $(PUBLISH_DEST)"); \
$(call rsync,$(j),$(PUBLISH_DEST)); )
$(EXTRA_PUBLISH_CMDS)
else
publish:
@echo PUBLISH_DEST not set
$(EXTRA_PUBLISH_CMDS)
endif