# # Yoink # Use this file with GNU make to compile and install Yoink. # # 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 SHELL = /bin/sh 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 # Recipe to create `config.h' which is included by some source files. config.h: config.mk $(Q)$(configure) --export-header=$@ # 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=$@ # Recipe to create `config.mk' which is the makefile with important configure # options set. config.mk: $(Q)$(configure) --interactive --print-instructions=no # Include the configure makefile; fail if it doesn't exist. include config.mk # This simple variable will be appended with targets which must be built # before the `install-data' target. data_targets := # This simple variable will be appended with targets which must be built # before the `install-exec' target. exec_targets := # 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 := # 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 # 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 # 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 # 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 # 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 \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 Q = @ func_print = printf "\x20\x20$1\t%s\n" $2; endif # Define the implicit rules. Targets and sources which match do not need to # be explicitly stated in the rule definitions. %.o: %.c $(Q)$(compile_c) %.h.gch: %.h $(Q)$(compile_pch) %.o: %.cc $(Q)$(compile_cc) %.o: %.cpp $(Q)$(compile_cc) %.hh.gch: %.hh $(Q)$(compile_pchh) %.o: %.rc $(Q)$(compile_rc) %: %.in $(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: $(Q)$(foreach f,$(clean),$(call remove,$f);) $(Q)if [ -d $(builddir) ]; then find $(builddir) -type d -empty -delete; fi # Make the project even cleaner by removing files created by configuration. distclean: clean $(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: $(Q)$(call dist,bzip2,bz2) dist-gzip: $(Q)$(call dist,gzip,gz) dist-lzma: $(Q)$(call dist,lzma,lzma) dist-xz: $(Q)$(call dist,xz,xz) # The `dist' target will create the distfile in whatever format was set in the # configuration. dist: dist-$(archiveFormat) # 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 endif # menuconfig