1# ----------------------------------------------------------------------------- 2# 3# (c) 2009 The University of Glasgow 4# 5# This file is part of the GHC build system. 6# 7# To understand how the build system works and how to modify it, see 8# https://gitlab.haskell.org/ghc/ghc/wikis/building/architecture 9# https://gitlab.haskell.org/ghc/ghc/wikis/building/modifying 10# 11# ----------------------------------------------------------------------------- 12 13 14define hs-suffix-way-rules # args: $1 = dir, $2 = distdir, $3 = way, $4 = stage 15 16ifeq "$3 $$($1_$2_DYNAMIC_TOO)" "dyn YES" 17# We only want this rule to be used for Haskell sources, not for 18# e.g. C sources, so we depend on the v_hisuf rather than v_osuf. 19$1/$2/build/%.$$(dyn_osuf): $1/$2/build/%.$$(v_hisuf) 20 @if [ ! -f $$@ ] ; then \ 21 echo "Panic! $$< exists, but $$@ does not."; \ 22 exit 1; \ 23 fi 24 25$1/$2/build/%.$$(dyn_osuf)-boot: $1/$2/build/%.$$(v_hisuf)-boot 26 @if [ ! -f $$@ ] ; then \ 27 echo "Panic! $$< exists, but $$@ does not."; \ 28 exit 1; \ 29 fi 30else 31 32# Note [Implicit rule search algorithm] 33# 34# The order in which implicit rules are defined can influence a build. 35# 36# Case study: genprimpos/Lexer.hs 37# 38# We have two implicit rules for creating .o files, which after instantiating 39# with a specific directory ($1=utils/genprimops) and distdir ($2=dist) look 40# like this: 41# 42# utils/genprimops/dist/build/%.o : utils/genprimops/dist/build/%.hs 43# <recipe1> 44# utils/genprimops/dist/build/%.o : utils/genprimops/./%.hs 45# <recipe2> 46# 47# The first rule is defined in hs-suffix-way-rules.mk (this file), the other 48# in hs-suffix-way-rules-srcdir.mk. 49# 50# Assume for rest of this story that %=Lexer. 51# 52# In a normal repository checkout, neither Lexer.hs exists, but we have a rule 53# to generate the one in the build directory by running alex on Lexer.x (the 54# rule for that operation is defined in hs-suffix-rules-srcdir.mk). Since make 55# needs to make a choice which of the above two implicit rules to follow (it 56# never runs 2 recipes for the same target, unless double colon rules are 57# used, which we don't), logically it will choose the first rule: Lexer.o will 58# depend on Lexer.hs in the build directory, that file will be built, and then 59# Lexer.o can be built. 60# 61# In an sdist however, Lexer.hs is present in the source directory. It was 62# copied there during the creation of the sdist by a rule in 63# sdist-ghc-file.mk. And this time we *don't* know how to generate the 64# Lexer.hs in the build directory, because 1) alex is not installed when 65# building from sdist and 2) the sdist creation process renamed Lexer.x to 66# Lexer.x.source. So normally make would now choose the second rule: Lexer.o 67# will depend on Lexer.hs in the source directory, for which nothing needs to 68# be done, and then Lexer.o can be built. 69# 70# There is however another actor in play, a rule in sdist-ghc-file.mk, which 71# after after instantiating with the same directory ($1=utils/genprimops) and 72# distdir ($2=dist) looks like this: 73# 74# sdist_utils/genprimops_dist_Lexer : utils/genprimops/dist/build/Lexer.hs 75# 76# Note that this is not an implicit rule, there aren't any %'s. This rule 77# *explicitly* depends on Lexer.hs in the build directory. What follows is the 78# following: 79# 80# * make thinks Lexer.hs in the build directory "ought to exist" [1], 81# because it is an explicit dependency of /some/ target. 82# 83# * this puts our two implicit rules on equal footing: one depends on a 84# file that exists, the other on a file that ought to exist. Make's 85# implicit rule search algorithm doesn't distinguish between these two 86# cases [1]. 87# 88# * to break the tie, make chooses the rule that is defined first. Lexer.o 89# will depend on Lexer.hs in the build directory, which doesn't exist, 90# and which make doesn't know how to build, causing a build failure. 91# 92# To prevent this from happening we define rules for haskell source files in 93# the source directory before those in the distdir. 94# 95# Alternative solutions: 96# 97# * Don't include the explicit rule above when not creating an sdist, as 98# that is the only time when it is needed. 99# 100# * Merge the two implicit rules, with help from $1_$2_HS_SRCS from 101# hs-sources.mk, which is sdist aware. 102# 103# * Require alex and happy to be installed when building from an sdist, 104# simplifying all this drastically. 105# 106# [1] https://www.gnu.org/software/make/manual/make.html#Implicit-Rule-Search 107 108$$(foreach dir,$$($1_$2_HS_SRC_DIRS),\ 109 $$(eval $$(call hs-suffix-way-rules-srcdir,$1,$2,$3,$$(dir),$4))) 110 111 112ifneq "$$(BINDIST)" "YES" 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 $$@ 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 $$@))) 119 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 $$@ 122 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 $$@))) 125 126endif 127 128 129endif 130 131endef # hs-suffix-way-rules 132 133