-
Notifications
You must be signed in to change notification settings - Fork 14
/
Makefile
189 lines (145 loc) · 5.84 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
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# Makefile for Navy Applications and Libraries
### *Get a more readable version of this Makefile* by `make html` (requires python-markdown)
html:
cat Makefile | sed 's/^\([^#]\)/ \1/g' | markdown_py > Makefile.html
.PHONY: html
## 1. Basic Setup and Checks
### Default to build an application
ifeq ($(MAKECMDGOALS),)
MAKECMDGOALS = app
.DEFAULT_GOAL = app
endif
### Override checks when `make clean/clean-all/html/init`
ifeq ($(findstring $(MAKECMDGOALS),clean|clean-all|html|init),)
### Print build info message
$(info # Building $(NAME)-$(MAKECMDGOALS) [$(ISA)])
### Check: environment variable `$NAVY_HOME` looks sane
ifeq ($(wildcard $(NAVY_HOME)/libs/libos/src/syscall.h),)
$(error $$NAVY_HOME must be a Navy-apps repo)
endif
### Check: environment variable `$ISA` must be in the supported list
ISAS = $(basename $(notdir $(shell ls $(NAVY_HOME)/scripts/*.mk)))
ifeq ($(filter $(ISAS), $(ISA)), )
$(error Expected $$ISA in {$(ISAS)}, Got "$(ISA)")
endif
### Checks end here
endif
## 2. General Compilation Targets
### Create the destination directory (`build/$ISA`)
WORK_DIR = $(shell pwd)
DST_DIR = $(WORK_DIR)/build/$(ISA)
$(shell mkdir -p $(DST_DIR))
### Compilation targets (application or archive)
APP ?= $(WORK_DIR)/build/$(NAME)-$(ISA)
ARCHIVE = $(WORK_DIR)/build/$(NAME)-$(ISA).a
### Add default libraries for ISA != native
ifneq ($(ISA), native)
LIBS += libc libos
CFLAGS += -U_FORTIFY_SOURCE # fix compile error in Newlib on ubuntu
else
WL = -Wl,
endif
### 32-bit ISA may need compiler-rt to support 64-bit mul/div
ifneq ($(findstring $(ISA), x86|mips32|riscv32|riscv32e|loongarch32r),)
LIBS += compiler-rt
endif
### All libraries to add to the include path
LIBS_INC := $(sort $(LIBS) $(LIB_DEP))
ifeq ($(MAKECMDGOALS),archive)
LIBS := $(LIB_DEP) # overwrite here to only build and archive the dependent libraries
endif
### Files to be linked: object files (`.o`) and libraries (`.a`)
OBJS = $(addprefix $(DST_DIR)/, $(addsuffix .o, $(basename $(SRCS))))
LIBS := $(sort $(LIBS)) # lazy evaluation ("=") causes infinite recursions
LINKAGE = $(OBJS) $(foreach l,$(LIBS),$(NAVY_HOME)/libs/$(l)/build/$(l)-$(ISA).a)
## 3. General Compilation Flags
### (Cross) compilers, e.g., mips-linux-gnu-g++
AS = $(CROSS_COMPILE)gcc
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
LD = $(CROSS_COMPILE)ld
AR = $(CROSS_COMPILE)ar
### Compilation flags
INC_PATH += $(WORK_DIR)/include $(foreach l,$(LIBS_INC),$(NAVY_HOME)/libs/$(l)/include/)
INCFLAGS += $(addprefix -I, $(INC_PATH))
CFLAGS += -O2 -MMD $(INCFLAGS) -static -D__NAVY__ \
-D__ISA__=\"$(ISA)\" -D__ISA_$(shell echo $(ISA) | tr a-z A-Z)__ \
-fno-asynchronous-unwind-tables -fno-builtin -fno-stack-protector
CXXFLAGS += $(CFLAGS) -fno-rtti -fno-exceptions
ASFLAGS += $(CFLAGS)
## 4. ISA-Specific Configurations
### Paste in ISA-specific configurations (e.g., from `scripts/x86.mk`)
-include $(NAVY_HOME)/scripts/$(ISA).mk
## 5. Compilation Rules
### Rule (compile): a single `.c` -> `.o` (gcc)
$(DST_DIR)/%.o: %.c
@mkdir -p $(dir $@) && echo + CC $<
@$(CC) -std=gnu11 $(CFLAGS) -c -o $@ $(realpath $<)
### Rule (compile): a single `.cc` -> `.o` (g++)
$(DST_DIR)/%.o: %.cc
@mkdir -p $(dir $@) && echo + CXX $<
@$(CXX) -std=c++17 $(CXXFLAGS) -c -o $@ $(realpath $<)
### Rule (compile): a single `.cpp` -> `.o` (g++)
$(DST_DIR)/%.o: %.cpp
@mkdir -p $(dir $@) && echo + CXX $<
@$(CXX) -std=c++17 $(CXXFLAGS) -c -o $@ $(realpath $<)
### Rule (compile): a single `.S` -> `.o` (gcc, which calls as)
$(DST_DIR)/%.o: %.S
@mkdir -p $(dir $@) && echo + AS $<
@$(AS) $(ASFLAGS) -c -o $@ $(realpath $<)
### Rule (recursive make): build dependent libraries (libc, libos, ...)
$(LIBS):
$(MAKE) -s -C $(NAVY_HOME)/libs/$@ archive
### Rule (link): objects (`*.o`) and libraries (`*.a`) -> `$(APP)`, the final ELF binary to be packed into application (ld)
$(APP): $(LINKAGE)
@echo + LD "->" $(shell realpath $@ --relative-to .)
@$(LD) $(LDFLAGS) -o $@ $(WL)--start-group $^ $(WL)--end-group
### Rule (archive): objects (`*.o`) -> `ARCHIVE.a` (ar)
$(ARCHIVE): $(LINKAGE)
@echo + AR "->" $(shell realpath $@ --relative-to .)
@$(AR) rcs --thin $@ $^
### Rule (`#include` dependencies): paste in `.d` files generated by gcc on `-MMD`
-include $(addprefix $(DST_DIR)/, $(addsuffix .d, $(basename $(SRCS))))
## 6. Miscellaneous
### Pull newlib from github if it does not exist
ifeq ($(wildcard $(NAVY_HOME)/libs/libc/Makefile),)
$(shell cd $(NAVY_HOME)/libs && git clone git@github.com:NJU-ProjectN/newlib-navy.git libc)
endif
### Build order control
app: $(LIBS) $(APP)
archive: $(LIBS) $(ARCHIVE)
.NOTPARALLEL: app archive
.PHONY: app archive $(LIBS)
### Install an application to fsimg
install: app
@echo + INSTALL "->" $(NAME)
@mkdir -p $(NAVY_HOME)/fsimg/bin
@cp $(APP) $(NAVY_HOME)/fsimg/bin/$(NAME)
.PHONY: install
### Clean a single project (remove `build/`)
clean:
rm -rf Makefile.html $(WORK_DIR)/build/ build/
.PHONY: clean
### Clean all sub-projects within depth 2 (and ignore errors)
CLEAN_ALL = $(dir $(shell find . -mindepth 2 -maxdepth 3 -name Makefile))
clean-all: $(CLEAN_ALL) clean
-@rm -f $(NAVY_HOME)/fsimg/bin/*
$(CLEAN_ALL):
-@$(MAKE) -s -C $@ clean
.PHONY: clean-all $(CLEAN_ALL)
### Build fsimg and ramdisk for Nanos-lite
APPS =
TESTS = dummy hello
fsimg: $(addprefix apps/, $(APPS)) $(addprefix tests/, $(TESTS))
-for t in $^; do $(MAKE) -s -C $(NAVY_HOME)/$$t install; done
RAMDISK = build/ramdisk.img
RAMDISK_H = build/ramdisk.h
$(RAMDISK): fsimg
$(eval FSIMG_FILES := $(shell find -L ./fsimg -type f))
@mkdir -p $(@D)
@cat $(FSIMG_FILES) > $@
@truncate -s \%512 $@
@echo "// file path, file size, offset in disk" > $(RAMDISK_H)
@wc -c $(FSIMG_FILES) | grep -v 'total$$' | sed -e 's+ ./fsimg+ +' | awk -v sum=0 '{print "\x7b\x22" $$2 "\x22\x2c " $$1 "\x2c " sum "\x7d\x2c";sum += $$1}' >> $(RAMDISK_H)
ramdisk: $(RAMDISK)
.PHONY: fsimg ramdisk