-
Notifications
You must be signed in to change notification settings - Fork 6
/
Makefile
118 lines (88 loc) · 3.17 KB
/
Makefile
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
CROSS_COMPILE ?= riscv64-unknown-elf-
AR = $(CROSS_COMPILE)ar
CFLAGS = -mcmodel=medany -ffunction-sections -fdata-sections
LDFLAGS = -nostartfiles -nostdlib -nostdinc -static -lgcc \
-Wl,--nmagic -Wl,--gc-sections
INCLUDES = -Ienv/common
libfemto_dirs = libfemto/std libfemto/drivers libfemto/arch/riscv
libfemto_src = $(sort $(foreach d,$(libfemto_dirs),$(wildcard $(d)/*.c)))
libfemto_asm = $(sort $(foreach d,$(libfemto_dirs),$(wildcard $(d)/*.s)))
libfemto_objs = $(patsubst %.s,%.o,$(libfemto_asm)) \
$(patsubst %.c,%.o,$(libfemto_src))
#
# Compiler configurations and target environment definitions
#
subdirs = examples
libs = libfemto
configs = rv64imac
CC_rv32imac = $(CROSS_COMPILE)gcc
CFLAGS_rv32imac = -Os -march=rv32imac -mabi=ilp32 -Ienv/common/rv32
LDFLAGS_rv32imac =
CC_rv64imac = $(CROSS_COMPILE)gcc
CFLAGS_rv64imac = -Os -march=rv64imac -mabi=lp64 -Ienv/common/rv64
LDFLAGS_rv64imac =
targets = rv64imac:qemu-sifive_u
#
# make rules
#
all: all_programs
clean:
rm -fr build
backup: clean
tar czf ../$(shell basename $(shell pwd)).tar.gz .
#
# To view commands use: make V=1
#
ifdef V
cmd = @mkdir -p $2 ; echo "$3"; $3
else
cmd = @echo "$1"; mkdir -p $2 ; $3
endif
#
# Build system functions to generate pattern rules for all configs
#
define pattern =
build/obj/$(2)/%.o: %.$(3)
$(call cmd,$(1).$(2) $$@,$$(@D),$(CC_$(2)) $(CFLAGS_$(2)) $(CFLAGS) \
$$(INCLUDES) -c $$^ -o $$@)
endef
$(foreach c,$(configs),$(eval $(call pattern,CC,$(c),c)))
$(foreach c,$(configs),$(eval $(call pattern,AS,$(c),s)))
#
# Build system functions to generate library rules for all configs
#
define archive =
build/lib/$(2)/$(3).a: $(addprefix build/obj/$(2)/,$($(3)_objs))
$(call cmd,$(1).$(2) $$@,$$(@D),$(AR) cr $$@ $$^)
LIBS_$(2) += build/lib/$(2)/$(3).a
endef
define lib =
$(foreach c,$(configs),$(eval $(call archive,AR,$(c),$(1))))
INCLUDES += -I$(1)/include
endef
$(foreach l,$(libs),$(eval $(call lib,$(l))))
#
# Build system functions to generate build rules for all subdirs
#
sub_makes := $(foreach dir,$(subdirs),$(wildcard ${dir}/*/rules.mk))
$(foreach makefile,$(sub_makes),$(eval include $(makefile)))
sub_dirs := $(foreach m,$(sub_makes),$(m:/rules.mk=))
module_name = $(lastword $(subst /, ,$(1)))
module_objs = $(addprefix build/obj/$(3)/,$(addprefix $(2)/,$($(1)_objs)))
config_arch = $(word 1,$(subst :, ,$(1)))
config_env = $(word 2,$(subst :, ,$(1)))
define rule =
build/bin/$(3)/$(4)/$(1): \
build/obj/$(3)/env/$(4)/crt.o $(2) $$(LIBS_$(3))
$$(call cmd,LD.$(3) $$@,$$(@D),$(CC_$(3)) $(CFLAGS_$(3)) $$(CFLAGS) \
$$(LDFLAGS_$(3)) $$(LDFLAGS) -T env/$(4)/default.lds $$^ -o $$@)
endef
define module =
program_names += $(foreach cfg,$(targets),build/bin/$(call \
config_arch,$(cfg))/$(call config_env,$(cfg))/$(1))
$(foreach cfg,$(targets),$(eval $(call rule,$(1),$(call \
module_objs,$(1),$(2),$(call config_arch,$(cfg))),$(call \
config_arch,$(cfg)),$(call config_env,$(cfg)))))
endef
$(foreach d,$(sub_dirs),$(eval $(call module,$(call module_name,$(d)),$(d))))
all_programs: $(program_names)