Created
July 25, 2016 03:36
-
-
Save ericpruitt/32f3f8b6c3df903d03f5e95ed8ba3428 to your computer and use it in GitHub Desktop.
Makefile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
DMENU_REPOSITORY = http://git.suckless.org/dmenu | |
DMENU_REVISION = 3c91eed | |
DWM_REPOSITORY = http://git.suckless.org/dwm | |
DWM_REVISION = 56a31dc | |
SLOCK_REPOSITORY = http://git.suckless.org/slock | |
SLOCK_REVISION = 65b8d52 | |
ST_REPOSITORY = http://git.suckless.org/st | |
ST_REVISION = 235b438 | |
PREFIX = $(HOME) | |
BINARIES = del dmenu dwm st | |
SUPERUSER_PREFIX = /usr/local | |
SUPERUSER_BINARIES = slock | |
SCRIPTS = mediacontrol screenshot window-screenshot | |
# For some targets, an if/wildcard combination ensures that a directory is only | |
# considered a dependency if it does not already exist. This ensures changing | |
# directory timestamps don't result in unnecessary recompiles. In other | |
# targets, wildcard expansion is used so that certain files are only added as | |
# dependencies if they already exist. Without using the wildcard function, the | |
# recipes fail when the files did not exist because there's no recipe for them | |
# in this Makefile. I attempted to use order-only prerequisites for *-src | |
# folders, but I ran into some problems with dependency chains; deleting | |
# "app-src" after creating the binary "app" then running "make" would only | |
# generate the config.h symlink; in order to rebuild th binary, "make" would | |
# have to be run again. | |
all: $(BINARIES) $(SUPERUSER_BINARIES) | |
reset: reset-dmenu reset-dwm reset-slock reset-st | |
# Dependency function for suckless projects. This accepts the project's name as | |
# its only argument e.g. $(call suckless,app) would gemerate a dependency list | |
# for the suckless project "app". | |
sucklessdeps = \ | |
$(1)-src/config.h \ | |
$(wildcard $(1)-src/*.[ch] $(1)-*.[ch] patches/$(1)-*.diff) \ | |
$(if $(wildcard $(1)-src),,$(1)-src) | |
# Generic target for fetching upstream Git repositories: given the target | |
# "app-src", this recipe will clone the URL specified by $(APP_REPOSITORY) into | |
# the folder "app-src" and attempt to reset the repository to the revision | |
# specified by $(APP_REVISION) if it is non-empty string. | |
%-src: | |
@echo "bin" "*-src" | tr ' ' '\n' > .git/info/exclude | |
git clone $($(shell echo $(subst -src,,$@) | tr a-z A-Z)_REPOSITORY) $@ | |
@revision=$($(shell echo $(subst -src,,$@) | tr a-z A-Z)_REVISION); \ | |
if [ -n "$$revision" ]; then \ | |
cd $@ && git reset --hard $$revision; \ | |
fi | |
# Generic target for resetting for a repository: given the target "reset-app", | |
# this recipe will run "git --reset --hard $(APP_REVISION)" inside "app-src" | |
# followed by "make clean". | |
reset-%: | |
@set -e; \ | |
dir=$(subst reset-,,$@)-src; \ | |
test ! -e $$dir && return; \ | |
cd $$dir; \ | |
git reset -q --hard \ | |
$($(shell echo $(subst reset-,,$@) | tr a-z A-Z)_REVISION); \ | |
$(MAKE) -s clean > /dev/null | |
# Generic target for applying patches to a repository: given the target | |
# "patched-app", this recipe will apply all patches matching the shell glob | |
# "patches/app-*.diff" to the contents of the folder "app-src". | |
patched-%: | |
@prefix=$(subst patched-,,$@); \ | |
echo "Applying patches to $$prefix:"; \ | |
for patch in patches/$$prefix-*.diff; do \ | |
echo "- $$patch"; \ | |
if ! patch -d $$prefix-src -s < $$patch; then \ | |
exit 1; \ | |
fi; \ | |
done | |
# Generic target for suckless config.h files: given the target | |
# "app-src/config.h", this recipe will symlink "app-config.h" into the folder | |
# "app-src". | |
%-src/config.h: %-config.h | %-src | |
@if ! [ -e $@ ]; then \ | |
ln -v -s ../$< $@; \ | |
fi | |
bin/dmenu: $(call sucklessdeps,dmenu) | |
@cd dmenu-src && $(MAKE) -s dmenu | |
@mv dmenu-src/dmenu $@ | |
dmenu: bin/dmenu | |
bin/dwm: $(call sucklessdeps,dwm) | |
@if (cd dwm-src && git diff --quiet -- *.c *.h); then \ | |
$(MAKE) -s patched-dwm; \ | |
else \ | |
echo "WARNING: dwm tree is dirty; no patches will be applied."; \ | |
fi | |
@ln -s -f ../dwm-build.mk dwm-src/config.mk | |
@cd dwm-src && $(MAKE) -s | |
@mv dwm-src/dwm $@ | |
dwm: bin/dwm | |
slock-src/slock: $(call sucklessdeps,slock) | |
@cd slock-src && $(MAKE) -s | |
slock: slock-src/slock | |
bin/st: $(call sucklessdeps,st) | |
@cd st-src && $(MAKE) -s | |
@mv st-src/st $@ | |
st: bin/st | |
bin/%: utilities/%.c | |
@command=$$(sed -n -e 's/.*\(\<cc\>.*\)/\1/p;/\<cc\>/q;/^$$/q' $^); \ | |
if [ -z "$$command" ]; then \ | |
echo "Could not extract compilation command from $^"; >&2 \ | |
exit 1; \ | |
fi; \ | |
sh -c "INPUT=$^; OUTPUT=$@; echo $$command && exec $$command" | |
del: bin/del | |
$(SUPERUSER_PREFIX)/bin/slock: slock-src/slock | |
sudo install -m 4755 -g root -o root $^ $(SUPERUSER_PREFIX)/bin | |
$(PREFIX)/bin/%: $(PWD)/bin/% | |
@if [ -h $@ ]; then \ | |
rm -v $@; \ | |
fi | |
ln -s $^ $@ | |
install: $(addprefix $(PREFIX)/bin/,$(BINARIES)) \ | |
$(addprefix $(SUPERUSER_PREFIX)/bin/,$(SUPERUSER_BINARIES)) | |
@if [ ! -e ~/.del ]; then \ | |
echo st > ~/.del; \ | |
echo "del -u" && exec del -u; \ | |
fi | |
clean: | |
rm -f *-src/config.h bin/* | |
cleaner: | |
rm -rf *-src bin/* | |
.PHONY: all clean cleaner install preinstall reset sanity | |
.PRECIOUS: %-src |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment