diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-02-08 16:36:45 -0500 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-02-08 16:36:45 -0500 |
commit | 7e704d7ac997387341e920e1757c24cac0efe5e9 (patch) | |
tree | a9f30eabaaad5496397a91053d3e03bab1ea57e4 | |
parent | 7785a72495e3eb0ea826b41720c241f58a15b601 (diff) |
Refactor the build system. Avoid recursive make.
This looks like a lot, but more things should "just work".
We have `make dist` now!
34 files changed, 998 insertions, 588 deletions
@@ -1,5 +1,20 @@ *~ #* + +/.var.* +.tmp* + +# Files generated for dist from git +.srcfiles.mk +/.srcversion-libretools.mk +/.srcversion-devtools.mk + +# The top-level distdir +/*-*/ + +# File extensions +*.ugly +*.tar.gz *.pot *.1 *.2 @@ -1,12 +1,9 @@ -topdir = . -include config.mk - -################################################################################ +include $(dir $(lastword $(MAKEFILE_LIST)))/config.mk +include $(topsrcdir)/automake.head.mk # these are the resulting packages -packages=doc libretools librelib gitget xbs +packages=libretools librelib gitget xbs # and which directories they contain -doc=doc libretools=\ src \ src/abslibre-tools \ @@ -21,41 +18,22 @@ xbs=\ src/xbs-abs \ src/xbs-abslibre -################################################################################ - -all: PHONY build -copy: PHONY $(addprefix copy-, $(packages)) -build: PHONY $(addprefix build-, $(packages)) -install: PHONY $(addprefix install-,$(packages)) -clean: PHONY $(addprefix clean-, $(packages)) - rm -f po/*.pot -pot: PHONY $(addprefix pot-, $(filter-out doc,$(packages))) -check: - @cd test && ./testenv $(TESTENVFLAGS) roundup +verbs=build install uninstall mostlyclean clean distclean maintainer-clean check +$(foreach verb,$(verbs),$(foreach package,$(packages),$(eval $(verb)-$(package): $(addsuffix /$(verb),$($(package)))))) +$(foreach verb,$(verbs),$(foreach package,$(packages),$(eval .PHONY: $(verb)-$(package)))) -%/build: PHONY % - $(MAKE) -C $* -%/install: PHONY % - $(MAKE) -C $* install -%/clean: PHONY % - $(MAKE) -C $* clean -%/pot: PHONY % - $(MAKE) -C $* pot -%/everything.pot: FORCE % - $(MAKE) -C $* everything.pot +$(outdir)/check:: + cd $(@D)/test && ./testenv $(TESTENVFLAGS) roundup -.SECONDEXPANSION: -$(addprefix copy-, $(packages)): copy-%: PHONY $$(addsuffix /copy, $$($$*)) -$(addprefix build-, $(packages)): build-%: PHONY $$(addsuffix /build, $$($$*)) -$(addprefix install-,$(packages)): install-%: PHONY $$(addsuffix /install,$$($$*)) -$(addprefix clean-, $(packages)): clean-%: PHONY $$(addsuffix /clean, $$($$*)) -$(addprefix pot-, $(packages)): pot-%: PHONY po/%.pot -$(addprefix pot-, $(packages)): pot-%: PHONY po/%.pot -$(foreach p,$(packages),po/$p.pot): po/%.pot: $$(addsuffix /everything.pot,$$($$*)) +_po_rule = \ +po/%(package).pot: $(addsuffix /everything.pot,$(%(package))); \ cat $^ | msguniq -Fi --to-code=UTF-8 > '$@' || rm -f '$@' +$(foreach package,$(packages),$(eval $(subst %(package),$(package),$(value _po_rule)))) -################################################################################ +pots = +am_out_files += $(foreach package,$(packages),po/$(package).pot) +am_clean_files += .var.* +am_gen_files += .srcversion-libretools.mk .srcversion-devtools.mk +am_subdirs = src -FORCE: PHONY -PHONY: -.PHONY: PHONY +include $(topsrcdir)/automake.tail.mk diff --git a/automake.head.mk b/automake.head.mk new file mode 100644 index 0000000..a3c90fd --- /dev/null +++ b/automake.head.mk @@ -0,0 +1,58 @@ +# Copyright (C) 2015-2016 Luke Shumaker +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +_am = am_ + +_am_noslash = $(patsubst %/.,%,$(patsubst %/,%,$1)) +# These are all $(call _am_func,parent,child) +#_am_relto = $(if $2,$(shell realpath -s --relative-to='$1' $2)) +_am_is_subdir = $(filter $(abspath $1)/%,$(abspath $2)/.) +_am_relto_helper = $(if $(call _am_is_subdir,$1,$2),$(patsubst $1/%,%,$(addsuffix /.,$2)),$(addprefix ../,$(call _am_relto_helper,$(patsubst %/,%,$(dir $1)),$2))) +_am_relto = $(call _am_noslash,$(call _am_relto_helper,$(call _am_noslash,$(abspath $1)),$(call _am_noslash,$(abspath $2)))) +# Note that _am_is_subdir says that a directory is a subdirectory of +# itself. +_am_path = $(call _am_relto,.,$1) + +## Declare the default target +all: build +.PHONY: all + +## Set topoutdir, outdir, and srcdir (assumes that topsrcdir is +## already set, and that $(topoutdir)/config.mk has been included) +ifeq ($(topoutdir),) +topoutdir := $(call _am_path,$(dir $(lastword $(filter %/config.mk config.mk,$(MAKEFILE_LIST))))) +endif + outdir := $(call _am_path,$(dir $(lastword $(filter-out %.mk,$(MAKEFILE_LIST))))) + srcdir := $(call _am_path,$(topsrcdir)/$(call _am_relto,$(topoutdir),$(outdir))) + +_am_included_makefiles := $(_am_included_makefiles) $(call _am_path,$(outdir)/Makefile) + +## Empty variables for use by the module +$(_am)subdirs = +$(_am)depdirs = + +$(_am)src_files = +$(_am)gen_files = +$(_am)cfg_files = +$(_am)out_files = +$(_am)sys_files = + +$(_am)clean_files = +$(_am)slow_files = + +ifeq ($(_am_NO_ONCE),) +include $(topsrcdir)/common.once.head.mk +endif +include $(topsrcdir)/common.each.head.mk diff --git a/automake.tail.mk b/automake.tail.mk new file mode 100644 index 0000000..5d6ad00 --- /dev/null +++ b/automake.tail.mk @@ -0,0 +1,140 @@ +# Copyright (C) 2015-2016 Luke Shumaker +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +include $(topsrcdir)/common.each.tail.mk + + +# Aggregate variables + +# Add some more defaults to the *_files variables +$(_am)clean_files += $($(_am)gen_files) $($(_am)out_files) +$(_am)cfg_files += Makefile + +# Now namespace the *_files variables +define _am_save_variables +_am_src_files/$(outdir) = $(addprefix $(srcdir)/,$($(_am)src_files)) +_am_gen_files/$(outdir) = $(addprefix $(srcdir)/,$($(_am)gen_files)) +_am_cfg_files/$(outdir) = $(addprefix $(outdir)/,$($(_am)cfg_files)) +_am_out_files/$(outdir) = $(addprefix $(outdir)/,$($(_am)out_files)) +_am_sys_files/$(outdir) = $(addprefix $(DESTDIR),$($(_am)sys_files)) +_am_clean_files/$(outdir) = $(addprefix $(outdir)/,$($(_am)clean_files)) +_am_slow_files/$(outdir) = $(addprefix $(outdir)/,$($(_am)slow_files)) +_am_subdirs/$(outdir) = $($(_am)subdirs) +endef +$(eval $(_am_save_variables)) + +# And add them to the $(parent)_*_files variables (if applicable) +define _am_add_subdir +_am_src_files/%(outdir) += $(_am_src_files/%(subdir)) +_am_gen_files/%(outdir) += $(_am_gen_files/%(subdir)) +_am_cfg_files/%(outdir) += $(_am_cfg_files/%(subdir)) +_am_out_files/%(outdir) += $(_am_out_files/%(subdir)) +_am_sys_files/%(outdir) += $(_am_sys_files/%(subdir)) +_am_clean_files/%(outdir) += $(_am_clean_files/%(subdir)) +_am_slow_files/%(outdir) += $(_am_slow_files/%(subdir)) +endef +$(foreach subdir,$(call _am_path,$(addprefix $(outdir)/,$($(_am)subdirs))),$(eval $(subst %(outdir),$(outdir),$(subst %(subdir),$(subdir),$(value _am_add_subdir))))) + +_am_outdirs := $(_am_outdirs) $(outdir) + + +# Do some per-directory magic + +_am_phony = build install uninstall mostlyclean clean distclean maintainer-clean check + +.PHONY: $(addprefix $(outdir)/,$(_am_phony)) + +$(addprefix $(outdir)/,uninstall mostlyclean clean distclean maintainer-clean):: + $(RM) -- $(sort $(_am_$(@F)/$(@D))) + $(RMDIRS) $(sort $(dir $(_am_$(@F)/$(@D)))) 2>/dev/null || $(TRUE) + +# 'build' and 'install' must be defined later, because the +# am_*_files/* variables might not be complete yet. + + +# Include Makefiles from other directories + +define _am_nl + + +endef + +$(foreach _am_NO_ONCE,y,\ + $(foreach makefile,$(foreach dir,$($(_am)subdirs) $($(_am)depdirs),$(call _am_path,$(outdir)/$(dir)/Makefile)),\ + $(eval include $(filter-out $(_am_included_makefiles),$(makefile))))) + + +# This only gets evaluated once, after all of the other Makefiles are read +ifeq ($(_am_NO_ONCE),) +# Empty directory-level variables +outdir = /bogus +srcdir = /bogus + +$(_am)subdirs = +$(_am)depdirs = + +$(_am)src_files = +$(_am)gen_files = +$(_am)cfg_files = +$(_am)out_files = +$(_am)sys_files = +$(_am)clean_files = +$(_am)slow_files = + +_am_clean_files/$(topoutdir) += $(topoutdir)/$(PACKAGE)-$(VERSION).tar.gz +$(addprefix $(topoutdir)/,mostlyclean clean distclean maintainer-clean) :: + $(RM) -r -- $(topoutdir)/$(PACKAGE)-$(VERSION) + +define _am_directory_rules +# Constructive phony targets +$(outdir)/build : $(_am_out_files/%(outdir)) +$(outdir)/install: $(_am_sys_files/%(outdir)) +# Destructive phony targets +_am_uninstall/%(outdir) = $(_am_sys_files/%(outdir)) +_am_mostlyclean/%(outdir) = $(filter-out $(_am_slow_files/%(outdir)) $(_am_cfg_files/%(outdir)) $(_am_gen_files/%(outdir)),$(_am_clean_files/%(outdir))) +_am_clean/%(outdir) = $(filter-out $(_am_cfg_files/%(outdir)) $(_am_gen_files/%(outdir)),$(_am_clean_files/%(outdir))) +_am_distclean/%(outdir) = $(filter-out $(_am_gen_files/%(outdir)),$(_am_clean_files/%(outdir))) +_am_maintainer-clean/%(outdir) = $(_am_clean_files/%(outdir)) +endef +$(foreach outdir,$(_am_outdirs),$(eval $(subst %(outdir),$(outdir),$(value _am_directory_rules)))) + +# Add the `dist` target +.PHONY: dist +dist: $(topoutdir)/$(PACKAGE)-$(VERSION).tar.gz +$(topoutdir)/$(PACKAGE)-$(VERSION).tar.gz: $(topoutdir)/$(PACKAGE)-$(VERSION) + $(TAR) czf $@ -C $(<D) $(<F) +_am_copyfile = $(MKDIRS) $(dir $2) && $(CP) -T $1 $2 +_am_addfile = $(call _am_copyfile,$3,$2/$(call _am_relto,$1,$3)) +$(topoutdir)/$(PACKAGE)-$(VERSION): $(_am_src_files/$(topoutdir)) $(_am_gen_files/$(topoutdir)) + $(RM) -r $@ + @PS4='' && set -x && \ + $(MKDIR) $(@D)/tmp.$(@F).$$$$ && \ + $(foreach f,$^,$(call _am_addfile,$(topsrcdir),$(@D)/tmp.$(@F).$$$$,$f) &&) \ + $(MV) $(@D)/tmp.$(@F).$$$$ $@ || $(RM) -r $(@D)/tmp.$(@F).$$$$ + +include $(topsrcdir)/common.once.tail.mk + +# For some reason I can't explain, RM doesn't really get set with ?= +CP ?= cp +MKDIR ?= mkdir +MKDIRS ?= mkdir -p +MV ?= mv +RM = rm -f +RMDIRS ?= rmdir -p +TAR ?= tar +TRUE ?= true + +.PHONY: noop +endif diff --git a/automake.txt b/automake.txt new file mode 100644 index 0000000..307b321 --- /dev/null +++ b/automake.txt @@ -0,0 +1,88 @@ +Luke's AutoMake +=============== + +Yo, this document is incomplete. It describes the magical +automake.{head,tail}.mk Makefiles and how to use them, kinda. + +I wrote a "clone" of automake. I say clone, because it works +differently. Yeah, I need a new name for it. + +Anyway, how to use it: + +In each source directory, you write a `Makefile`, very similarly to if +you were writing for plain GNU Make, with + +_am_phony = build install uninstall mostlyclean clean distclean maintainer-clean check + + + include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk + include $(topsrcdir)/automake.head.mk + + # your makefile + + include $(topsrcdir)/automake.tail.mk + +Write your own `common.each.mk` that gets included after the body of +your Makefile for each Makefile. + +Write your own `common.once.mk` that gets included once after +everything else has been parsed. + +There are several commands that generate files; simply record what +they the list of files in their output to the following variables: + +| Variable | Command | Description | Relative to | +|-----------+--------------+-----------------------------------+-------------| +| src_files | emacs | Files that the developer writes | srcdir | +| gen_files | ??? | Files the developer compiles | srcdir | +| cfg_files | ./configure | Users' compile-time configuration | outdir | +| out_files | make all | Files the user compiles | outdir | +| sys_files | make install | Files the user installs | DESTDIR | + +In addition, there are + + subdirs : A list of other directories containing Makefiles that + contain or generate files that are dependencies of + targets in this directory. They are not necesarily + actually subdirectories of this directory in the + filesystem. + + clean_files : A list of things to `rm` in addition to + `$(out_files)` when you run `make clean`. (Example: + `*.o`). + + slow_files : A list of things in `$(out_files)` that (as an + exception) should _not_ be deleted when you run `make + mostlyclean`. + +Each directory containing a Makefile is a "module". The module name +is one of 4 things (with / replaced with _ in all cases): + - `all` + - $(realpath --relative-to=. $dir_name) + - dep-top + - dep-$(realpath --relative-to=$(topoutdir) $dir_name) + +The dep-* options are only used if that directory is not a child of +the current directory. + +Here is a table of all of the .PHONY targets that automake takes care +of for you: + +| this | and this | are aliases for this | which is just a case of this | +|------+------------------+----------------------+------------------------------| +| all | build | build-all | build-$(module) | +| | install | install-all | install-$(module) | +| | uninstall | uninstall-all | uninstall-$(module) | +| | mostlyclean | mostlyclean-all | mostlyclean-$(module) | +| | clean | clean-all | clean-$(module) | +| | distclean | distclean-all | distclean-$(module) | +| | maintainer-clean | maintainer-clean-all | maintainer-clean-$(module) | +| | check | check-all | check-$(module) | +| | | | dist | + +---- +Copyright (C) 2016 Luke Shumaker + +This documentation file is placed into the public domain. If that is +not possible in your legal system, I grant you permission to use it in +absolutely every way that I can legally do so. diff --git a/common.each.head.mk b/common.each.head.mk new file mode 100644 index 0000000..8a2a68d --- /dev/null +++ b/common.each.head.mk @@ -0,0 +1,32 @@ +pkgconfdir = $(sysconfdir)/libretools.d +pkgdocdir = $(docdir)/libretools +pkglibexecdir = $(libexecdir)/libretools + +# Detect things about the directory we're in #################################### + +ifeq ($(wildcard $(topsrcdir)/.git),) +include $(srcdir)/.srcfiles.mk +else +$(srcdir)/.srcfiles.mk: FORCE + @echo am_src_files = $(filter-out $(addsuffix /%,$(_am_subdirs/$(@D))),$(shell cd $(@D) && git ls-files)) | $(write-ifchanged) $@ +-include $(srcdir)/.srcfiles.mk +endif + +detect-ignore = +detect-ignore-exec = +detect-ignore-conf = +detect-ignore-ronn = +detect-ignore-md = HACKING.md +detect-ignore-sh = + +devtools-files = + +install-mans = $(patsubst %.ronn,%,$(detect-ronn)) +install-bins = $(detect-exec) +install-libexecs = +install-libs = $(detect-sh) +install-docs = $(detect-md) $(detect-ronn) +install-confs = $(detect-conf) + +install-files = $(install-mans) $(install-bins) $(install-libexecs) $(install-libs) $(install-docs) $(install-confs) +pots = $(install-bins) $(install-libexecs) $(install-libs) diff --git a/common.each.tail.mk b/common.each.tail.mk new file mode 100644 index 0000000..3192ddb --- /dev/null +++ b/common.each.tail.mk @@ -0,0 +1,82 @@ +# Copyright (C) 2015 Luke Shumaker +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +am_gen_files += .srcfiles.mk $(devtools-files) +am_out_files += $(filter-out $(am_src_files) $(am_gen_files),$(install-files)) \ + $(if $(pots),everything.pot) +am_sys_files += $(addprefix $(bindir)/,$(install-bins)) \ + $(addprefix $(pkgconfdir)/,$(install-confs)) \ + $(addprefix $(pkglibexecdir)/,$(install-libexecs) $(install-libs)) \ + $(addprefix $(pkgdocdir)/,$(install-docs)) \ + $(addprefix $(mandir)/man1/,$(filter %.1,$(install-mans))) \ + $(addprefix $(mandir)/man2/,$(filter %.2,$(install-mans))) \ + $(addprefix $(mandir)/man3/,$(filter %.3,$(install-mans))) \ + $(addprefix $(mandir)/man4/,$(filter %.4,$(install-mans))) \ + $(addprefix $(mandir)/man5/,$(filter %.5,$(install-mans))) \ + $(addprefix $(mandir)/man6/,$(filter %.6,$(install-mans))) \ + $(addprefix $(mandir)/man7/,$(filter %.7,$(install-mans))) \ + $(addprefix $(mandir)/man8/,$(filter %.8,$(install-mans))) +am_clean_files += *.pot *.ugly .tmp* + +exec_$(outdir) := $(exec_$(outdir)) $(install-bins) $(install-libexecs) + +_is_executable = $(filter $(exec_$(@D)),$(@F)) + +$(srcdir)/%.in: $(devtoolsdir)/%.in + cp -T '$<' '$@' +$(srcdir)/%.in: $(devtoolsdir)/lib/% + cp -T '$<' '$@' +$(outdir)/%: $(srcdir)/%.in + @echo 'EDIT < $< > $@'; $(edit) < '$<' | install -T -m$(if $(_is_executable),755,644) /dev/stdin '$@' +$(outdir)/%: $(srcdir)/%.ronn + ronn --roff $(RONNFLAGS) < '$<' > '$@' +$(outdir)/%.html: $(srcdir)/%.ronn + ronn --html $(RONNFLAGS) < '$<' > '$@' +$(outdir)/%.pot: $(outdir)/% $(topsrcdir)/src/lib/librexgettext + $(topsrcdir)/src/lib/librexgettext $(LIBREXGETTEXT_FLAGS) '$<' > '$@' +$(outdir)/%.pot: $(srcdir)/% $(topsrcdir)/src/lib/librexgettext + $(topsrcdir)/src/lib/librexgettext $(LIBREXGETTEXT_FLAGS) '$<' > '$@' +$(outdir)/everything.pot: $(addprefix $(outdir)/,$(addsuffix .pot,$(pots))) + cat $^ | $(pofmt) > '$@' + +# If we have a .patch file, the flow is: +# $(devtoolsdir)/%.in -> %.in + %.patch -> %.ugly -> % +_do_patch = $(filter $(patsubst %.patch,%,$(filter %.patch,$(detect-all))),$(patsubst %.in,%,$(devtools-files))) +$(outdir)/%.ugly: $(srcdir)/%.in $(srcdir)/%.patch + cp -T $< $@ + patch $@ $(<D)/$*.patch +$(sort $(addprefix $(outdir)/,$(_do_patch))): $(outdir)/%: $(outdir)/%.ugly + @echo 'EDIT < $< > $@'; $(edit) < '$<' | install -T -m$(if $(_is_executable),755,644) /dev/stdin '$@' + @echo 'INDENT $@'; $(call indent,$@) + +$(DESTDIR)$(pkgconfdir)/% : $(outdir)/% ; install -T -Dm644 '$<' '$@' +$(DESTDIR)$(pkgdocdir)/% : $(outdir)/% ; install -T -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man1/%.1: $(outdir)/%.1; install -T -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man2/%.2: $(outdir)/%.2; install -T -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man3/%.3: $(outdir)/%.3; install -T -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man4/%.4: $(outdir)/%.4; install -T -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man5/%.5: $(outdir)/%.5; install -T -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man6/%.6: $(outdir)/%.6; install -T -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man7/%.7: $(outdir)/%.7; install -T -Dm644 '$<' '$@' +$(DESTDIR)$(mandir)/man8/%.8: $(outdir)/%.8; install -T -Dm644 '$<' '$@' +$(DESTDIR)$(pkglibexecdir)/%: $(outdir)/% ; mkdir -p '$(@D)' && cp -T '$<' '$@' +$(DESTDIR)$(bindir)/% : $(outdir)/% ; install -T -Dm755 '$<' '$@' +# Repeat the last two rules again with explicit targets because +# otherwise it would try to do src/xbs->/bin/xbs instead of +# src/xbs/xbs->/bin/xbs +ifneq ($(filter $(notdir $(outdir)),$(install-files)),) +$(DESTDIR)$(pkglibexecdir)/$(notdir $(outdir)): $(DESTDIR)$(pkglibexecdir)/%: $(outdir)/% ; mkdir -p '$(@D)' && cp -T '$<' '$@' +$(DESTDIR)$(bindir)/$(notdir $(outdir)): $(DESTDIR)$(bindir)/% : $(outdir)/% ; install -T -Dm755 '$<' '$@' +endif diff --git a/common.mk b/common.mk deleted file mode 100644 index 66d6c24..0000000 --- a/common.mk +++ /dev/null @@ -1,164 +0,0 @@ -topdir := $(dir $(lastword $(MAKEFILE_LIST))) -include $(topdir)/config.mk -pkgconfdir ?= $(sysconfdir)/libretools.d -pkgdocdir ?= $(docdir)/libretools -pkglibexecdir ?= $(libexecdir)/libretools - -# Misc variables for use in recipes ############################################ - -# Usage: <INPUT $(edit) >OUTPUT -# Expand m4_include macros to use librelib -# This is used when using sources grabbed from devtools -edit = sed \ - -e 's|^\#!\s*/bin/bash|\#!/usr/bin/env bash|' \ - -e 's|m4_include(lib/\(.*\))|. "$$(librelib \1)"|' \ - -e 's|@sysconfdir@|$(sysconfdir)|g' \ - -e 's|@pkgconfdir@|$(pkgconfdir)|g' \ - -e 's|@bindir@|$(bindir)|g' - -# Usage: $(call indent,FILENAME) -# Command to auto-indent a file. -indent = emacs --batch $1 \ - --eval '(setq make-backup-files nil)' \ - --eval '(setq sh-basic-offset 8)' \ - --eval '(indent-region (point-min) (point-max) nil)' \ - -f save-buffer &>/dev/null - -# Usage <INPUT $(pofmt) >OUTPUT -# Normalize a .po(t) file -pofmt = msguniq -Fi --to-code=UTF-8 - -# Detect things about the director we're in #################################### - -progs += $(filter-out $(no-progs),$(shell find . -maxdepth 1 -type f -executable -printf '%f\n')) -confs += $(filter-out $(no-conf) ,$(wildcard *.conf)) -mans += $(filter-out $(no-mans) ,$(patsubst %.ronn,%,$(wildcard *.ronn))) -docs += $(filter-out $(no-docs) HACKING.md,$(wildcard *.md) $(wildcard *.ronn)) -libexecs += -libs += - -copy_files += -build_files += $(progs) $(confs) $(mans) $(libexecs) $(libs) $(patsubst %.in,%,$(copy_files)) -install_files += $(addprefix $(DESTDIR)$(bindir)/,$(progs)) \ - $(addprefix $(DESTDIR)$(pkgconfdir)/,$(confs)) \ - $(addprefix $(DESTDIR)$(pkglibexecdir)/,$(libexecs) $(libs)) \ - $(addprefix $(DESTDIR)$(docdir)/libretools/,$(docs)) \ - $(addprefix $(DESTDIR)$(mandir)/man1/,$(filter %.1,$(mans))) \ - $(addprefix $(DESTDIR)$(mandir)/man2/,$(filter %.2,$(mans))) \ - $(addprefix $(DESTDIR)$(mandir)/man3/,$(filter %.3,$(mans))) \ - $(addprefix $(DESTDIR)$(mandir)/man4/,$(filter %.4,$(mans))) \ - $(addprefix $(DESTDIR)$(mandir)/man5/,$(filter %.5,$(mans))) \ - $(addprefix $(DESTDIR)$(mandir)/man6/,$(filter %.6,$(mans))) \ - $(addprefix $(DESTDIR)$(mandir)/man7/,$(filter %.7,$(mans))) \ - $(addprefix $(DESTDIR)$(mandir)/man8/,$(filter %.8,$(mans))) -clean_files += $(patsubst %.in,%,$(copy_files) $(wildcard *.in)) $(copy_files) $(mans) $(wildcard *.pot *.ugly*) - -pots += $(filter-out $(no-pots) ,$(sort $(progs) $(libexecs) $(libs))) -pot_files += $(addsuffix .pot,$(pots)) - -# Set the default target ####################################################### - -all: PHONY build - -# Copy (files from devtools) ################################################### - -copy: PHONY $(copy_files) - -%.in: $(devtoolsdir)/%.in - cp $< $@ -%.in: $(devtoolsdir)/lib/% - cp $< $@ - -# Build ######################################################################## - -build: PHONY $(build_files) - -%: %.ronn - ronn --roff $(RONNFLAGS) < '$<' > '$@' -%.html: %.ronn - ronn --html $(RONNFLAGS) < '$<' > '$@' - - -# If we have a .patch file, the flow is: -# $(devtoolsdir)/%.in -> %.in + %.patch -> %.ugly -> % -_do_patch = $(filter $(patsubst %.patch,%,$(wildcard *.patch)),$(patsubst %.in,%,$(copy_files))) -%.ugly: %.in %.patch Makefile - cp $*.in $@ - @echo 'PATCH $@ $*.patch'; patch $@ $*.patch -$(sort $(_do_patch)): %: %.ugly Makefile - @echo 'EDIT < $< > $@'; $(edit) <'$<' >'$@' - @echo 'INDENT $@'; $(call indent,$@) - $(if $(filter-out %.sh,$@),chmod 755 "$@") -# Otherwise, the flow is just -# $(devtoolsdir)/%.in -> %.in -> % -%: %.in - @echo 'EDIT < $< > $@'; $(edit) <"$<" >"$@" - $(if $(filter $@,$(progs) $(libexecs)),chmod 755 "$@") -# work-around for what I currently believe to be a regression in Make -%.sh: %.sh.in - @echo 'EDIT < $< > $@'; $(edit) <"$<" >"$@" - -# Build ######################################################################## - -pot: everything.pot - -everything.pot: $(pot_files) - cat $^ | $(pofmt) > '$@' - -%.pot: % $(topdir)/src/lib/librexgettext - $(topdir)/src/lib/librexgettext $(LIBREXGETTEXT_FLAGS) $< > '$@' - -# Install ###################################################################### - -install: PHONY $(install_files) - -# We sort the explicit targets because sort also removes duplicates; in a few -# cases, a target could be listed twice, which is a warning. - -# bindir: $(progs) vs $(libexecs) -$(sort $(addprefix $(DESTDIR)$(bindir)/,$(filter-out $(libexecs),$(progs)))): $(DESTDIR)$(bindir)/%: % - install -Dm755 '$<' '$@' -$(sort $(addprefix $(DESTDIR)$(bindir)/,$(libexecs))): $(DESTDIR)$(bindir)/%: % - install -d '$(@D)' - ln -srf '$(pkglibexecdir)/$(@F)' '$@' -# pkglibexecdir: $(libexecs) vs $(libs) -$(sort $(addprefix $(DESTDIR)$(pkglibexecdir)/,$(libexecs))): $(DESTDIR)$(pkglibexecdir)/%: % - install -Dm755 '$<' '$@' -$(sort $(addprefix $(DESTDIR)$(pkglibexecdir)/,$(libs))): $(DESTDIR)$(pkglibexecdir)/%: % - install -Dm644 '$<' '$@' -# everything else -$(DESTDIR)$(pkgconfdir)/%: % - install -Dm644 '$<' '$@' -$(DESTDIR)$(pkgdocdir)/%: % - install -Dm644 '$<' '$@' -$(DESTDIR)$(mandir)/man1/%.1: %.1 - install -Dm644 '$<' '$@' -$(DESTDIR)$(mandir)/man2/%.2: %.2 - install -Dm644 '$<' '$@' -$(DESTDIR)$(mandir)/man3/%.3: %.3 - install -Dm644 '$<' '$@' -$(DESTDIR)$(mandir)/man4/%.4: %.4 - install -Dm644 '$<' '$@' -$(DESTDIR)$(mandir)/man5/%.5: %.5 - install -Dm644 '$<' '$@' -$(DESTDIR)$(mandir)/man6/%.6: %.6 - install -Dm644 '$<' '$@' -$(DESTDIR)$(mandir)/man7/%.7: %.7 - install -Dm644 '$<' '$@' -$(DESTDIR)$(mandir)/man8/%.8: %.8 - install -Dm644 '$<' '$@' - -# Clean ######################################################################## - -clean: PHONY clean-hook - rm -f -- $(clean_files) - -clean-hook: PHONY - -# Boiler-plate ################################################################# - -FORCE: PHONY -PHONY: -.PHONY: FORCE PHONY - -.DELETE_ON_ERROR: diff --git a/common.once.head.mk b/common.once.head.mk new file mode 100644 index 0000000..f27fe07 --- /dev/null +++ b/common.once.head.mk @@ -0,0 +1,81 @@ +# Copyright (C) 2015 Luke Shumaker +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Configure how Make works +MAKEFLAGS += --no-builtin-rules --no-builtin-variables +.SECONDARY: +.DELETE_ON_ERROR: + +.PHONY: FORCE + +write-ifchanged = $(topsrcdir)/write-ifchanged + +# Magic for tracking variables that affect files. If a file changes +# based on a variable, just stick $(var)VARNAME as a dependency. +var = $(call _am_path,$(topoutdir)/.var.) +$(var)%: FORCE + @printf '%s' '$($*)' | $(write-ifchanged) $@ + +# Usage: <INPUT $(edit) >OUTPUT +# Expand m4_include macros to use librelib +# This is used when using sources grabbed from devtools +# Magic for doing @variable@ replacement in files +edit = sed \ + -e 's|^\#!\s*/bin/bash|\#!/usr/bin/env bash|' \ + -e 's|m4_include(lib/\(.*\))|. "$$(librelib \1)"|' \ + $(foreach v,$(patsubst $(var)%,%,$(filter $(var)%,$^)), -e 's|@$(v)@|$($(v))|g' ) + +# Usage: $(call indent,FILENAME) +# Command to auto-indent a file. +indent = emacs --batch $1 \ + --eval '(setq make-backup-files nil)' \ + --eval '(setq sh-basic-offset 8)' \ + --eval '(indent-region (point-min) (point-max) nil)' \ + -f save-buffer &>/dev/null + +# Usage <INPUT $(pofmt) >OUTPUT +# Normalize a .po(t) file +pofmt = msguniq -Fi --to-code=UTF-8 + +# It's easy to think of these as "each" variables, but because they +# will be evaluated on demand, only am_src_files needs to be "each". +detect-all = $(filter-out $(detect-ignore) ,$(am_src_files)) +detect-exec = $(filter-out $(detect-ignore-exec),$(patsubst $(srcdir)/%,%,$(shell find $(addprefix $(srcdir)/,$(detect-all)) -executable))) +detect-conf = $(filter-out $(detect-ignore-conf),$(filter %.conf ,$(detect-all))) +detect-ronn = $(filter-out $(detect-ignore-ronn),$(filter %.ronn ,$(detect-all))) +detect-md = $(filter-out $(detect-ignore-md) ,$(filter %.ronn %.md,$(detect-all))) +detect-sh = $(filter-out $(detect-ignore-sh) ,$(filter %.sh ,$(detect-all))) + +ifeq ($(wildcard $(topsrcdir)/.git),) +include $(topsrcdir)/.srcversion-libretools.mk +else +$(topsrcdir)/.srcversion-libretools.mk: FORCE + @{ \ + echo LIBRETOOLS_VERSION = $(patsubst v%,%,$(shell cd $(topsrcdir) && git describe --tags)); \ + echo LIBRETOOLS_COMMIT = $(shell cd $(topsrcdir) && git rev-parse HEAD); \ + :; } | $(write-ifchanged) $@ +-include $(topsrcdir)/.srcversion-libretools.mk +endif + +ifeq ($(wildcard $(devtoolsdir)/.git),) +include $(topsrcdir)/.srcversion-devtools.mk +else +$(topsrcdir)/.srcversion-devtools.mk: FORCE + @{ \ + echo DEVTOOLS_VERSION = $(patsubst libretools-%,%,$(shell cd $(devtoolsdir) && git describe --tags)); \ + echo DEVTOOLS_COMMIT = $(shell cd $(devtoolsdir) && git rev-parse HEAD); \ + :; } | $(write-ifchanged) $@ +-include $(topsrcdir)/.srcversion-devtools.mk +endif diff --git a/common.once.tail.mk b/common.once.tail.mk new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/common.once.tail.mk @@ -1,8 +1,13 @@ -# Configuration -# Note: $(topdir) is set to the directory containing this file. +# Note: In the default version of this file, commented out values +# indicate what the GNU standards dictate, when our values +# differ. We're not a GNU package. -# Note: In the default version of this file, commented out values indicate what -# the GNU standards dictate, when our values differ. +ifeq ($(topsrcdir),) +topsrcdir := $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST)))) +endif + +PACKAGE = libretools +VERSION = $(LIBRETOOLS_VERSION) DESTDIR = @@ -21,5 +26,5 @@ sysconfdir = /etc docdir = $(datarootdir)/doc mandir = $(datarootdir)/man -devtoolsdir = $(topdir)/../devtools-par +devtoolsdir = $(call abspath,$(topsrcdir)/../devtools-par) RONNFLAGS = --manual='libretools Manual' --organization='Parabola' diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 23f8a8f..0000000 --- a/doc/Makefile +++ /dev/null @@ -1 +0,0 @@ -include ../common.mk diff --git a/src/Makefile b/src/Makefile index 63f7782..8fbe735 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,2 +1,7 @@ -pkgconfdir=$(sysconfdir) -include ../common.mk +include $(dir $(lastword $(MAKEFILE_LIST)))/../config.mk +include $(topsrcdir)/automake.head.mk +pkgconfdir = $(sysconfdir) + +am_subdirs = abslibre-tools chroot-tools devtools gitget lib librefetch toru xbs xbs-abs xbs-abslibre + +include $(topsrcdir)/automake.tail.mk diff --git a/src/abslibre-tools/Makefile b/src/abslibre-tools/Makefile index 2c76089..2903f4a 100644 --- a/src/abslibre-tools/Makefile +++ b/src/abslibre-tools/Makefile @@ -1 +1,4 @@ -include ../../common.mk +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk + +include $(topsrcdir)/automake.tail.mk diff --git a/doc/createworkdir.md b/src/abslibre-tools/createworkdir.md index e50b00f..e50b00f 100644 --- a/doc/createworkdir.md +++ b/src/abslibre-tools/createworkdir.md diff --git a/src/chroot-tools/Makefile b/src/chroot-tools/Makefile index 1b77a97..a11e69c 100644 --- a/src/chroot-tools/Makefile +++ b/src/chroot-tools/Makefile @@ -1,28 +1,27 @@ -progs = chcleanup -clean_files = chcleanup.lib -# These files are coming from devtools -copy_files = makechrootpkg.sh.in mkarchroot.in arch-nspawn.in -# These are programs that we will use internally, but shouldn't be in PATH -libexecs = mkarchroot arch-nspawn distcc-tool chcleanup indent -no-progs = $(libexecs) -# These are the shell libraries we will use -libs = makechrootpkg.sh $(wildcard hooks-*.sh) - +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk pkglibexecdir = $(libexecdir)/libretools/chroot -include ../../common.mk -# makechrootpkg.sh is created from a command, not a library -makechrootpkg.sh.in: %.sh.in: $(devtoolsdir)/%.in +install-bins = chcleanup librechroot libremakepkg +install-libexecs += arch-nspawn chcleanup distcc-tool indent mkarchroot +install-libs += makechrootpkg.sh +devtools-files = makechrootpkg.sh.in mkarchroot.in arch-nspawn.in +am_clean_files += chcleanup.lib + +$(srcdir)/makechrootpkg.sh.in: $(srcdir)/%.sh.in: $(devtoolsdir)/%.in cp $< $@ -chcleanup: chcleanup.in chcleanup.lib - m4 -P $< | $(edit) > $@ - chmod 755 $@ -chcleanup.lib: ../lib/common.sh Makefile - bash -c '. ../lib/common.sh; declare -f _l plain msg msg2 error' > $@ +$(outdir)/chcleanup: $(srcdir)/chcleanup.in $(outdir)/chcleanup.lib + m4 -I$(@D) -P $< | $(edit) | install -m755 /dev/stdin $@ +$(outdir)/chcleanup.lib: $(call _am_path,$(topoutdir)/src/lib/common.sh) $(outdir)/Makefile + bash -c '. $<; declare -f _l plain msg msg2 error' > $@ + +$(outdir)/distcc-tool.pot: LIBREXGETTEXT_FLAGS+=--simple=errusage + +$(DESTDIR)$(bindir)/chcleanup: $(var)bindir $(var)libexecdir + mkdir -p $(@D) + ln -srfT $(DESTDIR)$(libexecdir)/libretools/chroot/chcleanup $@ -distcc-tool.pot: LIBREXGETTEXT_FLAGS+=--simple=errusage +am_depdirs = ../lib -# This is so gross. I hate recursive Make. Why did I implement it this way? -../lib/common.sh: $(devtoolsdir)/lib/common.sh ../lib/common.sh.top ../lib/Makefile - $(MAKE) -C ../lib common.sh +include $(topsrcdir)/automake.tail.mk diff --git a/src/devtools/Makefile b/src/devtools/Makefile index 3fc5d70..7ccbbcc 100644 --- a/src/devtools/Makefile +++ b/src/devtools/Makefile @@ -1,8 +1,12 @@ -progs = checkpkg find-libdeps finddeps lddd -copy_files = $(addsuffix .in,$(progs)) -install_files = $(DESTDIR)$(bindir)/find-libprovides -include ../../common.mk +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk + +install-bins += checkpkg find-libdeps finddeps lddd +devtools-files = $(addsuffix .in,$(install-bins)) +am_sys_files += $(bindir)/find-libprovides $(DESTDIR)$(bindir)/find-libprovides: install -d $(@D) ln -sf find-libdeps $@ + +include $(topsrcdir)/automake.tail.mk diff --git a/src/gitget/Makefile b/src/gitget/Makefile index 2c76089..2903f4a 100644 --- a/src/gitget/Makefile +++ b/src/gitget/Makefile @@ -1 +1,4 @@ -include ../../common.mk +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk + +include $(topsrcdir)/automake.tail.mk diff --git a/src/lib/Makefile b/src/lib/Makefile index 97b30eb..f9ec1e8 100644 --- a/src/lib/Makefile +++ b/src/lib/Makefile @@ -1,17 +1,17 @@ -copy_files = common.sh.in -libexecs = $(filter-out librelib,$(progs)) -# include common.sh in libs explicitly, because it might not exist yet -# when the wildcard is performed -libs = $(sort $(wildcard *.sh) common.sh conf.sh) +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk -include ../../common.mk +install-libs += common.sh conf.sh +devtools-files = common.sh.in # Build ############################################################## -common.sh: %: %.in %.top Makefile - @echo "GEN $@" +$(outdir)/conf.sh: $(var)sysconfdir $(var)pkgconfdir + +$(outdir)/common.sh: $(outdir)/%: $(srcdir)/%.in $(srcdir)/%.head $(srcdir)/%.tail $(outdir)/Makefile + @echo "OUT $@" @{ \ - cat '$*.top' && \ + cat '$(<D)/$*.head' && \ echo && \ sed -r \ -e '/encoding problem/d;/LANG=/d' \ @@ -19,21 +19,27 @@ common.sh: %: %.in %.top Makefile -e 's/gettext /_l _ /g' \ -e "s/^(\s+)(msg|error) '/\1_l \2 '/" \ -e 's|lock\(\)\s*\{|lock()\n{|' \ - '$*.in' && \ + '$(<D)/$*.in' && \ echo && \ - cat '$*.bottom' && \ + cat '$(<D)/$*.tail' && \ :; } > '$@' # Translate ########################################################## -LIBREXGETTEXT_FLAGS += --simple=_l:2 - -libreblacklist.pot: libreblacklist librexgettext - { \ +$(outdir)/blacklist.sh.pot: $(srcdir)/blacklist.sh $(srcdir)/librexgettext + @echo "OUT $@" + @{ \ sed -n '/^# Usage:/,/()/{ /^#/ { =; p; } }' $< | \ sed -r -e 's/^# (.*)/msgid "\1"\nmsgstr ""\n/' \ - -e 's/^[0-9]*$$/#. embedded usage text\n#: $<:&/'; \ - ./librexgettext $<; \ - } | $(pofmt) > $@ + -e 's/^[0-9]*$$/#. embedded usage text\n#: $<:&/' && \ + $(<D)/librexgettext --simple=_l:2 $< && \ + :; } | $(pofmt) > $@ +$(outdir)/common.sh.pot : LIBREXGETTEXT_FLAGS += --simple=_l:2 +$(outdir)/conf.sh.pot : LIBREXGETTEXT_FLAGS += --simple=_l:2 +$(outdir)/librelib.pot : LIBREXGETTEXT_FLAGS += --simple=_l:2 +$(outdir)/messages.sh.pot : LIBREXGETTEXT_FLAGS += --simple=_l:2 +$(outdir)/librexgettext.pot: LIBREXGETTEXT_FLAGS += --simple=errusage + +###################################################################### -librexgettext.pot: LIBREXGETTEXT_FLAGS += --simple=errusage +include $(topsrcdir)/automake.tail.mk diff --git a/src/lib/blacklist.sh b/src/lib/blacklist.sh new file mode 100644 index 0000000..0a3cc39 --- /dev/null +++ b/src/lib/blacklist.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# This may be included with or without `set -euE` + +# Copyright (C) 2013-2014, 2016 Luke Shumaker <lukeshu@sbcglobal.net> +# +# License: GNU GPLv2+ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# make sure XDG_CACHE_HOME is set +. "$(librelib conf)" + +# Usage: blacklist-normalize <$file +# Normalizes the syntax of the blacklist on stdin. +blacklist-normalize() { + sed -e '/^#/d' -e 's/^[^:]*$/&::/' -e 's/^[^:]*:[^:]*$/&:/' +} + +# Usage: blacklist-cat +# Prints the blacklist. +# Uses the cache, but downloads it if it doesn't exist. Also normalizes the blacklist for easier parsing. +blacklist-cat() { + local file="$XDG_CACHE_HOME/libretools/blacklist.txt" + if ! [[ -e $file ]]; then + # exit on failure, whether set -e or not + blacklist-update || return $? + fi + blacklist-normalize < "$file" +} + +# Usage: blacklist-update +# Updates (or creates) the cached copy of the blacklist. +blacklist-update() ( + . libremessages + load_files libretools || return 1 + check_vars libretools BLACKLIST || return 1 + + local remote_blacklist="$BLACKLIST" + local local_blacklist="$XDG_CACHE_HOME/libretools/blacklist.txt" + + _l stat_busy "Downloading blacklist of proprietary software packages" + + mkdir -p "${local_blacklist%/*}" + if wget -N -q -O "${local_blacklist}.part" "$remote_blacklist" 2>/dev/null; then + stat_done + mv -f "${local_blacklist}.part" "$local_blacklist" + else + stat_done + rm "${local_blacklist}.part" + if [[ -e "$local_blacklist" ]]; then + _l warning "Using local copy of blacklist" + else + _l error "Download failed, exiting" + return 1 + fi + + fi +) + +# Usage: blacklist-cat | blacklist-lookup $pkgname +# Filters to obtain the line for $pkgname from the blacklist on stdin. +# Exits successfully whether a line is found or not. +blacklist-lookup() { + local pkg=$1 + # we accept that $pkg contains no regex-nes + blacklist-normalize | grep "^$pkg:" || true +} + +# Usage: blacklist-cat | blacklist-get-pkg +# Prints only the package name field of the blacklist line(s) on stdin. +blacklist-get-pkg() { + blacklist-normalize | cut -d: -f1 +} + +# Usage: blacklist-cat | blacklist-get-rep +# Prints only the replacement package field of the blacklist line(s) on stdin. +blacklist-get-rep() { + blacklist-normalize | cut -d: -f2 +} + +# Usage: blacklist-cat | blacklist-get-reason +# Prints only the reason field of the blacklist line(s) on stdin. +blacklist-get-reason() { + blacklist-normalize | cut -d: -f3- +} diff --git a/src/lib/common.sh.top b/src/lib/common.sh.head index 23bfeb8..23bfeb8 100644 --- a/src/lib/common.sh.top +++ b/src/lib/common.sh.head diff --git a/src/lib/common.sh.bottom b/src/lib/common.sh.tail index e133fad..e133fad 100644 --- a/src/lib/common.sh.bottom +++ b/src/lib/common.sh.tail diff --git a/src/lib/libreblacklist b/src/lib/libreblacklist index 1e5a467..6c354fe 100755 --- a/src/lib/libreblacklist +++ b/src/lib/libreblacklist @@ -1,8 +1,5 @@ #!/usr/bin/env bash -# This may be included with or without `set -euE` -# When run directly, it does `set -euE` - -# Copyright (C) 2013-2014 Luke Shumaker <lukeshu@sbcglobal.net> +# Copyright (C) 2013-2014, 2016 Luke Shumaker <lukeshu@sbcglobal.net> # # License: GNU GPLv2+ # @@ -19,88 +16,17 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# make sure XDG_CACHE_HOME is set -. "$(librelib conf)" - -# Usage: blacklist-normalize <$file -# Normalizes the syntax of the blacklist on stdin. -blacklist-normalize() { - sed -e '/^#/d' -e 's/^[^:]*$/&::/' -e 's/^[^:]*:[^:]*$/&:/' -} - -# Usage: blacklist-cat -# Prints the blacklist. -# Uses the cache, but downloads it if it doesn't exist. Also normalizes the blacklist for easier parsing. -blacklist-cat() { - local file="$XDG_CACHE_HOME/libretools/blacklist.txt" - if ! [[ -e $file ]]; then - # exit on failure, whether set -e or not - blacklist-update || return $? - fi - blacklist-normalize < "$file" -} - -# Usage: blacklist-update -# Updates (or creates) the cached copy of the blacklist. -blacklist-update() ( - . libremessages - load_files libretools || return 1 - check_vars libretools BLACKLIST || return 1 - - local remote_blacklist="$BLACKLIST" - local local_blacklist="$XDG_CACHE_HOME/libretools/blacklist.txt" - - _l stat_busy "Downloading blacklist of proprietary software packages" - - mkdir -p "${local_blacklist%/*}" - if wget -N -q -O "${local_blacklist}.part" "$remote_blacklist" 2>/dev/null; then - stat_done - mv -f "${local_blacklist}.part" "$local_blacklist" - else - stat_done - rm "${local_blacklist}.part" - if [[ -e "$local_blacklist" ]]; then - _l warning "Using local copy of blacklist" - else - _l error "Download failed, exiting" - return 1 - fi - - fi -) - -# Usage: blacklist-cat | blacklist-lookup $pkgname -# Filters to obtain the line for $pkgname from the blacklist on stdin. -# Exits successfully whether a line is found or not. -blacklist-lookup() { - local pkg=$1 - # we accept that $pkg contains no regex-nes - blacklist-normalize | grep "^$pkg:" || true -} - -# Usage: blacklist-cat | blacklist-get-pkg -# Prints only the package name field of the blacklist line(s) on stdin. -blacklist-get-pkg() { - blacklist-normalize | cut -d: -f1 -} - -# Usage: blacklist-cat | blacklist-get-rep -# Prints only the replacement package field of the blacklist line(s) on stdin. -blacklist-get-rep() { - blacklist-normalize | cut -d: -f2 -} +if [[ "${0##*/}" != libreblacklist ]]; then + . "$(librelib blacklist)" +else + set -euE -# Usage: blacklist-cat | blacklist-get-reason -# Prints only the reason field of the blacklist line(s) on stdin. -blacklist-get-reason() { - blacklist-normalize | cut -d: -f3- -} + lib_file="$(librelib blacklist)" + . "$lib_file" -if [[ "${0##*/}" == libreblacklist ]]; then - set -euE usage-outside() { - sed -n '/^# Usage:/,/()/p' "$0" | - tr '\n' '\r' | sed 's/\s*()\s*[{(]/\n/g' + sed -n '/^# Usage:/,/()/p' "$lib_file" | + tr '\n' '\r' | sed 's/\s*()\s*[{(]/\n/g' } # The output format of this is: # - The first line is "Usage:" @@ -110,6 +36,7 @@ if [[ "${0##*/}" == libreblacklist ]]; then usage-inside() { sed 's/\r/\n/g'<<<"$1"|sed -e '/^$/d' -e 's/^# //' } + usage() { export TEXTDOMAIN='librelib' export TEXTDOMAINDIR='/usr/share/locale' @@ -120,33 +47,37 @@ if [[ "${0##*/}" == libreblacklist ]]; then echo print "Commands:" usage-outside | while read -r sec; do sec="$(usage-inside "$sec")" - cmd=$(<<<"$sec" sed -n '$s/^blacklist-//p') - desc="$(_ "$(sed -n 2p <<<"$sec")")" - flag "$cmd" "${desc//blacklist-/${0##*/} }" + cmd=$(<<<"$sec" sed -n '$s/^blacklist-//p') + desc="$(_ "$(sed -n 2p <<<"$sec")")" + flag "$cmd" "${desc//blacklist-/${0##*/} }" done else usage-outside | while read -r sec; do sec="$(usage-inside "$sec")" - cmd=$(<<<"$sec" sed -n '$s/^blacklist-//p') - if [[ "$cmd" == "$1" ]]; then - <<<"$sec" sed '$d' | - while read -r line; do print "$line"; done | - sed "s/blacklist-/${0##*/} /g" | - fmt -us - return 0 - fi + cmd=$(<<<"$sec" sed -n '$s/^blacklist-//p') + if [[ "$cmd" == "$1" ]]; then + <<<"$sec" sed '$d' | + while read -r line; do print "$line"; done | + sed "s/blacklist-/${0##*/} /g" | + fmt -us + return 0 + fi done fi } - if [[ $# -eq 0 ]]; then - usage >&2 - exit 1 - fi - _blacklist_cmd=$1 - shift - if [[ $_blacklist_cmd == -h ]]; then - usage "$@" - else - "blacklist-$_blacklist_cmd" "$@" - fi + main() { + if [[ $# -eq 0 ]]; then + usage >&2 + exit 1 + fi + _blacklist_cmd=$1 + shift + if [[ $_blacklist_cmd == -h ]]; then + usage "$@" + else + "blacklist-$_blacklist_cmd" "$@" + fi + } + + main "$@" fi diff --git a/src/lib/librelib.7.ronn b/src/lib/librelib.7.ronn index 31fb65f..33b0c55 100644 --- a/src/lib/librelib.7.ronn +++ b/src/lib/librelib.7.ronn @@ -11,8 +11,7 @@ There are three parts to librelib: 1. The `librelib`(1) executable. 2. The non-executable libraries installed in `/usr/lib/libretools` - 3. The executable libraries installed in both `/usr/bin` and - `/usr/lib/libretools`. + 3. The executable libraries installed in `/usr/bin` The `librelib` executable isn't very exciting, it just finds the libraries installed in `/usr/lib/libretools`. Think of it as a sort diff --git a/src/lib/libremessages b/src/lib/libremessages index 528d9b6..647204a 100755 --- a/src/lib/libremessages +++ b/src/lib/libremessages @@ -1,19 +1,5 @@ #!/usr/bin/env bash -# This may be included with or without `set -euE` -# When run directly, it does `set -euE` - -# Copyright (C) 2011 Joshua Ismael Haase Hernández (xihh) <hahj87@gmail.com> -# Copyright (C) 2012 Nicolás Reynolds <fauno@parabola.nu> -# Copyright (C) 2012-2014 Luke Shumaker <lukeshu@sbcglobal.net> - -# For just the setup_traps() function: -# Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org> -# Copyright (C) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> -# Copyright (C) 2005 Aurelien Foret <orelien@chez.com> -# Copyright (C) 2005 Christian Hamar <krics@linuxforum.hu> -# Copyright (C) 2006 Alex Smith <alex@alex-smith.me.uk> -# Copyright (C) 2006 Andras Voroskoi <voroskoi@frugalware.org> -# Copyright (C) 2006 Miklos Vajna <vmiklos@frugalware.org> +# Copyright (C) 2012-2014, 2016 Luke Shumaker <lukeshu@sbcglobal.net> # # License: GNU GPLv2+ # @@ -30,189 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -################################################################################ -# Inherit most functions from devtools # -################################################################################ - -. "$(librelib common.sh)" - -################################################################################ -# Own functions # -################################################################################ - -# Usage: panic -# -# For programming errors, bails immediately with little fanfare. -panic() { - echo "$(_l _ 'panic: malformed call to internal function')" >&2 - exit 1 -} - -# Usage: print MESG [ARGS...] -# -# Like printf, but gettext-aware, and prints a trailing newline -print() { - [[ $# -ge 1 ]] || panic - local mesg="$(_ "$1")" - shift - printf -- "$mesg\n" "$@" -} - -# Usage: whitespace_collapse <<<STRING -# -# Collapses whitespace on stadard I/O, similar to HTML whitespace -# collapsing, with the exception that it puts two spaces between -# sentences. It considers newline, tab, and space to be whitespace. -whitespace_collapse() { - [[ $# == 0 ]] || panic - - tr '\n' '\r' | sed -r \ - -e 's/\r/ /g' -e 's/\t/ /g' \ - -e 's/(^|[^.!? ]) +/\1 /g' -e 's/([.!?]) +/\1 /g' -} - - -# Usage: prose MESG [ARGS...] -# -# Do HTML-style whitespace collapsing on the first argument, translate -# it (gettext), then word-wrap it to 75 columns. This is useful for -# printing a paragraph of prose in --help text. -prose() { - [[ $# -ge 1 ]] || panic - local mesg="$(_ "$(whitespace_collapse <<<"$1")")"; shift - printf -- "$mesg" "$@" | fmt -u -} - -# Usage: bullet MESG [ARGS...] -# Like prose, but print a bullet "-" before the first line, and indent the -# remaining lines. -bullet() { - [[ $# -ge 1 ]] || panic - local mesg="$(_ "$(whitespace_collapse <<<"$1")")"; shift - # Wrap the text to 71 columns; 75 (the default) minus a 4 column indent - printf -- "$mesg" "$@" | fmt -u -w 71 | sed -e '1s/^/ - /' -e '2,$s/^/ /' -} - -# Usage: flag FLAG DESCRIPTION [FLAG2 DESCRIPTION2...] -# -# Print a flag and description formatted for --help text. -# -# ex: flag '-C <FILE>' 'Use this file instead of pacman.conf' -# -# The description is fed through gettext, the flag is not, so if part -# of the flag needs to be translated, you must do that yourself: -# -# ex: flag "-C <$(_ FILE)>" 'Use this file instead of pacman.conf' -# -# If you want to line-break the description in the source, so it isn't -# crazy-long, feel free, it is reflowed/wrapped the same way as prose -# and bullet. If you pass in multiple flag/description pairs at once, -# the descriptions are all alligned together. -flag() { - [[ $# == $(($#/2*2)) ]] || panic - local args=("$@") - - declare -i flaglen=0 - while [[ $# -gt 0 ]]; do - if [[ $1 == *: ]]; then - shift 1 - else - if [[ ${#1} -gt $flaglen ]]; then - flaglen=${#1} - fi - shift 2 - fi - done - set -- "${args[@]}" - - # Unless the $flaglen is extra-wide, the $desc should start at - # column 16 (that is two literal-tabs). If $flaglen is wide, - # this should be increased in increments of 8 (that is, a - # literal-tab). Everything should be wrapped to 75 columns. - - # The printf-format we use has 4 spaces built into it (two at - # the beginning, and two for a seperator). Therefore, the - # default indent is 16-4=12 columns. And the width left for - # $desc is (75-4)-indent = 71-indent. - - declare -i indent=12 - while [[ $indent -lt $flaglen ]]; do - indent+=8 - done - local fmt2 fmt1 - fmt2=" %-${indent}s %s\n" - printf -v fmt1 " %-${indent}s %%s\n" '' - - while [[ $# -gt 0 ]]; do - if [[ $1 == *: ]]; then - printf -- ' %s\n' "$(_ "$1")" - shift - else - local flag=$1 - local desc="$(_ "$(whitespace_collapse <<<"$2")")" - shift 2 - - local lines - IFS=$'\n' lines=($(fmt -u -w $((71-indent)) <<<"$desc")) - printf -- "$fmt2" "$flag" "${lines[0]}" - [[ ${#lines[@]} -lt 2 ]] || printf -- "$fmt1" "${lines[@]:1}" - fi - done -} - -# Usage: term_title MESG [ARGS...] -# -# Sets the terminal title. -term_title() { - [[ $# -ge 1 ]] || panic - local fmt='' - case "$TERM" in - screen|tmux) fmt='\ek%s\e\\';; - xterm*|rxvt*) fmt='\e]0;%s\a';; - esac - printf "$fmt" "$(printf -- "$@")" -} - -# Usage: setup_traps [handler] -# -# Sets up traps on TERM, HUP, QUIT and INT signals, as well as the ERR -# event, similar to makepkg. -# -# If `handler` is specified, instead of using the default handler -# (which is good for most purposes), it will call the command handler -# with the arguments: -# -# ${handler} SIGNAL_NAME MESSAGE_FMT [MESSAGE_PARAMS...] -# -# where MESSAGE_* are printf-like stuff. -# -# This function is based on code from pacman:makepkg -setup_traps() { - [[ $# -le 1 ]] || panic - if [[ $# == 1 ]]; then - eval "_libremessages_trap_exit() { $1 \"\$@\"; }" - else - _libremessages_trap_exit() { - local signal=$1; shift - echo - error "$@" - trap -- "$signal" - kill "-$signal" "$$" - } - fi - set -E - for signal in TERM HUP QUIT; do - trap "_libremessages_trap_exit $signal '%s signal caught. Exiting...' $signal" $signal - done - trap '_libremessages_trap_exit INT "Aborted by user! Exiting..."' INT - trap '_libremessages_trap_exit USR1 "An unknown error has occurred. Exiting..."' ERR -} - -################################################################################ -# Run one of the defined functions if invoked directly # -################################################################################ - -if [[ "${0##*/}" == libremessages ]]; then - set -euE - "$@" +if [[ "${0##*/}" != libremessages ]]; then + . "$(librelib messages)" +else + set -euE + . "$(librelib messages)" + "$@" fi diff --git a/src/lib/messages.sh b/src/lib/messages.sh new file mode 100644 index 0000000..4b4897e --- /dev/null +++ b/src/lib/messages.sh @@ -0,0 +1,208 @@ +#!/usr/bin/env bash +# This may be included with or without `set -euE` + +# Copyright (C) 2011 Joshua Ismael Haase Hernández (xihh) <hahj87@gmail.com> +# Copyright (C) 2012 Nicolás Reynolds <fauno@parabola.nu> +# Copyright (C) 2012-2014, 2016 Luke Shumaker <lukeshu@sbcglobal.net> +# +# For just the setup_traps() function: +# Copyright (C) 2002-2006 Judd Vinet <jvinet@zeroflux.org> +# Copyright (C) 2006-2010 Pacman Development Team <pacman-dev@archlinux.org> +# Copyright (C) 2005 Aurelien Foret <orelien@chez.com> +# Copyright (C) 2005 Christian Hamar <krics@linuxforum.hu> +# Copyright (C) 2006 Alex Smith <alex@alex-smith.me.uk> +# Copyright (C) 2006 Andras Voroskoi <voroskoi@frugalware.org> +# Copyright (C) 2006 Miklos Vajna <vmiklos@frugalware.org> +# +# License: GNU GPLv2+ +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +################################################################################ +# Inherit most functions from devtools # +################################################################################ + +. "$(librelib common.sh)" + +################################################################################ +# Own functions # +################################################################################ + +# Usage: panic +# +# For programming errors, bails immediately with little fanfare. +panic() { + echo "$(_l _ 'panic: malformed call to internal function')" >&2 + exit 1 +} + +# Usage: print MESG [ARGS...] +# +# Like printf, but gettext-aware, and prints a trailing newline +print() { + [[ $# -ge 1 ]] || panic + local mesg="$(_ "$1")" + shift + printf -- "$mesg\n" "$@" +} + +# Usage: whitespace_collapse <<<STRING +# +# Collapses whitespace on stadard I/O, similar to HTML whitespace +# collapsing, with the exception that it puts two spaces between +# sentences. It considers newline, tab, and space to be whitespace. +whitespace_collapse() { + [[ $# == 0 ]] || panic + + tr '\n' '\r' | sed -r \ + -e 's/\r/ /g' -e 's/\t/ /g' \ + -e 's/(^|[^.!? ]) +/\1 /g' -e 's/([.!?]) +/\1 /g' +} + + +# Usage: prose MESG [ARGS...] +# +# Do HTML-style whitespace collapsing on the first argument, translate +# it (gettext), then word-wrap it to 75 columns. This is useful for +# printing a paragraph of prose in --help text. +prose() { + [[ $# -ge 1 ]] || panic + local mesg="$(_ "$(whitespace_collapse <<<"$1")")"; shift + printf -- "$mesg" "$@" | fmt -u +} + +# Usage: bullet MESG [ARGS...] +# Like prose, but print a bullet "-" before the first line, and indent the +# remaining lines. +bullet() { + [[ $# -ge 1 ]] || panic + local mesg="$(_ "$(whitespace_collapse <<<"$1")")"; shift + # Wrap the text to 71 columns; 75 (the default) minus a 4 column indent + printf -- "$mesg" "$@" | fmt -u -w 71 | sed -e '1s/^/ - /' -e '2,$s/^/ /' +} + +# Usage: flag FLAG DESCRIPTION [FLAG2 DESCRIPTION2...] +# +# Print a flag and description formatted for --help text. +# +# ex: flag '-C <FILE>' 'Use this file instead of pacman.conf' +# +# The description is fed through gettext, the flag is not, so if part +# of the flag needs to be translated, you must do that yourself: +# +# ex: flag "-C <$(_ FILE)>" 'Use this file instead of pacman.conf' +# +# If you want to line-break the description in the source, so it isn't +# crazy-long, feel free, it is reflowed/wrapped the same way as prose +# and bullet. If you pass in multiple flag/description pairs at once, +# the descriptions are all alligned together. +flag() { + [[ $# == $(($#/2*2)) ]] || panic + local args=("$@") + + declare -i flaglen=0 + while [[ $# -gt 0 ]]; do + if [[ $1 == *: ]]; then + shift 1 + else + if [[ ${#1} -gt $flaglen ]]; then + flaglen=${#1} + fi + shift 2 + fi + done + set -- "${args[@]}" + + # Unless the $flaglen is extra-wide, the $desc should start at + # column 16 (that is two literal-tabs). If $flaglen is wide, + # this should be increased in increments of 8 (that is, a + # literal-tab). Everything should be wrapped to 75 columns. + + # The printf-format we use has 4 spaces built into it (two at + # the beginning, and two for a seperator). Therefore, the + # default indent is 16-4=12 columns. And the width left for + # $desc is (75-4)-indent = 71-indent. + + declare -i indent=12 + while [[ $indent -lt $flaglen ]]; do + indent+=8 + done + local fmt2 fmt1 + fmt2=" %-${indent}s %s\n" + printf -v fmt1 " %-${indent}s %%s\n" '' + + while [[ $# -gt 0 ]]; do + if [[ $1 == *: ]]; then + printf -- ' %s\n' "$(_ "$1")" + shift + else + local flag=$1 + local desc="$(_ "$(whitespace_collapse <<<"$2")")" + shift 2 + + local lines + IFS=$'\n' lines=($(fmt -u -w $((71-indent)) <<<"$desc")) + printf -- "$fmt2" "$flag" "${lines[0]}" + [[ ${#lines[@]} -lt 2 ]] || printf -- "$fmt1" "${lines[@]:1}" + fi + done +} + +# Usage: term_title MESG [ARGS...] +# +# Sets the terminal title. +term_title() { + [[ $# -ge 1 ]] || panic + local fmt='' + case "$TERM" in + screen|tmux) fmt='\ek%s\e\\';; + xterm*|rxvt*) fmt='\e]0;%s\a';; + esac + printf "$fmt" "$(printf -- "$@")" +} + +# Usage: setup_traps [handler] +# +# Sets up traps on TERM, HUP, QUIT and INT signals, as well as the ERR +# event, similar to makepkg. +# +# If `handler` is specified, instead of using the default handler +# (which is good for most purposes), it will call the command handler +# with the arguments: +# +# ${handler} SIGNAL_NAME MESSAGE_FMT [MESSAGE_PARAMS...] +# +# where MESSAGE_* are printf-like stuff. +# +# This function is based on code from pacman:makepkg +setup_traps() { + [[ $# -le 1 ]] || panic + if [[ $# == 1 ]]; then + eval "_libremessages_trap_exit() { $1 \"\$@\"; }" + else + _libremessages_trap_exit() { + local signal=$1; shift + echo + error "$@" + trap -- "$signal" + kill "-$signal" "$$" + } + fi + set -E + for signal in TERM HUP QUIT; do + trap "_libremessages_trap_exit $signal '%s signal caught. Exiting...' $signal" $signal + done + trap '_libremessages_trap_exit INT "Aborted by user! Exiting..."' INT + trap '_libremessages_trap_exit USR1 "An unknown error has occurred. Exiting..."' ERR +} diff --git a/src/librefetch/Makefile b/src/librefetch/Makefile index dcb64dc..b28e96e 100644 --- a/src/librefetch/Makefile +++ b/src/librefetch/Makefile @@ -1,5 +1,13 @@ -progs = librefetch-install -confs = librefetch-makepkg.conf -libexecs = $(shell find librefetchdir -type f -executable) -libs = $(shell find librefetchdir -type f -not -executable) -include ../../common.mk +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk + +install-bins = librefetch librefetch-install +install-confs += librefetch-makepkg.conf +install-libexecs += $(filter librefetchdir/%,$(detect-exec)) +install-libs += $(filter-out $(install-libexecs),$(filter librefetchdir/%,$(detect-all))) +pots = $(install-bins) + +$(outdir)/librefetch-install: $(var)pkgconfdir +$(outdir)/librefetch-makepkg.conf: $(var)bindir + +include $(topsrcdir)/automake.tail.mk diff --git a/src/toru/Makefile b/src/toru/Makefile index 2c76089..2903f4a 100644 --- a/src/toru/Makefile +++ b/src/toru/Makefile @@ -1 +1,4 @@ -include ../../common.mk +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk + +include $(topsrcdir)/automake.tail.mk diff --git a/doc/workflows.md b/src/workflows.md index 03dca4f..03dca4f 100644 --- a/doc/workflows.md +++ b/src/workflows.md diff --git a/src/xbs-abs/Makefile b/src/xbs-abs/Makefile index 8688ed7..81e1b4f 100644 --- a/src/xbs-abs/Makefile +++ b/src/xbs-abs/Makefile @@ -1,23 +1,27 @@ +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk pkgconfdir = $(sysconfdir)/xbs pkglibexecdir = $(libexecdir)/xbs -libexecs = helper-abs _helpers = archrelease commitpkg -no-progs = $(libexecs) $(_helpers) -copy_files = $(addsuffix .in,$(_helpers)) -install_files = $(addprefix $(DESTDIR)$(pkglibexecdir)/helper-abs.d/,$(_helpers)) -pots = $(_helpers) +install-bins = +install-libexecs = helper-abs +pots += $(_helpers) +devtools-files += $(addsuffix .in,$(_helpers)) +am_out_files += $(_helpers) +am_sys_files += $(addprefix $(pkglibexecdir)/helper-abs.d/,$(_helpers)) -include ../../common.mk - -commitpkg: commitpkg.in - { \ +$(outdir)/commitpkg: $(srcdir)/commitpkg.in + @echo "OUT $@" + @{ \ echo '#!/usr/bin/env bash'; \ echo '. "$$(librelib common)"'; \ echo '. ./PKGBUILD'; \ echo 'repo=$$1; arch=$$2;'; \ sed -n "/== 'any'/,\$$p" $<; \ - } > $@ + } | install -Dm755 /dev/stdin $@ -$(DESTDIR)$(pkglibexecdir)/helper-abs.d/%: % +$(DESTDIR)$(pkglibexecdir)/helper-abs.d/%: $(srcdir)/% install -Dm755 '$<' '$@' + +include $(topsrcdir)/automake.tail.mk diff --git a/src/xbs-abslibre/Makefile b/src/xbs-abslibre/Makefile index 420ae52..6c61803 100644 --- a/src/xbs-abslibre/Makefile +++ b/src/xbs-abslibre/Makefile @@ -1,4 +1,8 @@ +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk pkglibexecdir = $(libexecdir)/xbs -libexecs = helper-abslibre -no-progs = $(libexecs) -include ../../common.mk + +install-bins = +install-libexecs = helper-abslibre + +include $(topsrcdir)/automake.tail.mk diff --git a/src/xbs/Makefile b/src/xbs/Makefile index ea5e924..974586e 100644 --- a/src/xbs/Makefile +++ b/src/xbs/Makefile @@ -1,2 +1,5 @@ +include $(dir $(lastword $(MAKEFILE_LIST)))/../../config.mk +include $(topsrcdir)/automake.head.mk pkgconfdir = $(sysconfdir)/xbs -include ../../common.mk + +include $(topsrcdir)/automake.tail.mk diff --git a/test/librelib-test.sh b/test/librelib-test.sh index a74ce0a..24c4478 100644 --- a/test/librelib-test.sh +++ b/test/librelib-test.sh @@ -37,14 +37,16 @@ it_displays_usage_text() { empty $tmpdir/stderr } -# libremessages is executable +# Nothing in $(libdir) should be executable anymore (except that +# $(libexecdir)=$(libdir), and executable things go in there. But I +# digress, libremessages should not be executable anymore). it_finds_messages() { v1=$(librelib messages) v2=$(librelib libremessages) v3=$(librelib messages.sh) v4=$(librelib libremessages.sh) - [[ -x "$v1" ]] + [[ -r "$v1" && ! -x "$v1" ]] [[ "$v1" == "$v2" ]] [[ "$v1" == "$v3" ]] [[ "$v1" == "$v4" ]] diff --git a/write-ifchanged b/write-ifchanged new file mode 100755 index 0000000..c65fa16 --- /dev/null +++ b/write-ifchanged @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +outfile=$1 +tmpfile="$(dirname "$outfile")/.tmp${outfile##*/}" + +cat > "$tmpfile" || exit $? +if cmp -s "$tmpfile" "$outfile"; then + rm -f "$tmpfile" || : +else + mv -f "$tmpfile" "$outfile" +fi |