1 #PREMAKE_SOURCE_COMPILER#########################################################
2 # Compile any source-to-source languages before executing the majority of make ##
3 #################################################################################
4 define PREMAKE_SOURCE_COMPILER
=
5 # Find the sources for each source-to-source language
6 $(foreach slang
,$(SLANGS
),
7 $(eval SLANG_SRC
:= $(shell find
$(SRC_DIR
) -name
"*.$(slang)" -not
-name
".*"))
8 # Foreach target type in the source-to-source language, add this source's
9 # targets to the list of the current source-to-source language targets
10 $(eval undefine SLANG_TRG
)
11 $(foreach trg
,$($(slang
)_TRG
),
12 $(eval SLANG_TRG
+= $(SLANG_SRC
:%.
$(slang
)=%.
$(if
$($(slang
)_STEM
),$($(slang
)_STEM
).
)$(trg
))))
13 # Stat the source file's last-modified time to the var SRC_TIME
14 $(foreach src
,$(SLANG_SRC
),
15 # Establish a command to run for compiling this file
16 $(eval SHELL_CMD
:= cd
$(dir $(src
)) && $($(slang
)_C
) $($(slang
)_FLAGS
) $(notdir $(src
)))
17 # Evaluate missing targets
18 $(eval FOUND_TRG
:= $(shell find
$(dir $(src
)) -name
"$(basename $(notdir $(src))).*" -not
-name
".*"))
19 $(eval MISSING_TRG
:= $(filter-out $(FOUND_TRG
), $(SLANG_TRG
)))
20 # Check timings of existing files
21 $(eval SRC_TIME
:= $(shell stat
-c
%Y
$(src
)))
22 # For each of the targets created by this source language, evaluate the
23 # last-modified times of each potential target. If the file does not exist, set
24 # the time to '0', otherwise set it to the -c %Y result from statting the file.
25 $(foreach srctrg
,$(filter $(basename $(src
))%, $(SLANG_TRG
)),
26 $(eval TRG_TIMES
+= $(if
$(wildcard $(srctrg
)),$(shell stat
-c
%Y
$(srctrg
)),0)==$(srctrg
)))
27 # Sort TRG_TIMES, which will produce a list of oldest-first files and timestamps
28 # of the form [last-modified-deltatime]==[filename]
29 $(eval TRG_TIMES
:= $(shell echo
$(sort $(TRG_TIMES
)) |
$(call AWK_REVERSE_SQUASH
)))
30 # Evaluate the newest time from our ordered list by splitting the word up by its
31 # '==' connectors and looking at the first word
32 $(eval NEWEST_TRG_TIME
:= $(word 1,$(subst ==, ,$(TRG_TIMES
))))
33 # Find the older of the two times (between SRC_TIME and NEWEST_TRG_TIME)
34 $(eval OLDER_TIME
:= $(firstword $(sort $(NEWEST_TRG_TIME
) $(SRC_TIME
))))
35 # If the older of the two times is the newest target time found, then we need to
36 # rebuild, but only if our build rule intends to actually make something. If it
37 # instead does not intend to actually make a target, drop a functional rule that
38 # could hypothetically make the target for debugging and analysis purposes
40 $(eval BUILDGOALS
:= $(filter-out clean scrub purge
uninstall,$(MAKECMDGOALS
))),
41 $(eval BUILDGOALS
:= all))
42 $(if
$(and
$(BUILDGOALS
),$(or
$(MISSING_TRG
), $(filter $(OLDER_TIME
),$(NEWEST_TRG_TIME
)))),
43 $(if
$(findstring n
,$(MAKEFLAGS
)),
47 $(info $(SHELL_CMD
) $(eval
$(shell $(SHELL_CMD
)))))
49 # Put these targets on the MAKE_TARGETS list to be removed during "clean",
50 # regardless of whether or not they were built just now.
51 $(eval MAKE_TARGETS
+= $(SLANG_TRG
))
53 #/PREMAKE_SOURCE_COMPILER########################################################