summaryrefslogtreecommitdiff
path: root/cesar/common/make/build.mk
blob: 2619f840d151005d2314699d9f23b464e0576d7d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
58
59
60
61
62
63
64
65
66
67
68
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Define build rules.

# No default implicit rules.
.SUFFIXES:

# For each build type, define tools, and type.all rule.
# Call with: type, typevar
define BUILD_template

# Tools.
ifeq ($1,host)
$2_CC ?= $$(CC)
$2_CXX ?= $$(CXX)
$2_AR ?= $$(AR)
else
$2_CC ?= $$($2_CROSS_COMPILE)gcc
$2_CXX ?= $$($2_CROSS_COMPILE)g++
$2_AR ?= $$($2_CROSS_COMPILE)ar
$2_OBJCOPY ?= $$($2_CROSS_COMPILE)objcopy
$2_OBJDUMP ?= $$($2_CROSS_COMPILE)objdump
endif

# Command lines.
$2_COMPILE.c = $$($2_CC) $$($2_CPPFLAGS) $$($2_CFLAGS) -c
$2_COMPILE.cpp = $$($2_CXX) $$($2_CPPFLAGS) $$($2_CFLAGS) -c
$2_COMPILE.S = $$($2_CC) $$($2_CPPFLAGS) $$($2_ASFLAGS) -c
$2_LINK = $$($2_CC) $$($2_CFLAGS) $$($2_LDFLAGS)
$2_LINK_CXX = $$($2_CXX) $$($2_CXXFLAGS) $$($2_LDFLAGS)
ifneq ($1,host)
$2_MAKE_BIN_CMD = $$($2_OBJCOPY) -O binary
$2_MAKE_ROM_CMD = $$(TOOLS_DIR)/bin2rom
$2_MAKE_LST_CMD = $$($2_OBJDUMP) -S
$2_MAKE_SIZE_CMD = $$(TOOLS_DIR)/lram-size -dt --total-stderr
endif

$1.all: $$($2_EXES) \
	$$($2_LIBS) \
	$$(if $$($2_MAKE_BIN),$$($2_BINS)) \
	$$(if $$($2_MAKE_ROM),$$($2_ROMS)) \
	$$(if $$($2_MAKE_LST),$$($2_LSTS)) \
	$$(if $$($2_MAKE_SIZE),$$($2_SIZES))
endef
$(call foreach_type,BUILD_template)

.PHONY: build.all build.clean $(BUILD_TYPES:%=%.all) $(BUILD_TYPES:%=%.clean)

build.all: $(BUILD_TYPES:%=%.all)

# For each program, define the link rule.
# Call with: program, type, typevar, iscxx
PROGRAM_rule_template_echo := "LINK"
PROGRAM_rule_template_echo_CXX := "LDXX"
define PROGRAM_rule_template
.PHONY: $1
$1: $$(call prog2exe,$1,$2)
$$(call prog2exe,$1,$2): $$($1_OBJECTS) $$($1_MODULES_OBJECTS) $$($3_LINK_DEPS)
	@echo $(PROGRAM_rule_template_echo$4)" [$2] $$@"
	$Q$$($3_LINK$4) $$($1_OBJECTS) $$($1_MODULES_OBJECTS) $$($3_LDLIBS) $$($1_LDLIBS) -o $$@
endef
$(foreach type,$(BUILD_TYPES),\
$(foreach program,$($(call type2var,$(type))_PROGRAMS_LINKED),\
$(eval $(call PROGRAM_rule_template,$(program),$(type),$(call type2var,$(type)),$(call iscxx,$(program))))))

# For each library, define the archive rule.
# Call with: lib, type, typevar
LIB_rule_template_echo := "AR  "
define LIB_rule_template
.PHONY: $1
$1: $$(call prog2lib,$1)
$$(call prog2lib,$1): $$($1_OBJECTS) $$($1_MODULES_OBJECTS) $$($3_LINK_DEPS)
	@echo $(LIB_rule_template_echo)" [$2] $$@"
	$Q$$($3_AR) crs $$@ $$($1_OBJECTS) $$($1_MODULES_OBJECTS)
endef
$(foreach type,$(BUILD_TYPES),\
$(foreach lib,$($(call type2var,$(type))_PROGRAMS_LIBS),\
$(eval $(call LIB_rule_template,$(lib),$(type),$(call type2var,$(type))))))

# For each source, define the compile rule.
# Call with: source, type, typevar, source_suffix
SOURCE_rule_template_echo.c := "CC  "
SOURCE_rule_template_echo.cpp := "CXX "
SOURCE_rule_template_echo.S := "AS  "
define SOURCE_rule_template
$$(call src2obj,$1,$2): $1 | $$(OBJ_DIR_STAMP) $$($3_COMPILE_DEPS)
	@echo $(SOURCE_rule_template_echo$4)" [$2] $$<"
	$Q$$($3_COMPILE$4) -I$$(dir $$<).. -MMD -MP -MF $$(@:.o=.d) -MQ $$@ -o $$@ $$<
endef
$(foreach type,$(BUILD_TYPES),\
$(foreach source,$($(call type2var,$(type))_SOURCES),\
$(eval $(call SOURCE_rule_template,$(source),$(type),$(call type2var,$(type)),$(suffix $(source))))))

# For each program, define the binaries rules.
# Call with: program, type, typevar
MAKE_BIN_rule_template_echo := "BIN "
MAKE_ROM_rule_template_echo := "ROM "
MAKE_LST_rule_template_echo := "LST "
MAKE_SIZE_rule_template_echo := "SIZE"
define BINARIES_rule_template
.PHONY: $1.bin $1.rom $1.lst $1.size
# Binary file rule.
$1.bin: $$(call prog2bin,$1)
$$(call prog2bin,$1): $$(call prog2exe,$1,$2)
	@echo $$(MAKE_BIN_rule_template_echo)" [$2] $$@"
	$$Q$$($3_MAKE_BIN_CMD) $$< $$@

# ROM file rule.
$1.rom: $$(call prog2rom,$1)
$$(call prog2rom,$1): $$(call prog2bin,$1)
	@echo $$(MAKE_ROM_rule_template_echo)" [$2] $$@"
	$$Q$$($3_MAKE_ROM_CMD) < $$< > $$@

# List file rule.
$1.lst: $$(call prog2lst,$1)
$$(call prog2lst,$1): $$(call prog2exe,$1,$2)
	@echo $$(MAKE_LST_rule_template_echo)" [$2] $$@"
	$$Q$$($3_MAKE_LST_CMD) $$< > $$@

# SIZE file rule.
$1.size: $$(call prog2size,$1)
$$(call prog2size,$1): $$(call prog2exe,$1,$2)
	@echo $$(MAKE_SIZE_rule_template_echo)" [$2] $$@"
	$$Q$$($3_MAKE_SIZE_CMD) $$< > $$@
endef
$(foreach type,$(BUILD_TYPES),\
$(foreach program,$($(call type2var,$(type))_PROGRAMS_LINKED),\
$(eval $(call BINARIES_rule_template,$(program),$(type),$(call type2var,$(type))))))

# Include deps.
-include $(foreach type,$(BUILD_TYPES),$(call src2dep,$($(call type2var,$(type))_SOURCES),$(type)))

# Clean rules.
build.clean: $(BUILD_TYPES:%=%.clean)

$(BUILD_TYPES:%=%.clean): %.clean:
	rm -f $($(call type2var,$*)_PRODUCTS)
	@echo rm -f '[ $* .o and .d files ]'
	$Qrm -f $(call src2obj,$($(call type2var,$*)_SOURCES),$*) \
		$(call src2dep,$($(call type2var,$*)_SOURCES),$*)