]> Dogcows Code - chaz/yoink/blobdiff - Makefile
fixed documentation about where to find licenses
[chaz/yoink] / Makefile
index caf10e3daf15bdb421f14dba85d0536f7948c48e..dfdfaeb072e71a2ed66dabb04fbf4f3b563b6ed3 100644 (file)
--- a/Makefile
+++ b/Makefile
 
 #
 # 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 so that warnings are clearly visible.
+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))
+# If all we want is to bring up the configure script, then we really don't
+# need to define any other functions or recipes process anything else.
+menuconfig:
+       ./configure --interactive
+.PHONY: menuconfig
 else
-$(error You must run the configure script before you can make anything)
-endif
 
+# Recipe to create `config.h' which is included by some source files.
+config.h: config.mk
+       $(Q)$(configure) --export-header=$@
 
-#
-# Declare the default targets and implicit rules.
-#
-
-.PHONY: all
-all: all_
+# Recipe to create `config.sed' which is used by some recipes to search and
+# replace certain terms in some files, usually with a `.in' suffix.
+config.sed: config.mk
+       $(Q)$(configure) --export-terms=$@
 
-.SUFFIXES:
-.SUFFIXES: .a .c .cc .cpp .in .o .rc
+# Recipe to create `config.mk' which is the makefile with important configure
+# options set.
+config.mk:
+       $(Q)$(configure) --interactive --print-instructions=no
 
 
-#
-# Define some useful functions.
-#
+# Include the configure makefile; fail if it doesn't exist.
+include config.mk
 
-add_exe_suffix  = $(addsuffix $(EXEEXT),$1)
-remove_silencer = $(1:@%=%)
 
+# This simple variable will be appended with targets which must be built
+# before the `install-data' target.
+data_targets   :=
 
-#
-# Include the subdirectories--order is not important.
-#
+# This simple variable will be appended with targets which must be built
+# before the `install-exec' target.
+exec_targets   :=
 
-dir := src
-include $(dir)/rules.mk
+# This simple variable will be appended with subdirectories which contain
+# rules as well as their corresponding subdirectories under the build
+# directory, any directory which might have files to be installed.
+subdirs                :=
 
-dir := data
-include $(dir)/rules.mk
+# Function to include rules from subdirectories.  This is the core of the
+# non-recursive make method this build system uses.  It works by managing
+# several stacks and helping to append the appropriate values to the simple
+# variables defined above.
+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) $$(mandir_$$b) $$(datadir_$$b) $$(pkgdatadir_$$b) $$(desktop_$$b))
+exec   := $$(sort $$(exec) $$(bindir_$$b) $$(libdir_$$b))
+deps   := $$(filter %.d,$$(call depfile,$$(exec)))
+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)))
+
+# These shortcut variables are meant to be used to simplify included rules.
+builddir       = build/obj
+b              = $(builddir)/$(d)
+this           = $(d)/rules.mk
+
+# Function to convert object file paths to dependency file paths.  This also
+# supports pre-compiled header files.
+depfile        = $(patsubst %.h.gch,%.d,$(patsubst %.hh.gch,%.d,$(1:%.o=%.d)))
+
+# Determine the suffix that installed manual pages should have.
+ifeq (gzip,$(manCompression))
+MANEXT=.gz
+else
+ifeq (bzip2,$(manCompression))
+MANEXT=.bz2
+endif
+endif
 
-dir := doc
-include $(dir)/rules.mk
+# Now do the actual inclusion of the rules from these subdirectories.
+$(call include,src data doc)
 
+# Also include platform-specific rules, if they exist.
+-include build/arch/$(platform)/rules.mk
 
-#
-# Define some common rules.
-#
+# Handle automatic tracking of dependencies, if enabled.  This adds overhead
+# and should be disabled if not needed.
+ifeq (true,$(tracking))
+PKG_CFLAGS     += -MT $@ -MMD -MP -MF $(call depfile,$@)
+-include $(DEPFILE)
+endif
 
-ifeq ($(DEP_TRACKING),true)
-COMPILE = ./tools/compile.lua
+# Handle the inclusion of a PCH file, if enabled.  Using a PCH file can
+# improve build times in some (but not all) cases.  The rules should also
+# define the `pchfile' variable to the path of the PCH file.  Only one PCH
+# file can be used.  If the PCH file has a `.h' suffix, it is included only
+# when compiling C sources, otherwise it will be included only when compiling
+# C++ sources.
+ifeq (true,$(pch))
+ifneq (,$(pchfile))
+PCH_FLAGS      = -Winvalid-pch -include $(pchfile)
+endif
 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
+
+# The target C++ flags should mirror the target C flags by default.
+TGT_CXXFLAGS           = $(TGT_CFLAGS)
+
+# Define the default flags passed to the library archiver.
+ARFLAGS                = rc
+
+# Define the default install program.
+INSTALL                = install
+
+# Define the `tarname' to be used as a base filename for distributable
+# archives.
+tarname                = $(TARNAME)-$(VERSION)
+
+# Define the commands needed to make several different types of files.  Don't
+# used these commands directly because they don't account for verbosity;
+# instead use the commands without the `cmd_' prefix (defined below).
+cmd_compile_c  = $(CC) $(PKG_CFLAGS) $(TGT_CFLAGS) $(PCH_CFLAGS) $(CFLAGS) $(MYCFLAGS) $(CPPFLAGS) \
+                 $(TARGET_ARCH) -c $(OUTPUT_OPTION) $<
+cmd_compile_cc = $(CXX) $(PKG_CXXFLAGS) $(TGT_CXXFLAGS) $(PCH_CXXFLAGS) $(CXXFLAGS) $(MYCXXFLAGS) $(CPPFLAGS) \
+                 $(TARGET_ARCH) -c $(OUTPUT_OPTION) $<
+cmd_link_c     = $(CC) $(PKG_CFLAGS) $(TGT_CFLAGS) $(PCH_CFLAGS) $(CFLAGS) $(MYCFLAGS) $(CPPFLAGS) \
+                 $(PKG_LDFLAGS) $(TGT_LDFLAGS) $(LDFLAGS) $(MYLDFLAGS) \
+                 $(TARGET_ARCH) $^ $(LOADLIBES) $(PKG_LDLIBS) $(TGT_LDLIBS) $(LDLIBS) -o $@
+cmd_link_cc    = $(CXX) $(PKG_CXXFLAGS) $(TGT_CXXFLAGS) $(PCH_CXXFLAGS) $(CXXFLAGS) $(MYCXXFLAGS) $(CPPFLAGS) \
+                 $(PKG_LDFLAGS) $(TGT_LDFLAGS) $(LDFLAGS) $(MYLDFLAGS) \
+                 $(TARGET_ARCH) $^ $(LOADLIBES) $(PKG_LDLIBS) $(TGT_LDLIBS) $(LDLIBS) -o $@
+cmd_compile_pch        = $(CC) $(PKG_CFLAGS) $(TGT_CFLAGS) $(CFLAGS) $(MYCFLAGS) $(CPPFLAGS) \
+                 $(TARGET_ARCH) -c $(OUTPUT_OPTION) $<
+cmd_compile_pchh       = $(CXX) $(PKG_CXXFLAGS) $(TGT_CXXFLAGS) $(CXXFLAGS) $(MYCXXFLAGS) $(CPPFLAGS) \
+                         $(TARGET_ARCH) -c $(OUTPUT_OPTION) $<
+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
+
+# Define some useful functions.  Don't use these functions directly because
+# they don't account for verbosity; instead use the functions without the
+# `func_' prefix (defined below).
+func_remove    = rm -f $1
+func_install   = mkdir -p $(DESTDIR)$3 && $(INSTALL) -m $1 $2 $(DESTDIR)$3
+func_dist      = git archive HEAD --prefix='$(tarname)/' | $1 >"$(tarname).tar.$2" && \
+                 (openssl md5 "$(tarname).tar.$2" 2>/dev/null || \
+                 md5 "$(tarname).tar.$2" 2>/dev/null || \
+                 md5sum "$(tarname).tar.$2" 2>/dev/null)
+
+# These commands and functions should be used in most recipes to compile
+# sources, link objects, compress files, create distfiles, install files, etc.
+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)
+compile_pch    = $(call func_print,CC,$@)      $(cmd_compile_pch)
+compile_pchh   = $(call func_print,CXX,$@)     $(cmd_compile_pchh)
+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)
+remove         = $(call func_print,RM,$1)      $(func_remove)
+install                = $(call func_print,CP,$(DESTDIR:%/=%)$(3:%/=%)/$(notdir $2)) $(func_install)
+
+# The mechanism used by this makefile to handle verbosity simply requires (by
+# convention) commands in rules to be prefixed with `$Q' and the commands and
+# functions defined above will then print a single line describing the command
+# instead of the entire command.
+ifeq (1,$V)
+Q              =
+func_print     =
 else
-DO_CC              = @echo -e " CC \t$@";    $(COMMAND_CC)
-DO_CXX             = @echo -e " CXX \t$@";   $(COMMAND_CXX)
-DO_LD              = @echo -e " LD \t$@";    $(COMMAND_LD)
-DO_LDX             = @echo -e " LD \t$@";    $(COMMAND_LDX)
-DO_CCLD            = @echo -e " CCLD \t$@";  $(COMMAND_CCLD)
-DO_CXXLD           = @echo -e " CXXLD \t$@"; $(COMMAND_CXXLD)
-DO_AR              = @echo -e " AR \t$@";    $(COMMAND_AR)
-DO_RC              = @echo -e " RC \t$@";    $(COMMAND_RC)
-DO_INSTALL         = @echo -e " CP \t$2";    $(COMMAND_INSTALL)
-DO_RM              = @echo -e " RM \t$1";    $(COMMAND_RM)
-DO_IN              = @echo -e " MAKE \t$2";  $(COMMAND_IN)
-SHELL_LINE_PREFIX  = @
+Q              = @
+func_print     = printf "\x20\x20$1\t%s\n" $2;
 endif
 
 
-#
-# Define the implicit rules.
-#
-
+# Define the implicit rules.  Targets and sources which match do not need to
+# be explicitly stated in the rule definitions.
 %.o: %.c
-       $(DO_CC)
+       $(Q)$(compile_c)
+%.h.gch: %.h
+       $(Q)$(compile_pch)
 %.o: %.cc
-       $(DO_CXX)
+       $(Q)$(compile_cc)
 %.o: %.cpp
-       $(DO_CXX)
+       $(Q)$(compile_cc)
+%.hh.gch: %.hh
+       $(Q)$(compile_pchh)
 %.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,$<,$@)
-
-
-#
-# Define the phony targets.
-#
-
-.PHONY: clean
+       $(Q)$(sed)
+%.gz: %
+       $(Q)$(gzip)
+%.bz2: %
+       $(Q)$(bzip2)
+
+# More explicit rules which allow targets in the build directory to be made
+# directly.  A special rules is also defined to create directories or copy
+# files under the build directory to match the structure of the source
+# directory.
+$(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 default target(s).  This should `make' just about everything.
+.DEFAULT_GOAL :=
+all: $(exec_targets) $(data_targets)
+
+# Define the recipe to clean the targets.  This will remove the target files
+# and the empty directories of the build hierarchy.
 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
+# Make the project even cleaner by removing files created by configuration.
 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)
+
+# Installation happens in two separated phases, installing the executable
+# (i.e. platform-specific) files and installing the data files.
+install: install-data install-exec
+
+# Recipe to install the data files.  Right now, that includes files destined
+# for `pkgdatadir' and `mandir'.
+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/')%)));))
+
+# Recipe to install executable files.  Right now, that includes files destined
+# for `bindir'.
+install-exec: $(exec_targets)
+       $(Q)$(foreach d,$(subdirs),$(foreach f,$(bindir_$d),\
+               $(call install,755,$f,$(dir $(f:$d%=$(bindir)%)));))
+
+# Recipe to install desktop entry file(s) to /usr/share/applications.
+install-desktop-entry: $(data_targets)
+       $(Q)$(foreach d,$(subdirs),$(foreach f,$(desktop_$d),\
+               $(call install,644,$f,/usr/share/applications);))
+
+# Target used to create distfiles in all the supported compression formats.
+dist-all: dist-bzip2 dist-gzip dist-lzma dist-xz
+
+# Separate targets to create distfiles in the corresponding formats.
 dist-bzip2:
-       $(SHELL_LINE_PREFIX)git archive HEAD --prefix='$(TARNAME)/' | bzip2 > "$(TARNAME).tar.bz2"
-
-.PHONY: dist-gzip
+       $(Q)$(call dist,bzip2,bz2)
 dist-gzip:
-       $(SHELL_LINE_PREFIX)git archive HEAD --prefix='$(TARNAME)/' | gzip > "$(TARNAME).tar.gz"
+       $(Q)$(call dist,gzip,gz)
+dist-lzma:
+       $(Q)$(call dist,lzma,lzma)
+dist-xz:
+       $(Q)$(call dist,xz,xz)
 
-.PHONY: dist
-dist: dist-bzip2
+# The `dist' target will create the distfile in whatever format was set in the
+# configuration.
+dist: dist-$(archiveFormat)
 
 
-#
-# Prevent make from removing any build targets.
-#
+# Define which targets do not actually correspond to real files.
+.PHONY: all clean distclean
+.PHONY: install install-data install-exec install-desktop-entry
+.PHONY: dist dist-all dist-gzip dist-bzip2 dist-xz dist-lzma
 
-.SECONDARY:    $(CLEAN)
+endif  # menuconfig
 
This page took 0.027151 seconds and 4 git commands to generate.