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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list