blob: b97320140e33936c7f9cdd7642f402acf84c8965 [file] [log] [blame]
#
# 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