User:Solar/Makefile

From OSDev.wiki
Revision as of 16:49, 24 November 2011 by Solar (talk | contribs)
Jump to navigation Jump to search
.
├── bar
│   ├── build.mk
│   ├── includes
│   │   └── global.h
│   ├── obj
│   └── src
│       ├── bar_local.h
│       └── bar_test.c
├── bin
├── foo
│   ├── build.mk
│   ├── includes
│   │   └── global.h
│   ├── obj
│   └── src
│       ├── foo_local.h
│       ├── foo_test.c
│       └── main.c
├── includes
├── lib
└── Makefile
MODULES := foo bar

CFLAGS := -MMD -I includes
ARFLAGS := rc

.PHONY: clean mrproper

all:
	@echo "Default target."

define MK_template
include $(1)/build.mk
endef

define RULES_template
$(1)/obj/%.o: $(1)/src/%.c
	$$(CC) $$(CFLAGS) $$(CFLAGS_$(1)) -c $$< -o $$@
endef

define PROGRAM_template
DEPENDENCIES := $(DEPENDENCIES) $(patsubst %,$(2)/obj/%.d,$(basename $($(1)_SOURCES)))
bin/$(1): $(patsubst %,$(2)/obj/%.o,$(basename $($(1)_SOURCES))) $(foreach library,$($(1)_LIBRARIES),lib/$(library))
	$$(LD) $$(LDFLAGS) $$(LDFLAGS_$(2)) $$^ -o $$@
endef

define ARCHIVE_template
DEPENDENCIES := $(DEPENDENCIES) $(patsubst %,$(2)/obj/%.d,$(basename $($(1)_SOURCES)))
lib/$(1): $(patsubst %,$(2)/obj/%.o,$(basename $($(1)_SOURCES)))
	$$(AR) $$(ARFLAGS) $$@ $$?
endef

define INCLUDE_template
ifeq ($(wildcard includes/$(1)),)
    $$(shell ln -s ../$(1)/includes includes/$(1))
endif
endef

$(foreach module,$(MODULES),$(eval include $(module)/build.mk))
$(foreach module,$(MODULES),$(eval $(call RULES_template,$(module))))
$(foreach module,$(MODULES),$(eval $(foreach binary,$($(module)_PROGRAMS),$(call PROGRAM_template,$(binary),$(module)))))
$(foreach module,$(MODULES),$(eval $(foreach library,$($(module)_ARCHIVES),$(call ARCHIVE_template,$(library),$(module)))))
$(foreach module,$(MODULES),$(eval $(call INCLUDE_template,$(module))))

-include $(sort $(DEPENDENCIES))

clean:
	$(RM) $(foreach mod,$(MODULES),$(mod)/obj/*.o)

mrproper: clean
	$(RM) $(foreach mod,$(MODULES),$(mod)/obj/*.d) includes/* bin/* lib/*

CFLAGS_foo := -Wall

foo_PROGRAMS := foo
foo_ARCHIVES := foolib.a

foo_SOURCES := main.c
foo_LIBRARIES := foolib.a

foolib.a_SOURCES := foo_test.c