-
Notifications
You must be signed in to change notification settings - Fork 106
/
Makefile
212 lines (174 loc) · 6.1 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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
#
# Makefile
#
# Copyright (C) 2009-2011 Udo Steinberg <[email protected]>
# Economic rights: Technische Universitaet Dresden (Germany)
#
# Copyright (C) 2012-2013 Udo Steinberg, Intel Corporation.
# Copyright (C) 2019-2024 Udo Steinberg, BlueRock Security, Inc.
#
# This file is part of the NOVA microhypervisor.
#
# NOVA is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# NOVA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License version 2 for more details.
#
-include Makefile.conf
# Defaults
ARCH ?= x86_64
BOARD ?= acpi
COMP ?= gcc
CFP ?= none
# Tools
INSTALL ?= install -m 644
MKDIR ?= mkdir -p
ifeq ($(COMP),gcc)
HST_CC ?= g++
TGT_CC := $(PREFIX_$(ARCH))gcc
TGT_LD := $(PREFIX_$(ARCH))ld
TGT_OC := $(PREFIX_$(ARCH))objcopy
TGT_SZ := $(PREFIX_$(ARCH))size
else
$(error $(COMP) is not a valid compiler type)
endif
H2E := $(H2E_$(ARCH))
H2B := $(H2B_$(ARCH))
RUN := $(RUN_$(ARCH))
# In-place editing works differently between GNU/BSD sed
SEDI := $(shell if sed --version 2>/dev/null | grep -q GNU; then echo "sed -i"; else echo "sed -i ''"; fi)
# Directories
CMD_DIR := cmd
SRC_DIR := src/$(ARCH) src
INC_DIR := inc/$(ARCH) inc
BLD_DIR ?= build-$(ARCH)
# Patterns
PAT_CMD := $(BLD_DIR)/%
PAT_OBJ := $(BLD_DIR)/$(ARCH)-%.o
# Files
MFL := $(MAKEFILE_LIST)
SRC := hypervisor.ld $(sort $(notdir $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.S)))) $(sort $(notdir $(foreach dir,$(SRC_DIR),$(wildcard $(dir)/*.cpp))))
OBJ := $(patsubst %.ld,$(PAT_OBJ), $(patsubst %.S,$(PAT_OBJ), $(patsubst %.cpp,$(PAT_OBJ), $(SRC))))
OBJ_DEP := $(OBJ:%.o=%.d)
DIG := $(BLD_DIR)/digest
ifeq ($(ARCH),aarch64)
HYP := $(BLD_DIR)/$(ARCH)-$(BOARD)-nova
else
HYP := $(BLD_DIR)/$(ARCH)-nova
endif
ELF := $(HYP).elf
BIN := $(HYP).bin
# Messages
ifneq ($(findstring s,$(MAKEFLAGS)),)
message = @echo $(1) $(2)
endif
# Tool check
tools = $(if $(shell command -v $($(1)) 2>/dev/null),, $(error Missing $(1)=$($(1)) *** Configure it in Makefile.conf (see Makefile.conf.example)))
# Feature check
check = $(shell if $(TGT_CC) $(1) -Werror -c -xc++ /dev/null -o /dev/null >/dev/null 2>&1; then echo "$(1)"; fi)
# Version check
gitrv = $(shell (git rev-parse HEAD 2>/dev/null || echo 0) | cut -c1-7)
# Search path
VPATH := $(SRC_DIR)
# Optimization options
DFLAGS := -MP -MMD -pipe
OFLAGS := -Os
ifeq ($(ARCH),aarch64)
AFLAGS := -march=armv8-a -mcmodel=large -mgeneral-regs-only $(call check,-mno-outline-atomics) -mstrict-align
DEFINES += BOARD_$(BOARD)
else ifeq ($(ARCH),x86_64)
AFLAGS := -Wa,--divide,--noexecstack -march=x86-64-v2 -mcmodel=kernel -mgeneral-regs-only -mno-red-zone
else
$(error $(ARCH) is not a valid architecture)
endif
# Preprocessor options
PFLAGS := $(addprefix -D, $(DEFINES)) $(addprefix -I, $(INC_DIR))
# Language options
FFLAGS := $(or $(call check,-std=gnu++26), $(call check,-std=gnu++23), $(call check,-std=gnu++20))
FFLAGS += -ffreestanding -fdata-sections -ffunction-sections -fno-asynchronous-unwind-tables -fno-exceptions -fno-rtti -fno-use-cxa-atexit -fomit-frame-pointer
FFLAGS += $(call check,-fcf-protection=$(CFP))
FFLAGS += $(call check,-fdiagnostics-color=auto)
FFLAGS += $(call check,-fno-pic)
FFLAGS += $(call check,-fno-stack-protector)
FFLAGS += $(call check,-freg-struct-return)
FFLAGS += $(call check,-freorder-blocks)
# Warning options
WFLAGS := -Wall -Wextra -Walloca -Wcast-align -Wcast-qual -Wconversion -Wctor-dtor-privacy -Wdisabled-optimization -Wduplicated-branches -Wduplicated-cond -Wenum-conversion -Wextra-semi -Wformat=2 -Wmismatched-tags -Wmissing-format-attribute -Wmissing-noreturn -Wmultichar -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wpacked -Wpointer-arith -Wredundant-decls -Wredundant-tags -Wregister -Wshadow -Wsign-promo -Wvirtual-inheritance -Wvolatile -Wwrite-strings
WFLAGS += $(call check,-Wbidi-chars=any)
WFLAGS += $(call check,-Wlogical-op)
WFLAGS += $(call check,-Wstrict-null-sentinel)
WFLAGS += $(call check,-Wstrict-overflow=5)
WFLAGS += $(call check,-Wsuggest-override)
WFLAGS += $(call check,-Wvolatile-register-var)
WFLAGS += $(call check,-Wzero-as-null-pointer-constant)
ifeq ($(ARCH),aarch64)
WFLAGS += $(call check,-Wpedantic)
endif
# Compiler flags
CFLAGS := $(PFLAGS) $(DFLAGS) $(AFLAGS) $(FFLAGS) $(OFLAGS) $(WFLAGS)
# Linker flags
LFLAGS := --defsym=GIT_VER=0x$(call gitrv) --gc-sections --warn-common -static -n -s -T
# Rules
$(HYP): $(OBJ)
$(call message,LNK,$@)
$(TGT_LD) $(LFLAGS) $^ -o $@
$(ELF): $(HYP)
$(call message,ELF,$@)
$(H2E) $< $@
$(BIN): $(HYP)
$(call message,BIN,$@)
$(H2B) $< $@
$(PAT_OBJ): %.ld
$(call message,PRE,$@)
$(TGT_CC) $(CFLAGS) -xassembler-with-cpp -E -P -MT $@ $< -o $@
@$(SEDI) 's|$<|$(notdir $<)|' $(@:%.o=%.d)
$(PAT_OBJ): %.S
$(call message,ASM,$@)
$(TGT_CC) $(CFLAGS) -c $< -o $@
@$(SEDI) 's|$<|$(notdir $<)|' $(@:%.o=%.d)
$(PAT_OBJ): %.cpp
$(call message,CXX,$@)
$(TGT_CC) $(CFLAGS) -c $< -o $@
@$(SEDI) 's|$<|$(notdir $<)|' $(@:%.o=%.d)
$(PAT_CMD): $(CMD_DIR)/%.cpp
$(call message,CMD,$@)
$(HST_CC) $< -o $@
$(BLD_DIR):
$(call message,DIR,$@)
@$(MKDIR) $@
Makefile.conf:
$(call message,CFG,$@)
@cp [email protected] $@
$(DIG): $(MFL) | $(BLD_DIR) tool_hst_cc
$(OBJ): $(MFL) | $(BLD_DIR) tool_tgt_cc
# Zap old-fashioned suffixes
.SUFFIXES:
.PHONY: clean install run tool_hst_cc tool_tgt_cc
clean:
$(call message,CLN,$@)
$(RM) $(DIG) $(OBJ) $(HYP) $(ELF) $(BIN) $(OBJ_DEP)
install: $(HYP) | $(DIG)
$(call message,INS,$^ =\> $(INS_DIR))
$(INSTALL) $^ $(INS_DIR)
@$(TGT_SZ) $<
ifeq ($(ARCH),x86_64)
@echo Reference Integrity Measurements for $^
@echo $(shell $(DIG) $^ | sha1sum) "SHA1-160"
@echo $(shell $(DIG) $^ | sha256sum) "SHA2-256"
@echo $(shell $(DIG) $^ | sha384sum) "SHA2-384"
@echo $(shell $(DIG) $^ | sha512sum) "SHA2-512"
endif
run: $(ELF)
$(RUN) $<
tool_hst_cc:
$(call tools,HST_CC)
tool_tgt_cc:
$(call tools,TGT_CC)
# Include Dependencies
ifneq ($(MAKECMDGOALS),clean)
-include $(OBJ_DEP)
endif