#
# Yoink
-# Use this file with make to compile and install Yoink.
+# Use this file with GNU make to compile and install Yoink.
#
-# This makefile supports these targets:
-# all, install, clean, distclean, run, debug, dist, dist-gzip, dist-bzip2
-#
-# This build system incorporates the ideas written by Emile van Bergen:
-# http://www.xs4all.nl/~evbergen/nonrecursive-make.html
-#
-
-# Set this to `yes' to echo each build command in full.
-verbose := no
+# Set V to `1' to echo each build command in full. The default behavior
+# will keep output minimal.
+V = 0
-#
-# Include the configuration file, config.mk.
-#
+SHELL = /bin/sh
-SHELL := /bin/sh
-have_config := $(wildcard config.mk)
-ifneq ($(strip $(have_config)),)
-include config.mk
+ifeq (menuconfig,$(MAKECMDGOALS))
+menuconfig:
+ ./configure --interactive
+.PHONY: menuconfig
else
-$(error You must run the configure script before you can make anything)
-endif
+config.h: config.mk
+ $(Q)$(configure) --export-header=$@
-#
-# Declare the default targets and implicit rules.
-#
+config.sed: config.mk
+ $(Q)$(configure) --export-terms=$@
-.PHONY: all
-all: all_
+config.mk:
+ $(Q)$(configure) --interactive --print-instructions=no
-.SUFFIXES:
-.SUFFIXES: .a .c .cc .cpp .in .o .rc
+include config.mk
#
# Define some useful functions.
#
-add_exe_suffix = $(addsuffix $(EXEEXT),$1)
-remove_silencer = $(1:@%=%)
+DATA_TARGETS :=
+EXEC_TARGETS :=
+SUBDIRS :=
+
+define include_func =
+ifeq (,$$d)
+dir := $1
+else
+dir := $$d/$1
+endif
+sp := $$(sp).x
+dirstack_$$(sp) := $$d
+datstack_$$(sp) := $$(data)
+exestack_$$(sp) := $$(exec)
+d := $$(dir)
+data :=
+exec :=
+include $$(dir)/rules.mk
+SUBDIRS += $$d $$b
+data := $$(sort $$(data) $$(appdir_$$b) $$(mandir_$$b) $$(pkgdatadir_$$b) $$(desktop_$$b))
+exec := $$(sort $$(exec) $$(bindir_$$b) $$(libdir_$$b))
+deps := $$(filter %.d,$$(exec:%.o=%.d))
+clean := $$(clean) $$(deps) $$(exec) $$(data)
+DEPFILE := $$(DEPFILE) $$(deps)
+DATA_TARGETS += $$(data)
+EXEC_TARGETS += $$(exec)
+d := $$(dirstack_$$(sp))
+data := $$(datstack_$$(sp))
+exec := $$(exestack_$$(sp))
+sp := $$(basename $$(sp))
+endef
+include = $(foreach i,$1,$(eval $(call include_func,$i)))
+
+targets = $(EXEC_TARGETS) $(DATA_TARGETS)
+builddir = build/obj
+b = $(builddir)/$(d)
+this = $(d)/rules.mk
+
+ifeq (gzip,$(manCompression))
+MANEXT=.gz
+else
+ifeq (bzip2,$(manCompression))
+MANEXT=.bz2
+endif
+endif
#
# Include the subdirectories--order is not important.
#
-dir := src
-include $(dir)/rules.mk
-
-dir := data
-include $(dir)/rules.mk
-
-dir := doc
-include $(dir)/rules.mk
+$(call include,src data doc)
+-include build/arch/$(platform)/rules.mk
#
# Define some common rules.
#
-ifeq ($(DEP_TRACKING),true)
-COMPILE = ./tools/compile.lua
+ifeq (true,$(tracking))
+PKG_CFLAGS += -MD -MP -MF $(@:%.o=%.d) -MT $@
+-include $(DEPFILE)
endif
-COMMAND_CC = $(COMPILE) $(CC) $(CFLAGS) $(CF_TGT) -o $@ -c $<
-COMMAND_CXX = $(COMPILE) $(CXX) $(CXXFLAGS) $(CF_TGT) -o $@ -c $<
-COMMAND_LD = $(CC) $(LDFLAGS) $(LF_TGT) -o $@ $^ $(LL_TGT) $(LIBS)
-COMMAND_LDX = $(CXX) $(LDFLAGS) $(LF_TGT) -o $@ $^ $(LL_TGT) $(LIBS)
-COMMAND_CCLD = $(COMPILE) $(CC) $(CFLAGS) $(CF_TGT) $(LDFLAGS) $(LF_TGT) -o $@ $< $(LL_TGT) $(LIBS)
-COMMAND_CXXLD = $(COMPILE) $(CXX) $(CXXFLAGS) $(CF_TGT) $(LDFLAGS) $(LF_TGT) -o $@ $< $(LL_TGT) $(LIBS)
-COMMAND_AR = $(AR) rcs $@ $^; $(RANLIB) $@
-COMMAND_RC = $(WINDRES) $(DDEFINES) $(DF_TGT) -o $@ -i $<
-COMMAND_INSTALL = ./tools/install.sh -m $1 $2 -d $3
-COMMAND_RM = rm -f $1
-COMMAND_IN = sed -f config.sed <"$1" >"$2"
-
-ifeq ($(verbose),yes)
-DO_CC = $(COMMAND_CC)
-DO_CXX = $(COMMAND_CXX)
-DO_LD = $(COMMAND_LD)
-DO_LDX = $(COMMAND_LDX)
-DO_CCLD = $(COMMAND_CCLD)
-DO_CXXLD = $(COMMAND_CXXLD)
-DO_AR = $(COMMAND_AR)
-DO_RC = $(COMMAND_RC)
-DO_INSTALL = $(COMMAND_INSTALL)
-DO_RM = $(COMMAND_RM)
-DO_IN = $(COMMAND_IN)
-SHELL_LINE_PREFIX =
+# Include current directory to allow sources to include config.h.
+override CPPFLAGS += -I. -DHAVE_CONFIG_H=1
+TGT_CXXFLAGS = $(TGT_CFLAGS)
+ARFLAGS = rc
+INSTALL = install
+
+tarname = $(TARNAME)-$(VERSION)
+
+cmd_compile_c = $(CC) $(PKG_CFLAGS) $(TGT_CFLAGS) $(CFLAGS) $(CPPFLAGS) \
+ $(TARGET_ARCH) -c $(OUTPUT_OPTION) $<
+cmd_compile_cc = $(CXX) $(PKG_CXXFLAGS) $(TGT_CXXFLAGS) $(CXXFLAGS) $(CPPFLAGS) \
+ $(TARGET_ARCH) -c $(OUTPUT_OPTION) $<
+cmd_link_c = $(CC) $(PKG_CFLAGS) $(TGT_CFLAGS) $(CFLAGS) $(CPPFLAGS) \
+ $(PKG_LDFLAGS) $(TGT_LDFLAGS) $(LDFLAGS) \
+ $(TARGET_ARCH) $^ $(LOADLIBES) $(PKG_LDLIBS) $(TGT_LDLIBS) $(LDLIBS) -o $@
+cmd_link_cc = $(CXX) $(PKG_CXXFLAGS) $(TGT_CXXFLAGS) $(CXXFLAGS) $(CPPFLAGS) \
+ $(PKG_LDFLAGS) $(TGT_LDFLAGS) $(LDFLAGS) \
+ $(TARGET_ARCH) $^ $(LOADLIBES) $(PKG_LDLIBS) $(TGT_LDLIBS) $(LDLIBS) -o $@
+cmd_ar = $(AR) $(ARFLAGS) $@ $^; $(RANLIB) $@
+cmd_compile_rc = $(WINDRES) $(CPPFLAGS) $(TARGET_ARCH) $(OUTPUT_OPTION) -i $<
+cmd_sed = sed -f config.sed <$< >$@
+cmd_gzip = gzip -c $< >$@
+cmd_bzip2 = bzip2 -c $< >$@
+cmd_xxd = id=$(subst .,_,$(notdir $<)); \
+ printf "\#include <stddef.h>\nsize_t\tdata_%s_size = %d;\nchar\tdata_%s[] = {\n" \
+ $$id $$(wc -c <$<) $$id >$@; \
+ xxd -i <$< >>$@; \
+ printf ", 0x00\n};\n" >>$@
+cmd_configure = ./configure
+func_install = mkdir -p $(DESTDIR)$3 && $(INSTALL) -m $1 $2 $(DESTDIR)$3
+func_remove = rm -f $1
+func_dist = git archive HEAD --prefix='$(tarname)/' | $1 >"$(tarname).tar.$2" && \
+ (md5 "$(tarname).tar.$2" 2>/dev/null || md5sum "$(tarname).tar.$2")
+
+compile_c = $(call func_print,CC,$@) $(cmd_compile_c)
+compile_cc = $(call func_print,CXX,$@) $(cmd_compile_cc)
+compile_rc = $(call func_print,RC,$@) $(cmd_compile_rc)
+link_c = $(call func_print,LINK,$@) $(cmd_link_c)
+link_cc = $(call func_print,LINK,$@) $(cmd_link_cc)
+ar = $(call func_print,AR,$@) $(cmd_ar)
+sed = $(call func_print,SED,$@) $(cmd_sed)
+gzip = $(call func_print,GZIP,$@) $(cmd_gzip)
+bzip2 = $(call func_print,BZIP2,$@) $(cmd_bzip2)
+xxd = $(call func_print,XXD,$@) $(cmd_xxd)
+configure = $(call func_print,MAKE,$@) $(cmd_configure)
+dist = $(call func_print,DIST,$1) $(func_dist)
+install = $(call func_print,CP,$(DESTDIR:%/=%)$(3:%/=%)/$(notdir $2)) $(func_install)
+remove = $(call func_print,RM,$1) $(func_remove)
+
+ifeq (1,$V)
+Q =
+func_print =
else
-DO_CC = @echo " CC $@"; $(COMMAND_CC)
-DO_CXX = @echo " CXX $@"; $(COMMAND_CXX)
-DO_LD = @echo " LD $@"; $(COMMAND_LD)
-DO_LDX = @echo " LD $@"; $(COMMAND_LDX)
-DO_CCLD = @echo " CCLD $@"; $(COMMAND_CCLD)
-DO_CXXLD = @echo " CXXLD $@"; $(COMMAND_CXXLD)
-DO_AR = @echo " AR $@"; $(COMMAND_AR)
-DO_RC = @echo " RC $@"; $(COMMAND_RC)
-DO_INSTALL = @echo " CP $2"; $(COMMAND_INSTALL)
-DO_RM = @echo " RM $1"; $(COMMAND_RM)
-DO_IN = @echo " MAKE $2"; $(COMMAND_IN)
-SHELL_LINE_PREFIX = @
+Q = @
+func_print = printf "\x20\x20$1\t%s\n" $2;
endif
# Define the implicit rules.
#
-%.o: %.c
- $(DO_CC)
%.o: %.cc
- $(DO_CXX)
+ $(Q)$(compile_cc)
%.o: %.cpp
- $(DO_CXX)
+ $(Q)$(compile_cc)
+%.o: %.c
+ $(Q)$(compile_c)
%.o: %.rc
- $(DO_RC)
-%: %.o
- $(DO_LD)
-%: %.c
- $(DO_CCLD)
-%: %.cc
- $(DO_CXXLD)
-%: %.cpp
- $(DO_CXXLD)
-%.a: %.o
- $(DO_AR)
+ $(Q)$(compile_rc)
%: %.in
- $(call DO_IN,$<,$@)
+ $(Q)$(sed)
+%.gz: %
+ $(Q)$(gzip)
+%.bz2: %
+ $(Q)$(bzip2)
+
+$(builddir)/%.o: %.cc
+ $(Q)$(compile_cc)
+$(builddir)/%.o: %.cpp
+ $(Q)$(compile_cc)
+$(builddir)/%.o: %.c
+ $(Q)$(compile_c)
+$(builddir)/%.o: %.rc
+ $(Q)$(compile_rc)
+$(builddir)/%: %.in
+ $(Q)$(sed)
+$(builddir)/%.gz: %
+ $(Q)$(gzip)
+$(builddir)/%.bz2: %
+ $(Q)$(bzip2)
+$(builddir)/%: %
+ $(Q)if [ -d $< ]; then mkdir -p $@; elif [ -f $< ]; then cp -f $< $@; fi
#
# Define the phony targets.
#
-.PHONY: clean
+.DEFAULT_GOAL :=
+all: $(targets)
+
clean:
- $(SHELL_LINE_PREFIX)files='$(CLEAN)'; for file in $$files; \
- do \
- $(call remove_silencer,$(call DO_RM,$$file)); \
- done
+ $(Q)$(foreach f,$(clean),$(call remove,$f);)
+ $(Q)if [ -d $(builddir) ]; then find $(builddir) -type d -empty -delete; fi
-.PHONY: distclean
distclean: clean
- $(call DO_RM,config.h)
- $(call DO_RM,config.mk)
- $(call DO_RM,config.sed)
-
-.PHONY: all_
-all_: $(BINARIES) $(MANPAGES)
-
-.PHONY: install
-install: all
- $(SHELL_LINE_PREFIX)files='$(DATAFILES)'; for file in $$files; \
- do \
- full=`echo "$$file" | cut -d\; -f1`; \
- base=`echo "$$file" | cut -d\; -f2`; \
- $(call remove_silencer,$(call DO_INSTALL,644,$$full,$(DESTDIR)$(datadir)$$base)); \
- done
- $(SHELL_LINE_PREFIX)files='$(BINARIES)'; for file in $$files; \
- do \
- $(call remove_silencer,$(call DO_INSTALL,755,$$file,$(DESTDIR)$(bindir))); \
- done
- $(SHELL_LINE_PREFIX)files='$(MANPAGES)'; for file in $$files; \
- do \
- $(call remove_silencer,$(call DO_INSTALL,644,$$file,$(DESTDIR)$(mandir))); \
- done
-
-.PHONY: uninstall
-uninstall:
- $(SHELL_LINE_PREFIX)files='$(BINARIES)'; for file in $$files; \
- do \
- base="/`basename $$file`"; \
- $(call remove_silencer,$(call DO_RM,$(DESTDIR)$(bindir)$$base)); \
- done
- $(SHELL_LINE_PREFIX)files='$(DATAFILES)'; for file in $$files; \
- do \
- full="`echo "$$file" | cut -d\; -f1`"; \
- base="`echo "$$file" | cut -d\; -f2`/`basename $$full`"; \
- $(call remove_silencer,$(call DO_RM,$(DESTDIR)$(datadir)$$base)); \
- done
-
-.PHONY: dist-bzip2
+ $(Q)cd build && $(MAKE) clean
+ $(Q)$(call remove,config.h);$(call remove,config.mk);$(call remove,config.sed)
+
+
+install: install-data install-exec
+
+install-data: $(DATA_TARGETS)
+ $(Q)$(foreach d,$(SUBDIRS),$(foreach f,$(pkgdatadir_$d),\
+ $(call install,644,$f,$(dir $(f:$d%=$(pkgdatadir)%)));))
+ $(Q)$(foreach d,$(SUBDIRS),$(foreach f,$(mandir_$d),\
+ $(call install,644,$f,\
+ $(dir $(f:$d%=$(mandir)/man$(shell echo "$f" | sed 's/[^.]*\.\([^.]*\).*/\1/')%)));))
+
+install-exec: $(EXEC_TARGETS)
+ $(Q)$(foreach d,$(SUBDIRS),$(foreach f,$(bindir_$d),\
+ $(call install,755,$f,$(dir $(f:$d%=$(bindir)%)));))
+
+install-desktop-entry: $(DATA_TARGETS)
+ $(Q)$(foreach d,$(SUBDIRS),$(foreach f,$(desktop_$d),\
+ $(call install,644,$f,/usr/share/applications);))
+
+
+dist-all: dist-bzip2 dist-gzip dist-lzma dist-xz
+
dist-bzip2:
- $(SHELL_LINE_PREFIX)git archive HEAD --prefix='$(TARNAME)/' | bzip2 > "$(TARNAME).tar.bz2"
+ $(Q)$(call dist,bzip2,bz2)
-.PHONY: dist-gzip
dist-gzip:
- $(SHELL_LINE_PREFIX)git archive HEAD --prefix='$(TARNAME)/' | gzip > "$(TARNAME).tar.gz"
+ $(Q)$(call dist,gzip,gz)
-.PHONY: dist
-dist: dist-bzip2
+dist-lzma:
+ $(Q)$(call dist,lzma,lzma)
+
+dist-xz:
+ $(Q)$(call dist,xz,xz)
+
+dist: dist-$(archiveFormat)
#
# Prevent make from removing any build targets.
#
-.SECONDARY: $(CLEAN)
+.SECONDARY: $(clean)
+
+.PHONY: all clean distclean install install-data install-exec
+.PHONY: install-desktop-entry
+.PHONY: dist dist-all dist-gzip dist-bzip2 dist-xz dist-lzma
+
+endif # menuconfig