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
13define build-dependencies
14$(call trace, build-dependencies($1,$2,$3))
15$(call profStart, build-dependencies($1,$2,$3))
16# $1 = dir
17# $2 = distdir
18# $3 = GHC stage to use (0 == bootstrapping compiler)
19
20$1_$2_depfile_haskell = $$($1_$2_depfile_base).haskell
21$1_$2_depfile_c_asm = $$($1_$2_depfile_base).c_asm
22
23$1_$2_C_FILES_DEPS = $$(filter-out $$($1_$2_C_FILES_NODEPS),$$($1_$2_C_FILES))
24
25$1_$2_MKDEPENDHS_FLAGS = -dep-makefile $$($1_$2_depfile_haskell).tmp $$(foreach way,$$($1_$2_WAYS),-dep-suffix "$$(patsubst %o,%,$$($$(way)_osuf))")
26$1_$2_MKDEPENDHS_FLAGS += -include-pkg-deps
27$1_$2_MKDEPENDHS_FLAGS += $(addprefix -I,$($1_INCLUDE_DIRS))
28
29ifneq "$$(NO_GENERATED_MAKEFILE_RULES)" "YES"
30
31# Some of the Haskell files (e.g. utils/hsc2hs/Main.hs) (directly or
32# indirectly) include the generated includes files.
33$$($1_$2_depfile_haskell) : $$(includes_$3_H_CONFIG) $$(includes_$3_H_PLATFORM)
34
35$$($1_$2_depfile_haskell) : $$($1_$2_HS_SRCS) $$($1_$2_HS_BOOT_SRCS) $$$$($1_$2_HC_MK_DEPEND_DEP) | $$$$(dir $$$$@)/.
36	$$(call removeFiles,$$@.tmp)
37ifneq "$$($1_$2_HS_SRCS)" ""
38	"$$($1_$2_HC_MK_DEPEND)" -M \
39	    $$($1_$2_$$(firstword $$($1_$2_WAYS))_MOST_DIR_HC_OPTS) \
40	    $$($1_$2_MKDEPENDHS_FLAGS) \
41	    $$($1_$2_HS_SRCS)
42endif
43	echo "$1_$2_depfile_haskell_EXISTS = YES" >> $$@.tmp
44ifneq "$$($1_$2_SLASH_MODS)" ""
45	for dir in $$(sort $$(foreach mod,$$($1_$2_SLASH_MODS),$1/$2/build/$$(dir $$(mod)))); do \
46		if test ! -d $$$$dir; then mkdir -p $$$$dir; fi \
47	done
48endif
49#    Some packages are from the bootstrapping compiler, so are not
50#    within the build tree. On Windows this causes a problem as they look
51#    like bad rules, due to the two colons, so we filter them out.
52	grep -v ' : [a-zA-Z]:/' $$@.tmp > $$@.tmp2
53# Insert the calls to hi-rule. Basically, we look for the
54#     Foo.dyn_o Foo.o : Foo.hs
55# lines, and create corresponding hi-rule lines
56#     <dollar>(eval <dollar>(call hi-rule,Foo.dyn_hi Foo.hi : %hi: %o Foo.hs))
57	sed -e '/hs$$$$/ p' -e '/hs$$$$/ s/o /hi /g' \
58             -e '/hs$$$$/ s/:/ : %hi: %o /'                       \
59             -e '/hs$$$$/ s/^/$$$$(eval $$$$(call hi-rule,/'      \
60             -e '/hs$$$$/ s/$$$$/))/'                             \
61             -e '/hs-boot$$$$/ p' -e '/hs-boot$$$$/ s/o-boot /hi-boot /g' \
62             -e '/hs-boot$$$$/ s/:/ : %hi-boot: %o-boot /'        \
63             -e '/hs-boot$$$$/ s/^/$$$$(eval $$$$(call hi-rule,/' \
64             -e '/hs-boot$$$$/ s/$$$$/))/'                        \
65             $$@.tmp2 > $$@
66# Some of the C files (directly or indirectly) include the generated
67# includes files.
68$$($1_$2_depfile_c_asm) : $$(includes_$3_H_CONFIG) $$(includes_$3_H_PLATFORM)
69
70$$($1_$2_depfile_c_asm) : $$($1_$2_C_FILES_DEPS) $$($1_$2_S_FILES) $$($1_$2_CMM_FILES) | $$$$(dir $$$$@)/.
71	$$(call removeFiles,$$@.tmp)
72ifneq "$$(strip $$($1_$2_C_FILES_DEPS) $$($1_$2_S_FILES)) $$($1_$2_CMM_FILES))" ""
73# We ought to actually do this for each way in $$($1_$2_WAYS), but then
74# it takes a long time to make the C deps for the RTS (30 seconds rather
75# than 3), so instead we just pass the list of ways in and let addCFileDeps
76# copy the deps for each way on the assumption that they are the same
77	$$(foreach f,$$($1_$2_C_FILES_DEPS) $$($1_$2_S_FILES) $$($1_$2_CMM_FILES), \
78	    $$(call addCFileDeps,$1,$2,$$($1_$2_depfile_c_asm),$$f,$$($1_$2_WAYS)))
79	$$(call removeFiles,$$@.bit)
80endif
81	echo "$1_$2_depfile_c_asm_EXISTS = YES" >> $$@.tmp
82	mv $$@.tmp $$@
83
84endif # NO_GENERATED_MAKEFILE_RULES
85
86# Note sed magic above: mkdependC can't do -odir stuff, so we have to
87# munge the dependencies it generates to refer to the correct targets.
88
89$(call profEnd, build-dependencies($1,$2,$3))
90endef
91
92# This comment is outside the "define addCFileDeps" as that definition
93# is a list of command lines, and if it is inside it then we pass this
94# comment to the shell every time we call the definition.
95# $1 = dir
96# $2 = distdir
97# $3 = depfile
98# $4 = file
99# $5 = ways
100#
101# The formatting of this definition (e.g. the blank line above) is
102# important, in order to get make to generate the right makefile code.
103#
104# 's|\\|/|g'
105#    We first normalise all slashes to be forward slashes. Note that
106#    $(TOP) also uses forward slashes.
107# 's| /$$| \\|'
108#    But now we need to fix the line continuation characters that we
109#    just broke.
110# "1s|\.o|\.$($w_osuf)|"
111#    We will have dependencies for .o files, so we need to fix them up
112#    for the right object suffix for the way we're doing
113# "1s|^|$(dir $4)|"
114#    We always get deps for just foo.o when the file we're making is
115#    a/b/c/foo.o, so we need to prepend the directory of the source file
116# "1s|$1/|$1/$2/build/|"
117#    Well, almost. We actually need to insert e.g. "dist/build" in the
118#    middle of that directory
119# "1s|$2/build/$2/build|$2/build|g"
120#    But some source files, e.g. sm/Evac_thr.c, are also inside the
121#    "dist/build" directory, so now we've just made
122#    "dist/build/dist/build", so we need to remove the duplication
123#    again
124# "s|$(TOP)/||g$(CASE_INSENSITIVE_SED)"
125#    Finally, when making deps for packages like ghc stage2, we have
126#    some include paths for packages registered in the in-tree package
127#    database. These include paths are full (i.e. not relative) paths,
128#    which means that the "cpp -MM" output uses full paths in some cases.
129#    This causes 2 problems:
130#    * they don't match up with the rules to rebuild the files, where
131#      appropriate.
132#    * on Windows, make interprets the colon in c:/foo/bar.h as make
133#      syntax.
134#    So we sed off $(TOP). Unfortunately, on Windows, the case for the
135#    drive letter is sometimes different in what $(TOP) starts with, and
136#    what the path in the package database starts with. We therefore
137#	 need to do the substitution case-insensitively on Windows. But
138#    the s///i modifier isn't portable, so we set CASE_INSENSITIVE_SED
139#    to "i" on Windows and "" on any other platform.
140
141# We use this not only for .c files, but also for .S and .cmm files.
142# As gcc doesn't know what a .cmm file is, it treats it as a linker
143# input and ignores it. We therefore tell gcc that all files are C
144# files with "-x c" so that it actually processes them all.
145
146define addCFileDeps
147
148	$(CPP) $($1_$2_MKDEPENDC_OPTS) $($1_$2_$(firstword $($1_$2_WAYS))_ALL_CC_OPTS) $($(basename $4)_CC_OPTS) -MM -x c $4 -MF $3.bit
149	$(foreach w,$5,sed -e 's|\\|/|g' -e 's| /$$| \\|' -e "1s|\.o|\.$($w_osuf)|" -e "1s|^|$(dir $4)|" -e "1s|$1/|$1/$2/build/|" -e "1s|$2/build/$2/build|$2/build|g" -e "s|^$(TOP)/||g$(CASE_INSENSITIVE_SED)" $3.bit >> $3.tmp &&) true
150endef
151
152ifeq "$(Windows_Host)" "YES"
153CASE_INSENSITIVE_SED = i
154else
155CASE_INSENSITIVE_SED =
156endif
157
158