1 2MAKEFLAGS += --warn-undefined-variables 3 4SHELL := bash 5.DEFAULT_GOAL := all 6 7# See config/config.vars.in (sets bup_python, among other things) 8-include config/config.vars 9 10pf := set -o pipefail 11cfg_py := $(CURDIR)/config/bin/python 12 13define isok 14 && echo " ok" || echo " no" 15endef 16 17# If ok, strip trailing " ok" and return the output, otherwise, error 18define shout 19$(if $(subst ok,,$(lastword $(1))),$(error $(2)),$(shell x="$(1)"; echo $${x%???})) 20endef 21 22sampledata_rev := $(shell t/configure-sampledata --revision $(isok)) 23sampledata_rev := \ 24 $(call shout,$(sampledata_rev),Could not parse sampledata revision) 25 26current_sampledata := t/sampledata/var/rev/v$(sampledata_rev) 27 28os := $(shell ($(pf); uname | sed 's/[-_].*//') $(isok)) 29os := $(call shout,$(os),Unable to determine OS) 30 31CFLAGS := -Wall -O2 -Wno-unknown-pragmas $(PYINCLUDE) $(CFLAGS) 32CFLAGS := -D_FILE_OFFSET_BITS=64 $(PYINCLUDE) $(CFLAGS) 33SOEXT:=.so 34 35ifeq ($(os),CYGWIN) 36 SOEXT:=.dll 37endif 38 39ifdef TMPDIR 40 test_tmp := $(TMPDIR) 41else 42 test_tmp := $(CURDIR)/t/tmp 43endif 44 45initial_setup := $(shell dev/update-checkout-info lib/bup/checkout_info.py $(isok)) 46initial_setup := $(call shout,$(initial_setup),update-checkout-info failed)) 47 48config/config.vars: \ 49 configure config/configure config/configure.inc \ 50 $(wildcard config/*.in) 51 MAKE="$(MAKE)" ./configure 52 53# On some platforms, Python.h and readline.h fight over the 54# _XOPEN_SOURCE version, i.e. -Werror crashes on a mismatch, so for 55# now, we're just going to let Python's version win. 56 57ifneq ($(strip $(bup_readline_cflags)),) 58 readline_cflags += $(bup_readline_cflags) 59 readline_xopen := $(filter -D_XOPEN_SOURCE=%,$(readline_cflags)) 60 readline_xopen := $(subst -D_XOPEN_SOURCE=,,$(readline_xopen)) 61 readline_cflags := $(filter-out -D_XOPEN_SOURCE=%,$(readline_cflags)) 62 readline_cflags += $(addprefix -DBUP_RL_EXPECTED_XOPEN_SOURCE=,$(readline_xopen)) 63 CFLAGS += $(readline_cflags) 64endif 65 66LDFLAGS += $(bup_readline_ldflags) 67 68ifeq ($(bup_have_libacl),1) 69 CFLAGS += $(bup_libacl_cflags) 70 LDFLAGS += $(bup_libacl_ldflags) 71endif 72 73config/bin/python: config/config.vars 74 75bup_cmds := \ 76 $(patsubst cmd/%-cmd.py,cmd/bup-%,$(wildcard cmd/*-cmd.py)) \ 77 $(patsubst cmd/%-cmd.sh,cmd/bup-%,$(wildcard cmd/*-cmd.sh)) 78 79bup_deps := lib/bup/_helpers$(SOEXT) $(bup_cmds) 80 81all: $(bup_deps) Documentation/all $(current_sampledata) 82 83$(current_sampledata): 84 t/configure-sampledata --setup 85 86PANDOC ?= $(shell type -p pandoc) 87 88ifeq (,$(PANDOC)) 89 $(shell echo "Warning: pandoc not found; skipping manpage generation" 1>&2) 90 man_md := 91else 92 man_md := $(wildcard Documentation/*.md) 93endif 94 95man_roff := $(patsubst %.md,%.1,$(man_md)) 96man_html := $(patsubst %.md,%.html,$(man_md)) 97 98INSTALL=install 99PREFIX=/usr/local 100MANDIR=$(PREFIX)/share/man 101DOCDIR=$(PREFIX)/share/doc/bup 102BINDIR=$(PREFIX)/bin 103LIBDIR=$(PREFIX)/lib/bup 104 105dest_mandir := $(DESTDIR)$(MANDIR) 106dest_docdir := $(DESTDIR)$(DOCDIR) 107dest_bindir := $(DESTDIR)$(BINDIR) 108dest_libdir := $(DESTDIR)$(LIBDIR) 109 110install: all 111 $(INSTALL) -d $(dest_bindir) \ 112 $(dest_libdir)/bup $(dest_libdir)/cmd \ 113 $(dest_libdir)/web $(dest_libdir)/web/static 114 test -z "$(man_roff)" || install -d $(dest_mandir)/man1 115 test -z "$(man_roff)" || $(INSTALL) -m 0644 $(man_roff) $(dest_mandir)/man1 116 test -z "$(man_html)" || install -d $(dest_docdir) 117 test -z "$(man_html)" || $(INSTALL) -m 0644 $(man_html) $(dest_docdir) 118 dev/install-python-script lib/cmd/bup "$(dest_libdir)/cmd/bup" 119 set -e; \ 120 for cmd in $$(ls cmd/bup-*); do \ 121 dev/install-python-script "$$cmd" "$(dest_libdir)/$$cmd"; \ 122 done 123 cd "$(dest_bindir)" && \ 124 ln -sf "$$($(bup_python) -c 'import os; print(os.path.relpath("$(abspath $(dest_libdir))/cmd/bup"))')" 125 set -e; \ 126 $(INSTALL) -pm 0644 \ 127 lib/bup/*.py \ 128 $(dest_libdir)/bup 129 $(INSTALL) -pm 0755 \ 130 lib/bup/*$(SOEXT) \ 131 $(dest_libdir)/bup 132 $(INSTALL) -pm 0644 \ 133 lib/web/static/* \ 134 $(dest_libdir)/web/static/ 135 $(INSTALL) -pm 0644 \ 136 lib/web/*.html \ 137 $(dest_libdir)/web/ 138 if test -e lib/bup/checkout_info.py; then \ 139 $(INSTALL) -pm 0644 lib/bup/checkout_info.py \ 140 $(dest_libdir)/bup/source_info.py; \ 141 else \ 142 ! grep -qF '$$Format' lib/bup/source_info.py; \ 143 $(INSTALL) -pm 0644 lib/bup/source_info.py $(dest_libdir)/bup/; \ 144 fi 145 146config/config.h: config/config.vars 147 148lib/bup/_helpers$(SOEXT): \ 149 config/config.h lib/bup/bupsplit.h \ 150 lib/bup/bupsplit.c lib/bup/_helpers.c lib/bup/csetup.py 151 @rm -f $@ 152 cd lib/bup && $(cfg_py) csetup.py build "$(CFLAGS)" "$(LDFLAGS)" 153 # Make sure there's just the one file we expect before we copy it. 154 $(cfg_py) -c \ 155 "import glob; assert(len(glob.glob('lib/bup/build/*/_helpers*$(SOEXT)')) == 1)" 156 cp lib/bup/build/*/_helpers*$(SOEXT) "$@" 157 158t/tmp: 159 mkdir t/tmp 160 161runtests: runtests-python runtests-cmdline 162 163python_tests := \ 164 lib/bup/t/tbloom.py \ 165 lib/bup/t/tclient.py \ 166 lib/bup/t/tgit.py \ 167 lib/bup/t/thashsplit.py \ 168 lib/bup/t/thelpers.py \ 169 lib/bup/t/tindex.py \ 170 lib/bup/t/tmetadata.py \ 171 lib/bup/t/toptions.py \ 172 lib/bup/t/tresolve.py \ 173 lib/bup/t/tshquote.py \ 174 lib/bup/t/tvfs.py \ 175 lib/bup/t/tvint.py \ 176 lib/bup/t/txstat.py 177 178# The "pwd -P" here may not be appropriate in the long run, but we 179# need it until we settle the relevant drecurse/exclusion questions: 180# https://groups.google.com/forum/#!topic/bup-list/9ke-Mbp10Q0 181runtests-python: all t/tmp 182 mkdir -p t/tmp/test-log 183 $(pf); cd $$(pwd -P); TMPDIR="$(test_tmp)" \ 184 ./wvtest.py $(python_tests) 2>&1 \ 185 | tee -a t/tmp/test-log/$$$$.log 186 187cmdline_tests := \ 188 t/test-help \ 189 t/test.sh \ 190 t/test-argv \ 191 t/test-cat-file.sh \ 192 t/test-command-without-init-fails.sh \ 193 t/test-compression.sh \ 194 t/test-drecurse.sh \ 195 t/test-fsck.sh \ 196 t/test-fuse.sh \ 197 t/test-ftp \ 198 t/test-web.sh \ 199 t/test-gc.sh \ 200 t/test-import-duplicity.sh \ 201 t/test-import-rdiff-backup.sh \ 202 t/test-index.sh \ 203 t/test-index-check-device.sh \ 204 t/test-index-clear.sh \ 205 t/test-list-idx.sh \ 206 t/test-ls \ 207 t/test-ls-remote \ 208 t/test-main.sh \ 209 t/test-meta.sh \ 210 t/test-on.sh \ 211 t/test-packsizelimit \ 212 t/test-prune-older \ 213 t/test-redundant-saves.sh \ 214 t/test-restore-map-owner.sh \ 215 t/test-restore-single-file.sh \ 216 t/test-rm.sh \ 217 t/test-rm-between-index-and-save.sh \ 218 t/test-save-creates-no-unrefs.sh \ 219 t/test-save-restore \ 220 t/test-save-errors \ 221 t/test-save-restore-excludes.sh \ 222 t/test-save-strip-graft.sh \ 223 t/test-save-with-valid-parent.sh \ 224 t/test-sparse-files.sh \ 225 t/test-split-join.sh \ 226 t/test-tz.sh \ 227 t/test-xdev.sh 228 229tmp-target-run-test-get-%: all t/tmp 230 $(pf); cd $$(pwd -P); TMPDIR="$(test_tmp)" \ 231 t/test-get $* 2>&1 | tee -a t/tmp/test-log/$$$$.log 232 233test_get_targets += \ 234 tmp-target-run-test-get-replace \ 235 tmp-target-run-test-get-universal \ 236 tmp-target-run-test-get-ff \ 237 tmp-target-run-test-get-append \ 238 tmp-target-run-test-get-pick \ 239 tmp-target-run-test-get-new-tag \ 240 tmp-target-run-test-get-unnamed 241 242# For parallel runs. 243# The "pwd -P" here may not be appropriate in the long run, but we 244# need it until we settle the relevant drecurse/exclusion questions: 245# https://groups.google.com/forum/#!topic/bup-list/9ke-Mbp10Q0 246tmp-target-run-test%: all t/tmp 247 $(pf); cd $$(pwd -P); TMPDIR="$(test_tmp)" \ 248 t/test$* 2>&1 | tee -a t/tmp/test-log/$$$$.log 249 250runtests-cmdline: $(test_get_targets) $(subst t/test,tmp-target-run-test,$(cmdline_tests)) 251 252stupid: 253 PATH=/bin:/usr/bin $(MAKE) test 254 255test: all 256 if test -e t/tmp/test-log; then rm -r t/tmp/test-log; fi 257 mkdir -p t/tmp/test-log 258 ./wvtest watch --no-counts \ 259 $(MAKE) runtests 2>t/tmp/test-log/$$$$.log 260 ./wvtest report t/tmp/test-log/*.log 261 262check: test 263 264distcheck: all 265 ./wvtest run t/test-release-archive.sh 266 267long-test: export BUP_TEST_LEVEL=11 268long-test: test 269 270long-check: export BUP_TEST_LEVEL=11 271long-check: check 272 273.PHONY: check-both 274check-both: 275 $(MAKE) clean && PYTHON=python3 $(MAKE) check 276 $(MAKE) clean && PYTHON=python2 $(MAKE) check 277 278cmd/bup-%: cmd/%-cmd.py 279 rm -f $@ 280 ln -s $*-cmd.py $@ 281 282cmd/bup-%: cmd/%-cmd.sh 283 rm -f $@ 284 ln -s $*-cmd.sh $@ 285 286.PHONY: Documentation/all 287Documentation/all: $(man_roff) $(man_html) 288 289Documentation/substvars: $(bup_deps) 290 echo "s,%BUP_VERSION%,$$(./bup version),g" > $@ 291 echo "s,%BUP_DATE%,$$(./bup version --date),g" >> $@ 292 293Documentation/%.1: Documentation/%.md Documentation/substvars 294 $(pf); sed -f Documentation/substvars $< \ 295 | $(PANDOC) -s -r markdown -w man -o $@ 296 297Documentation/%.html: Documentation/%.md Documentation/substvars 298 $(pf); sed -f Documentation/substvars $< \ 299 | $(PANDOC) -s -r markdown -w html -o $@ 300 301.PHONY: Documentation/clean 302Documentation/clean: 303 cd Documentation && rm -f *~ .*~ *.[0-9] *.html substvars 304 305# Note: this adds commits containing the current manpages in roff and 306# html format to the man and html branches respectively. The version 307# is determined by "git describe --always". 308.PHONY: update-doc-branches 309update-doc-branches: Documentation/all 310 dev/update-doc-branches refs/heads/man refs/heads/html 311 312# push the pregenerated doc files to origin/man and origin/html 313push-docs: export-docs 314 git push origin man html 315 316# import pregenerated doc files from origin/man and origin/html, in case you 317# don't have pandoc but still want to be able to install the docs. 318import-docs: Documentation/clean 319 $(pf); git archive origin/html | (cd Documentation && tar -xvf -) 320 $(pf); git archive origin/man | (cd Documentation && tar -xvf -) 321 322clean: Documentation/clean config/bin/python 323 cd config && rm -rf config.var 324 cd config && rm -f *~ .*~ \ 325 ${CONFIGURE_DETRITUS} ${CONFIGURE_FILES} ${GENERATED_FILES} 326 rm -f *.o lib/*/*.o *.so lib/*/*.so *.dll lib/*/*.dll *.exe \ 327 .*~ *~ */*~ lib/*/*~ lib/*/*/*~ \ 328 *.pyc */*.pyc lib/*/*.pyc lib/*/*/*.pyc \ 329 lib/bup/checkout_info.py \ 330 randomgen memtest \ 331 testfs.img lib/bup/t/testfs.img 332 for x in $$(ls cmd/*-cmd.py cmd/*-cmd.sh | grep -vF python-cmd.sh | cut -b 5-); do \ 333 echo "cmd/bup-$${x%-cmd.*}"; \ 334 done | xargs -t rm -f 335 if test -e t/mnt; then t/cleanup-mounts-under t/mnt; fi 336 if test -e t/mnt; then rm -r t/mnt; fi 337 if test -e t/tmp; then t/cleanup-mounts-under t/tmp; fi 338 # FIXME: migrate these to t/mnt/ 339 if test -e lib/bup/t/testfs; \ 340 then umount lib/bup/t/testfs || true; fi 341 rm -rf *.tmp *.tmp.meta t/*.tmp lib/*/*/*.tmp build lib/bup/build lib/bup/t/testfs 342 if test -e t/tmp; then t/force-delete t/tmp; fi 343 t/configure-sampledata --clean 344 # Remove last so that cleanup tools can depend on it 345 rm -rf config/bin 346