hs-suffix-way-rules.mk 5.38 KB
Newer Older
1 2 3 4 5 6 7
# -----------------------------------------------------------------------------
#
# (c) 2009 The University of Glasgow
#
# This file is part of the GHC build system.
#
# To understand how the build system works and how to modify it, see
8 9
#      http://ghc.haskell.org/trac/ghc/wiki/Building/Architecture
#      http://ghc.haskell.org/trac/ghc/wiki/Building/Modifying
10 11 12
#
# -----------------------------------------------------------------------------

Ian Lynagh's avatar
Ian Lynagh committed
13

14
define hs-suffix-way-rules  # args: $1 = dir,  $2 = distdir, $3 = way
Ian Lynagh's avatar
Ian Lynagh committed
15

16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
ifeq "$3 $$($1_$2_DYNAMIC_TOO)" "dyn YES"
# We only want this rule to be used for Haskell sources, not for
# e.g. C sources, so we depend on the v_hisuf rather than v_osuf.
$1/$2/build/%.$$(dyn_osuf): $1/$2/build/%.$$(v_hisuf)
	@if [ ! -f $$@ ] ; then \
	    echo "Panic! $$< exists, but $$@ does not."; \
	    exit 1; \
	fi

$1/$2/build/%.$$(dyn_osuf)-boot: $1/$2/build/%.$$(v_hisuf)-boot
	@if [ ! -f $$@ ] ; then \
	    echo "Panic! $$< exists, but $$@ does not."; \
	    exit 1; \
	fi
else

thomie's avatar
thomie committed
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
# Note [Implicit rule search algorithm]
#
# The order in which implicit rules are defined can influence a build.
#
# Case study: genprimpos/Lexer.hs
#
# We have two implicit rules for creating .o files, which after instantiating
# with a specific directory ($1=utils/genprimops) and distdir ($2=dist) look
# like this:
#
# utils/genprimops/dist/build/%.o : utils/genprimops/dist/build/%.hs
# 	<recipe1>
# utils/genprimops/dist/build/%.o : utils/genprimops/./%.hs
# 	<recipe2>
#
# The first rule is defined in hs-suffix-way-rules.mk (this file), the other
# in hs-suffix-way-rules-srcdir.mk.
#
# Assume for rest of this story that %=Lexer.
#
# In a normal repository checkout, neither Lexer.hs exists, but we have a rule
# to generate the one in the build directory by running alex on Lexer.x (the
# rule for that operation is defined in hs-suffix-rules-srcdir.mk). Since make
# needs to make a choice which of the above two implicit rules to follow (it
# never runs 2 recipes for the same target, unless double colon rules are
# used, which we don't), logically it will choose the first rule: Lexer.o will
Gabor Greif's avatar
Gabor Greif committed
58 59
# depend on Lexer.hs in the build directory, that file will be built, and then
# Lexer.o can be built.
thomie's avatar
thomie committed
60 61 62 63 64 65 66 67
#
# In an sdist however, Lexer.hs is present in the source directory. It was
# copied there during the creation of the sdist by a rule in
# sdist-ghc-file.mk. And this time we *don't* know how to generate the
# Lexer.hs in the build directory, because 1) alex is not installed when
# building from sdist and 2) the sdist creation process renamed Lexer.x to
# Lexer.x.source. So normally make would now choose the second rule: Lexer.o
# will depend on Lexer.hs in the source directory, for which nothing needs to
Gabor Greif's avatar
Gabor Greif committed
68
# be done, and then Lexer.o can be built.
thomie's avatar
thomie committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
#
# There is however another actor in play, a rule in sdist-ghc-file.mk, which
# after after instantiating with the same directory ($1=utils/genprimops) and
# distdir ($2=dist) looks like this:
#
#     sdist_utils/genprimops_dist_Lexer : utils/genprimops/dist/build/Lexer.hs
#
# Note that this is not an implicit rule, there aren't any %'s. This rule
# *explicitly* depends on Lexer.hs in the build directory. What follows is the
# following:
#
#    * make thinks Lexer.hs in the build directory "ought to exist" [1],
#      because it is an explicit dependency of /some/ target.
#
#    * this puts our two implicit rules on equal footing: one depends on a
#      file that exists, the other on a file that ought to exist. Make's
#      implicit rule search algorithm doesn't distinguish between these two
#      cases [1].
#
#    * to break the tie, make chooses the rule that is defined first. Lexer.o
#      will depend on Lexer.hs in the build directory, which doesn't exist,
#      and which make doesn't know how to build, causing a build failure.
#
# To prevent this from happening we define rules for haskell source files in
# the source directory before those in the distdir.
#
# Alternative solutions:
#
#     * Don't include the explicit rule above when not creating an sdist, as
#       that is the only time when it is needed.
#
#     * Merge the two implicit rules, with help from $1_$2_HS_SRCS from
#       hs-sources.mk, which is sdist aware.
#
#     * Require alex and happy to be installed when building from an sdist,
#       simplifying all this drastically.
#
# [1] https://www.gnu.org/software/make/manual/make.html#Implicit-Rule-Search

$$(foreach dir,$$($1_$2_HS_SRC_DIRS),\
  $$(eval $$(call hs-suffix-way-rules-srcdir,$1,$2,$3,$$(dir))))


112
ifneq "$$(BINDIST)" "YES"
Ian Lynagh's avatar
Ian Lynagh committed
113

114
$1/$2/build/%.$$($3_hcsuf) : $1/$2/build/%.hs $$(LAX_DEPS_FOLLOW) $$$$($1_$2_HC_DEP)
115
	$$(call cmd,$1_$2_HC) $$($1_$2_$3_ALL_HC_OPTS) -C $$< -o $$@
Ian Lynagh's avatar
Ian Lynagh committed
116

117
$1/$2/build/%.$$($3_osuf) : $1/$2/build/%.hs $$(LAX_DEPS_FOLLOW) $$$$($1_$2_HC_DEP)
118
	$$(call cmd,$1_$2_HC) $$($1_$2_$3_ALL_HC_OPTS) -c $$< -o $$@ $$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),-dyno $$(addsuffix .$$(dyn_osuf),$$(basename $$@)))
Ian Lynagh's avatar
Ian Lynagh committed
119

Edward Z. Yang's avatar
Edward Z. Yang committed
120
$1/$2/build/%.$$($3_hcsuf) : $1/$2/build/$$(or $$($1_EXECUTABLE),$$($1_$2_PROGNAME),.)/autogen/%.hs $$(LAX_DEPS_FOLLOW) $$$$($1_$2_HC_DEP)
121
	$$(call cmd,$1_$2_HC) $$($1_$2_$3_ALL_HC_OPTS) -C $$< -o $$@
Ian Lynagh's avatar
Ian Lynagh committed
122

Edward Z. Yang's avatar
Edward Z. Yang committed
123
$1/$2/build/%.$$($3_osuf) : $1/$2/build/$$(or $$($1_EXECUTABLE),$$($1_$2_PROGNAME),.)/autogen/%.hs $$(LAX_DEPS_FOLLOW) $$$$($1_$2_HC_DEP)
124
	$$(call cmd,$1_$2_HC) $$($1_$2_$3_ALL_HC_OPTS) -c $$< -o $$@ $$(if $$(findstring YES,$$($1_$2_DYNAMIC_TOO)),-dyno $$(addsuffix .$$(dyn_osuf),$$(basename $$@)))
Ian Lynagh's avatar
Ian Lynagh committed
125

126
endif
Ian Lynagh's avatar
Ian Lynagh committed
127

128

129 130
endif

131
endef # hs-suffix-way-rules
Ian Lynagh's avatar
Ian Lynagh committed
132