+# keep intermediate files from the below implicit rules around
+.PRECIOUS: $(addsuffix .o,$(progs))
+
+# Make any btrfs-foo out of btrfs-foo.o, with appropriate libs.
+# The $($(subst...)) bits below takes the btrfs_*_libs definitions above and
+# turns them into a list of libraries to link against if they exist
+#
+# For static variants, use an extra $(subst) to get rid of the ".static"
+# from the target name before translating to list of libs
+
+btrfs-%.static: btrfs-%.static.o $(static_objects) $(patsubst %.o,%.static.o,$(standalone_deps)) $(static_libbtrfs_objects)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $@.o $(static_objects) \
+ $(patsubst %.o, %.static.o, $($(subst -,_,$(subst .static,,$@)-objects))) \
+ $(static_libbtrfs_objects) $(STATIC_LDFLAGS) \
+ $($(subst -,_,$(subst .static,,$@)-libs)) $(STATIC_LIBS)
+
+btrfs-%: btrfs-%.o $(objects) $(standalone_deps) $(libs_static)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $(objects) $@.o \
+ $($(subst -,_,$@-objects)) \
+ $(libs_static) \
+ $(LDFLAGS) $(LIBS) $($(subst -,_,$@-libs))
+
+btrfs: btrfs.o $(objects) $(cmds_objects) $(libs_static)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) $(LIBS_COMP)
+
+btrfs.static: btrfs.static.o $(static_objects) $(static_cmds_objects) $(static_libbtrfs_objects)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(STATIC_LDFLAGS) $(STATIC_LIBS) $(STATIC_LIBS_COMP)
+
+# For backward compatibility, 'btrfs' changes behaviour to fsck if it's named 'btrfsck'
+btrfsck: btrfs
+ @echo " [LN] $@"
+ $(Q)$(LN_S) -f btrfs btrfsck
+
+btrfsck.static: btrfs.static
+ @echo " [LN] $@"
+ $(Q)$(LN_S) -f $^ $@
+
+mkfs.btrfs: $(mkfs_objects) $(objects) $(libs_static)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+mkfs.btrfs.static: $(static_mkfs_objects) $(static_objects) $(static_libbtrfs_objects)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(STATIC_LDFLAGS) $(STATIC_LIBS)
+
+btrfstune: btrfstune.o $(objects) $(libs_static)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+btrfstune.static: btrfstune.static.o $(static_objects) $(static_libbtrfs_objects)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(STATIC_LDFLAGS) $(STATIC_LIBS)
+
+btrfs-image: $(image_objects) $(objects) $(libs_static)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(LDFLAGS) $(LIBS) $(LIBS_COMP)
+
+btrfs-image.static: $(static_image_objects) $(static_objects) $(static_libbtrfs_objects)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(STATIC_LDFLAGS) $(STATIC_LIBS) $(STATIC_LIBS_COMP)
+
+btrfs-convert: $(convert_objects) $(objects) $(libs_static)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(LDFLAGS) $(btrfs_convert_libs) $(LIBS)
+
+btrfs-convert.static: $(static_convert_objects) $(static_objects) $(static_libbtrfs_objects)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(STATIC_LDFLAGS) $(btrfs_convert_libs) $(STATIC_LIBS)
+
+dir-test: dir-test.o $(objects) $(libs)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+quick-test: quick-test.o $(objects) $(libs)
+ @echo " [LD] $@"
+ $(Q)$(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+ioctl-test.o: ioctl-test.c ioctl.h kerncompat.h ctree.h
+ @echo " [CC] $@"
+ $(Q)$(CC) $(CFLAGS) -c $< -o $@
+
+ioctl-test-32.o: ioctl-test.c ioctl.h kerncompat.h ctree.h
+ @echo " [CC32] $@"
+ $(Q)$(CC) $(CFLAGS) -m32 -c $< -o $@
+
+ioctl-test-64.o: ioctl-test.c ioctl.h kerncompat.h ctree.h
+ @echo " [CC64] $@"
+ $(Q)$(CC) $(CFLAGS) -m64 -c $< -o $@
+
+ioctl-test: ioctl-test.o
+ @echo " [LD] $@"
+ $(Q)$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
+ @echo " ?[PAHOLE] $@.pahole"
+ -$(Q)pahole $@ > $@.pahole
+
+ioctl-test-32: ioctl-test-32.o
+ @echo " [LD32] $@"
+ $(Q)$(CC) -m32 -o $@ $< $(LDFLAGS)
+ @echo " ?[PAHOLE] $@.pahole"
+ -$(Q)pahole $@ > $@.pahole
+
+ioctl-test-64: ioctl-test-64.o
+ @echo " [LD64] $@"
+ $(Q)$(CC) -m64 -o $@ $< $(LDFLAGS)
+ @echo " ?[PAHOLE] $@.pahole"
+ -$(Q)pahole $@ > $@.pahole
+
+test-ioctl: ioctl-test ioctl-test-32 ioctl-test-64
+ @echo " [TEST/ioctl]"
+ $(Q)./ioctl-test > ioctl-test.log
+ $(Q)./ioctl-test-32 > ioctl-test-32.log
+ $(Q)./ioctl-test-64 > ioctl-test-64.log
+
+library-test: library-test.c libbtrfs.so
+ @echo " [TEST PREP] $@"$(eval TMPD=$(shell mktemp -d))
+ $(Q)mkdir -p $(TMPD)/include/btrfs && \
+ cp $(libbtrfs_headers) $(TMPD)/include/btrfs && \
+ cd $(TMPD) && $(CC) -I$(TMPD)/include -o $@ $(addprefix $(ABSTOPDIR)/,$^) -Wl,-rpath=$(ABSTOPDIR) -lbtrfs
+ @echo " [TEST RUN] $@"
+ $(Q)cd $(TMPD) && ./$@
+ @echo " [TEST CLEAN] $@"
+ $(Q)$(RM) -rf -- $(TMPD)
+
+library-test.static: library-test.c $(libs_static)
+ @echo " [TEST PREP] $@"$(eval TMPD=$(shell mktemp -d))
+ $(Q)mkdir -p $(TMPD)/include/btrfs && \
+ cp $(libbtrfs_headers) $(TMPD)/include/btrfs && \
+ cd $(TMPD) && $(CC) -I$(TMPD)/include -o $@ $(addprefix $(ABSTOPDIR)/,$^) $(STATIC_LDFLAGS) $(STATIC_LIBS)
+ @echo " [TEST RUN] $@"
+ $(Q)cd $(TMPD) && ./$@
+ @echo " [TEST CLEAN] $@"
+ $(Q)$(RM) -rf -- $(TMPD)
+
+fssum: tests/fssum.c tests/sha224-256.c
+ @echo " [LD] $@"
+ $(Q)$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
+
+test-build: test-build-pre test-build-real
+
+test-build-pre:
+ $(MAKE) $(MAKEOPTS) clean-all
+ ./autogen.sh
+ ./configure
+
+test-build-real:
+ $(MAKE) $(MAKEOPTS) library-test
+ -$(MAKE) $(MAKEOPTS) library-test.static
+ $(MAKE) $(MAKEOPTS) -j 8 all
+ -$(MAKE) $(MAKEOPTS) -j 8 static
+ $(MAKE) $(MAKEOPTS) -j 8 $(progs_extra)