Import two test scripts from libvirt code which validate that
all symbols in libvirt-glib symbol files exist in the ELF binary, and also
validate the alphabetical sorting. These are hooked up to run with 'make
check'.
This commit is based on a libosinfo patch from Daniel P. Berrange
---
Makefile.am | 2 +
build-aux/check-symfile.pl | 70 +++++++++++++++++++++++++++++
build-aux/check-symsorting.pl | 100 ++++++++++++++++++++++++++++++++++++++++++
configure.ac | 8 ++++
libvirt-gconfig/Makefile.am | 15 +++++++
libvirt-glib/Makefile.am | 15 +++++++
libvirt-gobject/Makefile.am | 15 +++++++
7 files changed, 225 insertions(+)
create mode 100755 build-aux/check-symfile.pl
create mode 100755 build-aux/check-symsorting.pl
diff --git a/Makefile.am b/Makefile.am
index 9101fdb..9b03676 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -14,6 +14,8 @@ EXTRA_DIST = $(PACKAGE).spec \
maint.mk \
cfg.mk \
AUTHORS.in \
+ build-aux/check-symfile.pl \
+ build-aux/check-symsorting.pl \
$(NULL)
DISTCLEAN_FILES = $(PACKAGE).spec $(pkgconfig_DATA)
diff --git a/build-aux/check-symfile.pl b/build-aux/check-symfile.pl
new file mode 100755
index 0000000..d59a213
--- /dev/null
+++ b/build-aux/check-symfile.pl
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2012-2013 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see
+# <
http://www.gnu.org/licenses/>.
+
+die "syntax: $0 SYMFILE ELFLIB(S)" unless int(@ARGV) >= 2;
+
+my $symfile = shift @ARGV;
+my @elflibs = @ARGV;
+
+my %wantsyms;
+my %gotsyms;
+
+my $ret = 0;
+
+open SYMFILE, $symfile or die "cannot read $symfile: $!";
+
+while (<SYMFILE>) {
+ next if /{/;
+ next if /}/;
+ next if /global:/;
+ next if /local:/;
+ next if /^\s*$/;
+ next if /^\s*#/;
+ next if /\*/;
+
+ die "malformed line $_" unless /^\s*(\S+);$/;
+
+ if (exists $wantsyms{$1}) {
+ print STDERR "Symbol $1 is listed twice\n";
+ $ret = 1;
+ } else {
+ $wantsyms{$1} = 1;
+ }
+}
+close SYMFILE;
+
+foreach my $elflib (@elflibs) {
+ open NM, "-|", "nm", $elflib or die "cannot run 'nm
$elflib': $!";
+
+ while (<NM>) {
+ next unless /^\S+\s(?:[TBD])\s(\S+)\s*$/;
+
+ $gotsyms{$1} = 1;
+ }
+
+ close NM;
+}
+
+foreach my $sym (keys(%wantsyms)) {
+ next if exists $gotsyms{$sym};
+
+ print STDERR "Expected symbol $sym is not in ELF library\n";
+ $ret = 1;
+}
+
+exit($ret);
diff --git a/build-aux/check-symsorting.pl b/build-aux/check-symsorting.pl
new file mode 100755
index 0000000..470247c
--- /dev/null
+++ b/build-aux/check-symsorting.pl
@@ -0,0 +1,100 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2012-2013 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library 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
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see
+# <
http://www.gnu.org/licenses/>.
+
+use strict;
+use warnings;
+
+die "syntax: $0 SRCDIR SYMFILE..." unless int(@ARGV) >= 2;
+
+my $ret = 0;
+my $srcdir = shift;
+my $incomment = 0;
+my $name;
+foreach my $symfile (@ARGV) {
+ open SYMFILE, $symfile or die "cannot read $symfile: $!";
+
+ my $line = 0;
+ my @group;
+
+ while (<SYMFILE>) {
+ chomp;
+
+ if ($incomment) {
+ if (m,\*/,) {
+ $incomment = 0;
+ } else {
+ # skip
+ }
+ } else {
+ if (m,/\*,) {
+ $incomment = 1;
+ } elsif (/^(.*)\s*{\s*$/) {
+ @group = ();
+ $line = $.;
+ $name = $1;
+ } elsif (/^\s*}(.*);$/) {
+ &check_sorting(\@group, $symfile, $line, $name);
+ } elsif (/^\s*(global|local):/) {
+ # skip
+ } elsif (/^\s*\*;\s*$/) {
+ # skip
+ } elsif (/^\s*$/) {
+ # skip
+ } else {
+ $_ =~ s/;//;
+ push @group, $_;
+ }
+ }
+ }
+
+ close SYMFILE;
+}
+
+sub check_sorting {
+ my $group = shift;
+ my $symfile = shift;
+ my $line = shift;
+ my $name = shift;
+
+ my @group = @{$group};
+ my @sorted = sort { lc $a cmp lc $b } @group;
+ my $sorted = 1;
+ my $first;
+ my $last;
+
+ # Check that symbols within a group are in order
+ for (my $i = 0 ; $i <= $#sorted ; $i++) {
+ if ($sorted[$i] ne $group[$i]) {
+ $first = $i unless defined $first;
+ $last = $i;
+ $sorted = 0;
+ }
+ }
+ if (!$sorted) {
+ @group = splice @group, $first, ($last-$first+1);
+ @sorted = splice @sorted, $first, ($last-$first+1);
+ print "Symbol block $name at $symfile:$line: symbols not sorted\n";
+ print map { " " . $_ . "\n" } @group;
+ print "Correct ordering\n";
+ print map { " " . $_ . "\n" } @sorted;
+ print "\n";
+ $ret = 1;
+ }
+}
+
+exit $ret;
diff --git a/configure.ac b/configure.ac
index 9b5d09c..81e0d4a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -232,6 +232,14 @@ AC_SUBST([PYTHON_VERSION])
AC_SUBST([PYTHON_INCLUDES])
AC_SUBST([PYTHON_SITE_PACKAGES])
+
+with_linux=no
+case $host in
+ *-*-linux*) with_linux=yes ;;
+esac
+AM_CONDITIONAL([WITH_LINUX], [test "$with_linux" = "yes"])
+
+
AC_ARG_ENABLE([introspection],
AS_HELP_STRING([--enable-introspection], [enable GObject introspection]),
[], [enable_introspection=check])
diff --git a/libvirt-gconfig/Makefile.am b/libvirt-gconfig/Makefile.am
index 7550afe..d11493b 100644
--- a/libvirt-gconfig/Makefile.am
+++ b/libvirt-gconfig/Makefile.am
@@ -215,6 +215,21 @@ libvirt-gconfig-enum-types.c: $(GCONFIG_HEADER_FILES)
libvirt-gconfig-enum-types
$(AM_V_GEN) ( $(GLIB_MKENUMS) --template $(srcdir)/libvirt-gconfig-enum-types.c.template
$(GCONFIG_HEADER_FILES:%=$(srcdir)/%) ) | \
sed -e "s/G_TYPE_VIR_CONFIG/GVIR_CONFIG_TYPE/" -e
"s/g_vir/gvir/" > libvirt-gconfig-enum-types.c
+# .libs/libvirt-gconfig.so is built by libtool as a side-effect of the Makefile
+# rule for libosvirt-gconfig.la. However, checking symbols relies on Linux ELF layout
+if WITH_LINUX
+check-symfile: libvirt-gconfig.sym libvirt-gconfig-1.0.la
+ $(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symfile.pl libvirt-gconfig.sym \
+ .libs/libvirt-gconfig-1.0.so
+else ! WITH_LINUX
+check-symfile:
+endif ! WITH_LINUX
+check-symsorting:
+ $(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symsorting.pl \
+ $(srcdir) libvirt-gconfig.sym
+check-local: check-symfile check-symsorting
+
+
if WITH_GOBJECT_INTROSPECTION
LibvirtGConfig-1.0.gir: libvirt-gconfig-1.0.la $(G_IR_SCANNER) Makefile.am
diff --git a/libvirt-glib/Makefile.am b/libvirt-glib/Makefile.am
index 1370ebc..c7b8123 100644
--- a/libvirt-glib/Makefile.am
+++ b/libvirt-glib/Makefile.am
@@ -37,6 +37,21 @@ libvirt_glib_1_0_la_LDFLAGS = \
-Wl,--version-script=$(srcdir)/libvirt-glib.sym \
-version-info $(LIBVIRT_GLIB_VERSION_INFO)
+# .libs/libvirt-glib.so is built by libtool as a side-effect of the Makefile
+# rule for libosvirt-glib.la. However, checking symbols relies on Linux ELF layout
+if WITH_LINUX
+check-symfile: libvirt-glib.sym libvirt-glib-1.0.la
+ $(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symfile.pl libvirt-glib.sym \
+ .libs/libvirt-glib-1.0.so
+else ! WITH_LINUX
+check-symfile:
+endif ! WITH_LINUX
+check-symsorting:
+ $(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symsorting.pl \
+ $(srcdir) libvirt-glib.sym
+check-local: check-symfile check-symsorting
+
+
if WITH_GOBJECT_INTROSPECTION
LibvirtGLib-1.0.gir: libvirt-glib-1.0.la $(G_IR_SCANNER) Makefile.am
diff --git a/libvirt-gobject/Makefile.am b/libvirt-gobject/Makefile.am
index 3284b2c..0cc11e7 100644
--- a/libvirt-gobject/Makefile.am
+++ b/libvirt-gobject/Makefile.am
@@ -119,6 +119,21 @@ BUILT_SOURCES = $(GOBJECT_GENERATED_FILES)
CLEANFILES = $(BUILT_SOURCES)
+# .libs/libvirt-gobject.so is built by libtool as a side-effect of the Makefile
+# rule for libosvirt-gobject.la. However, checking symbols relies on Linux ELF layout
+if WITH_LINUX
+check-symfile: libvirt-gobject.sym libvirt-gobject-1.0.la
+ $(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symfile.pl libvirt-gobject.sym \
+ .libs/libvirt-gobject-1.0.so
+else ! WITH_LINUX
+check-symfile:
+endif ! WITH_LINUX
+check-symsorting:
+ $(AM_V_GEN)$(PERL) $(top_srcdir)/build-aux/check-symsorting.pl \
+ $(srcdir) libvirt-gobject.sym
+check-local: check-symfile check-symsorting
+
+
if WITH_GOBJECT_INTROSPECTION
LibvirtGObject-1.0.gir: libvirt-gobject-1.0.la $(G_IR_SCANNER) Makefile.am
--
1.8.4.2