.DEFAULT_GOAL = app # Add necessary options if the target is a shared library ifeq ($(SHARE),1) SO = -so CFLAGS += -fPIC -fvisibility=hidden LDFLAGS += -shared -fPIC endif WORK_DIR = $(shell pwd) BUILD_DIR = $(WORK_DIR)/build INC_PATH := $(WORK_DIR)/include $(BUILD_DIR)/include $(INC_PATH) OBJ_DIR = $(BUILD_DIR)/obj-$(NAME)$(SO) BINARY = $(BUILD_DIR)/$(NAME)$(SO) # Compilation flags ifeq ($(CC),clang) CXX := clang++ else CXX := g++ endif LD := $(CXX) INCLUDES = $(addprefix -I, $(INC_PATH)) CFLAGS := -O2 -MMD -Wall $(INCLUDES) $(CFLAGS) LDFLAGS := -O2 $(LDFLAGS) OBJS = $(SRCS:%.c=$(OBJ_DIR)/%.o) $(CXXSRC:%.cc=$(OBJ_DIR)/%.o) # Compilation patterns $(OBJ_DIR)/%.o: %.c @echo + CC $< @mkdir -p $(dir $@) @$(CC) $(CFLAGS) -c -o $@ $< $(call call_fixdep, $(@:.o=.d), $@) $(OBJ_DIR)/%.o: %.cc @echo + CXX $< @mkdir -p $(dir $@) @$(CXX) $(CFLAGS) $(CXXFLAGS) -c -o $@ $< $(call call_fixdep, $(@:.o=.d), $@) $(OBJ_DIR)/%.tag.c: %.y @echo + YACC $< @mkdir -p $(dir $@) $(BUILD_DIR)/include @$(YACC) $(YFLAGS) --header=$(BUILD_DIR)/include/$(notdir $(<:.y=.h)) -o $@ $< $(OBJ_DIR)/%.yy.c: %.l $(OBJ_DIR)/%.tag.c @echo + LEX $< @mkdir -p $(dir $@) $(BUILD_DIR)/include @$(LEX) $(LFLAGS) --header=$(BUILD_DIR)/include/$(notdir $(<:.l=_lex.h)) -o $@ $< $(OBJ_DIR)/%.tag.o: $(OBJ_DIR)/%.tag.c @echo + CC $< @mkdir -p $(dir $@) @$(CC) $(CFLAGS) -c -o $@ $< $(call call_fixdep, $(@:.o=.d), $@) $(OBJ_DIR)/%.yy.o: $(OBJ_DIR)/%.yy.c @echo + CC $< @mkdir -p $(dir $@) @$(CC) $(CFLAGS) -c -o $@ $< $(call call_fixdep, $(@:.o=.d), $@) # Depencies -include $(OBJS:.o=.d) # Some convenient rules .PHONY: app install clean app: $(BINARY) $(BINARY):: $(OBJS) $(ARCHIVES) @echo + LD $@ @$(LD) -o $@ $(OBJS) $(LDFLAGS) $(ARCHIVES) $(LIBS) install: $(BINARY) ifeq ($(SHARE),1) @mkdir -p $(PREFIX)/lib @cp $(BINARY) $(PREFIX)/lib/ else @mkdir -p $(PREFIX)/bin @cp $(BINARY) $(PREFIX)/bin/ endif clean: -rm -rf $(BUILD_DIR)