proper DESTDIR handling for device-mapper and LVM2
RFC PATCH 1/1 proper DESTDIR handling for device-mapper and LVM2
The patches below are intended to make the DESTDIR handling in the device-mapper and LVM2 Makefiles a little more useful, and to fix a number of problems with the current DESTDIR handling. The patches are against the latest tarballs (device-mapper.1.00.08 and LVM2.2.00.08). Links to the patches are:
http://www.backtobasicsmgmt.com/uClibc/device-mapper-DESTDIR.patch
http://www.backtobasicsmgmt.com/uClibc/LVM2-DESTDIR.patch
Commented versions are inline below. The patches assume that DESTDIR is used only for "make install"-type targets, not during compile and/or link phases. This is the most common usage of DESTDIR, unless I'm very much mistaken :-) If so, please correct my misunderstanding...
--- snip patch for device-mapper ---
dmsetup/Makefile.in +1 -2
@@ -16,11 +16,10 @@ dmsetup: $(OBJECTS) $(interfacedir)/libdevmapper.so \ $(interfacedir)/libdevmapper.a $(CC) -o dmsetup $(OBJECTS) $(LD_FLAGS) \ - -L$(interfacedir) -L$(DESTDIR)/lib $(LIBS) \ - -ldevmapper + $(LIBS) -ldevmapper
*** $(interfacedir) is in $(LD_FLAGS) courtesy of make_tmpl
*** -L$(DESTDIR)/lib is just wrong; DESTDIR should not be provided at link time, only install time, but if it is provided at link time dmsetup could be linked against the wrong system libraries
install: dmsetup
- $(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< $(sbindir)/$<
+ $(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< $(DESTDIR)$(sbindir)/$<
*** see comments for make_tmpl below
.PHONY: install
Only in device-mapper.new/dmsetup: Makefile.in~ Only in device-mapper.new/lib: .export.sym
lib/Makefile.in +4 -4
@@ -22,29 +22,29 @@ install: install_@interface@ - $(LN_S) -f libdevmapper.so.$(LIB_VERSION) $(libdir)/libdevmapper.so + $(LN_S) -f libdevmapper.so.$(LIB_VERSION) $(DESTDIR)$(libdir)/libdevmapper.so $(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 444 libdevmapper.h \ - $(includedir)/libdevmapper.h + $(DESTDIR)$(includedir)/libdevmapper.h install_static: install_@interface@_static - $(LN_S) -f libdevmapper.a.$(LIB_VERSION) $(libdir)/libdevmapper.a + $(LN_S) -f libdevmapper.a.$(LIB_VERSION) $(DESTDIR)$(libdir)/libdevmapper.a $(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 444 libdevmapper.h \ - $(includedir)/libdevmapper.h + $(DESTDIR)$(includedir)/libdevmapper.h .PHONY: install install_@interface@ install_static
install_@interface@_static
install_fs: fs/libdevmapper.so
$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \
- $(libdir)/libdevmapper.so.$(LIB_VERSION)
+ $(DESTDIR)$(libdir)/libdevmapper.so.$(LIB_VERSION)
install_ioctl: ioctl/libdevmapper.so
$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \
- $(libdir)/libdevmapper.so.$(LIB_VERSION)
+ $(DESTDIR)$(libdir)/libdevmapper.so.$(LIB_VERSION)
install_ioctl_static: ioctl/libdevmapper.a
$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \
- $(libdir)/libdevmapper.a.$(LIB_VERSION)
+ $(DESTDIR)$(libdir)/libdevmapper.a.$(LIB_VERSION)
distclean_lib:
$(RM) libdm-common.h
Only in device-mapper.new/lib: Makefile.in~
make.tmpl.in +2 -2
@@ -31,8 +31,8 @@ LD_DEPS += @LD_DEPS@ # Setup directory variables -prefix = $(DESTDIR)@prefix@ -exec_prefix = $(DESTDIR)@exec_prefix@ +prefix = @prefix@ +exec_prefix = @exec_prefix@
*** this works very poorly; first, autoconf substitutes ${prefix} for @exec_prefix@ if the user does not provide --exec-prefix on the configure command line, so exec_prefix ends up being "$(DESTDIR)$(DESTDIR)${prefix}", and installation fails
*** second, if the user specifies any of --bindir/--sbindir/etc. on the configure command line, those exact values are substituted into this file, and ${prefix}/${exec_prefix} are not part of the substituted values. this means that DESTDIR=/temp_install will have no effect if, for example, --bindir=/bin was specified on the command line, but the installation should be done to /temp_install/bin
*** changing all the Makefiles to used $(DESTDIR) as a prefix to these autoconf-generated variables solves this problem
bindir = @bindir@
includedir = @includedir@
libdir = @libdir@
@@ -80,10 +80,6 @@
INCLUDES+=-I. -I$(top_srcdir)/include
-ifdef DESTDIR
- INCLUDES+=-I$(DESTDIR)/usr/include -endif
-
** again, this is bad; DESTDIR should not even be supplied@compile time, so I can't see how this is useful
ifneq ("@missingkernel@", "yes")
INCLUDES+=-I$(kerneldir)/include
endif
Only in device-mapper.new: make.tmpl.in~
man/Makefile.in +1 -1
@@ -21,7 +21,7 @@ VPATH = @srcdir@ MANUALS=$(wildcard *.8) -MAN8DIR=${mandir}/man8 +MAN8DIR=$(DESTDIR)${mandir}/man8 include ../make.tmpl
Only in device-mapper.new/man: Makefile.in~
--- snip patch for LVM2 ---
*** same general comments regarding make_tmpl and use of $(DESTDIR) in install targets apply here as well
lib/format1/Makefile.in +2 -2
@@ -24,8 +24,8 @@ install: liblvm2format1.so $(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \ - $(libdir)/liblvm2format1.so.$(LIB_VERSION) - $(LN_S) -f liblvm2format1.so.$(LIB_VERSION) $(libdir)/liblvm2format1.so + $(DESTDIR)$(libdir)/liblvm2format1.so.$(LIB_VERSION) + $(LN_S) -f liblvm2format1.so.$(LIB_VERSION) $(DESTDIR)$(libdir)/liblvm2format1.so .PHONY: install
make.tmpl.in +2 -6
@@ -30,8 +30,8 @@ CFLAGS += @CFLAGS@ # Setup directory variables -prefix = $(DESTDIR)@prefix@ -exec_prefix = $(DESTDIR)@exec_prefix@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ sbindir = @sbindir@
@@ -73,10 +73,6 @@ INCLUDES+=-I. -I$(top_srcdir)/include INC_LNS=$(top_srcdir)/include/.symlinks_created -ifdef DESTDIR - INCLUDES+=-I$(DESTDIR)/usr/include -endif - STRIP= #STRIP=-s
man/Makefile.in +2 -2
@@ -28,8 +28,8 @@ vgconvert.8 vgdisplay.8 vgexport.8 vgextend.8 vgimport.8 \ vgmerge.8 vgmknodes.8 vgreduce.8 vgremove.8 vgrename.8 \ vgs.8 vgscan.8 vgsplit.8 -MAN5DIR=${mandir}/man5 -MAN8DIR=${mandir}/man8 +MAN5DIR=$(DESTDIR)${mandir}/man5 +MAN8DIR=$(DESTDIR)${mandir}/man8 include ../make.tmpl
tools/Makefile.in +4 -4
@@ -79,7 +79,7 @@ lvm: $(OBJECTS) $(top_srcdir)/lib/liblvm.a $(CC) -o lvm $(OBJECTS) $(LD_FLAGS) -L$(top_srcdir)/lib \ - -L$(DESTDIR)/lib $(LVMLIBS) $(LIBS) + $(LVMLIBS) $(LIBS) .commands: commands.h cmdnames.h Makefile $(CC) -E -P cmdnames.h 2> /dev/null | \
@@ -87,11 +87,11 @@ install: $(TARGETS) $(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) lvm \ - $(sbindir)/lvm - @echo Creating symbolic links for individual commands in $(sbindir) + $(DESTDIR)$(sbindir)/lvm + @echo Creating symbolic links for individual commands in $(DESTDIR)$(sbindir) @( \ for v in `cat .commands`; do \ - cd $(sbindir); \ + cd $(DESTDIR)$(sbindir); \ $(LN_S) -f lvm $$v; \ done; \ )
Quoted 2 lines · Kevin P. Fleming
device-mapper and LVM2 Makefiles a little more useful, and to fix a number of problems with the current DESTDIR handling.
Thanks for the tidying: I'll work through this properly late next week. (Office moves today.) Quick comments: I'd prefer not to see DESTDIR in Makefiles though: only in the template, and some (I thought most?) people *do* want to pick up some include files etc. from their DESTDIR (they're not installed on their main system, or the ones on their system are different versions from the ones in DESTDIR which has the correct environment the software uses when it runs): perhaps that should be split into a separate configuration option (enabled by default)?
Alasdair
Quoted 5 lines · Alasdair G Kergon
Thanks for the tidying: I'll work through this properly late next week. (Office moves today.) Quick comments: I'd prefer not to see DESTDIR in Makefiles though: only in the template, and some (I thought most?) people *do* want to pick up some include files etc. from their DESTDIR (they're not installed on their main system, or the ones on their system are different
versions from the ones in DESTDIR which has the correct environment the
software uses when it runs): perhaps that should be split into a separate
configuration option (enabled by default)?
To keep DESTDIR only in the template, you'll have to replace the
bindir = @bindir@
lines (and similar) in make.tmpl with
bindir = $(DESTDIR)@bindir@
to avoid the problem of @bindir@ not including ${prefix}. Just don't bother putting $(DESTDIR) into prefix/exec_prefix at all, IMHO.
I can't speak to what everyone else does with DESTDIR, but most packaging systems point DESTDIR to an _empty_ subtree to do the install into, so they can package up all the resulting files. If someone wanted to build LVM2 on a system that had device-mapper _only_ installed into DESTDIR (i.e. /usr/lib did not contain libdevmapper.so, /usr/include did not contain libdevmapper.h, etc.) this would take a lot more work than what was already in the Makefiles, and even then it would tend to break because /usr/sbin/lvm would end up linked to
/foo/usr/lib/libdevmapper.so
instead of
/usr/lib/libdevmapper.so
and so /usr/sbin/lvm wouldn't run properly once the DESTDIR directory was used as a real environment.
So just to be completely redundant <G>, I'll reiterate the way I've always seen DESTDIR used: it's used _only_ at "make install" time to redirect the installation to a different path than the package was compiled to run from.
Quoted 4 lines · Kevin P. Fleming
To keep DESTDIR only in the template, you'll have to replace the bindir = @bindir@
lines (and similar) in make.tmpl with
bindir = $(DESTDIR)@bindir@
Yes.
Quoted 7 lines
what was already in the Makefiles, and even then it would tend to break because
/usr/sbin/lvmwould end up linked to /foo/usr/lib/libdevmapper.so
instead of/usr/lib/libdevmapper.so
and so/usr/sbin/lvmwouldn't run properly once the DESTDIR directory was used as a real environment.
If this was Solaris, yes, we'd need -R to set the default run-time library path. But AFAIK linux only searches LD_LIBRARY_PATH, ld.so.cache and /usr/lib:/lib.
I still think it's wrong to use the version of any include file found on the host system if there is a different version of it present in DESTDIR. [That copes fine for people installing into an empty directory, and AFAICT also caters for people building multiple packages with dependencies.]
Alasdair
Signature · 1 line
[email protected]
Quoted 3 lines · Alasdair G Kergon
I still think it's wrong to use the version of any include file found on the host system if there is a different version of it present in DESTDIR. [That copes fine for people installing into an empty directory, and AFAICT also caters for people building multiple packages with dependencies.]
OK, no problem, that wasn't a big deal for me. The most important parts of my patch you've already accepted :-)