From a0d514f13d3334b79745d7d1f90a6ac615afa7c2 Mon Sep 17 00:00:00 2001 From: Richard Jones Date: Wed, 25 Aug 2010 11:53:00 +0100 Subject: [PATCH] Include statically linked binaries in the binary distribution. --- .gitignore | 5 +++- Makefile.am | 29 +++++++++++++------- fish/Makefile.am | 6 +++++ fuse/Makefile.am | 6 +++++ relink-static.sh | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++ test-tool/Makefile.am | 6 +++++ 6 files changed, 117 insertions(+), 10 deletions(-) create mode 100755 relink-static.sh diff --git a/.gitignore b/.gitignore index 094acb3..9e13363 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/Makefile.am b/Makefile.am index 55e3ed1..a33c91c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -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 diff --git a/fish/Makefile.am b/fish/Makefile.am index 9bc5b73..4060f1f 100644 --- a/fish/Makefile.am +++ b/fish/Makefile.am @@ -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. diff --git a/fuse/Makefile.am b/fuse/Makefile.am index 1bfc375..db0e418 100644 --- a/fuse/Makefile.am +++ b/fuse/Makefile.am @@ -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 index 0000000..9dd5a22 --- /dev/null +++ b/relink-static.sh @@ -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 +# +# 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[@]}" diff --git a/test-tool/Makefile.am b/test-tool/Makefile.am index 66d06e0..0f03088 100644 --- a/test-tool/Makefile.am +++ b/test-tool/Makefile.am @@ -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 \ -- 1.8.3.1