| # | |
| # 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 |