Commit d16e3ce4 authored by Jose A. Lopes's avatar Jose A. Lopes

Optimize Haskell compilation

The idea is to compile (on demand, that is, when necessary) each
source file to a normal object file, a coverage object file, a
profiling object file, and a test object file.  Also, a given Haskell
binary is linked with the proper object files.  This is achieved with
the following Makefile variables:

Compilation modes (profiles):
1. HPROFILE enables/disables profiling
2. HCOVERAGE enables/disables coverage
3. HTEST enables/disables 'TEST' preprocessor definition

A few words on testing: testing means the problem described in issue
535: https://code.google.com/p/ganeti/issues/detail?id=535.  With
HTEST enable, ghc will be instructed to define the preprocessor
definition TEST, for modules that use '#ifdef TEST'.

Haskell binary targets fetch the proper dependencies.  They are also
'.PHONY' targets so that 'make' does not check for the file timestamp
and instead it will always call 'ghc --make ...'.  This is not a
problem because 'ghc' with the '--make' flag only compiles the
necessary object files.
Signed-off-by: default avatarJose A. Lopes <jabolopes@google.com>
Reviewed-by: default avatarMichele Tartara <mtartara@google.com>
parent dfcebee3
......@@ -973,70 +973,84 @@ install-exec-hook:
done
endif
HNORMAL_SUFFIX = .o
HPROFILE_SUFFIX = .prof.o
HCOVERAGE_SUFFIX = .hpc.o
HTEST_SUFFIX = .test.o
HSUFFIX = $(if $(HPROFILE),$(HPROFILE_SUFFIX), \
$(if $(HCOVERAGE),$(HCOVERAGE_SUFFIX), \
$(if $(HTEST),$(HTEST_SUFFIX), \
$(HNORMAL_SUFFIX))))
HFLAGS += $(if $(HPROFILE),-prof -auto-all,)
HFLAGS += $(if $(HCOVERAGE),-fhpc,)
HFLAGS += $(if $(HTEST),-DTEST,)
HS2PY_CONSTANTS_SRCS = src/hs2py-constants.hs \
src/AutoConf.hs \
src/Ganeti/BasicTypes.hs \
src/Ganeti/ConstantUtils.hs \
src/Ganeti/JSON.hs \
src/Ganeti/THH.hs \
src/Ganeti/Hs2Py/GenConstants.hs \
src/Ganeti/Hs2Py/ListConstants.hs \
src/Ganeti/HsConstants.hs \
src/Ganeti/PyValueInstances.hs
# This target cannot be merged with the '$(HS_ALL_PROGS)' target
# because 'hs2py-constants' cannot depend on 'Ganeti.Constants'. And
# the reason for this is because 'hs2py-constants' needs to generate
# Python code, and 'Ganeti.Constants' is generated by Python.
src/hs2py-constants: src/hs2py-constants.hs src/AutoConf.hs \
src/Ganeti/BasicTypes.hs src/Ganeti/ConstantUtils.hs \
src/Ganeti/JSON.hs src/Ganeti/THH.hs \
src/Ganeti/Hs2Py/GenConstants.hs \
src/Ganeti/Hs2Py/ListConstants.hs \
src/Ganeti/HsConstants.hs \
src/Ganeti/PyValueInstances.hs \
.NOTPARALLEL: src/hs2py-constants
.PHONY: src/hs2py-constants
src/hs2py-constants: $(HS2PY_CONSTANTS_SRCS) \
| stamp-srclinks
$(GHC) --make \
$(HFLAGS) \
-osuf $(notdir $@).o -hisuf $(notdir $@).hi \
$(HEXTRA) $(HEXTRA_INT) src/hs2py-constants.hs
$(HS_ALL_PROGS): %: %.hs $(HS_LIBTESTBUILT_SRCS) Makefile
@rm -f $@.tix
$(GHC) --make $(HFLAGS) \
-osuf $(HSUFFIX) \
-hisuf $(patsubst %.o,%.hi,$(HSUFFIX)) \
$(HEXTRA) \
src/hs2py-constants.hs
HS_SRCS = $(HS_LIBTESTBUILT_SRCS)
.NOTPARALLEL: $(HS_ALL_PROGS)
.PHONY: $(HS_ALL_PROGS)
$(HS_ALL_PROGS): %: %.hs $(HS_SRCS) Makefile
@if [ "$(notdir $@)" = "test" ] && [ "$(HS_NODEV)" ]; then \
echo "Error: cannot run unittests without the development" \
" libraries (see devnotes.rst)" 1>&2; \
exit 1; \
fi
@rm -f $(notdir $@).tix
$(GHC) --make \
$(HFLAGS) \
$(HS_PARALLEL3) $(HS_REGEX_PCRE) \
-osuf $(notdir $@).o -hisuf $(notdir $@).hi \
$(HEXTRA) $(HEXTRA_INT) $@
$(GHC) --make $(HFLAGS) \
-osuf $(HSUFFIX) \
-hisuf $(patsubst %.o,%.hi,$(HSUFFIX)) \
$(HS_PARALLEL3) $(HS_REGEX_PCRE) $(HEXTRA) $@
@touch "$@"
# for the test/hs/htest binary, we need to enable profiling/coverage
test/hs/htest: HEXTRA_INT=-fhpc -itest/hs
test/hs/htest: HCOVERAGE = true
test/hs/htest: HFLAGS += -itest/hs
# we compile the hpc-htools binary with the program coverage
test/hs/hpc-htools: HEXTRA_INT=-fhpc
test/hs/hpc-htools: HCOVERAGE = true
# we compile the hpc-mon-collector binary with the program coverage
test/hs/hpc-mon-collector: HEXTRA_INT=-fhpc
test/hs/hpc-mon-collector: HCOVERAGE = true
# test dependency
test/hs/offline-test.sh: test/hs/hpc-htools test/hs/hpc-mon-collector
# rules for building profiling-enabled versions of the haskell
# programs: hs-prof does the full two-step build, whereas
# hs-prof-quick does only the final rebuild (hs-prof must have been
# run before)
.PHONY: hs-prof hs-prof-quick
# rule for building profiling-enabled versions of the haskell programs
.PHONY: hs-prof
hs-prof:
@if [ -z "$(TARGET)" ]; then \
echo "You need to define TARGET when running this rule" 1>&2; \
exit 1; \
fi
$(MAKE) $(AM_MAKEFLAGS) clean
$(MAKE) $(AM_MAKEFLAGS) $(TARGET) HEXTRA="-osuf o"
rm -f $(HS_ALL_PROGS)
$(MAKE) $(AM_MAKEFLAGS) hs-prof-quick
hs-prof-quick:
@if [ -z "$(TARGET)" ]; then \
echo "You need to define TARGET when running this rule" 1>&2; \
exit 1; \
fi
$(MAKE) $(AM_MAKEFLAGS) $(TARGET) HEXTRA="-osuf prof_o -prof -auto-all"
$(MAKE) $(AM_MAKEFLAGS) HPROFILE=y $(TARGET)
dist_sbin_SCRIPTS = \
tools/ganeti-listrunner
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment