Implemented batch-compilation of Java files. Reduced compilation time of a large Java project I used as a test case by 5 times.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/tools/make/trunk@28783 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Nicola Pero 2009-10-08 00:31:00 +00:00
parent 2702966142
commit 96d7a27285
6 changed files with 136 additions and 18 deletions

View file

@ -1,3 +1,23 @@
2009-10-09 Nicola Pero <nicola.pero@meta-innovation.com>
Implemented batch-compilation of Java files (ie, all files built
in a single javac invocation) to speed up building Java software.
In the the large Java project I used as a test case, this change
produced a 5x reduction in building time.
* rules.make (%.class): If BATCH_COMPILE_JAVA_FILES is not set to
no, and JAVA_FILES_TO_BATCH_COMPILE is set and the file we're
compiling is in that variable, do a batch compile instead of a
single-file compile.
* messages.make (INSIDE_ECHO_JAVA_COMPILING): New message.
(INSIDE_ECHO_JAVA_BATCH_COMPILING): New message.
* Instance/Shared/java.make: If appropriate, set
JAVA_FILES_TO_BATCH_COMPILE to the list of files we want to batch
compile.
($(GNUSTEP_INSTANCE)_BATCH_COMPILE_JAVA_FILES): New variable
allowing to disable the batch compilation of Java files if needed.
* Documentation/releasenotes.texi: Updated.
* RELEASENOTES: Regenerated.
2009-09-27 Nicola Pero <nicola.pero@meta-innovation.com>
* configure.ac: Turn off autodependencies on cygwin.

View file

@ -33,6 +33,20 @@ specified. If you do not want the debugging symbols, remember that
you can use the 'make strip=yes' option to have them stripped out from
all object files when they are installed.
@item batch-compilation of Java files
gnustep-make used to compile Java files one by one. In most Java
compilers this is very suboptimal. Starting from release 2.2.1,
gnustep-make will compile all Java files in a Java project with a
single Java compiler invocation. This can significantly speed up
compilation of large projects. To disable it and get the behaviour of
gnustep-make 2.2.0, please set the variable BATCH_COMPILE_JAVA_FILES
to 'no' (or the variable xxx_BATCH_COMPILE_JAVA_FILES to 'no' to
disable it for a single instance). Please note that if you are using
the xxx_FILE_FLAGS or xxx_FILE_FILTER_OUT_FLAGS functionality for Java
files, which allows you to customize the compilation flags for each
Java file, then batch compilation is automatically disabled and all
files are compiled separately.
@end table
@section Version 2.2.0

View file

@ -4,9 +4,9 @@
# Makefile fragment with rules to compile and install java files,
# with associated property files.
#
# Copyright (C) 2000, 2002 Free Software Foundation, Inc.
# Copyright (C) 2000, 2002, 2009 Free Software Foundation, Inc.
#
# Author: Nicola Pero <nicola@brainstorm.co.uk>
# Author: Nicola Pero <nicola.pero@meta-innovation.com>
#
# This file is part of the GNUstep Makefile Package.
#
@ -20,19 +20,31 @@
# If not, write to the Free Software Foundation,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# Note: we do not support building Java stuff in parallel (yet ?).
# Not sure it would be faster - needs testing.
#
#
# input variables:
#
# JAVA_OBJ_FILES, JAVA_JNI_OBJ_FILES, SUBPROJECT_OBJ_FILES :
# the list of object files (built by Instance/rules.make)
# $(GNUSTEP_INSTANCE)_JAVA_FILES: The list of Java files to compile.
# These are the files that will be batch-compiled unless
# xxx_BATCH_COMPILE_JAVA_FILES is set to no, or unless they can't be
# batch-compiled because each of them uses a different flag.
#
# JAVA_OBJ_FILES, JAVA_JNI_OBJ_FILES, SUBPROJECT_OBJ_FILES: the list
# of object files (built by Instance/rules.make). These are the
# files that will always be built. If some of the JAVA_OBJ_FILES are
# not built from xxx_JAVA_FILES but from something else, they'll
# still be compiled, but one by one - not batched with the
# xxx_JAVA_FILES.
#
# $(GNUSTEP_INSTANCE)_JAVA_PROPERTIES_FILES : the list of .properties files
# to install together with the .java files
#
# BATCH_COMPILE_JAVA_FILES: if this variable is set to 'no', batch compilation
# of all Java files is disabled.
#
# $(GNUSTEP_INSTANCE)_BATCH_COMPILE_JAVA_FILES: if this variable is set to 'no',
# batch compilation of xxx_JAVA_FILES is disabled and they are compiled one by one.
# Else, it's enabled by default.
#
# GNUSTEP_SHARED_JAVA_INSTALLATION_DIR : the base directory where to
# install the files.
@ -47,7 +59,6 @@
# shared-instance-java-clean
#
.PHONY: \
shared-instance-java-all \
shared-instance-java-install \
@ -55,11 +66,43 @@ shared-instance-java-install-dirs \
shared-instance-java-uninstall \
shared-instance-java-clean
shared-instance-java-all: $(JAVA_OBJ_FILES) \
$(JAVA_JNI_OBJ_FILES) \
$(SUBPROJECT_OBJ_FILES)
# By default, we enable "batch compilation" of Java files. This means
# that whenever make determines that a Java files needs recompilation,
# the command that recompiles that files will actually recompile all
# the files in the batch as well - causing make to then skip all
# subsequent rebuilding - which is much more efficient.
#
# You can turn this off by setting
#
# xxx_BATCH_COMPILE_JAVA_FILES = no
#
# and this will cause all files to be always compiled one by one.
ifeq ($(BATCH_COMPILE_JAVA_FILES),)
BATCH_COMPILE_JAVA_FILES = $($(GNUSTEP_INSTANCE)_BATCH_COMPILE_JAVA_FILES)
endif
# First set it to an empty string, which disables batch compilation.
JAVA_FILES_TO_BATCH_COMPILE =
ifneq ($(BATCH_COMPILE_JAVA_FILES), no)
# We can only batch compile the files if they all have the same flags.
# So, if any file has a non-empty xxx_FILE_FILTER_OUT_FLAGS or
# xxx_FILE_FLAGS set, we disable batch compilation.
#
# PS: Here it would be nicer if we could not disable it completely,
# but only batch compile the files that require no special flags.
ifeq ($(strip $(foreach f,$($(GNUSTEP_INSTANCE)_JAVA_FILES),$($(f)_FILE_FILTER_OUT_FLAGS))$(foreach f,$($(GNUSTEP_INSTANCE)_JAVA_FILES),$($(f)_FILE_FLAGS))),)
# OK - batch compilation is enabled, and all files have the same compilation flags, so turn it on :-)
# By default, batch compile all xxx_JAVA_FILES.
JAVA_FILES_TO_BATCH_COMPILE = $($(GNUSTEP_INSTANCE)_JAVA_FILES)
endif
endif
# Say that you have a Pisa.java source file. Here we install both
# Pisa.class (the main class) and also, if they exist, all class files
# with names beginning wih Pisa$ (such as Pisa$1$Nicola.class); these

View file

@ -35,6 +35,21 @@ using a newer version of the make system.
option to have them stripped out from all object files when they
are installed.
`batch-compilation of Java files'
gnustep-make used to compile Java files one by one. In most Java
compilers this is very suboptimal. Starting from release 2.2.1,
gnustep-make will compile all Java files in a Java project with a
single Java compiler invocation. This can significantly speed up
compilation of large projects. To disable it and get the
behaviour of gnustep-make 2.2.0, please set the variable
BATCH_COMPILE_JAVA_FILES to 'no' (or the variable
xxx_BATCH_COMPILE_JAVA_FILES to 'no' to disable it for a single
instance). Please note that if you are using the xxx_FILE_FLAGS
or xxx_FILE_FILTER_OUT_FLAGS functionality for Java files, which
allows you to customize the compilation flags for each Java file,
then batch compilation is automatically disabled and all files are
compiled separately.
1.2 Version 2.2.0
=================

View file

@ -3,9 +3,9 @@
#
# Prepare messages
#
# Copyright (C) 2002 Free Software Foundation, Inc.
# Copyright (C) 2002, 2009 Free Software Foundation, Inc.
#
# Author: Nicola Pero <n.pero@mi.flashnet.it>
# Author: Nicola Pero <nicola.pero@meta-innovation.com>
#
# This file is part of the GNUstep Makefile Package.
#
@ -34,6 +34,10 @@ ifneq ($(messages),yes)
ECHO_PREPROCESSING = @(echo " Preprocessing file $< ...";
ECHO_PRECOMPILING = @(echo " Precompiling header file $< ...";
ECHO_COMPILING = @(echo " Compiling file $< ...";
# The following two are special as they don't have the initial '@(' for technical reasons.
# We use 'INSIDE_ECHO_' instead of 'ECHO_' to mark the difference.
INSIDE_ECHO_JAVA_COMPILING = echo "Compiling file $< ...";
INSIDE_ECHO_JAVA_BATCH_COMPILING = echo " Compiling Java files for $(GNUSTEP_INSTANCE) ...";
ECHO_LINKING = @(echo " Linking $(GNUSTEP_TYPE) $(GNUSTEP_INSTANCE) ...";
ECHO_JAVAHING = @(echo " Running javah on $< ...";
ECHO_INSTALLING = @(echo " Installing $(GNUSTEP_TYPE) $(GNUSTEP_INSTANCE)...";
@ -98,6 +102,8 @@ else
ECHO_PREPROCESSING =
ECHO_PRECOMPILING =
ECHO_COMPILING =
INSIDE_ECHO_JAVA_COMPILING =
INSIDE_ECHO_JAVA_BATCH_COMPILING =
ECHO_LINKING =
ECHO_JAVAHING =
ECHO_INSTALLING =

View file

@ -3,11 +3,11 @@
#
# All of the common makefile rules.
#
# Copyright (C) 1997, 2001 Free Software Foundation, Inc.
# Copyright (C) 1997, 2001, 2009 Free Software Foundation, Inc.
#
# Author: Scott Christley <scottc@net-community.com>
# Author: Ovidiu Predescu <ovidiu@net-community.com>
# Author: Nicola Pero <nicola@brainstorm.co.uk>
# Author: Nicola Pero <nicola.pero@meta-innovation.com>
#
# This file is part of the GNUstep Makefile Package.
#
@ -548,10 +548,30 @@ $(GNUSTEP_OBJ_DIR)/PrecompiledHeaders/ObjCC/:
endif
# FIXME - using a different build dir with java
# This rule is complicated because it supports for compiling a single
# file, and batch-compiling a chunk of files. By default, every file
# is compiled separately. But if you set JAVA_FILES_TO_BATCH_COMPILE
# to a list of .java files, and the file we are compiling falls in
# that list, we compile all the JAVA_FILES_TO_BATCH_COMPILE in this
# invocation instead of just that file. This is worth it as it
# can speed up compilation by orders of magnitude.
%.class : %.java
$(ECHO_COMPILING)$(JAVAC) \
$(filter-out $($<_FILE_FILTER_OUT_FLAGS),$(ALL_JAVACFLAGS)) \
$($<_FILE_FLAGS) $<$(END_ECHO)
ifeq ($(BATCH_COMPILE_JAVA_FILES), no)
$(ECHO_COMPILING)$(JAVAC) $(filter-out $($<_FILE_FILTER_OUT_FLAGS),$(ALL_JAVACFLAGS)) \
$($<_FILE_FLAGS) $<$(END_ECHO)
else
# Explanation: $(filter $<,$(JAVA_FILES_TO_BATCH_COMPILE)) is empty if
# $< (the file we are compiling) does not appear in
# $(JAVA_FILES_TO_BATCH_COMPILE), and not-empty if it appears in
# there.
$(ECHO_NOTHING)if [ "$(filter $<,$(JAVA_FILES_TO_BATCH_COMPILE))"x != ""x ]; then \
$(INSIDE_ECHO_JAVA_BATCH_COMPILING)$(JAVAC) $(ALL_JAVACFLAGS) $(JAVA_FILES_TO_BATCH_COMPILE); \
else \
$(INSIDE_ECHO_JAVA_COMPILING)$(JAVAC) $(filter-out $($<_FILE_FILTER_OUT_FLAGS),$(ALL_JAVACFLAGS)) \
$($<_FILE_FLAGS) $<; \
fi$(END_ECHO)
endif
# A jni header file which is created using JAVAH
# Example of how this rule will be applied: