# # Copyright 2022 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # V ?= @ BUILD_DIR := build BIN_DIR := bin # # Set `gcc` as default compiler # CC := $(if $(CC)=cc,gcc,$(CC)) AS := $(if $(AS)=as,$(CC),$(AS)) LD := $(if $(LD)=ld,$(CC),$(LD)) CFLAGS := $(if $(DEBUG),-O0 -g,-O3) CFLAGS += -std=c11 -Wall -Wextra -Wdouble-promotion # # Declarations # lib_list := bin_list := define add-lib $(eval $(1)_bin ?= $(1).a) $(eval $(1)_bin := $(addprefix $(BIN_DIR)/,$($(1)_bin))) lib_list += $(1) LIB += $($(1)_bin) endef define add-bin $(eval $(1)_bin ?= $(1)) $(eval $(1)_bin := $(addprefix $(BIN_DIR)/,$($(1)_bin))) $($(1)_bin): LDLIBS += $(if $(filter $(LIBC),bionic),\ $(filter-out rt pthread,$($(1)_ldlibs)),$($(1)_ldlibs)) $($(1)_bin): LDFLAGS += $($(1)_ldflags) bin_list += $(1) BIN += $($(1)_bin) endef define set-target $(eval $(1)_obj ?= $(patsubst %.c,%.o,$(filter %.c,$($(1)_src))) \ $(patsubst %.s,%.o,$(filter %.s,$($(1)_src)))) $(eval $(1)_obj := $(addprefix $(BUILD_DIR)/,$($(1)_obj))) $(eval $(1)_lib := $(foreach lib, $($(1)_lib), $($(lib)_bin))) $($(1)_obj): INCLUDE += $($(1)_include) $($(1)_obj): DEFINE += $($(1)_define) $($(1)_obj): CFLAGS += $($(1)_cflags) -include $($(1)_obj:.o=.d) $($(1)_bin): $($(1)_lib) $($(1)_bin): $($(1)_obj) $($(1)_bin): $($(1)_dependencies) .PHONY: $(1) $(1): $($(1)_bin) endef .PHONY: default default: INCLUDE += include SRC_DIR = src include $(SRC_DIR)/makefile.mk TOOLS_DIR = tools -include $(TOOLS_DIR)/makefile.mk TEST_DIR := test -include $(TEST_DIR)/makefile.mk # # Rules # MAKEFILE_DEPS := $(MAKEFILE_LIST) $(foreach lib, $(lib_list), $(eval $(call set-target,$(lib)))) $(foreach bin, $(bin_list), $(eval $(call set-target,$(bin)))) $(BUILD_DIR)/%.o: %.c $(MAKEFILE_DEPS) @echo " CC $(notdir $<)" $(V)mkdir -p $(dir $@) $(V)$(CC) $< -c $(CFLAGS) \ $(addprefix -I,$(INCLUDE)) \ $(addprefix -D,$(DEFINE)) -MMD -MF $(@:.o=.d) -o $@ $(BUILD_DIR)/%.o: %.s $(MAKEFILE_DEPS) @echo " AS $(notdir $<)" $(V)mkdir -p $(dir $@) $(V)$(AS) $< -c $(CFLAGS) \ $(addprefix -I,$(INCLUDE)) \ $(addprefix -D,$(DEFINE)) -MMD -MF $(@:.o=.d) -o $@ $(LIB): $(MAKEFILE_DEPS) @echo " AR $(notdir $@)" $(V)mkdir -p $(dir $@) $(V)$(AR) rcs $@ $(filter %.o,$^) $(BIN): $(MAKEFILE_DEPS) @echo " LD $(notdir $@)" $(V)mkdir -p $(dir $@) $(V)$(LD) $(filter %.o,$^) $(filter %.a,$^) $(LDFLAGS) \ $(addprefix -l,$(LDLIBS)) -o $@ clean: $(V)rm -rf $(BUILD_DIR) $(V)rm -rf $(BIN_DIR) clean-all: clean