aboutsummaryrefslogtreecommitdiff
path: root/rules.mk
blob: ed72b270aff0ef7f3c8c4d7f55e146fcdd0eab2f (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
139
140
141
142
143
144
145
146
# variables
VCS_ROOT = $(shell git rev-parse --show-toplevel)
CWD = $(shell pwd)

# generate build rules from variables
# This makefile defines the following targets:
# - all: default goal, build all default targets

# generate objects from sources
# arg 1:  target.SRCS
# arg 2:  object suffix prefix
# returns: target.OBJS
objects = $(foreach f,$($1),$(addprefix build/,$(addsuffix $2.o,$(basename $f))))

# generate depends from .S .c .cpp sources
# arg 1:  target.SRCS
# arg 2:  dependency suffix prefix
# returns: target.DEPS
depends = $(foreach f,$(filter %.S %.c %.cpp,$($1)),$(addprefix build/,$(addsuffix $2.d,$(basename $f))))

# default target
.DEFAULT_GOAL := all


# TARGETBIN: binaries using the target architecture
$(foreach T,${TARGETBIN},\
	$(eval  $T.OBJS += $(call objects,$T.SRCS,_${ARCH})  ) \
	$(eval  $T.DEPS += $(call depends,$T.SRCS,_${ARCH})  ) \
	$(eval  -include $($T.DEPS)                          ) \
	$(eval  $T.elf: ${$T.OBJS}                           ) \
	$(eval  DEFAULT_TARGETS += $T.elf) \
)

# TARGETLIB: static libraries using the target architecture
$(foreach T,${TARGETLIB},\
	$(eval  $T.OBJS += $(call objects,$T.SRCS,_${ARCH})  ) \
	$(eval  $T.DEPS += $(call depends,$T.SRCS,_${ARCH})  ) \
	$(eval  -include $($T.DEPS)                          ) \
	$(eval  $T.a: ${$T.OBJS}                             ) \
	$(eval  DEFAULT_TARGETS += $T.a) \
)

# HOSTTARGETBIN: binaries using the host compiler
$(foreach T,${HOSTTARGETBIN},\
	$(eval  $T.OBJS += $(call objects,$T.SRCS,)  ) \
	$(eval  $T.DEPS += $(call depends,$T.SRCS,)  ) \
	$(eval  -include $($T.DEPS)                  ) \
	$(eval  $T: ${$T.OBJS}; @echo '  HOST LD    $T'; ${HOST_CXX} ${HOST_LDFLAGS} -o $T ${$T.OBJS}   ) \
	$(eval  DEFAULT_TARGETS += $T) \
)

list-targets:
	@echo TARGETBIN
	@echo ${TARGETBIN} | tr ' ' '\n' | xargs -n1 echo "                "
	@echo TARGETLIB
	@echo ${TARGETLIB} | tr ' ' '\n' | xargs -n1 echo "                "
	@echo HOSTTARGETBIN
	@echo ${HOSTTARGETBIN} | tr ' ' '\n' | xargs -n1 echo "                "
	@echo HOSTTARGETLIB
	@echo ${HOSTTARGETLIB} | tr ' ' '\n' | xargs -n1 echo "                "
	@echo DEFAULT_TARGETS
	@echo ${DEFAULT_TARGETS} | tr ' ' '\n' | xargs -n1 echo "                "
	@echo TESTS
	@echo ${TESTS} | tr ' ' '\n' | xargs -n1 echo "                "

%.info:
	@echo "Target: $(basename $@)"
	@echo "  ARCH: ${ARCH}"
	@echo "  SRCS: ${$(basename $@).SRCS}"
	@echo "  OBJS: ${$(basename $@).OBJS}"
	@echo "  DEPS: ${$(basename $@).DEPS}"
	@echo "  LD    ${${ARCH}_LDFLAGS}"

all: ${DEFAULT_TARGETS}
	@echo " -> Built all in ${COMPONENT}"

# extra flags
${ARCH}_CFLAGS   += -I${VCS_ROOT}/lib/libk \
		    -Werror=implicit-function-declaration
${ARCH}_CXXFLAGS += -I${VCS_ROOT}/lib/libk -Drestrict=__restrict__

# Target suffix rules
# -MD         output makefile dependency rule
# -MT target  change the target of the rule
# -MF file    write the dependencies to file
%.a:
	@echo '       AR    $@'
	@${${ARCH}_AR} ${${ARCH}_ARFLAGS} $@ $(filter %.o,$^)

build/%_${ARCH}.o: %.s
	@echo '       AS    $<'
	@mkdir -p $(dir $@)
	@${${ARCH}_AS} ${${ARCH}_ASFLAGS} -c -o $@ $<

build/%_${ARCH}.o: %.S
	@echo '       CC    $<'
	@mkdir -p $(dir $@)
	@${${ARCH}_CC} ${${ARCH}_CFLAGS} -MD -MT $@ -MF $(@:.o=.d) -c -o $@ $<

build/%_${ARCH}.o: %.c
	@echo '       CC    $<'
	@mkdir -p $(dir $@)
	@${${ARCH}_CC} ${${ARCH}_CFLAGS} -MD -MT $@ -MF $(@:.o=.d) -c -o $@ $<

%.elf:
	@echo '       LD    $@'
	@${${ARCH}_LD} ${${ARCH}_LDFLAGS} -o $@ $^
	@echo -n '  B2b  '
	@b2sum $@ | cut -d' ' -f1

# Host suffix rules
build/%.o: %.c
	@echo '  HOST CC    $<'
	@mkdir -p $(dir $@)
	@${HOST_CC} ${HOST_CFLAGS} -MD -MT $@ -MF $(@:.o=.d) -c -o $@ $<

build/%.o: %.cc
	@echo '  HOST CXX   $<'
	@mkdir -p $(dir $@)
	@${HOST_CXX} ${HOST_CXXFLAGS} -MD -MT $@ -MF $(@:.o=.d) -c -o $@ $<

.PHONY: test test.quiet valgrind valgrind.quiet clean.base FORCE
test: ${TESTS}
	@echo " -> Running tests in $(CWD:${VCS_ROOT}/%=%)"
	@[[ -z "${TESTS}" ]] || ${VCS_ROOT}/scripts/test_runner.py --verbose ${TESTS}

test.quiet: ${TESTS}
	@echo " -> Running tests in $(CWD:${VCS_ROOT}/%=%)"
	@[[ -z "${TESTS}" ]] || ${VCS_ROOT}/scripts/test_runner.py ${TESTS}

valgrind: ${TESTS}
	@echo " -> Running valgrind on tests in $(CWD:${VCS_ROOT}/%=%)"
	@[[ -z "${TESTS}" ]] || ${VCS_ROOT}/scripts/test_runner.py --verbose --valgrind ${TESTS}

valgrind.quiet: ${TESTS}
	@echo " -> Running valgrind on tests in $(CWD:${VCS_ROOT}/%=%)"
	@[[ -z "${TESTS}" ]] || ${VCS_ROOT}/scripts/test_runner.py --valgrind ${TESTS}

clean: FORCE
	@echo " -> Cleaning $(shell pwd | xargs basename)"
	@$(foreach V,$(filter %.OBJS, ${.VARIABLES}), rm -rf $($(V)))
	@$(foreach V,$(filter %.DEPS, ${.VARIABLES}), rm -rf $($(V)))
	@rm -rf *.a ${CLEAN_FILES}
	@rm -rf ${TESTS}

FORCE: ;