1# 2# Copyright 2022 Google LLC 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at: 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16 17V ?= @ 18 19BUILD_DIR := build 20BIN_DIR := bin 21 22 23# 24# Set `gcc` as default compiler 25# 26 27CC := $(if $(CC)=cc,gcc,$(CC)) 28AS := $(if $(AS)=as,$(CC),$(AS)) 29LD := $(if $(LD)=ld,$(CC),$(LD)) 30 31CFLAGS := $(if $(DEBUG),-O0 -g,-O3) 32CFLAGS += -std=c11 -Wall -Wextra -Wdouble-promotion -Wvla -pedantic 33 34 35# 36# Declarations 37# 38 39lib_list := 40bin_list := 41 42define add-lib 43 $(eval $(1)_bin ?= $(1).a) 44 $(eval $(1)_bin := $(addprefix $(BIN_DIR)/,$($(1)_bin))) 45 46 lib_list += $(1) 47 LIB += $($(1)_bin) 48endef 49 50define add-bin 51 $(eval $(1)_bin ?= $(1)) 52 $(eval $(1)_bin := $(addprefix $(BIN_DIR)/,$($(1)_bin))) 53 54 $($(1)_bin): LDLIBS += $(if $(filter $(LIBC),bionic),\ 55 $(filter-out rt pthread,$($(1)_ldlibs)),$($(1)_ldlibs)) 56 $($(1)_bin): LDFLAGS += $($(1)_ldflags) 57 58 bin_list += $(1) 59 BIN += $($(1)_bin) 60endef 61 62define set-target 63 $(eval $(1)_obj ?= $(patsubst %.c,%.o,$(filter %.c,$($(1)_src))) \ 64 $(patsubst %.s,%.o,$(filter %.s,$($(1)_src))) \ 65 $(patsubst %.cc,%.o,$(filter %.cc,$($(1)_src)))) 66 $(eval $(1)_obj := $(addprefix $(BUILD_DIR)/,$($(1)_obj))) 67 $(eval $(1)_lib := $(foreach lib, $($(1)_lib), $($(lib)_bin))) 68 69 $($(1)_obj): INCLUDE += $($(1)_include) 70 $($(1)_obj): DEFINE += $($(1)_define) 71 $($(1)_obj): CFLAGS += $($(1)_cflags) 72 $($(1)_obj): CXXFLAGS += $($(1)_cxxflags) 73 74 -include $($(1)_obj:.o=.d) 75 76 $($(1)_bin): $($(1)_lib) 77 $($(1)_bin): $($(1)_obj) 78 $($(1)_bin): $($(1)_dependencies) 79 80 .PHONY: $(1) 81 $(1): $($(1)_bin) 82endef 83 84.PHONY: default 85default: 86 87 88INCLUDE += include 89 90SRC_DIR = src 91include $(SRC_DIR)/makefile.mk 92 93TOOLS_DIR = tools 94-include $(TOOLS_DIR)/makefile.mk 95 96TEST_DIR := test 97-include $(TEST_DIR)/makefile.mk 98 99FUZZ_DIR := fuzz 100-include $(FUZZ_DIR)/makefile.mk 101 102 103# 104# Rules 105# 106 107MAKEFILE_DEPS := $(MAKEFILE_LIST) 108 109$(foreach lib, $(lib_list), $(eval $(call set-target,$(lib)))) 110$(foreach bin, $(bin_list), $(eval $(call set-target,$(bin)))) 111 112$(BUILD_DIR)/%.o: %.c $(MAKEFILE_DEPS) 113 @echo " CC $(notdir $<)" 114 $(V)mkdir -p $(dir $@) 115 $(V)$(CC) $< -c $(CFLAGS) \ 116 $(addprefix -I,$(INCLUDE)) \ 117 $(addprefix -D,$(DEFINE)) -MMD -MF $(@:.o=.d) -o $@ 118 119$(BUILD_DIR)/%.o: %.s $(MAKEFILE_DEPS) 120 @echo " AS $(notdir $<)" 121 $(V)mkdir -p $(dir $@) 122 $(V)$(AS) $< -c $(CFLAGS) \ 123 $(addprefix -I,$(INCLUDE)) \ 124 $(addprefix -D,$(DEFINE)) -MMD -MF $(@:.o=.d) -o $@ 125 126$(BUILD_DIR)/%.o: %.cc $(MAKEFILE_DEPS) 127 @echo " CXX $(notdir $<)" 128 $(V)mkdir -p $(dir $@) 129 $(V)$(CXX) $< -c $(CXXFLAGS) \ 130 $(addprefix -I,$(INCLUDE)) \ 131 $(addprefix -D,$(DEFINE)) -MMD -MF $(@:.o=.d) -o $@ 132 133$(LIB): $(MAKEFILE_DEPS) 134 @echo " AR $(notdir $@)" 135 $(V)mkdir -p $(dir $@) 136 $(V)$(AR) rcs $@ $(filter %.o,$^) 137 138$(BIN): $(MAKEFILE_DEPS) 139 @echo " LD $(notdir $@)" 140 $(V)mkdir -p $(dir $@) 141 $(V)$(LD) $(filter %.o,$^) $(filter %.a,$^) $(LDFLAGS) \ 142 $(addprefix -l,$(LDLIBS)) -o $@ 143 144clean: 145 $(V)rm -rf $(BUILD_DIR) 146 $(V)rm -rf $(BIN_DIR) 147 148clean-all: clean 149