diff --git a/.gitignore b/.gitignore index 9e4b0ee..c56d83d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ *.elc +# Makefile prerequisites. +*.el.d *-pkg.el *-autoloads.el diff --git a/Makefile b/Makefile index 2d56356..d04a273 100644 --- a/Makefile +++ b/Makefile @@ -1,30 +1,82 @@ PROTO_PATH := /usr/share/xcb +ifeq ($(shell ! test -d $(PROTO_PATH) && echo ok),ok) + $(warning Please set `PROTO_PATH` to the path to the XCB protocol definitions): + $(warning make $(MFLAGS) $(MAKEOVERRIDES) $(MAKECMDGOALS) `PROTO_PATH=/opt/X11/...`) + $(error Could not find directory `$(PROTO_PATH)`) +endif + EXTENSIONS := bigreq composite damage dbe dpms dri2 dri3 ge glx present randr \ record render res screensaver shape shm sync xc_misc xevie xf86dri \ xf86vidmode xfixes xinerama xinput xkb xprint xselinux xtest xvmc xv -EXT_LIBS = $(addprefix xcb-,$(addsuffix .el,$(EXTENSIONS))) -LIBS = xcb-xproto.el $(EXT_LIBS) +ELXS = $(addprefix xcb-,$(addsuffix .el,$(EXTENSIONS))) +ELGS = xcb-xproto.el $(ELXS) +ELLS = xcb-cursor.el xcb-debug.el xcb-ewmh.el xcb-icccm.el xcb-keysyms.el \ + xcb-renderutil.el xcb-systemtray.el xcb-types.el xcb-xembed.el xcb-xim.el \ + xcb-xlib.el xcb-xsettings.el xcb.el xelb.el +ELS = $(ELLS) $(ELGS) +ELCS = $(ELS:.el=.elc) xelb-gen.elc -all: clean $(LIBS) +.PHONY: all +all: compile generate xcb-%.el: $(PROTO_PATH)/%.xml - @echo -n "\n"Generating $@... + @printf '%s\n' 'Generating $@...' @./xelb-gen $< > $@ -$(EXT_LIBS): xcb-xproto.el +# Generate an intermediate `.el` file from the xelb-gen script so that +# byte-compiling rules below apply. This file will be deleted after the `.elc` +# is created. +.INTERMEDIATE: xelb-gen.el +xelb-gen.el: xelb-gen + cp $< $@ -xcb-composite.el: xcb-xfixes.el -xcb-damage.el: xcb-xfixes.el -xcb-present.el: xcb-randr.el xcb-xfixes.el xcb-sync.el -xcb-randr.el: xcb-render.el -xcb-xfixes.el: xcb-render.el xcb-shape.el -xcb-xinput.el: xcb-xfixes.el -xcb-xvmc.el: xcb-xv.el -xcb-xv.el: xcb-shm.el +# Dependencies needed for generating. +# We generate makefile fragments by grepping the ``s in the `.xml` +# protocol definitions. +# See https://www.gnu.org/software/make/manual/html_node/Automatic-Prerequisites.html . +ELGDS=$(ELGS:.el=.el.d) +$(ELGDS): xcb-%.el.d: $(PROTO_PATH)/%.xml + @printf "Inferring dependencies for $<\n" + @{ IMPORTS=$$(grep '' $< | sed -E -e 's,^[[:space:]]*([^<]+),xcb-\1,' | tr '\n' ' '); \ + test -n "$$IMPORTS" && printf '%s' 'xcb-$*.el:' && printf ' %s.el' $$IMPORTS && printf '\n'; \ + test -n "$$IMPORTS" && printf '%s' 'xcb-$*.elc:' && printf ' %s.elc' $$IMPORTS && printf '\n'; \ + true; \ + } >$@ +# All generated `.el` files require `xcb-types.el`. +$(ELGS): xcb-types.el +$(ELGS:.el=.elc): xcb-types.elc -.PHONY: clean +# Dependencies needed for byte-compiling. +# We grep the `require`s in non-generated `.el` files. +ELLDS=$(ELLS:.el=.el.d) +$(ELLDS): %.el.d: %.el + @printf "Inferring dependencies for $<\n" + @{ printf '%s' '$*.elc: '; \ + grep "require 'xcb" $< | \ + sed -E -e "s,.*\(require '([^)]+)\).*,\1.elc," | \ + tr '\n' ' '; \ + printf '\n'; \ + } >$@ + +# This is a small crutch: we want to avoid generating the `.el.d`s (which means +# parsing the XML and generating the corresponding `.el`s) in order to clean. +ifneq ($(MAKECMDGOALS),clean) +include $(ELLDS) +include $(ELGDS) +endif + +%.elc: %.el + @printf "Compiling $<\n" + @emacs --batch -Q -L . -f batch-byte-compile $< +.PHONY: compile +compile: $(ELCS) + +.PHONY: generate +generate: $(ELGS) + +.PHONY: clean clean: - @rm -vf $(LIBS) + @rm -vf $(ELGS) $(ELLDS) $(ELCS) $(ELGDS) diff --git a/xelb-gen b/xelb-gen index daff68c..7b14d31 100755 --- a/xelb-gen +++ b/xelb-gen @@ -180,6 +180,7 @@ an `xelb-auto-padding' attribute." "Parse an XCB protocol description file FILE (XML)." (let ((pp-escape-newlines nil) ;do not escape newlines (pp-default-function 'pp-28) ;avoid unecessary churn + (load-prefer-newer 't) ;avoid loading outdated bytecode result header) (with-temp-buffer (insert-file-contents file)