Include statically linked binaries in the binary distribution.
authorRichard Jones <rjones@redhat.com>
Wed, 25 Aug 2010 10:53:00 +0000 (11:53 +0100)
committerRichard Jones <rjones@redhat.com>
Wed, 25 Aug 2010 16:22:54 +0000 (17:22 +0100)
.gitignore
Makefile.am
fish/Makefile.am
fuse/Makefile.am
relink-static.sh [new file with mode: 0755]
test-tool/Makefile.am

index 094acb3..9e13363 100644 (file)
@@ -60,10 +60,12 @@ examples/to-xml
 fish/cmds.c
 fish/completion.c
 fish/guestfish
+fish/guestfish.static
 fish/rc_protocol.c
 fish/rc_protocol.h
 fuse/guestmount
 fuse/guestmount.1
+fuse/guestmount.static
 guestfish.1
 guestfish-actions.pod
 guestfs.3
@@ -225,8 +227,9 @@ src/.pod2text.data
 src/stamp-generator
 stamp-h1
 test1.img
-test-tool/libguestfs-test-tool.1
 test-tool/libguestfs-test-tool
+test-tool/libguestfs-test-tool.1
+test-tool/libguestfs-test-tool.static
 test-tool/libguestfs-test-tool-helper
 tools/test.img
 tools/virt-*.1
index 55e3ed1..a33c91c 100644 (file)
@@ -209,9 +209,14 @@ quickcheck:
        test-tool/libguestfs-test-tool \
          --helper test-tool/libguestfs-test-tool-helper
 
-# Binary distribution.
-# Note we remove the supermin appliance and adjust some
-# directories to make them non-Fedora-specific.
+# Mostly static binary distribution.
+#
+# Some binaries are relinked partially statically.  You can make these
+# binaries "more static" by making sure that as many foo-static
+# packages are installed as possible.
+#
+# We remove the supermin appliance and adjust some directories to make
+# them non-Fedora-specific.
 
 BINTMPDIR = /tmp/libguestfs-bin
 bindist:
@@ -219,10 +224,16 @@ bindist:
        mkdir $(BINTMPDIR)
        $(MAKE)
        $(MAKE) DESTDIR=$(BINTMPDIR) install
-       rm -r $(BINTMPDIR)/$(libdir)/guestfs/supermin.d
-       rm $(BINTMPDIR)/$(libdir)/guestfs/kmod.whitelist
-       mv $(BINTMPDIR)/$(prefix)/lib64/* $(BINTMPDIR)/$(libdir)
-       mv $(BINTMPDIR)/usr/lib64/* $(BINTMPDIR)/$(libdir)
+       rm -r $(BINTMPDIR)$(libdir)/guestfs/supermin.d
+       rm $(BINTMPDIR)$(libdir)/guestfs/kmod.whitelist
+       mv $(BINTMPDIR)$(prefix)/lib64/* $(BINTMPDIR)$(libdir)
+       mv $(BINTMPDIR)/usr/lib64/* $(BINTMPDIR)$(libdir)
        -find $(BINTMPDIR) -type d -exec rmdir --ignore-fail-on-non-empty {} \;
-       (cd $(BINTMPDIR) && tar zcf - .) \
-         > libguestfs-$(VERSION)-$(host_cpu).tar.gz
+       $(MAKE) -C fish guestfish.static
+       cp fish/guestfish.static $(BINTMPDIR)$(bindir)/guestfish
+       $(MAKE) -C fuse guestmount.static
+       cp fuse/guestmount.static $(BINTMPDIR)$(bindir)/guestmount
+       $(MAKE) -C test-tool libguestfs-test-tool.static
+       cp test-tool/libguestfs-test-tool.static $(BINTMPDIR)$(bindir)/libguestfs-test-tool
+       (cd $(BINTMPDIR) && tar cf - .) | \
+         gzip -c -9 > libguestfs-$(VERSION)-$(host_cpu).tar.gz
index 9bc5b73..4060f1f 100644 (file)
@@ -92,6 +92,12 @@ rc_protocol.h: rc_protocol.x
        mv $@-t $@
 endif
 
+# Build a partly-static library (for the binary distribution).
+
+guestfish.static$(EXEEXT): $(guestfish_OBJECTS) $(guestfish_DEPENDENCIES)
+       $(top_srcdir)/relink-static.sh \
+       $(guestfish_LINK) $(guestfish_OBJECTS) -static $(guestfish_LDADD) $(guestfish_LIBS) -lpcre -lhivex -lmagic -lz -lm
+
 # Manual page.
 # guestfish-actions.pod is autogenerated.  There is no include
 # mechanism for POD, so we have to do it by hand.
index 1bfc375..db0e418 100644 (file)
@@ -42,6 +42,12 @@ guestmount_LDADD = \
        $(top_builddir)/src/libguestfs.la \
        ../gnulib/lib/libgnu.la
 
+# Build a partly-static library (for the binary distribution).
+
+guestmount.static$(EXEEXT): $(guestmount_OBJECTS) $(guestmount_DEPENDENCIES)
+       $(top_srcdir)/relink-static.sh \
+       $(guestmount_LINK) $(guestmount_OBJECTS) -static $(guestmount_LDADD) $(guestmount_LIBS) -lpcre -lhivex -lmagic -lz
+
 # Documentation.
 
 man_MANS = guestmount.1
diff --git a/relink-static.sh b/relink-static.sh
new file mode 100755 (executable)
index 0000000..9dd5a22
--- /dev/null
@@ -0,0 +1,75 @@
+#!/bin/bash -
+# Copyright (C) 2010 Red Hat Inc.
+#
+# 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, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# Written by Richard W.M. Jones <rjones@redhat.com>
+#
+# Take a dynamically linked ELF binary and relink it, maximizing the
+# use of static libraries.
+#
+# Example:
+#   binary foo
+#            ---> dynamically links to libbar.so.0
+#            ---> dynamically links to libzab.so.3
+# If libbar.a is available, but there is no libzab.a, then we would
+# end up with:
+#   binary foo.static with libbar.a statically inside it
+#            ---> still dynamically linking with libzab.so.3
+#
+# We need to have access to the original link command.  This script
+# works by post-processing it to find the '-lbar' arguments, which are
+# replaced sometimes by direct static library names.
+#
+# Therefore to use this, you have to add this rule to your
+# Makefile.am:
+#
+# foo.static$(EXEEXT): $(foo_OBJECTS) $(foo_DEPENDENCIES)
+#   relink-static.sh \
+#   $(foo_LINK) $(foo_OBJECTS) -static $(foo_LDADD) $(foo_LIBS)
+
+declare -a args
+
+i=0
+for arg; do
+    case "$arg" in
+    -l*)    # get just the library name (eg. "xml2")
+            lib=${arg:2}
+            # does a static version exist?
+            for d in /usr/local/lib{64,} /usr/lib{64,} /lib{64,}; do
+                path="$d/lib$lib.a"
+                if [ -f "$path" ]; then
+                    arg="$path"
+                    break
+                fi
+            done
+            ;;
+    *.la)   # hack around libtool mess
+            d=$(dirname "$arg")
+            b=$(basename "$arg")
+            b=${b:0:${#b}-3}
+            if [ -f "$d/.libs/$b.a" ]; then
+                arg="$d/.libs/$b.a"
+            fi
+            ;;
+    *) ;;
+    esac
+    args[$i]="$arg"
+    i=$(($i+1))
+done
+
+# Run the final command.
+echo "${args[@]}"
+"${args[@]}"
index 66d06e0..0f03088 100644 (file)
@@ -39,6 +39,12 @@ libguestfs_test_tool_LDADD = \
 libguestfs_test_tool_helper_SOURCES = helper.c
 libguestfs_test_tool_helper_LDFLAGS = -all-static
 
+# Build a partly-static library (for the binary distribution).
+
+libguestfs-test-tool.static$(EXEEXT): $(libguestfs_test_tool_OBJECTS) $(libguestfs_test_tool_DEPENDENCIES)
+       $(top_srcdir)/relink-static.sh \
+       $(libguestfs_test_tool_LINK) $(libguestfs_test_tool_OBJECTS) -static $(libguestfs_test_tool_LDADD) $(libguestfs_test_tool_LIBS) -lpcre -lhivex -lmagic -lz
+
 libguestfs-test-tool.1: libguestfs-test-tool.pod
        $(POD2MAN) \
          --section 1 \