;; makefile mode setup. (add-hook-and-eval 'awk-mode-hook (lambda () (local-set-key (kbd "C-c c") 'makefile-config) (local-set-key (kbd "C-c d") 'makefile-doc) (local-set-key (kbd "C-c m") 'makefile-main) (local-set-key (kbd "C-c s") 'makefile-c))) (define-skeleton makefile-main "Insert root Makefile." nil "ROOT = . include ${ROOT}/config.mk ################################################################################ ## Build. .PHONY: all all: app doc .PHONY: app app: ${MAKE} -C ${srcdir} .PHONY: doc doc: ${MAKE} -C ${docsrcdir} .PHONY: debug debug: CFLAGS+=\"-g3 -O0 -DDEBUG=9\" ${MAKE} .PHONY: test test: ${MAKE} -C ${testdir} .PHONY: clean clean: ${MAKE} -C ${srcdir} clean ${MAKE} -C ${docsrcdir} clean ${MAKE} -C ${testdir} clean ################################################################################ ## Install / Uninstall. INSTALL ?= install INSTALL_DATA ?= ${INSTALL} -m644 INSTALL_DIR ?= ${INSTALL} -d prefix ?= /usr/local exec_prefix ?= ${prefix} datarootdir ?= ${prefix}/share bindir ?= ${exec_prefix}/bin datadir ?= ${datarootdir} docdir ?= ${datarootdir}/doc includedir ?= ${prefix}/include infodir ?= ${datarootdir}/info libdir ?= ${exec_prefix}/lib libexecdir ?= ${exec_prefix}/libexecdir licensedir ?= ${datarootdir}/licenses localedir ?= ${datarootdir}/locale localstatedir ?= ${prefix}/var mandir ?= ${datarootdir}/man runstatedir ?= ${prefix}/run sbindir ?= ${exec_prefix}/sbin sharedstatedir ?= ${prefix}/com sysconfdir ?= ${perfix}/etc .PHONY: install install: ${MAKE} ${INSTALL_DIR} ${DESTDIR}${bindir} ${INSTALL} ${srcdir}/${cmdname} ${DESTDIR}${bindir}/${cmdname} ${INSTALL_DIR} ${DESTDIR}${mandir}/man1 ${INSTALL_DATA} ${docsrcdir}/${cmdname}.1 ${DESTDIR}${mandir}/man1/${cmdname}.1 ${INSTALL_DIR} ${DESTDIR}${licensedir}/${cmdname} ${INSTALL_DATA} LICENSE ${DESTDIR}${licensedir}/${cmdname}/LICENSE .PHONY: uninstall uninstall: -rm -f ${DESTDIR}${bindir}/${cmdname} -rmdir -p ${DESTDIR}${bindir} -rm -f ${DESTDIR}${mandir}/${cmdname}.${mansection}.gz -rmdir -p ${DESTDIR}${mandir} -rm -f ${DESTDIR}${licensedir}/${cmdname}/LICENSE -rmdir -p ${DESTDIR}${licensedir}/${cmdname} " > \n) (define-skeleton makefile-doc "Insert documentation Makefile." nil ".SUFFIXES: .in ROOT ?= .. include ${ROOT}/config.mk manpages = ${cmdname}.1 all: ${manpages} .in: awk -v date=`date '+%Y-%m-%d'` 'BEGIN {section=\"$@\"; sub (/.*\\./, \"\", section); manname=toupper(\"$@\"); sub(/\\.[^.]+$$/, \"\", manname); print \".ds appname ${appname}\\n.ds authors ${authors}\\n.ds cmdname ${cmdname}\\n.ds date \" date \"\\n.ds manname \" manname \"\\n.ds section \" section \"\\n.ds version ${version}\\n.ds year ${year}\\n.\"}' > $@ cat $< >> $@ clean: rm -f ${manpages} " > \n) (define-skeleton makefile-c "Insert Makefile for building c." nil "ROOT ?= .. include ${ROOT}/config.mk CPPFLAGS += -DAUTHORS=\"${authors}\" -DVERSION=${version} -DYEAR=${year} CPPFLAGS += -D_POSIX_C_SOURCE=200809L CPPFLAGS += -DHAVE_INLINE LDLIBS += -lm ${cmdname}: ${cmdname}.o .PHONY: debug debug: CFLAGS+=\"-g3 -O0 -DDEBUG=9\" ${MAKE} .PHONY: clean clean: rm -f ${cmdname} *.d *.o ## Generate prerequisites automatically. GNU Make only. ## The 'awk' part is used to add the .d file itself to the target, so that it ## gets updated on changes. The -MQ option is to add full path to object files ## in subfolders. (-MM strips parent directories.) %.d: %.c ${CC} -MM -MQ ${<:.c=.o} ${CPPFLAGS} $< | awk -v stem=$* -v target=$@ '{gsub (stem \".o[ :]*\", stem \".o \" target \" : \")} 1' > $@ sources = $(wildcard *.c) deps = ${sources:.c=.d} -include ${deps} " > \n) (define-skeleton makefile-config "Insert Makefile config." nil "## This file is included by all (sub-)makefiles. ## Properties. appname = Name authors = Pierre Neidhardt cmdname = name url = http://ambrevar.bitbucket.org/ version = 1.0 year = 2014 ## Folders. srcdir = src docsrcdir = doc testdir = tests ## USER SETTINGS ## Optional compilation flags. CFLAGS ?= -pedantic -std=c99 -Wall -Wextra -Wshadow ## END OF USER SETTINGS " > \n) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Dist rules ;; They are somewhat obsolete since VCS can go better. Here follows some ;; examples for historical interest. ; arcdir = ${ROOT}/${cmdname}-${version} ; arc = ${ROOT}/${arcdir}.tar.xz ; srcfiles = ${srcdir}/Makefile ${srcdir}/${cmdname}.c ${srcdir}/${cmdname}.h ; docsfiles = ${docsdir}/Makefile ${docsdir}/${cmdname}.1.in ; testfiles = ${testdir}/check.c ${testdir}/Makefile ; rootfiles = Makefile TODO ; .PHONY: dist ; dist: ${arc} ; ${arc}: ${rootfiles} ${srcfiles} ${docsfiles} ${testfiles} ; -mkdir ${arcdir}/ ; ln -f ${rootfiles} ${arcdir}/ ; -mkdir ${arcdir}/${srcdir} ; ln -f ${srcfiles} ${arcdir}/${srcdir}/ ; -mkdir ${arcdir}/${docsdir} ; ln -f ${docsfiles} ${arcdir}/${docsdir}/ ; -mkdir ${arcdir}/${testdir} ; ln -f ${testfiles} ${arcdir}/${testdir} ; tar -cahf ${arc} ${cmdname}-${version} ; rm -rf ${cmdname}-${version} ;; This one is using a list of files generated by an external program (here ;; git). The good is that it is more dynamic. The bad is that it does not depend ;; on any file. ; arc = ${ROOT}/${cmdname}-${version}.tar.xz ; .PHONY: dist ; dist: ${arc} ; ${arc}: ; git ls-files -z | { pwd="$$(pwd)" ; sed -z "s/^/$${pwd##*/}\//" ; } | tar caf ${arc} -C .. --null -T - (provide 'mode-makefile) ;; End of file.