Explorar o código

Merge branch 'master' of ssh://git.debian.org/git/dpkg/dpkg

Conflicts:

	man/po/pl.po
Robert Luberda %!s(int64=19) %!d(string=hai) anos
pai
achega
3dc3d8e800
Modificáronse 51 ficheiros con 10192 adicións e 2038 borrados
  1. 56 0
      ChangeLog
  2. 1 1
      configure.ac
  3. 54 2
      debian/changelog
  4. 1 0
      debian/control
  5. 10 0
      debian/dpkg-dev.install
  6. 19 0
      man/ChangeLog
  7. 2 0
      man/Makefile.am
  8. 8 1
      man/deb-control.5
  9. 52 0
      man/deb-symbols.5
  10. 3 2
      man/dpkg-buildpackage.1
  11. 164 0
      man/dpkg-gensymbols.1
  12. 120 22
      man/dpkg-shlibdeps.1
  13. 409 287
      man/po/de.po
  14. 237 140
      man/po/dpkg-man.pot
  15. 286 168
      man/po/es.po
  16. 297 170
      man/po/fr.po
  17. 254 153
      man/po/hu.po
  18. 255 153
      man/po/ja.po
  19. 117 81
      man/po/pl.po
  20. 252 157
      man/po/pt_BR.po
  21. 253 152
      man/po/ru.po
  22. 301 176
      man/po/sv.po
  23. 50 0
      scripts/Dpkg/ErrorHandling.pm
  24. 82 0
      scripts/Dpkg/Path.pm
  25. 92 0
      scripts/Dpkg/Shlibs.pm
  26. 339 0
      scripts/Dpkg/Shlibs/Objdump.pm
  27. 326 0
      scripts/Dpkg/Shlibs/SymbolFile.pm
  28. 205 0
      scripts/Dpkg/Version.pm
  29. 37 1
      scripts/Makefile.am
  30. 7 4
      scripts/controllib.pl
  31. 17 6
      scripts/dpkg-buildpackage.pl
  32. 3 2
      scripts/dpkg-gencontrol.pl
  33. 240 0
      scripts/dpkg-gensymbols.pl
  34. 391 358
      scripts/dpkg-shlibdeps.pl
  35. 1 1
      scripts/dpkg-source.pl
  36. 6 1
      scripts/po/POTFILES.in
  37. 11 0
      scripts/t/000_pod.t
  38. 80 0
      scripts/t/100_Dpkg_Version.t
  39. 148 0
      scripts/t/200_Dpkg_Shlibs.t
  40. 9 0
      scripts/t/200_Dpkg_Shlibs/ld.so.conf
  41. 1 0
      scripts/t/200_Dpkg_Shlibs/ld.so.conf.d/inf_recurse.conf
  42. 1 0
      scripts/t/200_Dpkg_Shlibs/ld.so.conf.d/normal.conf
  43. 1 0
      scripts/t/200_Dpkg_Shlibs/ld.so.conf.d/recursive.conf
  44. 1 0
      scripts/t/200_Dpkg_Shlibs/ld.so.conf_2
  45. 350 0
      scripts/t/200_Dpkg_Shlibs/objdump.glib-ia64
  46. 2276 0
      scripts/t/200_Dpkg_Shlibs/objdump.libc6-2.3
  47. 2345 0
      scripts/t/200_Dpkg_Shlibs/objdump.libc6-2.6
  48. 4 0
      scripts/t/200_Dpkg_Shlibs/symbols.fake-1
  49. 8 0
      scripts/t/200_Dpkg_Shlibs/symbols.fake-2
  50. 7 0
      scripts/t/200_Dpkg_Shlibs/symbols.include-1
  51. 3 0
      scripts/t/200_Dpkg_Shlibs/symbols.include-2

+ 56 - 0
ChangeLog

@@ -1,3 +1,59 @@
+2007-10-08  Raphael Hertzog  <hertzog@debian.org>,
+	    Frank Lichtenheld <djpig@debian.org>
+
+	* Merge dpkg-shlibdeps-buxy branch.
+
+	* scripts/dpkg-shlibdeps.pl: heavily reworked to support "symbols"
+	files. Lots of the code has been modularized in perl modules
+	Dpkg::Shlibs::*.
+
+	* scripts/dpkg-gensymbols.pl: new script used to generated symbols
+	files at package build time. It shall be used by packages of libraries.
+
+	* man/dpkg-{shlibdeps,gensymbols}.1: updated and created manual
+	pages documenting the changes above.
+
+	* scripts/t/*: Added some non-regression test on many parts of the
+	newly introduced perl modules.
+
+2007-10-08  Guillem Jover  <guillem@debian.org>
+
+	* configure.ac: Bump version to 1.14.8~.
+
+2007-10-08  Guillem Jover  <guillem@debian.org>
+
+	* configure.ac: Release 1.14.7.
+
+2007-10-08  Guillem Jover  <guillem@debian.org>
+
+	* scripts/dpkg-source.pl: Do not replace substvars for build
+	dependencies.
+
+2007-10-08  Guillem Jover  <guillem@debian.org>
+
+	* scripts/dpkg-gencontrol.pl: Refer to host architecture (instead of
+	build) in error string, and quote architecture name.
+
+2007-10-08  Frank Lichtenheld  <djpig@debian.org>,
+            Guillem Jover  <guillem@debian.org>
+
+	* scripts/controllib.pl (debarch_is): Check if $alias is equal to
+	$real or 'any' before mapping them to debtriplets.
+	(debarch_to_debtriplet): Do not special case 'any' nor 'all'.
+	(debarch_eq): Check if $a and $b are equal before mapping them to
+	debtriplets.
+
+2007-10-07  Guillem Jover  <guillem@debian.org>
+
+	* scripts/dpkg-buildpackage.pl: Warn if run as root and $rootcommand
+	has been specified. Error if run as non-root and $rootcommand is not
+	found.
+
+2007-10-07  Guillem Jover  <guillem@debian.org>
+
+	* scripts/dpkg-buildpackage.pl (usage): Remove details about running
+	fakeroot only if it's available.
+
 2007-10-07  Frank Lichtenheld  <djpig@debian.org>
 	    Marcel Toele  <mtoele@kern.nl>
 

+ 1 - 1
configure.ac

@@ -1,7 +1,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.59)
-AC_INIT([dpkg], [1.14.7~], [debian-dpkg@lists.debian.org])
+AC_INIT([dpkg], [1.14.8~], [debian-dpkg@lists.debian.org])
 AC_CONFIG_SRCDIR([lib/dpkg.h])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_AUX_DIR([config])

+ 54 - 2
debian/changelog

@@ -1,4 +1,49 @@
-dpkg (1.14.7) UNRELEASED; urgency=low
+dpkg (1.14.8) UNRELEASED; urgency=low
+
+  [ Raphael Hertzog ]
+  * Merge dpkg-shlibdeps-buxy branch, dpkg-shlibdeps has been heavily
+    reworked:
+    * it supports "symbols" files to generate finer-grained
+      dependencies. Closes: #430367
+      Those files can be created by the new dpkg-gensymbols
+      command.
+    * it uses now all paths in RPATH (instead of only the first).
+      Closes: #395942
+    * it's now able to parse include directives in /etc/ld.so.conf.
+      Closes: #431597
+    * libraries are also searched in the public directories of packages
+      being built and thus debian/shlibs.local can effectively define
+      dependencies for libraries that are being built. Closes: #80340
+    * "symbols" files use the full SONAME as key instead of splitting it in
+      (name, version) like the "shlibs" format requires it. This allows
+      binaries to be linked with unversioned libraries and not fail.
+      Closes: #48208
+      Note that unversioned libraries are still a very bad idea.
+    * dpkg-shlibdeps now supports "-x<package>" options that can be used
+      to exclude packages from generated dependencies. This is
+      particalularly useful to avoid dependencies on ourselves when a
+      package contains a binary and a library (without requiring an
+      shlibs.local file to override the usual shlibs file). It might also
+      be used to avoid other unwanted dependencies (use with care though).
+      Closes: #41907, #109954
+    * If dpkg-shlibdeps doesn't find any dependency information for a
+      shared library that is actively used, then it will fail. This can be
+      disabled with the option --ignore-missing-info. Closes: #10807
+
+ -- Raphael Hertzog <hertzog@debian.org>  Mon, 08 Oct 2007 20:49:51 +0200
+
+dpkg (1.14.8~newshlib) experimental; urgency=low
+
+  [ Raphael Hertzog ]
+  * Snapshot of upcoming dpkg 1.14.8 with improved dpkg-shlibdeps
+    supporting symbols files.
+
+  [ Updated man pages translations ]
+  * German (Helge Kreutzmann).
+
+ -- Raphael Hertzog <hertzog@debian.org>  Mon, 08 Oct 2007 20:22:57 +0200
+
+dpkg (1.14.7) unstable; urgency=low
 
   [ Guillem Jover ]
   * Add back $dpkglib into @INC, needed by the controllib.pl require in
@@ -15,6 +60,13 @@ dpkg (1.14.7) UNRELEASED; urgency=low
     instead of unconditionally setting it to 'Installed'. Closes: #432893
     Thanks to Brian M. Carlson.
   * Add Vcs-Browser and Vcs-Git fields to debian/control.
+  * Add a Homepage field to debian/control (to be changed later when
+    there's a more formal site).
+  * Allow comparing unsupported architectures for equality and identity.
+    Based on a patch by Frank Lichtenheld. Closes: #427210
+  * Document Origin and Bugs fields in deb-control.5. Closes: #173463
+  * Do not replace substvars for build dependencies (it was not supported
+    anyway).
 
   [ Frank Lichtenheld ]
   * Add _MTN to dpkg-source -i default regex. Suggested by Jari Aalto.
@@ -59,7 +111,7 @@ dpkg (1.14.7) UNRELEASED; urgency=low
   * Correct a typo in the French translation. Closes: #443276
   * Swedish (Peter Karlsson).
 
- -- Frank Lichtenheld <djpig@debian.org>  Sun, 23 Sep 2007 02:40:20 +0200
+ -- Guillem Jover <guillem@debian.org>  Mon, 08 Oct 2007 07:31:34 +0300
 
 dpkg (1.14.6) unstable; urgency=low
 

+ 1 - 0
debian/control

@@ -5,6 +5,7 @@ Maintainer: Dpkg Developers <team@dpkg.org>
 Uploaders: Frank Lichtenheld <djpig@debian.org>, Guillem Jover <guillem@debian.org>, Brendan O'Dea <bod@debian.org>, Christian Perrier <bubulle@debian.org>
 Origin: debian
 Bugs: debbugs://bugs.debian.org
+Homepage: http://wiki.debian.org/Teams/Dpkg
 Vcs-Browser: http://git.debian.org/?p=dpkg/dpkg.git
 Vcs-Git: git://git.debian.org/git/dpkg/dpkg.git
 Standards-Version: 3.7.2

+ 10 - 0
debian/dpkg-dev.install

@@ -8,6 +8,7 @@ usr/bin/dpkg-checkbuilddeps
 usr/bin/dpkg-distaddfile
 usr/bin/dpkg-genchanges
 usr/bin/dpkg-gencontrol
+usr/bin/dpkg-gensymbols
 usr/bin/dpkg-name
 usr/bin/dpkg-parsechangelog
 usr/bin/dpkg-scanpackages
@@ -16,6 +17,11 @@ usr/bin/dpkg-shlibdeps
 usr/bin/dpkg-source
 usr/lib/dpkg/controllib.pl
 usr/lib/dpkg/parsechangelog
+usr/share/perl5/Dpkg/Path.pm
+usr/share/perl5/Dpkg/Version.pm
+usr/share/perl5/Dpkg/ErrorHandling.pm
+usr/share/perl5/Dpkg/Shlibs.pm
+usr/share/perl5/Dpkg/Shlibs
 usr/share/locale/*/LC_MESSAGES/dpkg-dev.mo
 usr/share/man/*/*/822-date.1
 usr/share/man/*/822-date.1
@@ -27,6 +33,8 @@ usr/share/man/*/*/deb-override.5
 usr/share/man/*/deb-override.5
 usr/share/man/*/*/deb-shlibs.5
 usr/share/man/*/deb-shlibs.5
+usr/share/man/*/*/deb-symbols.5
+usr/share/man/*/deb-symbols.5
 usr/share/man/*/*/deb-old.5
 usr/share/man/*/deb-old.5
 usr/share/man/*/*/deb.5
@@ -43,6 +51,8 @@ usr/share/man/*/*/dpkg-genchanges.1
 usr/share/man/*/dpkg-genchanges.1
 usr/share/man/*/*/dpkg-gencontrol.1
 usr/share/man/*/dpkg-gencontrol.1
+usr/share/man/*/*/dpkg-gensymbols.1
+usr/share/man/*/dpkg-gensymbols.1
 usr/share/man/*/*/dpkg-name.1
 usr/share/man/*/dpkg-name.1
 usr/share/man/*/*/dpkg-parsechangelog.1

+ 19 - 0
man/ChangeLog

@@ -1,3 +1,22 @@
+2007-10-08  Helge Kreutzmann  <debian@helgefjell.de>
+
+	* po/de.po: Updated to 1249t0f54u.
+	* Removed the FIXMEs left in de.po by accident
+
+2007-10-08  Guillem Jover  <guillem@debian.org>
+
+	* po/dpkg-man.pot: Regenerated.
+	* po/*.po: Merged with dpkg-man.pot.
+
+2007-10-08  Guillem Jover  <guillem@debian.org>
+
+	* deb-control.5: Document Origin and Bugs fields.
+
+2007-10-07  Guillem Jover  <guillem@debian.org>
+
+	* dpkg-buildpackage.1: Document that fakeroot is now the default
+	value in case -r is not specified.
+
 2007-10-07  Helge Kreutzmann  <debian@helgefjell.de>
 
 	* po/de.po: Updated to 1238t0f52u.

+ 2 - 0
man/Makefile.am

@@ -53,6 +53,7 @@ dist_man_MANS = \
 	deb-control.5 \
 	deb-shlibs.5 \
 	deb-substvars.5 \
+	deb-symbols.5 \
 	deb-old.5 \
 	deb-override.5 \
 	deb.5 \
@@ -64,6 +65,7 @@ dist_man_MANS = \
 	dpkg-divert.8 \
 	dpkg-genchanges.1 \
 	dpkg-gencontrol.1 \
+	dpkg-gensymbols.1 \
 	dpkg-name.1 \
 	dpkg-parsechangelog.1 \
 	dpkg-query.1 \

+ 8 - 1
man/deb-control.5

@@ -1,6 +1,6 @@
 .\" Author: Raul Miller
 .\" Includes text from the debian Guidelines by Ian Jackson, Ian Murdock
-.TH deb\-control 5 "2007-08-31" "Debian Project" "Debian"
+.TH deb\-control 5 "2007-10-08" "Debian Project" "Debian"
 .SH NAME
 deb\-control \- Debian packages' master control file format
 .
@@ -84,6 +84,13 @@ etc. Note that the
 option is meant for packages that are architecture independent. Some examples
 of this are shell and Perl scripts, and documentation.
 .TP
+.BR Origin: " <name>"
+The name of the distribution this package is originating from.
+.TP
+.BR Bugs: " <url>"
+The url of the bug tracking system for this package. The current used format
+is \fB<bts_type>://<bts_address>\fP, like \fBdebbugs://bugs.debian.org\fP.
+.TP
 .BR Homepage: " <url>"
 The upstream project home page URL.
 .TP

+ 52 - 0
man/deb-symbols.5

@@ -0,0 +1,52 @@
+.\" Author: Raphael Hertzog
+.TH deb\-symbols 5 "2007-07-16" "Debian Project" "dpkg utilities"
+.SH NAME
+deb\-symbols \- Debian's extended shared library information file
+.
+.SH SYNOPSIS
+symbols
+.
+.SH DESCRIPTION
+The format for an extended shared library dependency information entry
+in these files is:
+.PP
+<library soname> <main dependency template>
+.br
+[ | <alternative dependency template> ]
+.br
+[ ... ]
+ <symbol> <mininal version>[ <id of dependency template> ]
+.P
+The \fIlibrary soname\fR is exactly the value of the SONAME field
+as exported by \fBobjdump\fR. A \fIdependency template\fR is a
+dependency where \fI#MINVER#\fR is dynamically replaced either by
+a version check like "(>= \fIminimal version\fR)" or by nothing (if
+an unversionned dependency is deemed sufficient). 
+.P
+Each exported \fIsymbol\fR (listed as \fIname\fR@\fIversion\fR, with
+\fIversion\fR being "Base" if the library is not versioned) is associated
+to a \fIminimal version\fR of its dependency template (the main dependency
+template is used if \fIid of dependency template\fR is not present). The
+first alternative dependency template is numbered 1, the second one 2,
+etc.
+.SH EXAMPLES
+.SS Simple symbols file
+.PP 
+libftp.so.3 libftp3 #MINVER#
+ DefaultNetbuf@Base 3.1-1-6
+ FtpAccess@Base 3.1-1-6
+ [...]
+.SS Advanced symbols file
+.PP 
+libGL.so.1 libgl1
+.br
+| libgl1-mesa-glx #MINVER#
+ publicGlSymbol@Base 6.3-1
+ [...]
+ implementationSpecificSymbol@Base 6.5.2-7 1
+ [...]
+.SH SEE ALSO
+.BR http://wiki.debian.org/Projects/ImprovedDpkgShlibdeps
+.br
+.BR dpkg\-shlibdeps (1),
+.BR dpkg\-gensymbols (1).

+ 3 - 2
man/dpkg-buildpackage.1

@@ -1,4 +1,4 @@
-.TH dpkg\-buildpackage 1 "2007-07-18" "Debian Project" "dpkg utilities"
+.TH dpkg\-buildpackage 1 "2007-09-28" "Debian Project" "dpkg utilities"
 .SH NAME
 dpkg\-buildpackage \- build binary or source packages from sources
 .
@@ -114,7 +114,8 @@ When
 needs to execute part of the build process as root, it prefixes the
 command it executes with
 .I gain-root-command
-if one has been specified.
+if one has been specified. Otherwise, if none has been specified,
+\fBfakeroot\fP will be used by default, if the command is present.
 .I gain-root-command
 should be the name of a program on the
 .B PATH

+ 164 - 0
man/dpkg-gensymbols.1

@@ -0,0 +1,164 @@
+.\" Author: Raphael Hertzog
+.TH dpkg\-gensymbols 1 "2007-07-16" "Debian Project" "dpkg utilities"
+.SH NAME
+dpkg\-gensymbols \- generate symbols files (shared library dependency information)
+.
+.SH SYNOPSIS
+.B dpkg\-gensymbols
+.RI [ options ]
+.
+.SH DESCRIPTION
+.B dpkg\-gensymbols
+scans a temporary build tree (debian/tmp by default) looking for libraries
+and generate a \fIsymbols\fR file describing them. This file, if
+non-empty, is then installed in the DEBIAN subdirectory of the build tree
+so that it ends up included in the control information of the package.
+.P
+When generating those files, it uses as input some symbols files
+provided by the maintainer. It looks for the following files (and use the
+first that is found):
+.IP \(bu 4
+debian/\fIpackage\fR.symbols.\fIarch\fR
+.IP \(bu 4
+debian/symbols.\fIarch\fR
+.IP \(bu 4
+debian/\fIpackage\fR.symbols
+.IP \(bu 4
+debian/symbols
+.P
+The main interest of those files is to provide the minimal version
+associated to each symbol provided by the libraries. Usually it
+corresponds to the first version of that package that provided the symbol,
+but it can be manually incremented by the maintainer if the ABI of the
+symbol is extended without breaking backwards compatibility. It's the
+responsibility of the maintainer to keep those files up-to-date and
+accurate, but \fBdpkg\-gensymbols\fR helps him.
+.P
+When the generated symbols files differ from the maintainer supplied
+one, \fBdpkg\-gensymbols\fR will print a diff between the two versions.
+Furthermore if the difference are too significant, it will even fail (you
+can customize how much difference you can tolerate, see the \fB\-c\fR
+option).
+.SH MAINTAINING SYMBOLS FILES
+The symbols files are really useful only if they reflect the evolution of
+the package through several releases. Thus the maintainer has to update
+them every time that a new symbol is added so that its associated minimal
+version matches reality. To do this properly he can use the diffs contained
+in the build logs. In most cases, the diff can be directly applied to his
+debian/\fIpackage\fR.symbols file.
+.P
+Before applying any patch to the symbols file, the maintainer should
+double-check that it's sane. Public symbols are not supposed to disappear,
+so the patch should ideally only add new lines.
+.SS Using includes
+.P 
+When the set of exported symbols differ between architectures, it's no
+more possible to use a common symbols file. Using one file per
+architecture works, but it can also lead to duplication of information.
+In those cases, you can factorize the common part in some external file
+and include that file in your \fIpackage\fR.symbols.\fIarch\fR file by
+using an include directive like this:
+.PP
+#include "\fIpackages\fR.symbols.common"
+.P
+The symbols files are read line by line, and include directives
+are processed as soon as they are encountered. This means that
+the content of the included file can override any content that appeared
+before the include directive and that any content after the
+directive can override anything contained in the included file.
+.P
+An included file must be a valid symbols file on its own. Thus you have
+to repeat the header line containing the SONAME of the library and the
+dependency template. Remember that those lines might override the header
+defined previously in the main symbols file. Thus the recommended way to
+handle architecture specific information is to put include directives
+directly at the beginning of the symbols file:
+.PP
+#include "libsomething1.symbols.common"
+.br
+libsomething.so.1 libsomething1 #MINVER#
+ arch_specific_symbol@Base 1.0
+.SS Good library management
+.P
+A well-maintained library has the following features:
+.IP \(bu 4
+its API is stable (public symbols are never dropped, only new public
+symbols are added) and changes in incompatible ways only when the SONAME
+changes;
+.IP \(bu 4
+ideally, it uses symbol versioning to achieve ABI stability despite
+internal changes and API extension;
+.IP \(bu 4
+it doesn't export private symbols.
+.P
+While maintaining the symbols file, it's easy to notice appearance and
+disappearance of symbols. But it's more difficult to catch incompatible
+API and ABI change. Thus the maintainer should read thoroughly the
+upstream changelog looking for cases where the rules of good library
+management have been broken. If potential problems are discovered,
+the upstream author should be notified as an upstream fix is always better
+than a Debian specific work-around.
+.SH OPTIONS
+.TP
+.BI \-P package-build-dir
+Scan \fIpackage-build-dir\fR instead of debian/tmp.
+.TP
+.BI \-p package
+Define the package name. Required if more than one binary package is listed in
+debian/control (or if there's no debian/control file).
+.TP
+.BI \-v version
+Define the package version. Defaults to the version extracted from
+debian/changelog. Required if called outside of a source package tree.
+.TP
+.BI \-e library-file
+Only analyze libraries explicitely listed instead of finding all public
+libraries. You can use a regular expression in \fIlibrary-file\fR to match
+multiple libraries with a single argument (otherwise you need multiple
+\fB\-e\fR).
+.TP
+.B \-O
+Print the generated symbols file to standard output, rather than being
+stored in the package build tree.
+.TP 
+.BI \-O filename
+Store the generated symbols file as \fIfilename\fR. If \fIfilename\fR is
+pre-existing, its content is used as basis for the generated symbols file.
+You can use this feature to update a symbols file so that it matches a
+newer upstream version of your library.
+.TP
+.BI \-c [0-4]
+Define the checks to do when comparing the generated symbols file
+with the file used as starting point. By default the level is 1.
+Increasing levels do more checks and include all checks of lower levels.
+Level 0 disables all checks. Level 1 fails if some symbols have
+disappeared. Level 2 fails if some new symbols have been introduced.
+Level 3 fails if some libraries have disappeared. Level 4 fails if some
+libraries have been introduced.
+.TP
+.BI \-d
+Enable debug mode. Numerous messages are displayed to explain what 
+.B dpkg\-gensymbols
+does.
+.TP
+.BR \-h ", " \-\-help
+Show the usage message and exit.
+.TP
+.BR \-\-version
+Show the version and exit.
+.
+.SH "SEE ALSO"
+.BR http://people.redhat.com/drepper/symbol-versioning
+.br
+.BR http://people.redhat.com/drepper/goodpractice.pdf
+.br
+.BR http://people.redhat.com/drepper/dsohowto.pdf
+.br
+.BR deb\-symbols (5),
+.BR dpkg\-shlibdeps (1).
+.
+.SH AUTHORS
+Copyright (C) 2007 Rapha\[:e]l Hertzog
+.sp
+This is free software; see the GNU General Public Licence version 2 or later
+for copying conditions. There is NO WARRANTY.

+ 120 - 22
man/dpkg-shlibdeps.1

@@ -1,4 +1,4 @@
-.TH dpkg\-shlibdeps 1 "2007-06-12" "Debian Project" "dpkg utilities"
+.TH dpkg\-shlibdeps 1 "2007-07-16" "Debian Project" "dpkg utilities"
 .SH NAME
 dpkg\-shlibdeps \- generate shared library substvar dependencies
 .
@@ -21,18 +21,76 @@ where
 is a dependency field name. Any other variables starting
 .I shlibs:
 are removed from the file.
+.P
 .B dpkg\-shlibdeps
-will read shared library dependency information from
-.BR debian/shlibs.local ,
-.BR /etc/dpkg/shlibs.override ,
-the
-.B shlibs
-control area file of the package containing the file which
-.B objdump
-reports as satisfying the library dependency, or
-.BR /etc/dpkg/shlibs.default .
-The first match will be used.
-.
+has two possible sources of information to generate dependency
+information. Either
+.I symbols
+files or
+.I shlibs
+files. For each binary that
+.B dpkg\-shlibdeps
+analyzes, it finds out the list of libraries that it's linked with.
+Then, for each library, it looks up either the 
+.I symbols
+file, or the
+.I shlibs
+file (if the former doesn't exist). Both files are supposed to be provided
+by the library package and should thus be available as
+/var/lib/dpkg/info/\fIpackage\fR.\fIsymbols\fR
+or /var/lib/dpkg/info/\fIpackage\fR.\fIshlibs\fR. The package name is
+identified in two steps: find the library file on the system (looking in
+the same directories that \fBld.so\fR would use), then use
+.BI "dpkg -S " library\-file
+to lookup the package providing the library.
+.SS Symbols files
+Symbols files contain finer-grained dependency information by providing
+the minimum dependency for each symbol that the library exports. The
+script tries to find a symbols file associated to a library package
+in the following places (first match is used):
+.IP debian/*/DEBIAN/symbols
+Shared library information generated by the current build process that also invoked
+.BR dpkg\-shlibdeps .
+They are generated by 
+.BR dpkg\-gensymbols (1).
+.IP /etc/dpkg/symbols/\fIpackage\fR.symbols.\fIarch\fR
+.IP /etc/dpkg/symbols/\fIpackage\fR.symbols
+Per-system overriding shared library dependency information.
+\fIarch\fR is the architecture of the current system (obtained by
+.BR "dpkg-architecture -qDEB_HOST_ARCH" ).
+.IP \fIadmindir\fR/info/\fIpackage\fR.symbols
+Package-provided shared library dependency information.
+Unless overriden, \fIadmindir\fR is /var/lib/dpkg.
+.P 
+While scanning the symbols used by all binaries,
+.B dpkg\-shlibdeps
+remembers the (biggest) minimal version needed for each library. At the end
+of the process, it is able to write out the minimal dependency for every
+library used (provided that the information of the \fIsymbols\fR files are
+accurate).
+.SS Shlibs files
+Shlibs files associate directly a library to a dependency (without looking
+at the symbols). It's thus often stronger than really needed but very safe
+and easy to handle.
+.P
+The dependencies for a library are looked up in several places. The first
+file providing informations for the library of interest is used:  
+.IP debian/shlibs.local
+Package-local overriding shared library dependency information.
+.IP /etc/dpkg/shlibs.override
+Per-system overriding shared library dependency information.
+.IP debian/*/DEBIAN/shlibs
+Shared library information generated by the current build process that also invoked
+.BR dpkg\-shlibdeps .
+.IP \fIadmindir\fR/info/\fIpackage\fR.shlibs
+Package-provided shared library dependency information.
+Unless overriden, \fIadmindir\fR is /var/lib/dpkg.
+.IP /etc/dpkg/shlibs.default
+Per-system default shared library dependency information.
+.P
+The extracted dependencies are then directly used (except if they are
+filtered out because they have been identified as duplicate, or as weaker
+than another dependency).
 .SH OPTIONS
 .B dpkg\-shlibdeps
 interprets non-option arguments as executable names, just as if they'd
@@ -103,6 +161,24 @@ Write substitution variables in
 the default is
 .BR debian/substvars .
 .TP
+.BI \-v
+Enable verbose mode. Numerous messages are displayed to explain what 
+.B dpkg\-shlibdeps
+does.
+.TP
+.BI \-x package
+Exclude the package from the generated dependencies. This is useful to
+avoid self-dependencies for packages which provide ELF binaries
+(executables or library plugins) using a library contained in the same
+package. This option can be used multiple times to exclude several
+packages.
+.TP
+.BI \-\-ignore\-missing\-info
+Do not fail if dependency information can't be found for a shared library.
+Usage of this option is discouraged, all libraries should provide
+dependency information (either with shlibs files, or with symbols files)
+even if they are not yet used by other packages.  
+.TP
 .BI \-\-admindir= dir
 Change the location of the \fBdpkg\fR database. The default location is
 \fI/var/lib/dpkg\fP.
@@ -113,24 +189,46 @@ Show the usage message and exit.
 .BR \-\-version
 Show the version and exit.
 .
-.SH FILES
-.TP
-.B debian/shlibs.local
-Package-local overriding shared library dependency information.
+.SH WARNINGS
+Since
+.B dpkg\-shlibdeps
+analyzes the set of symbols used by each binary of the generated package,
+it is able to emit warnings in several cases. They inform you of things
+that can be improved in the package. In most cases, those improvements
+concern the upstream sources directly. By order of decreasing importance,
+here are the various warnings that you can encounter:
 .TP
-.B /etc/dpkg/shlibs.override
-Per-system overriding shared library dependency information.
+.BI symbol " sym" " used by " binary " found in none of the libraries."
+The indicated symbol has not been found in the libraries linked with the
+binary. The \fIbinary\fR is most likely a library and it needs to be linked
+with an additional library during the build process (option \fB-l\fR\fIlibrary\fR
+of the linker).
 .TP
-.B /etc/dpkg/shlibs.default
-Per-system default shared library dependency information.
-.
+.IB binary " shouldn't be linked with " library " (it uses none of its symbols)."
+The \fIbinary\fR is linked to a library that it doesn't need. It's not a
+problem but some small performance improvements in binary load time
+can be obtained by not linking this library to this binary. 
+
+Furthermore, in some cases, this will lead to a non-versionned dependency
+on the library that could have been avoided if the binary was only linked
+against the library that it really uses. The exception to this rule is
+when several binaries are linked against the same set of libraries but
+each binary only uses a subset of those. You will have warnings on
+individual binaries, but the set of libraries needed at the package level
+is the same whether you fix the binaries or not.
 .SH "SEE ALSO"
-.BR deb\-shlibs (5).
+.BR deb\-shlibs (5),
+.BR deb\-symbols (5),
+.BR dpkg-gensymbols (1).
 .
 .SH AUTHORS
 Copyright (C) 1995-1996 Ian Jackson
 .br
 Copyright (C) 2000 Wichert Akkerman
+.br
+Copyright (C) 2006 Frank Lichtenheld
+.br
+Copyright (C) 2007 Rapha\[:e]l Hertzog
 .sp
 This is free software; see the GNU General Public Licence version 2 or later
 for copying conditions. There is NO WARRANTY.

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 409 - 287
man/po/de.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 237 - 140
man/po/dpkg-man.pot


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 286 - 168
man/po/es.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 297 - 170
man/po/fr.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 254 - 153
man/po/hu.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 255 - 153
man/po/ja.po


+ 117 - 81
man/po/pl.po

@@ -4,7 +4,7 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: dpkg 1.14.6\n"
-"POT-Creation-Date: 2007-09-27 23:05+0200\n"
+"POT-Creation-Date: 2007-10-08 07:26+0300\n"
 "PO-Revision-Date: 2007-10-03 23:01+0200\n"
 "Last-Translator: Robert Luberda <robert@debian.org>\n"
 "Language-Team: Polish <debian-l10n-polish@lists.debian.org>\n"
@@ -179,7 +179,7 @@ msgstr "B<822-date> nie wymaga podania 
 # type: SH
 #: ../../man/822-date.1:24 ../../man/cleanup-info.8:48
 #: ../../man/deb-substvars.5:125 ../../man/dpkg.1:618
-#: ../../man/dpkg-buildpackage.1:190 ../../man/dpkg-deb.1:221
+#: ../../man/dpkg-buildpackage.1:191 ../../man/dpkg-deb.1:221
 #: ../../man/dpkg-name.1:87 ../../man/dpkg-source.1:253
 #: ../../man/dpkg-split.1:200 ../../man/dselect.1:427
 #: ../../man/update-alternatives.8:383
@@ -195,11 +195,11 @@ msgstr "To polecenie powinno by
 
 # type: SH
 #: ../../man/822-date.1:28 ../../man/cleanup-info.8:51 ../../man/deb.5:67
-#: ../../man/deb-control.5:221 ../../man/deb-old.5:51
+#: ../../man/deb-control.5:227 ../../man/deb-old.5:51
 #: ../../man/deb-override.5:67 ../../man/deb-shlibs.5:29
 #: ../../man/deb-substvars.5:129 ../../man/dpkg.1:608
 #: ../../man/dpkg-architecture.1:268 ../../man/dpkg.cfg.5:21
-#: ../../man/dpkg-buildpackage.1:195 ../../man/dpkg-deb.1:238
+#: ../../man/dpkg-buildpackage.1:196 ../../man/dpkg-deb.1:238
 #: ../../man/dpkg-divert.8:118 ../../man/dpkg-name.1:97
 #: ../../man/dpkg-query.1:161 ../../man/dpkg-scanpackages.1:97
 #: ../../man/dpkg-scansources.1:65 ../../man/dpkg-shlibdeps.1:127
@@ -253,9 +253,9 @@ msgstr "cleanup-info"
 
 # type: TH
 #: ../../man/cleanup-info.8:1 ../../man/deb-substvars.5:2 ../../man/dpkg.1:1
-#: ../../man/dpkg-buildpackage.1:1 ../../man/dpkg-checkbuilddeps.1:1
-#: ../../man/dpkg-divert.8:1 ../../man/dpkg-genchanges.1:1
-#: ../../man/dpkg-name.1:6 ../../man/dpkg-query.1:1 ../../man/dpkg-split.1:2
+#: ../../man/dpkg-checkbuilddeps.1:1 ../../man/dpkg-divert.8:1
+#: ../../man/dpkg-genchanges.1:1 ../../man/dpkg-name.1:6
+#: ../../man/dpkg-query.1:1 ../../man/dpkg-split.1:2
 #: ../../man/dpkg-statoverride.8:1 ../../man/install-info.8:5
 #: ../../man/update-alternatives.8:8
 #, no-wrap
@@ -344,7 +344,7 @@ msgstr "B<--help>"
 
 # type: Plain text
 #: ../../man/cleanup-info.8:39 ../../man/dpkg-architecture.1:64
-#: ../../man/dpkg-buildpackage.1:186 ../../man/dpkg-checkbuilddeps.1:30
+#: ../../man/dpkg-buildpackage.1:187 ../../man/dpkg-checkbuilddeps.1:30
 #: ../../man/dpkg-distaddfile.1:35 ../../man/dpkg-deb.1:165
 #: ../../man/dpkg-divert.8:70 ../../man/dpkg-genchanges.1:130
 #: ../../man/dpkg-gencontrol.1:101 ../../man/dpkg-name.1:59
@@ -358,7 +358,7 @@ msgstr "Wy
 
 # type: TP
 #: ../../man/cleanup-info.8:39 ../../man/dpkg.1:247
-#: ../../man/dpkg-architecture.1:64 ../../man/dpkg-buildpackage.1:186
+#: ../../man/dpkg-architecture.1:64 ../../man/dpkg-buildpackage.1:187
 #: ../../man/dpkg-distaddfile.1:35 ../../man/dpkg-deb.1:165
 #: ../../man/dpkg-divert.8:70 ../../man/dpkg-genchanges.1:130
 #: ../../man/dpkg-gencontrol.1:101 ../../man/dpkg-parsechangelog.1:36
@@ -374,7 +374,7 @@ msgstr "B<--version>"
 # type: Plain text
 #
 #: ../../man/cleanup-info.8:42 ../../man/dpkg-architecture.1:67
-#: ../../man/dpkg-buildpackage.1:189 ../../man/dpkg-distaddfile.1:38
+#: ../../man/dpkg-buildpackage.1:190 ../../man/dpkg-distaddfile.1:38
 #: ../../man/dpkg-deb.1:168 ../../man/dpkg-divert.8:73
 #: ../../man/dpkg-genchanges.1:133 ../../man/dpkg-gencontrol.1:104
 #: ../../man/dpkg-name.1:62 ../../man/dpkg-parsechangelog.1:39
@@ -429,7 +429,7 @@ msgstr "Copyright (C) 1996 Kim-Minh Kaplan"
 
 # type: Plain text
 #: ../../man/cleanup-info.8:58 ../../man/deb-substvars.5:142
-#: ../../man/dpkg-buildpackage.1:210 ../../man/dpkg-checkbuilddeps.1:38
+#: ../../man/dpkg-buildpackage.1:211 ../../man/dpkg-checkbuilddeps.1:38
 #: ../../man/dpkg-distaddfile.1:53 ../../man/dpkg-deb.1:248
 #: ../../man/dpkg-divert.8:125 ../../man/dpkg-genchanges.1:150
 #: ../../man/dpkg-gencontrol.1:125 ../../man/dpkg-name.1:109
@@ -609,9 +609,9 @@ msgstr "deb-control"
 
 # type: TH
 #: ../../man/deb-control.5:3
-#, no-wrap
-msgid "2007-08-31"
-msgstr "2007-08-31"
+#, fuzzy, no-wrap
+msgid "2007-10-08"
+msgstr "2007-03-08"
 
 # type: Plain text
 #
@@ -770,11 +770,11 @@ msgstr ""
 "`optional' (opcjonalny), `extra' (dodatkowy) itp."
 
 # type: Plain text
-#: ../../man/deb-control.5:72
+#: ../../man/deb-control.5:71
+#, fuzzy
 msgid ""
 "In Debian, the B<Section> and B<Priority> fields have a defined set of "
-"accepted values based on the Policy Manual.  They are used to decide how the "
-"packages are layed out in the archive.  A list of these values can be "
+"accepted values based on the Policy Manual.  A list of these values can be "
 "obtained from the latest version of the B<debian-policy> package."
 msgstr ""
 "W Debianie pola B<Section> i B<Pririty> maj± ¶ci¶le zdefiniowany zbiór "
@@ -783,13 +783,13 @@ msgstr ""
 "wersji pakietu B<debian-policy>."
 
 # type: TP
-#: ../../man/deb-control.5:72
+#: ../../man/deb-control.5:71
 #, no-wrap
 msgid "B<Essential:> E<lt>yes|noE<gt>"
 msgstr "B<Essential:> E<lt>yes|noE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:79
+#: ../../man/deb-control.5:78
 msgid ""
 "This field is usually only needed when the answer is `yes'. It denotes a "
 "package that is required for proper operation of the system. Dpkg or any "
@@ -803,13 +803,13 @@ msgstr ""
 "takiego pakietu)."
 
 # type: TP
-#: ../../man/deb-control.5:79
+#: ../../man/deb-control.5:78
 #, no-wrap
 msgid "B<Architecture:> E<lt>arch|allE<gt>"
 msgstr "B<Architecture:> E<lt>architektura|allE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:87
+#: ../../man/deb-control.5:86
 msgid ""
 "The architecture specifies which type of hardware this package was compiled "
 "for. Common architectures are `i386', `m68k', `sparc', `alpha', `powerpc' "
@@ -823,24 +823,49 @@ msgstr ""
 "przyk³ad zawiera tylko skrypty pow³oki lub Perla albo dokumentacjê."
 
 # type: TP
-#: ../../man/deb-control.5:87
+#: ../../man/deb-control.5:86
+#, fuzzy, no-wrap
+msgid "B<Origin:> E<lt>nameE<gt>"
+msgstr "B<Source:> E<lt>nazwa ¼ród³aE<gt>"
+
+# type: Plain text
+#: ../../man/deb-control.5:89
+msgid "The name of the distribution this package is originating from."
+msgstr ""
+
+# type: TP
+#: ../../man/deb-control.5:89
+#, fuzzy, no-wrap
+msgid "B<Bugs:> E<lt>urlE<gt>"
+msgstr "B<Homepage:> E<lt>urlE<gt>"
+
+# type: Plain text
+#: ../../man/deb-control.5:93
+msgid ""
+"The url of the bug tracking system for this package. The current used format "
+"is B<E<lt>bts_typeE<gt>://E<lt>bts_addressE<gt>>, like B<debbugs://bugs."
+"debian.org>."
+msgstr ""
+
+# type: TP
+#: ../../man/deb-control.5:93
 #, no-wrap
 msgid "B<Homepage:> E<lt>urlE<gt>"
 msgstr "B<Homepage:> E<lt>urlE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:90
+#: ../../man/deb-control.5:96
 msgid "The upstream project home page URL."
 msgstr "URL do strony domowej projektu."
 
 # type: TP
-#: ../../man/deb-control.5:90
+#: ../../man/deb-control.5:96
 #, no-wrap
 msgid "B<Tag:> E<lt>tag listE<gt>"
 msgstr "B<Tag:> E<lt>lista znacznikówE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:94
+#: ../../man/deb-control.5:100
 msgid ""
 "List of tags describing the qualities of the package. The description and "
 "list of supported tags can be found in the B<debtags> package."
@@ -849,13 +874,13 @@ msgstr ""
 "znaczników mo¿na znale¼æ w pakiecie B<debtags>."
 
 # type: TP
-#: ../../man/deb-control.5:94
+#: ../../man/deb-control.5:100
 #, no-wrap
 msgid "B<Source:> E<lt>source nameE<gt>"
 msgstr "B<Source:> E<lt>nazwa ¼ród³aE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:98
+#: ../../man/deb-control.5:104
 msgid ""
 "The name of the source package that this binary package came from, if "
 "different than the name of the package itself."
@@ -864,14 +889,14 @@ msgstr ""
 "binarny, je¿eli jest ró¿na od nazwy tego pakietu binarnego."
 
 # type: TP
-#: ../../man/deb-control.5:98
+#: ../../man/deb-control.5:104
 #, no-wrap
 msgid "B<Depends:> E<lt>package listE<gt>"
 msgstr "B<Depends:> E<lt>lista pakietówE<gt>"
 
 # check me!
 # type: Plain text
-#: ../../man/deb-control.5:108
+#: ../../man/deb-control.5:114
 #, fuzzy
 msgid ""
 "List of packages that are required for this package to provide a non-trivial "
@@ -889,13 +914,13 @@ msgstr ""
 "skryptami pakietów, które od nich zale¿±, a skrypty przedusuwaj±ce "
 
 # type: TP
-#: ../../man/deb-control.5:108
+#: ../../man/deb-control.5:114
 #, no-wrap
 msgid "B<Pre-Depends:> E<lt>package listE<gt>"
 msgstr "B<Pre-Depends:> E<lt>lista pakietówE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:115
+#: ../../man/deb-control.5:121
 msgid ""
 "List of packages that must be installed B<and> configured before this one "
 "can be installed. This is usually used in the case where this package "
@@ -907,13 +932,13 @@ msgstr ""
 "preinstalacyjnych."
 
 # type: TP
-#: ../../man/deb-control.5:115
+#: ../../man/deb-control.5:121
 #, no-wrap
 msgid "B<Recommends:> E<lt>package listE<gt>"
 msgstr "B<Recommends:> E<lt>lista pakietówE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:122
+#: ../../man/deb-control.5:128
 msgid ""
 "Lists packages that would be found together with this one in all but unusual "
 "installations. The package maintenance software will warn the user if they "
@@ -925,13 +950,13 @@ msgstr ""
 "wymienionych w polu B<Recommends>."
 
 # type: TP
-#: ../../man/deb-control.5:122
+#: ../../man/deb-control.5:128
 #, no-wrap
 msgid "B<Suggests:> E<lt>package listE<gt>"
 msgstr "B<Suggests:> E<lt>lista pakietówE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:127
+#: ../../man/deb-control.5:133
 msgid ""
 "Lists packages that are related to this one and can perhaps enhance its "
 "usefulness, but without which installing this package is perfectly "
@@ -941,7 +966,7 @@ msgstr ""
 "u¿yteczno¶æ, ale bez których pakiet mo¿e siê obej¶æ."
 
 # type: Plain text
-#: ../../man/deb-control.5:139
+#: ../../man/deb-control.5:145
 msgid ""
 "The syntax of B<Depends>, B<Pre-Depends>, B<Recommends> and B<Suggests> "
 "fields is a list of groups of alternative packages. Each group is a list of "
@@ -959,7 +984,7 @@ msgstr ""
 "nawiasach."
 
 # type: Plain text
-#: ../../man/deb-control.5:145
+#: ../../man/deb-control.5:151
 msgid ""
 "A version number may start with a `E<gt>E<gt>', in which case any later "
 "version will match, and may specify or omit the Debian packaging revision "
@@ -975,13 +1000,13 @@ msgstr ""
 "równy."
 
 # type: TP
-#: ../../man/deb-control.5:145
+#: ../../man/deb-control.5:151
 #, no-wrap
 msgid "B<Breaks:> E<lt>package listE<gt>"
 msgstr "B<Breaks:> E<lt>lista pakietówE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:153
+#: ../../man/deb-control.5:159
 msgid ""
 "Lists packages that this one breaks, for example by exposing bugs when the "
 "named packages rely on this one. The package maintenance software will not "
@@ -994,13 +1019,13 @@ msgstr ""
 "problemu jest aktualizacja pakietu wymienionego w polu B<Breaks>."
 
 # type: TP
-#: ../../man/deb-control.5:153
+#: ../../man/deb-control.5:159
 #, no-wrap
 msgid "B<Conflicts:> E<lt>package listE<gt>"
 msgstr "B<Conflicts:> E<lt>lista pakietówE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:161
+#: ../../man/deb-control.5:167
 msgid ""
 "Lists packages that conflict with this one, for example by containing files "
 "with the same names. The package maintenance software will not allow "
@@ -1014,13 +1039,13 @@ msgstr ""
 "wskazuj±ce na drugi pakiet."
 
 # type: TP
-#: ../../man/deb-control.5:161
+#: ../../man/deb-control.5:167
 #, no-wrap
 msgid "B<Replaces:> E<lt>package listE<gt>"
 msgstr "B<Replaces:> E<lt>lista pakietówE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:169
+#: ../../man/deb-control.5:175
 msgid ""
 "List of packages files from which this one replaces. This is used for "
 "allowing this package to overwrite the files of another package and is "
@@ -1033,13 +1058,13 @@ msgstr ""
 "innego pakietu, je¿eli zawiera on pliki o takich samych nazwach."
 
 # type: TP
-#: ../../man/deb-control.5:169
+#: ../../man/deb-control.5:175
 #, no-wrap
 msgid "B<Provides:> E<lt>package listE<gt>"
 msgstr "B<Provides:> E<lt>lista pakietówE<gt>"
 
 # type: Plain text
-#: ../../man/deb-control.5:179
+#: ../../man/deb-control.5:185
 msgid ""
 "This is a list of virtual packages that this one provides. Usually this is "
 "used in the case of several packages all providing the same service.  For "
@@ -1052,7 +1077,7 @@ msgid ""
 msgstr ""
 
 # type: Plain text
-#: ../../man/deb-control.5:194
+#: ../../man/deb-control.5:200
 msgid ""
 "The syntax of B<Conflicts>, B<Replaces> and B<Provides> is a list of package "
 "names, separated by commas (and optional whitespace).  In the B<Conflicts> "
@@ -1067,13 +1092,13 @@ msgstr ""
 "wy¿ej."
 
 # type: SH
-#: ../../man/deb-control.5:195
+#: ../../man/deb-control.5:201
 #, no-wrap
 msgid "EXAMPLE"
 msgstr "PRZYK£AD"
 
 # type: Plain text
-#: ../../man/deb-control.5:218
+#: ../../man/deb-control.5:224
 #, no-wrap
 msgid ""
 "# Comment\n"
@@ -1120,7 +1145,7 @@ msgstr ""
 
 # type: Plain text
 #
-#: ../../man/deb-control.5:225
+#: ../../man/deb-control.5:231
 msgid "B<deb>(5), B<debtags>(1), B<dpkg>(1), B<dpkg-deb>(1)."
 msgstr "B<deb>(5), B<debtags>(1), B<dpkg>(1), B<dpkg-deb>(1)."
 
@@ -1633,7 +1658,7 @@ msgstr ""
 "(1), B<dpkg-source>(1)."
 
 # type: Plain text
-#: ../../man/deb-substvars.5:138 ../../man/dpkg-buildpackage.1:204
+#: ../../man/deb-substvars.5:138 ../../man/dpkg-buildpackage.1:205
 #: ../../man/dpkg-distaddfile.1:49 ../../man/dpkg-deb.1:246
 #: ../../man/dpkg-genchanges.1:146 ../../man/dpkg-gencontrol.1:121
 #: ../../man/dpkg-parsechangelog.1:50 ../../man/dpkg-shlibdeps.1:132
@@ -1642,7 +1667,7 @@ msgid "Copyright (C) 1995-1996 Ian Jackson"
 msgstr "Copyright (C) 1995-1996 Ian Jackson"
 
 # type: Plain text
-#: ../../man/deb-substvars.5:140 ../../man/dpkg-buildpackage.1:206
+#: ../../man/deb-substvars.5:140 ../../man/dpkg-buildpackage.1:207
 #: ../../man/dpkg-distaddfile.1:51 ../../man/dpkg-genchanges.1:148
 #: ../../man/dpkg-gencontrol.1:123 ../../man/dpkg-parsechangelog.1:52
 #: ../../man/dpkg-shlibdeps.1:134 ../../man/dpkg-source.1:273
@@ -2976,7 +3001,7 @@ msgstr ""
 "Jest to dok³adnie to samo, co B<--refuse-downgrade>."
 
 # type: TP
-#: ../../man/dpkg.1:456 ../../man/dpkg-buildpackage.1:179
+#: ../../man/dpkg.1:456 ../../man/dpkg-buildpackage.1:180
 #: ../../man/dpkg-checkbuilddeps.1:19 ../../man/dpkg-query.1:70
 #: ../../man/dpkg-shlibdeps.1:105
 #, no-wrap
@@ -3466,7 +3491,7 @@ msgid "B<--no-act> usually gives less information than might be helpful."
 msgstr "B<--no-act> podaje raczej zbyt ma³o pomocnych informacji."
 
 # type: SH
-#: ../../man/dpkg.1:621 ../../man/dpkg-buildpackage.1:202
+#: ../../man/dpkg.1:621 ../../man/dpkg-buildpackage.1:203
 #: ../../man/dpkg-distaddfile.1:47 ../../man/dpkg-genchanges.1:144
 #: ../../man/dpkg-gencontrol.1:119 ../../man/dpkg-parsechangelog.1:48
 #: ../../man/dpkg-shlibdeps.1:130 ../../man/dpkg-source.1:269
@@ -4326,6 +4351,12 @@ msgstr "B<dpkg>(1)."
 msgid "dpkg-buildpackage"
 msgstr "dpkg-buildpackage"
 
+# type: TH
+#: ../../man/dpkg-buildpackage.1:1
+#, fuzzy, no-wrap
+msgid "2007-09-28"
+msgstr "2007-09-08"
+
 # type: Plain text
 #: ../../man/dpkg-buildpackage.1:4
 msgid "dpkg-buildpackage - build binary or source packages from sources"
@@ -4632,28 +4663,29 @@ msgstr "B<-r>I<polecenie-uzyskiwania-praw-administratora>"
 
 # type: Plain text
 #.  what happens, if it contains spaces? (hs)
-#: ../../man/dpkg-buildpackage.1:136
+#: ../../man/dpkg-buildpackage.1:137
 msgid ""
 "When B<dpkg-buildpackage> needs to execute part of the build process as "
 "root, it prefixes the command it executes with I<gain-root-command> if one "
-"has been specified.  I<gain-root-command> should be the name of a program on "
-"the B<PATH> and will get as arguments the name of the real command to run "
-"and the arguments it should take.  I<gain-root-command> should not contain "
-"spaces or any other shell metacharacters.  I<gain-root-command> might "
-"typically be B<fakeroot>, B<sudo>, B<super> or B<really>.  B<su> is not "
-"suitable, since it requires a B<-c> option to run a command and even then it "
-"can only invoke the user's shell with B<-c> instead of passing arguments "
-"individually to the command to be run."
+"has been specified. Otherwise, if none has been specified, B<fakeroot> will "
+"be used by default, if the command is present.  I<gain-root-command> should "
+"be the name of a program on the B<PATH> and will get as arguments the name "
+"of the real command to run and the arguments it should take.  I<gain-root-"
+"command> should not contain spaces or any other shell metacharacters.  "
+"I<gain-root-command> might typically be B<fakeroot>, B<sudo>, B<super> or "
+"B<really>.  B<su> is not suitable, since it requires a B<-c> option to run a "
+"command and even then it can only invoke the user's shell with B<-c> instead "
+"of passing arguments individually to the command to be run."
 msgstr ""
 
 # type: TP
-#: ../../man/dpkg-buildpackage.1:136
+#: ../../man/dpkg-buildpackage.1:137
 #, no-wrap
 msgid "B<-p>I<sign-command>"
 msgstr "B<-p>I<polecenie-podpisywania>"
 
 # type: Plain text
-#: ../../man/dpkg-buildpackage.1:161
+#: ../../man/dpkg-buildpackage.1:162
 msgid ""
 "When B<dpkg-buildpackage> needs to execute GPG or PGP to sign a source "
 "control (B<.dsc>)  file or a B<.changes> file it will run I<sign-command> "
@@ -4665,66 +4697,66 @@ msgid ""
 msgstr ""
 
 # type: TP
-#: ../../man/dpkg-buildpackage.1:161
+#: ../../man/dpkg-buildpackage.1:162
 #, no-wrap
 msgid "B<-k>I<key-id>"
 msgstr "B<-k>I<id-klucza>"
 
 # type: Plain text
 #
-#: ../../man/dpkg-buildpackage.1:164
+#: ../../man/dpkg-buildpackage.1:165
 msgid "Specify a key-ID to use when signing packages."
 msgstr "Okre¶la ID klucza u¿ywanego do podpisywania pakietów."
 
 # type: TP
-#: ../../man/dpkg-buildpackage.1:164
+#: ../../man/dpkg-buildpackage.1:165
 #, no-wrap
 msgid "B<-us>"
 msgstr "B<-us>"
 
 # type: Plain text
 #
-#: ../../man/dpkg-buildpackage.1:167
+#: ../../man/dpkg-buildpackage.1:168
 msgid "Do not sign the source package."
 msgstr "Nie próbuje podpisywaæ pakietów."
 
 # type: TP
-#: ../../man/dpkg-buildpackage.1:167
+#: ../../man/dpkg-buildpackage.1:168
 #, no-wrap
 msgid "B<-uc>"
 msgstr "B<-uc>"
 
 # type: Plain text
-#: ../../man/dpkg-buildpackage.1:170
+#: ../../man/dpkg-buildpackage.1:171
 msgid "Do not sign the .changes file."
 msgstr "Nie próbuje podpisywaæ plików .changes."
 
 # type: TP
-#: ../../man/dpkg-buildpackage.1:170 ../../man/dpkg-source.1:108
+#: ../../man/dpkg-buildpackage.1:171 ../../man/dpkg-source.1:108
 #, no-wrap
 msgid "B<-i>[I<regexp>]"
 msgstr "B<-i>[I<wyra¿-regul>]"
 
 # type: Plain text
-#: ../../man/dpkg-buildpackage.1:174
+#: ../../man/dpkg-buildpackage.1:175
 msgid "Passed unchanged to B<dpkg-source>."
 msgstr "Przekazywana bez zmian do B<dpkg-source>."
 
 # type: TP
-#: ../../man/dpkg-buildpackage.1:174
+#: ../../man/dpkg-buildpackage.1:175
 #, no-wrap
 msgid "B<-I>I<[pattern]>"
 msgstr "B<-I>I<[wzorzec]>"
 
 # type: Plain text
-#: ../../man/dpkg-buildpackage.1:179
+#: ../../man/dpkg-buildpackage.1:180
 msgid "Passed unchanged to B<dpkg-source>.  May be repeated multiple times."
 msgstr ""
 "Przekazywana bez zmian do B<dpkg-source>. Mo¿e byæ powtórzona wiele razy."
 
 # type: Plain text
 #
-#: ../../man/dpkg-buildpackage.1:183 ../../man/dpkg-checkbuilddeps.1:23
+#: ../../man/dpkg-buildpackage.1:184 ../../man/dpkg-checkbuilddeps.1:23
 #: ../../man/dpkg-query.1:74 ../../man/dpkg-shlibdeps.1:109
 msgid ""
 "Change the location of the B<dpkg> database. The default location is I</var/"
@@ -4733,7 +4765,7 @@ msgstr ""
 "Zmienia po³o¿enie bazy danych B<dpkg>. Domy¶lnie jest to I</var/lib/dpkg>."
 
 # type: TP
-#: ../../man/dpkg-buildpackage.1:183 ../../man/dpkg-distaddfile.1:32
+#: ../../man/dpkg-buildpackage.1:184 ../../man/dpkg-distaddfile.1:32
 #: ../../man/dpkg-deb.1:162 ../../man/dpkg-genchanges.1:127
 #: ../../man/dpkg-gencontrol.1:98 ../../man/dpkg-name.1:56
 #: ../../man/dpkg-parsechangelog.1:33 ../../man/dpkg-query.1:59
@@ -4744,7 +4776,7 @@ msgid "B<-h>, B<--help>"
 msgstr "B<-h>, B<--help>"
 
 # type: Plain text
-#: ../../man/dpkg-buildpackage.1:194
+#: ../../man/dpkg-buildpackage.1:195
 msgid ""
 "It should be possible to specify spaces and shell metacharacters in and "
 "initial arguments for I<gain-root-command> and I<sign-command>."
@@ -4754,7 +4786,7 @@ msgstr ""
 
 # type: Plain text
 #
-#: ../../man/dpkg-buildpackage.1:201
+#: ../../man/dpkg-buildpackage.1:202
 msgid ""
 "B<dpkg-source>(1), B<dpkg-architecture>(1), B<dpkg-genchanges>(1), B<gpg>"
 "(1), B<pgp>(1)."
@@ -4763,7 +4795,7 @@ msgstr ""
 "(1), B<pgp>(1)."
 
 # type: Plain text
-#: ../../man/dpkg-buildpackage.1:208
+#: ../../man/dpkg-buildpackage.1:209
 msgid "Copyright (C) 2007 Frank Lichtenheld"
 msgstr "Copyright (C) 2007 Frank Lichtenheld"
 
@@ -7212,8 +7244,8 @@ msgstr ""
 # type: Plain text
 #
 #: ../../man/dpkg-source.1:44
-#, no-wrap
-msgid "B<-b> [I<options>] I<directory> [I<orig-directory>|I<orig-targz>|'']"
+#, fuzzy, no-wrap
+msgid "B<-b> I<directory> [I<orig-directory>|I<orig-targz>|'']"
 msgstr "B<-b> [I<opcje>] I<katalog> [I<oryg-katalog>|I<oryg-targz>|'']"
 
 # type: Plain text
@@ -11160,3 +11192,7 @@ msgstr ""
 #: ../../man/update-alternatives.8:405
 msgid "B<ln>(1), FHS, the Filesystem Hierarchy Standard."
 msgstr "B<ln>(1), FHS - standard hierarchii systemu plików."
+
+# type: TH
+#~ msgid "2007-08-31"
+#~ msgstr "2007-08-31"

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 252 - 157
man/po/pt_BR.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 253 - 152
man/po/ru.po


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 301 - 176
man/po/sv.po


+ 50 - 0
scripts/Dpkg/ErrorHandling.pm

@@ -0,0 +1,50 @@
+package Dpkg::ErrorHandling;
+
+use Dpkg::Gettext;
+
+use base qw(Exporter);
+our @EXPORT_OK = qw( failure syserr error internerr warning
+                     warnerror subprocerr );
+
+our $warnable_error = 0;
+our $quiet_warnings = 0;
+our $progname = "unknown";
+
+sub failure { die sprintf(_g("%s: failure: %s"), $progname, $_[0])."\n"; }
+sub syserr { die sprintf(_g("%s: failure: %s: %s"), $progname, $_[0], $!)."\n"; }
+sub error { die sprintf(_g("%s: error: %s"), $progname, $_[0])."\n"; }
+sub internerr { die sprintf(_g("%s: internal error: %s"), $progname, $_[0])."\n"; }
+
+sub warning
+{
+    if (!$quiet_warnings) {
+	warn sprintf(_g("%s: warning: %s"), $progname, $_[0])."\n";
+    }
+}
+
+sub warnerror
+{
+    if ($warnable_error) {
+	warning(@_);
+    } else {
+	error(@_);
+    }
+}
+
+sub subprocerr {
+    my ($p) = @_;
+    require POSIX;
+    if (POSIX::WIFEXITED($?)) {
+	die sprintf(_g("%s: failure: %s gave error exit status %s"),
+		    $progname, $p, POSIX::WEXITSTATUS($?))."\n";
+    } elsif (POSIX::WIFSIGNALED($?)) {
+	die sprintf(_g("%s: failure: %s died from signal %s"),
+		    $progname, $p, POSIX::WTERMSIG($?))."\n";
+    } else {
+	die sprintf(_g("%s: failure: %s failed with unknown exit code %d"),
+		    $progname, $p, $?)."\n";
+    }
+}
+
+
+1;

+ 82 - 0
scripts/Dpkg/Path.pm

@@ -0,0 +1,82 @@
+# Copyright 2007 Raphaël Hertzog <hertzog@debian.org>
+
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+package Dpkg::Path;
+
+use strict;
+use warnings;
+
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT_OK = qw(get_pkg_root_dir relative_to_pkg_root);
+
+=head1 NAME
+
+Dpkg::Path - some common path handling functions
+
+=head1 DESCRIPTION
+
+It provides some functions to handle various path.
+
+=head1 METHODS
+
+=over 8
+
+=item get_pkg_root_dir($file)
+
+This function will scan upwards the hierarchy of directory to find out
+the directory which contains the "DEBIAN" sub-directory and it will return
+its path. This directory is the root directory of a package being built.
+
+=cut
+
+sub get_pkg_root_dir($) {
+    my $file = shift;
+    $file =~ s{/+$}{};
+    $file =~ s{/+[^/]+$}{} if not -d $file;
+    do {
+	return $file if -d "$file/DEBIAN";
+	last if $file !~ m{/};
+	$file =~ s{/+[^/]+$}{};
+    } while ($file);
+    return undef;
+}
+
+=item relative_to_pkg_root($file)
+
+Returns the filename relative to get_pkg_root_dir($file).
+
+=cut
+
+sub relative_to_pkg_root($) {
+    my $file = shift;
+    my $pkg_root = get_pkg_root_dir($file);
+    if (defined $pkg_root) {
+	$pkg_root .= "/";
+	return $file if ($file =~ s/^\Q$pkg_root\E//);
+    }
+    return undef;
+}
+
+=back
+
+=head1 AUTHOR
+
+Raphael Hertzog <hertzog@debian.org>.
+
+=cut
+
+1;

+ 92 - 0
scripts/Dpkg/Shlibs.pm

@@ -0,0 +1,92 @@
+# Copyright (C) 2007  Raphael Hertzog
+
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+package Dpkg::Shlibs;
+
+use strict;
+use warnings;
+
+use base qw(Exporter);
+our @EXPORT_OK = qw(@librarypaths find_library);
+
+use Dpkg::Gettext;
+use Dpkg::ErrorHandling qw(syserr);
+use Dpkg::Shlibs::Objdump;
+
+textdomain("dpkg-dev");
+
+use constant DEFAULT_LIBRARY_PATH =>
+    qw(/lib /usr/lib /lib32 /usr/lib32 /lib64 /usr/lib64
+       /emul/ia32-linux/lib /emul/ia32-linux/usr/lib);
+our @librarypaths = (DEFAULT_LIBRARY_PATH);
+
+# Update library paths with LD_LIBRARY_PATH
+if ($ENV{LD_LIBRARY_PATH}) {
+    foreach my $path (reverse split( /:/, $ENV{LD_LIBRARY_PATH} )) {
+	$path =~ s{/+$}{};
+	unless (scalar grep { $_ eq $path } @librarypaths) {
+	    unshift @librarypaths, $path;
+	}
+    }
+}
+
+# Update library paths with ld.so config
+parse_ldso_conf("/etc/ld.so.conf") if -e "/etc/ld.so.conf";
+
+my %visited;
+sub parse_ldso_conf {
+    my $file = shift;
+    open my $fh, "<", $file
+	or syserr(sprintf(_g("couldn't open %s"), $file));
+    $visited{$file}++;
+    while (<$fh>) {
+	next if /^\s*$/;
+	chomp;
+	s{/+$}{};
+	if (/^include\s+(\S.*\S)\s*$/) {
+	    foreach my $include (glob($1)) {
+		parse_ldso_conf($include) if -e $include
+		    && !$visited{$include};
+	    }
+	} elsif (m{^\s*/}) {
+	    s/^\s+//;
+	    my $libdir = $_;
+	    unless (scalar grep { $_ eq $libdir } @librarypaths) {
+		push @librarypaths, $libdir;
+	    }
+	}
+    }
+    close $fh or syserr(sprintf(_g("couldn't close %s"), $file));;
+}
+
+# find_library ($soname, \@rpath, $format, $root)
+sub find_library {
+    my ($lib, $rpath, $format, $root) = @_;
+    $root = "" if not defined($root);
+    $root =~ s{/+$}{};
+    my @rpath = @{$rpath};
+    foreach my $dir (@rpath, @librarypaths) {
+	if (-e "$root$dir/$lib") {
+	    my $libformat = Dpkg::Shlibs::Objdump::get_format("$root$dir/$lib");
+	    if ($format eq $libformat) {
+		return "$root$dir/$lib";
+	    }
+	}
+    }
+    return undef;
+}
+
+1;

+ 339 - 0
scripts/Dpkg/Shlibs/Objdump.pm

@@ -0,0 +1,339 @@
+# Copyright (C) 2007  Raphael Hertzog
+
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+use strict;
+use warnings;
+
+package Dpkg::Shlibs::Objdump;
+
+use Dpkg::Gettext;
+use Dpkg::ErrorHandling qw(syserr subprocerr warning);
+textdomain("dpkg-dev");
+
+sub new {
+    my $this = shift;
+    my $class = ref($this) || $this;
+    my $self = { 'objects' => {} };
+    bless $self, $class;
+    return $self;
+}
+
+sub parse {
+    my ($self, $file) = @_;
+    my $obj = Dpkg::Shlibs::Objdump::Object->new($file);
+
+    my $id = $obj->get_id;
+    if ($id) {
+	$self->{objects}{$id} = $obj;
+    }
+    return $id;
+}
+
+
+sub locate_symbol {
+    my ($self, $name) = @_;
+    foreach my $obj (values %{$self->{objects}}) {
+	my $sym = $obj->get_symbol($name);
+	if (defined($sym) && $sym->{defined}) {
+	    return $sym;
+	}
+    }
+    return undef;
+}
+
+sub get_object {
+    my ($self, $objid) = @_;
+    if (exists $self->{objects}{$objid}) {
+	return $self->{objects}{$objid};
+    }
+    return undef;
+}
+
+{
+    my %format; # Cache of result
+    sub get_format {
+	my ($file) = @_;
+
+	if (exists $format{$file}) {
+	    return $format{$file};
+	} else {
+	    local $ENV{LC_ALL} = "C";
+	    open(P, "-|", "objdump", "-a", "--", $file)
+		|| syserr(_g("cannot fork for objdump"));
+	    while (<P>) {
+		chomp;
+		if (/^\s*\S+:\s*file\s+format\s+(\S+)\s*$/) {
+		    $format{$file} = $1;
+		    return $format{$file};
+		}
+	    }
+	    close(P) or subprocerr(sprintf(_g("objdump on \`%s'"), $file));
+	}
+    }
+}
+
+sub is_elf {
+    my ($file) = @_;
+    open(FILE, "<", $file) ||
+	syserr(sprintf(_g("Can't open %s for test: %s"), $file, $!));
+    my ($header, $result) = ("", 0);
+    if (read(FILE, $header, 4) == 4) {
+	$result = 1 if ($header =~ /^\177ELF$/);
+    }
+    close(FILE);
+    return $result;
+}
+
+package Dpkg::Shlibs::Objdump::Object;
+
+use Dpkg::Gettext;
+use Dpkg::ErrorHandling qw(syserr warning);
+
+sub new {
+    my $this = shift;
+    my $file = shift || '';
+    my $class = ref($this) || $this;
+    my $self = {};
+    bless $self, $class;
+
+    $self->reset;
+    if ($file) {
+	$self->_read($file);
+    }
+
+    return $self;
+}
+
+sub reset {
+    my ($self) = @_;
+
+    $self->{file} = '';
+    $self->{id} = '';
+    $self->{SONAME} = '';
+    $self->{NEEDED} = [];
+    $self->{RPATH} = [];
+    $self->{dynsyms} = {};
+
+    return $self;
+}
+
+
+sub _read {
+    my ($self, $file) = @_;
+
+    $file ||= $self->{file};
+    return unless $file;
+
+    $self->reset;
+    $self->{file} = $file;
+
+    local $ENV{LC_ALL} = 'C';
+    open(my $objdump, "-|", "objdump", "-w", "-f", "-p", "-T", $file)
+	|| syserr(sprintf(_g("Can't execute objdump: %s"), $!));
+    my $ret = $self->_parse($objdump);
+    close($objdump);
+    return $ret;
+}
+
+sub _parse {
+    my ($self, $fh) = @_;
+
+    my $section = "none";
+    while (defined($_ = <$fh>)) {
+	chomp;
+	next if /^\s*$/;
+
+	if (/^DYNAMIC SYMBOL TABLE:/) {
+	    $section = "dynsym";
+	    next;
+	} elsif (/^Dynamic Section:/) {
+	    $section = "dyninfo";
+	    next;
+	} elsif (/^Program Header:/) {
+	    $section = "header";
+	    next;
+	} elsif (/^Version definitions:/) {
+	    $section = "verdef";
+	    next;
+	} elsif (/^Version References:/) {
+	    $section = "verref";
+	    next;
+	}
+
+	if ($section eq "dynsym") {
+	    $self->parse_dynamic_symbol($_);
+	} elsif ($section eq "dyninfo") {
+	    if (/^\s*NEEDED\s+(\S+)/) {
+		push @{$self->{NEEDED}}, $1;
+	    } elsif (/^\s*SONAME\s+(\S+)/) {
+		$self->{SONAME} = $1;
+	    } elsif (/^\s*HASH\s+(\S+)/) {
+		$self->{HASH} = $1;
+	    } elsif (/^\s*GNU_HASH\s+(\S+)/) {
+		$self->{GNU_HASH} = $1;
+	    } elsif (/^\s*RPATH\s+(\S+)/) {
+		push @{$self->{RPATH}}, split (/:/, $1);
+	    }
+	} elsif ($section eq "none") {
+	    if (/^\s*\S+:\s*file\s+format\s+(\S+)\s*$/) {
+		$self->{format} = $1;
+	    } elsif (/^architecture:\s*\S+,\s*flags\s*\S+:\s*$/) {
+		# Parse 2 lines of "-f"
+		# architecture: i386, flags 0x00000112:
+		# EXEC_P, HAS_SYMS, D_PAGED
+		# start address 0x08049b50
+		$_ = <$fh>;
+		chomp;
+		$self->{flags}{$_} = 1 foreach (split(/,\s*/));
+	    }
+	}
+    }
+
+    return $section ne "none";
+}
+
+# Output format of objdump -w -T
+#
+# /lib/libc.so.6:     file format elf32-i386
+#
+# DYNAMIC SYMBOL TABLE:
+# 00056ef0 g    DF .text  000000db  GLIBC_2.2   getwchar
+# 00000000 g    DO *ABS*  00000000  GCC_3.0     GCC_3.0
+# 00069960  w   DF .text  0000001e  GLIBC_2.0   bcmp
+# 00000000  w   D  *UND*  00000000              _pthread_cleanup_pop_restore
+# 0000b788 g    DF .text  0000008e  Base        .protected xine_close
+# 0000b788 g    DF .text  0000008e              .hidden IA__g_free
+# |        ||||||| |      |         |           |
+# |        ||||||| |      |         Version str (.visibility) + Symbol name
+# |        ||||||| |      Alignment
+# |        ||||||| Section name (or *UND* for an undefined symbol)
+# |        ||||||F=Function,f=file,O=object
+# |        |||||d=debugging,D=dynamic
+# |        ||||I=Indirect
+# |        |||W=warning
+# |        ||C=constructor
+# |        |w=weak
+# |        g=global,l=local,!=both global/local
+# Size of the symbol
+#
+# GLIBC_2.2 is the version string associated to the symbol
+# (GLIBC_2.2) is the same but the symbol is hidden, a newer version of the
+# symbol exist
+
+sub parse_dynamic_symbol {
+    my ($self, $line) = @_;
+    my $vis_re = '(\.protected|\.hidden|\.internal|0x\S+)';
+    if ($line =~ /^[0-9a-f]+ (.{7})\s+(\S+)\s+[0-9a-f]+\s+(\S+)?(?:(?:\s+$vis_re)?\s+(\S+))/) {
+
+	my ($flags, $sect, $ver, $vis, $name) = ($1, $2, $3, $4, $5);
+
+	# Special case if version is missing but extra visibility
+	# attribute replaces it in the match
+	if (defined($ver) and $ver =~ /^$vis_re$/) {
+	    $vis = $ver;
+	    $ver = '';
+	}
+
+	# Cleanup visibility field
+	$vis =~ s/^\.// if defined($vis);
+
+	my $symbol = {
+		name => $name,
+		version => defined($ver) ? $ver : '',
+		section => $sect,
+		dynamic => substr($flags, 5, 1) eq "D",
+		debug => substr($flags, 5, 1) eq "d",
+		type => substr($flags, 6, 1),
+		weak => substr($flags, 1, 1) eq "w",
+		local => substr($flags, 0, 1) eq "l",
+		global => substr($flags, 0, 1) eq "g",
+		visibility => defined($vis) ? $vis : '',
+		hidden => '',
+		defined => $sect ne '*UND*'
+	    };
+
+	# Handle hidden symbols
+	if (defined($ver) and $ver =~ /^\((.*)\)$/) {
+	    $ver = $1;
+	    $symbol->{version} = $1;
+	    $symbol->{hidden} = 1;
+	}
+
+	# Register symbol
+	$self->add_dynamic_symbol($symbol);
+    } elsif ($line =~ /^[0-9a-f]+ (.{7})\s+(\S+)\s+[0-9a-f]+/) {
+	# Same start but no version and no symbol ... just ignore
+    } elsif ($line =~ /^REG_G\d+\s+/) {
+	# Ignore some s390-specific output like
+	# REG_G6           g     R *UND*      0000000000000000              #scratch
+    } else {
+	warning(sprintf(_g("Couldn't parse dynamic symbol definition: %s"), $line));
+    }
+}
+
+
+sub add_dynamic_symbol {
+    my ($self, $symbol) = @_;
+    $symbol->{soname} = $self->{SONAME};
+    if ($symbol->{version}) {
+	$self->{dynsyms}{$symbol->{name} . '@' . $symbol->{version}} = $symbol;
+    } else {
+	$self->{dynsyms}{$symbol->{name}} = $symbol;
+    }
+}
+
+sub get_id {
+    my $self = shift;
+    return $self->{SONAME} || $self->{file};
+}
+
+sub get_symbol {
+    my ($self, $name) = @_;
+    if (exists $self->{dynsyms}{$name}) {
+	return $self->{dynsyms}{$name};
+    }
+    return undef;
+}
+
+sub get_exported_dynamic_symbols {
+    my ($self) = @_;
+    return grep { $_->{defined} && $_->{dynamic} && !$_->{local} }
+	    values %{$self->{dynsyms}};
+}
+
+sub get_undefined_dynamic_symbols {
+    my ($self) = @_;
+    return grep { (!$_->{defined}) && $_->{dynamic} }
+	    values %{$self->{dynsyms}};
+}
+
+sub get_needed_libraries {
+    my $self = shift;
+    return @{$self->{NEEDED}};
+}
+
+sub is_executable {
+    my $self = shift;
+    return exists $self->{flags}{EXEC_P} and $self->{flags}{EXEC_P};
+}
+
+sub is_public_library {
+    my $self = shift;
+    return exists $self->{flags}{DYNAMIC} and $self->{flags}{DYNAMIC}
+	and exists $self->{SONAME} and $self->{SONAME};
+}
+
+1;

+ 326 - 0
scripts/Dpkg/Shlibs/SymbolFile.pm

@@ -0,0 +1,326 @@
+# Copyright (C) 2007  Raphael Hertzog
+
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+package Dpkg::Shlibs::SymbolFile;
+
+use Dpkg::Gettext;
+use Dpkg::ErrorHandling qw(syserr warning error);
+use Dpkg::Version qw(vercmp);
+textdomain("dpkg-dev");
+
+my %blacklist = (
+    '__bss_end__' => 1,		# arm
+    '__bss_end' => 1,		# arm
+    '_bss_end__' => 1,		# arm
+    '__bss_start' => 1,		# ALL
+    '__bss_start__' => 1,	# arm
+    '__data_start' => 1,	# arm
+    '__do_global_ctors_aux' => 1,   # ia64
+    '__do_global_dtors_aux' => 1,   # ia64
+    '__do_jv_register_classes' => 1,# ia64
+    '_DYNAMIC' => 1,		# ALL
+    '_edata' => 1,		# ALL
+    '_end' => 1,		# ALL
+    '__end__' => 1,		# arm
+    '_fbss' => 1,		# mips, mipsel
+    '_fdata' => 1,		# mips, mipsel
+    '_fini' => 1,		# ALL
+    '_ftext' => 1,		# mips, mipsel
+    '_GLOBAL_OFFSET_TABLE_' => 1,   # hppa, mips, mipsel
+    '__gmon_start__' => 1,	# hppa
+    '_gp' => 1,			# mips, mipsel
+    '_init' => 1,		# ALL
+    '_PROCEDURE_LINKAGE_TABLE_' => 1, # sparc, alpha
+    '_SDA2_BASE_' => 1,		# powerpc
+    '_SDA_BASE_' => 1,		# powerpc
+);
+
+for (my $i = 14; $i <= 31; $i++) {
+    # Many powerpc specific symbols
+    $blacklist{"_restfpr_$i"} = 1;
+    $blacklist{"_restfpr_$i\_x"} = 1;
+    $blacklist{"_restgpr_$i"} = 1;
+    $blacklist{"_restgpr_$i\_x"} = 1;
+    $blacklist{"_savefpr_$i"} = 1;
+    $blacklist{"_savegpr_$i"} = 1;
+}
+
+sub new {
+    my $this = shift;
+    my $file = shift;
+    my $class = ref($this) || $this;
+    my $self = { };
+    bless $self, $class;
+    if (defined($file) ) {
+	$self->{file} = $file;
+	$self->load($file) if -e $file;
+    }
+    return $self;
+}
+
+sub clear {
+    my ($self) = @_;
+    $self->{objects} = {};
+}
+
+sub clear_except {
+    my ($self, @ids) = @_;
+    my %has;
+    $has{$_} = 1 foreach (@ids);
+    foreach my $objid (keys %{$self->{objects}}) {
+	delete $self->{objects}{$objid} unless exists $has{$objid};
+    }
+}
+
+# Parameter seen is only used for recursive calls
+sub load {
+    my ($self, $file, $seen) = @_;
+
+    if (defined($seen)) {
+	return if exists $seen->{$file}; # Avoid include loops
+    } else {
+	$self->{file} = $file;
+	$seen = {};
+    }
+    $seen->{$file} = 1;
+
+    open(my $sym_file, "<", $file)
+	|| syserr(sprintf(_g("Can't open %s: %s"), $file));
+    my ($object);
+    while (defined($_ = <$sym_file>)) {
+	chomp($_);
+	if (/^\s+(\S+)\s(\S+)(?:\s(\d+))?/) {
+	    if (not defined ($object)) {
+		error(sprintf(_g("Symbol information must be preceded by a header (file %s, line %s).", $file, $.)));
+	    }
+	    # New symbol
+	    my $sym = {
+		minver => $2,
+		dep_id => defined($3) ? $3 : 0,
+		deprecated => 0
+	    };
+	    $self->{objects}{$object}{syms}{$1} = $sym;
+	} elsif (/^#include\s+"([^"]+)"/) {
+	    my $filename = $1;
+	    my $dir = $file;
+	    $dir =~ s{[^/]+$}{}; # Strip filename
+	    $self->load("$dir$filename", $seen);
+	} elsif (/^#DEPRECATED: ([^#]+)#\s*(\S+)\s(\S+)(?:\s(\d+))?/) {
+	    my $sym = {
+		minver => $3,
+		dep_id => defined($4) ? $4 : 0,
+		deprecated => $1
+	    };
+	    $self->{objects}{$object}{syms}{$2} = $sym;
+	} elsif (/^#/) {
+	    # Skip possible comments
+	} elsif (/^\|\s*(.*)$/) {
+	    # Alternative dependency template
+	    push @{$self->{objects}{$object}{deps}}, "$1";
+	} elsif (/^(\S+)\s+(.*)$/) {
+	    # New object and dependency template
+	    $object = $1;
+	    if (exists $self->{objects}{$object}) {
+		# Update/override infos only
+		$self->{objects}{$object}{deps} = [ "$2" ];
+	    } else {
+		# Create a new object
+		$self->{objects}{$object} = {
+		    syms => {},
+		    deps => [ "$2" ]
+		};
+	    }
+	} else {
+	    warning(sprintf(_g("Failed to parse a line in %s: %s"), $file, $_));
+	}
+    }
+    close($sym_file);
+}
+
+sub save {
+    my ($self, $file, $with_deprecated) = @_;
+    $file = $self->{file} unless defined($file);
+    my $fh;
+    if ($file eq "-") {
+	$fh = \*STDOUT;
+    } else {
+	open($fh, ">", $file)
+	    || syserr(sprintf(_g("Can't open %s for writing: %s"), $file, $!));
+    }
+    $self->dump($fh, $with_deprecated);
+    close($fh) if ($file ne "-");
+}
+
+sub dump {
+    my ($self, $fh, $with_deprecated) = @_;
+    $with_deprecated = 1 unless defined($with_deprecated);
+    foreach my $soname (sort keys %{$self->{objects}}) {
+	print $fh "$soname $self->{objects}{$soname}{deps}[0]\n";
+	print $fh "| $_" foreach (@{$self->{objects}{$soname}{deps}}[ 1 .. -1 ]);
+	foreach my $sym (sort keys %{$self->{objects}{$soname}{syms}}) {
+	    my $info = $self->{objects}{$soname}{syms}{$sym};
+	    next if $info->{deprecated} and not $with_deprecated;
+	    print $fh "#DEPRECATED: $info->{deprecated}#" if $info->{deprecated};
+	    print $fh " $sym $info->{minver}";
+	    print $fh " $info->{dep_id}" if $info->{dep_id};
+	    print $fh "\n";
+	}
+    }
+}
+
+# merge_symbols($object, $minver)
+# Needs $Objdump->get_object($soname) as parameter
+# Don't merge blacklisted symbols related to the internal (arch-specific)
+# machinery
+sub merge_symbols {
+    my ($self, $object, $minver) = @_;
+    my $soname = $object->{SONAME} || error(_g("Can't merge symbols from objects without SONAME."));
+    my %dynsyms;
+    foreach my $sym ($object->get_exported_dynamic_symbols()) {
+	next if exists $blacklist{$sym->{name}};
+	if ($sym->{version}) {
+	    $dynsyms{$sym->{name} . '@' . $sym->{version}} = $sym;
+	} else {
+	    $dynsyms{$sym->{name}} = $sym;
+	}
+    }
+
+    unless ($self->{objects}{$soname}) {
+	$self->create_object($soname, '');
+    }
+    # Scan all symbols provided by the objects
+    foreach my $sym (keys %dynsyms) {
+	if (exists $self->{objects}{$soname}{syms}{$sym}) {
+	    # If the symbol is already listed in the file
+	    my $info = $self->{objects}{$soname}{syms}{$sym};
+	    if ($info->{deprecated}) {
+		# Symbol reappeared somehow
+		$info->{deprecated} = 0;
+		$info->{minver} = $minver;
+		next;
+	    }
+	    # We assume that the right dependency information is already
+	    # there.
+	    if (vercmp($minver, $info->{minver}) < 0) {
+		$info->{minver} = $minver;
+	    }
+	} else {
+	    # The symbol is new and not present in the file
+	    my $info = {
+		minver => $minver,
+		deprecated => 0,
+		dep_id => 0
+	    };
+	    $self->{objects}{$soname}{syms}{$sym} = $info;
+	}
+    }
+
+    # Scan all symbols in the file and mark as deprecated those that are
+    # no more provided (only if the minver is bigger than the version where
+    # the symbol was introduced)
+    foreach my $sym (keys %{$self->{objects}{$soname}{syms}}) {
+	if (! exists $dynsyms{$sym}) {
+	    my $info = $self->{objects}{$soname}{syms}{$sym};
+	    if (vercmp($minver, $info->{minver}) > 0) {
+		$self->{objects}{$soname}{syms}{$sym}{deprecated} = $minver;
+	    }
+	}
+    }
+}
+
+sub is_empty {
+    my ($self) = @_;
+    return scalar(keys %{$self->{objects}}) ? 0 : 1;
+}
+
+sub has_object {
+    my ($self, $soname) = @_;
+    return exists $self->{objects}{$soname};
+}
+
+sub create_object {
+    my ($self, $soname, @deps) = @_;
+    $self->{objects}{$soname} = {
+	syms => {},
+	deps => [ @deps ]
+    };
+}
+
+sub get_dependency {
+    my ($self, $soname, $dep_id) = @_;
+    $dep_id = 0 unless defined($dep_id);
+    return $self->{objects}{$soname}{deps}[$dep_id];
+}
+
+sub lookup_symbol {
+    my ($self, $name, $sonames, $inc_deprecated) = @_;
+    $inc_deprecated = 0 unless defined($inc_deprecated);
+    foreach my $so (@{$sonames}) {
+	next if (! exists $self->{objects}{$so});
+	if (exists $self->{objects}{$so}{syms}{$name} and
+	    ($inc_deprecated or not
+	    $self->{objects}{$so}{syms}{$name}{deprecated}))
+	{
+	    my $dep_id = $self->{objects}{$so}{syms}{$name}{dep_id};
+	    return {
+		'depends' => $self->{objects}{$so}{deps}[$dep_id],
+		'soname' => $so,
+		%{$self->{objects}{$so}{syms}{$name}}
+	    };
+	}
+    }
+    return undef;
+}
+
+sub has_new_symbols {
+    my ($self, $ref) = @_;
+    foreach my $soname (keys %{$self->{objects}}) {
+	my $mysyms = $self->{objects}{$soname}{syms};
+	next if not exists $ref->{objects}{$soname};
+	my $refsyms = $ref->{objects}{$soname}{syms};
+	foreach my $sym (grep { not $mysyms->{$_}{deprecated} }
+	    keys %{$mysyms})
+	{
+	    if ((not exists $refsyms->{$sym}) or
+		$refsyms->{$sym}{deprecated})
+	    {
+		return 1;
+	    }
+	}
+    }
+    return 0;
+}
+
+sub has_lost_symbols {
+    my ($self, $ref) = @_;
+    return $ref->has_new_symbols($self);
+}
+
+
+sub has_new_libs {
+    my ($self, $ref) = @_;
+    foreach my $soname (keys %{$self->{objects}}) {
+	return 1 if not exists $ref->{objects}{$soname};
+    }
+    return 0;
+}
+
+sub has_lost_libs {
+    my ($self, $ref) = @_;
+    return $ref->has_new_libs($self);
+}
+
+1;

+ 205 - 0
scripts/Dpkg/Version.pm

@@ -0,0 +1,205 @@
+# Copyright Colin Watson <cjwatson@debian.org>
+# Copyright Ian Jackson <iwj@debian.org>
+# Copyright 2007 by Don Armstrong <don@donarmstrong.com>.
+
+# 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+package Dpkg::Version;
+
+use strict;
+use warnings;
+
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT_OK = qw(vercmp);
+
+=head1 NAME
+
+Dpkg::Version - pure-Perl dpkg-style version comparison
+
+=head1 DESCRIPTION
+
+The Dpkg::Version module provides pure-Perl routines to compare
+dpkg-style version numbers, as used in Debian packages. If you have the
+libapt-pkg Perl bindings available (Debian package libapt-pkg-perl), they
+may offer better performance.
+
+=head1 METHODS
+
+=over 8
+
+=cut
+
+sub parseversion ($)
+{
+    my $ver = shift;
+    my %verhash;
+    if ($ver =~ /:/)
+    {
+	$ver =~ /^(\d+):(.+)/ or die "bad version number '$ver'";
+	$verhash{epoch} = $1;
+	$ver = $2;
+    }
+    else
+    {
+	$verhash{epoch} = 0;
+    }
+    if ($ver =~ /(.+)-(.+)$/)
+    {
+	$verhash{version} = $1;
+	$verhash{revision} = $2;
+    }
+    else
+    {
+	$verhash{version} = $ver;
+	$verhash{revision} = 0;
+    }
+    return %verhash;
+}
+
+# verrevcmp
+
+# This function is almost exactly equivalent
+# to dpkg's verrevcmp function, including the
+# order subroutine which it uses.
+
+sub verrevcmp($$)
+{
+
+     sub order{
+	  my ($x) = @_;
+	  ##define order(x) ((x) == '~' ? -1 \
+	  #           : cisdigit((x)) ? 0 \
+	  #           : !(x) ? 0 \
+	  #           : cisalpha((x)) ? (x) \
+	  #           : (x) + 256)
+	  # This comparison is out of dpkg's order to avoid
+	  # comparing things to undef and triggering warnings.
+	  if (not defined $x) {
+	       return 0;
+	  }
+	  elsif ($x eq '~') {
+	       return -1;
+	  }
+	  elsif ($x =~ /^\d$/) {
+	       return 0;
+	  }
+	  elsif ($x =~ /^[A-Z]$/i) {
+	       return ord($x);
+	  }
+	  else {
+	       return ord($x) + 256;
+	  }
+     }
+
+     sub next_elem(\@){
+	  my $a = shift;
+	  return @{$a} ? shift @{$a} : undef;
+     }
+     my ($val, $ref) = @_;
+     $val = "" if not defined $val;
+     $ref = "" if not defined $ref;
+     my @val = split //,$val;
+     my @ref = split //,$ref;
+     my $vc = next_elem @val;
+     my $rc = next_elem @ref;
+     while (defined $vc or defined $rc) {
+	  my $first_diff = 0;
+	  while ((defined $vc and $vc !~ /^\d$/) or
+		 (defined $rc and $rc !~ /^\d$/)) {
+	       my $vo = order($vc); my $ro = order($rc);
+	       # Unlike dpkg's verrevcmp, we only return 1 or -1 here.
+	       return (($vo - $ro > 0) ? 1 : -1) if $vo != $ro;
+	       $vc = next_elem @val; $rc = next_elem @ref;
+	  }
+	  while (defined $vc and $vc eq '0') {
+	       $vc = next_elem @val;
+	  }
+	  while (defined $rc and $rc eq '0') {
+	       $rc = next_elem @ref;
+	  }
+	  while (defined $vc and $vc =~ /^\d$/ and
+		 defined $rc and $rc =~ /^\d$/) {
+	       $first_diff = ord($vc) - ord($rc) if !$first_diff;
+	       $vc = next_elem @val; $rc = next_elem @ref;
+	  }
+	  return 1 if defined $vc and $vc =~ /^\d$/;
+	  return -1 if defined $rc and $rc =~ /^\d$/;
+	  return $first_diff if $first_diff;
+     }
+     return 0;
+}
+
+=item vercmp
+
+Compare the two arguments as dpkg-style version numbers. Returns -1 if the
+first argument represents a lower version number than the second, 1 if the
+first argument represents a higher version number than the second, and 0 if
+the two arguments represent equal version numbers.
+
+=cut
+
+sub vercmp ($$)
+{
+    my %version = parseversion $_[0];
+    my %refversion = parseversion $_[1];
+    return 1 if $version{epoch} > $refversion{epoch};
+    return -1 if $version{epoch} < $refversion{epoch};
+    my $r = verrevcmp($version{version}, $refversion{version});
+    return $r if $r;
+    return verrevcmp($version{revision}, $refversion{revision});
+}
+
+=item compare_versions
+
+Emulates dpkg --compare-versions. Takes two versions as arguments
+one and three and one operator as argument two. Supports the following
+operators: 'gt', 'ge', 'eq', 'le', 'lt', and '>>', '>=', '=', '<=', '<<'.
+Returns a true value if the specified condition is true, a false value
+otherwise.
+
+=cut
+
+sub compare_versions ($$$)
+{
+    my $rel = $_[1];
+    my $res = vercmp($_[0], $_[2]);
+
+    if ($rel eq 'gt' or $rel =~ />?>/) {
+	return $res > 0;
+    } elsif ($rel eq 'ge' or $rel eq '>=') {
+	return $res >= 0;
+    } elsif ($rel eq 'eq' or $rel eq '=') {
+	return $res == 0;
+    } elsif ($rel eq 'le' or $rel eq '<=') {
+	return $res <= 0;
+    } elsif ($rel eq 'lt' or $rel =~ /<?</) {
+	return $res < 0;
+    } else {
+	die "bad relation '$rel'";
+    }
+}
+
+=back
+
+=head1 AUTHOR
+
+Don Armstrong <don@donarmstrong.com> and Colin Watson
+E<lt>cjwatson@debian.orgE<gt>, based on the implementation in
+C<dpkg/lib/vercmp.c> by Ian Jackson and others.
+
+=cut
+
+1;

+ 37 - 1
scripts/Makefile.am

@@ -10,6 +10,7 @@ bin_SCRIPTS = \
 	dpkg-distaddfile \
 	dpkg-genchanges \
 	dpkg-gencontrol \
+	dpkg-gensymbols \
 	dpkg-name \
 	dpkg-parsechangelog \
 	dpkg-scanpackages \
@@ -36,6 +37,7 @@ EXTRA_DIST = \
 	dpkg-distaddfile.pl \
 	dpkg-genchanges.pl \
 	dpkg-gencontrol.pl \
+	dpkg-gensymbols.pl \
 	dpkg-name.sh \
 	dpkg-parsechangelog.pl \
 	dpkg-scanpackages.pl \
@@ -47,7 +49,22 @@ EXTRA_DIST = \
 	dpkg-statoverride.pl \
 	install-info.pl \
 	update-alternatives.pl \
-	changelog/debian.pl
+	changelog/debian.pl \
+	t/000_pod.t \
+	t/100_Dpkg_Version.t \
+	t/200_Dpkg_Shlibs.t \
+	t/200_Dpkg_Shlibs/symbols.fake-1 \
+	t/200_Dpkg_Shlibs/symbols.fake-2 \
+	t/200_Dpkg_Shlibs/symbols.include-1 \
+	t/200_Dpkg_Shlibs/symbols.include-2 \
+	t/200_Dpkg_Shlibs/ld.so.conf \
+	t/200_Dpkg_Shlibs/ld.so.conf_2 \
+	t/200_Dpkg_Shlibs/ld.so.conf.d/normal.conf \
+	t/200_Dpkg_Shlibs/ld.so.conf.d/inf_recurse.conf \
+	t/200_Dpkg_Shlibs/ld.so.conf.d/recursive.conf \
+	t/200_Dpkg_Shlibs/objdump.glib-ia64 \
+	t/200_Dpkg_Shlibs/objdump.libc6-2.3 \
+	t/200_Dpkg_Shlibs/objdump.libc6-2.6
 
 CLEANFILES = \
 	$(bin_SCRIPTS) $(sbin_SCRIPTS) $(changelog_SCRIPTS) \
@@ -55,8 +72,14 @@ CLEANFILES = \
 
 perllibdir = $(PERL_LIBDIR)
 nobase_dist_perllib_DATA = \
+	Dpkg/Shlibs.pm \
+	Dpkg/Shlibs/Objdump.pm \
+	Dpkg/Shlibs/SymbolFile.pm \
+	Dpkg/ErrorHandling.pm \
 	Dpkg/BuildOptions.pm \
 	Dpkg/Gettext.pm \
+	Dpkg/Path.pm \
+	Dpkg/Version.pm \
 	Dpkg.pm
 
 dist_pkglib_SCRIPTS = \
@@ -109,3 +132,16 @@ install-data-hook:
 uninstall-local:
 	rm -f $(DESTDIR)$(sysconfdir)/alternatives/README
 	rm -f $(DESTDIR)$(sbindir)/install-info
+
+TEST_FILES= $(srcdir)/t/*.t
+TEST_VERBOSE= 0
+
+clean-local:
+	chmod -R +w t.tmp
+	rm -fr t.tmp
+
+check: $(TEST_FILES) $(wildcard $(srcdir)/t/200_Dpkg_Shlibs/ld.so.conf*)
+# a bit hacky...
+	$(mkdir_p) t.tmp
+	cp -dRl $(srcdir)/t/200_Dpkg_Shlibs/ld.so.conf* t.tmp/
+	srcdir=$(srcdir) PERL_DL_NONLAZY=1 $(PERL) -I$(srcdir) "-MExtUtils::Command::MM" "-e" "test_harness($(TEST_VERBOSE), '.')" $(TEST_FILES)

+ 7 - 4
scripts/controllib.pl

@@ -249,10 +249,7 @@ sub debarch_to_debtriplet($)
     local ($_) = @_;
     my $arch;
 
-    # FIXME: 'any' is handled here, to be able to do debarch_eq('any', foo).
-    if (/^any$/ || /^all$/) {
-	return ($_, $_, $_);
-    } elsif (/^linux-([^-]*)/) {
+    if (/^linux-([^-]*)/) {
 	# XXX: Might disappear in the future, not sure yet.
 	$arch = $1;
     } else {
@@ -288,6 +285,9 @@ sub debwildcard_to_debtriplet($)
 sub debarch_eq($$)
 {
     my ($a, $b) = @_;
+
+    return 1 if ($a eq $b);
+
     my @a = debarch_to_debtriplet($a);
     my @b = debarch_to_debtriplet($b);
 
@@ -299,6 +299,9 @@ sub debarch_eq($$)
 sub debarch_is($$)
 {
     my ($real, $alias) = @_;
+
+    return 1 if ($alias eq $real or $alias eq 'any');
+
     my @real = debarch_to_debtriplet($real);
     my @alias = debwildcard_to_debtriplet($alias);
 

+ 17 - 6
scripts/dpkg-buildpackage.pl

@@ -37,8 +37,7 @@ Usage: %s [<options> ...]
 
 Options:
   -r<gain-root-command>
-                 command to gain root privileges (default is fakeroot if it
-                 exists).
+                 command to gain root privileges (default is fakeroot).
   -p<sign-command>
   -d             do not check build dependencies and conflicts.
   -D             check build dependencies and conflicts.
@@ -85,10 +84,6 @@ sub testcommand {
 }
 
 my $rootcommand = '';
-if (testcommand('fakeroot')) {
-    $rootcommand = 'fakeroot';
-}
-
 my $signcommand = '';
 if ( ( ($ENV{GNUPGHOME} && -e $ENV{GNUPGHOME})
        || ($ENV{HOME} && -e "$ENV{HOME}/.gnupg") )
@@ -201,6 +196,22 @@ while (@ARGV) {
     }
 }
 
+if ($< == 0) {
+    warning(_g("using a gain-root-command while being root")) if ($rootcommand);
+} else {
+    $rootcommand ||= 'fakeroot';
+
+    if (!testcommand($rootcommand)) {
+	if ($rootcommand eq 'fakeroot') {
+	    error(_g("fakeroot not found, either install the fakeroot\n" .
+	             "package, specify a command with the -r option, " .
+	             "or run this as root"));
+	} else {
+	    error(sprintf(_g("gain-root-commmand '%s' not found"), $rootcommand));
+	}
+    }
+}
+
 unless ($signcommand) {
     $signsource = 0;
     $signchanges = 0;

+ 3 - 2
scripts/dpkg-gencontrol.pl

@@ -183,8 +183,9 @@ for $_ (keys %fi) {
 		              join("' `", @invalid_archs)))
 		    if @invalid_archs >= 1;
 		grep(debarch_is($host_arch, $_), @archlist) ||
-                    &error(sprintf(_g("current build architecture %s does not".
-                                      " appear in package's list (%s)"),
+		    error(sprintf(_g("current host architecture '%s' does " .
+		                     "not appear in package's architecture " .
+		                     "list (%s)"),
 		                   $host_arch, "@archlist"));
 		$f{$_} = $host_arch;
             }

+ 240 - 0
scripts/dpkg-gensymbols.pl

@@ -0,0 +1,240 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+our $version;
+our $dpkglibdir;
+BEGIN {
+    $version="1.14.4"; # This line modified by Makefile
+    $dpkglibdir="."; # This line modified by Makefile
+    push(@INC,$dpkglibdir);
+}
+require 'controllib.pl';
+
+use Dpkg::Shlibs qw(@librarypaths);
+use Dpkg::Shlibs::Objdump;
+use Dpkg::Shlibs::SymbolFile;
+use Dpkg::Gettext;
+
+textdomain("dpkg-dev");
+
+our $progname;
+our (%f, %fi);
+our %p2i;
+our @librarypaths;
+
+our $host_arch= `dpkg-architecture -qDEB_HOST_ARCH`;
+chomp $host_arch;
+
+my $controlfile = 'debian/control';
+my $changelogfile = 'debian/changelog';
+my $packagebuilddir = 'debian/tmp';
+
+my $sourceversion;
+my $stdout;
+my $oppackage;
+my $compare = 1; # Bail on missing symbols by default
+my $output;
+my $debug = 0;
+
+sub version {
+    printf _g("Debian %s version %s.\n"), $progname, $version;
+
+    printf _g("
+Copyright (C) 2007 Raphael Hertzog.
+");
+
+    printf _g("
+This is free software; see the GNU General Public Licence version 2 or
+later for copying conditions. There is NO warranty.
+");
+}
+
+sub usage {
+    printf _g(
+"Usage: %s [<option> ...]
+
+Options:
+  -p<package>              generate symbols file for package.
+  -P<packagebuilddir>      temporary build dir instead of debian/tmp.
+  -e<library>              explicitely list libraries to scan.
+  -v<version>              version of the packages (defaults to
+                           version extracted from debian/changelog).
+  -c<level>                compare generated symbols file with the
+                           reference file in the debian directory.
+			   Fails if difference are too important
+			   (level goes from 0 for no check, to 4
+			   for all checks). By default checks at
+			   level 1.
+  -O<file>                 write to <file>, not .../DEBIAN/symbols.
+  -O                       write to stdout, not .../DEBIAN/symbols.
+  -d                       display debug information during work.
+  -h, --help               show this help message.
+      --version            show the version.
+"), $progname;
+}
+
+my @files;
+while (@ARGV) {
+    $_=shift(@ARGV);
+    if (m/^-p([-+0-9a-z.]+)$/) {
+	$oppackage= $1;
+    } elsif (m/^-c(\d)?$/) {
+	$compare = defined($1) ? $1 : 1;
+    } elsif (m/^-d$/) {
+	$debug = 1;
+    } elsif (m/^-v(.*)/) {
+	$sourceversion = $1;
+    } elsif (m/^-e(.*)/) {
+	my $file = $1;
+	if (-e $file) {
+	    push @files, $file;
+	} else {
+	    push @files, glob($file);
+	}
+    } elsif (m/^-p(.*)/) {
+	&error(sprintf(_g("Illegal package name \`%s'"), $1));
+    } elsif (m/^-P(.*)$/) {
+	$packagebuilddir = $1;
+	$packagebuilddir =~ s{/+$}{};
+    } elsif (m/^-O$/) {
+	$stdout= 1;
+    } elsif (m/^-O(.+)$/) {
+	$output= $1;
+    } elsif (m/^-(h|-help)$/) {
+	&usage; exit(0);
+    } elsif (m/^--version$/) {
+	&version; exit(0);
+    } else {
+	&usageerr(sprintf(_g("unknown option \`%s'"), $_));
+    }
+}
+
+if (not defined($sourceversion)) {
+    parsechangelog($changelogfile);
+    $sourceversion = $fi{"L Version"};
+}
+if (not defined($oppackage)) {
+    parsecontrolfile($controlfile);
+    my @packages = grep(m/^C /, keys %p2i);
+    @packages==1 ||
+	&error(sprintf(_g("must specify package since control info has many (%s)"), "@packages"));
+    $oppackage = $packages[0];
+    $oppackage =~ s/^C //;
+}
+
+my $symfile = Dpkg::Shlibs::SymbolFile->new();
+my $ref_symfile = Dpkg::Shlibs::SymbolFile->new();
+# Load source-provided symbol information
+foreach my $file ($output, "debian/$oppackage.symbols.$host_arch",
+    "debian/symbols.$host_arch", "debian/$oppackage.symbols",
+    "debian/symbols")
+{
+    if (defined $file and -e $file) {
+	print "Using references symbols from $file\n" if $debug;
+	$symfile->load($file);
+	$ref_symfile->load($file) if $compare;
+	last;
+    }
+}
+
+# Scan package build dir looking for libraries
+if (not scalar @files) {
+    foreach my $path (@librarypaths) {
+	my $libdir = "$packagebuilddir$path";
+	$libdir =~ s{/+}{/}g;
+	next if not -d $libdir;
+	opendir(DIR, "$libdir") ||
+	    syserr(sprintf(_g("Can't read directory %s: %s"), $libdir, $!));
+	push @files, grep {
+	    /(\.so\.|\.so$)/ && -f $_ &&
+	    Dpkg::Shlibs::Objdump::is_elf($_);
+	} map { "$libdir/$_" } readdir(DIR);
+	close(DIR);
+    }
+}
+
+# Merge symbol information
+my $od = Dpkg::Shlibs::Objdump->new();
+foreach my $file (@files) {
+    print "Scanning $file for symbol information\n" if $debug;
+    my $objid = $od->parse($file);
+    unless (defined($objid) && $objid) {
+	warning(sprintf(_g("Objdump couldn't parse %s\n"), $file));
+	next;
+    }
+    my $object = $od->get_object($objid);
+    if ($object->{SONAME}) { # Objects without soname are of no interest
+	print "Merging symbols from $file as $object->{SONAME}\n" if $debug;
+	if (not $symfile->has_object($object->{SONAME})) {
+	    $symfile->create_object($object->{SONAME}, "$oppackage #MINVER#");
+	}
+	$symfile->merge_symbols($object, $sourceversion);
+    } else {
+	print "File $file doesn't have a soname. Ignoring.\n" if $debug;
+    }
+}
+$symfile->clear_except(keys %{$od->{objects}});
+
+# Write out symbols files
+if ($stdout) {
+    $output = "standard output";
+    $symfile->save("-");
+} else {
+    unless (defined($output)) {
+	unless($symfile->is_empty()) {
+	    $output = "$packagebuilddir/DEBIAN/symbols";
+	    mkdir("$packagebuilddir/DEBIAN") if not -e "$packagebuilddir/DEBIAN";
+	}
+    }
+    if (defined($output)) {
+	print "Storing symbols in $output.\n" if $debug;
+	$symfile->save($output);
+    } else {
+	print "No symbol information to store.\n" if $debug;
+    }
+}
+
+# Check if generated files differs from reference file
+my $exitcode = 0;
+if ($compare) {
+    use File::Temp;
+    use Digest::MD5;
+    # Compare
+    if ($symfile->has_new_libs($ref_symfile)) {
+	warning(_g("new libraries appeared in the symbols file."));
+	$exitcode = 4 if ($compare >= 4);
+    }
+    if ($symfile->has_lost_libs($ref_symfile)) {
+	warning(_g("some libraries disappeared in the symbols file."));
+	$exitcode = 3 if ($compare >= 3);
+    }
+    if ($symfile->has_new_symbols($ref_symfile)) {
+	warning(_g("some new symbols appeared in the symbols file."));
+	$exitcode = 2 if ($compare >= 2);
+    }
+    if ($symfile->has_lost_symbols($ref_symfile)) {
+	warning(_g("some symbols disappeared in the symbols file."));
+	$exitcode = 1 if ($compare >= 1);
+    }
+    # Output diffs between symbols files if needed
+    my $before = File::Temp->new(TEMPLATE=>'dpkg-gensymbolsXXXXXX');
+    my $after = File::Temp->new(TEMPLATE=>'dpkg-gensymbolsXXXXXX');
+    $ref_symfile->dump($before); $symfile->dump($after);
+    seek($before, 0, 0); seek($after, 0, 0);
+    my ($md5_before, $md5_after) = (Digest::MD5->new(), Digest::MD5->new());
+    $md5_before->addfile($before);
+    $md5_after->addfile($after);
+    if ($md5_before->hexdigest() ne $md5_after->hexdigest()) {
+	if (defined($ref_symfile->{file})) {
+	    warning(sprintf(_g("%s doesn't match completely %s\n"),
+		    $output, $ref_symfile->{file}));
+	} else {
+	    warning(sprintf(_g("no debian/symbols file used as basis for generating %s\n"), $output));
+	}
+	my ($a, $b) = ($before->filename, $after->filename);
+	system("diff", "-u", $a, $b) if -x "/usr/bin/diff";
+    }
+}
+exit($exitcode);

+ 391 - 358
scripts/dpkg-shlibdeps.pl

@@ -1,7 +1,4 @@
-#! /usr/bin/perl
-#
-# dpkg-shlibdeps
-# $Id$
+#!/usr/bin/perl -w
 
 use strict;
 use warnings;
@@ -10,28 +7,281 @@ use English;
 use POSIX qw(:errno_h :signal_h);
 use Dpkg;
 use Dpkg::Gettext;
+use Dpkg::Path qw(relative_to_pkg_root);
+use Dpkg::Version qw(vercmp);
+use Dpkg::Shlibs qw(find_library);
+use Dpkg::Shlibs::Objdump;
+use Dpkg::Shlibs::SymbolFile;
+
+our $host_arch= `dpkg-architecture -qDEB_HOST_ARCH`;
+chomp $host_arch;
+
+# By increasing importance
+my @depfields= qw(Suggests Recommends Depends Pre-Depends);
+my $i=0; my %depstrength = map { $_ => $i++ } @depfields;
+
+push(@INC, $dpkglibdir);
+require 'controllib.pl';
+textdomain("dpkg-dev");
 
 my $shlibsoverride= '/etc/dpkg/shlibs.override';
 my $shlibsdefault= '/etc/dpkg/shlibs.default';
 my $shlibslocal= 'debian/shlibs.local';
-my $shlibsppdir;
-my $shlibsppext= '.shlibs';
-my $varnameprefix= 'shlibs';
+my $packagetype= 'deb';
 my $dependencyfield= 'Depends';
 my $varlistfile= 'debian/substvars';
-my $packagetype= 'deb';
+my $varnameprefix= 'shlibs';
+my $ignore_missing_info= 0;
+my $debug= 0;
+my @exclude = ();
+
+my (@pkg_shlibs, @pkg_symbols);
+if (-d "debian") {
+    push @pkg_symbols, <debian/*/DEBIAN/symbols>;
+    push @pkg_shlibs, <debian/*/DEBIAN/shlibs>;
+}
 
-my @depfields= qw(Suggests Recommends Depends Pre-Depends);
-my %depstrength;
-my $i=0; grep($depstrength{$_}= ++$i, @depfields);
+my ($stdout, %exec);
+foreach (@ARGV) {
+    if (m/^-T(.*)$/) {
+	$varlistfile= $1;
+    } elsif (m/^-p(\w[-:0-9A-Za-z]*)$/) {
+	$varnameprefix= $1;
+    } elsif (m/^-L(.*)$/) {
+	$shlibslocal= $1;
+    } elsif (m/^-O$/) {
+	$stdout= 1;
+    } elsif (m/^-(h|-help)$/) {
+	usage(); exit(0);
+    } elsif (m/^--version$/) {
+	version(); exit(0);
+    } elsif (m/^--admindir=(.*)$/) {
+	$admindir = $1;
+	-d $admindir ||
+	    error(sprintf(_g("administrative directory '%s' does not exist"),
+			  $admindir));
+    } elsif (m/^-d(.*)$/) {
+	$dependencyfield= capit($1);
+	defined($depstrength{$dependencyfield}) ||
+	    warning(sprintf(_g("unrecognised dependency field \`%s'"), $dependencyfield));
+    } elsif (m/^-e(.*)$/) {
+	$exec{$1} = $dependencyfield;
+    } elsif (m/^--ignore-missing-info$/) {
+	$ignore_missing_info = 1;
+    } elsif (m/^-t(.*)$/) {
+	$packagetype = $1;
+    } elsif (m/^-v$/) {
+	$debug = 1;
+    } elsif (m/^-x(.*)$/) {
+	push @exclude, $1;
+    } elsif (m/^-/) {
+	usageerr(sprintf(_g("unknown option \`%s'"), $_));
+    } else {
+	$exec{$_} = $dependencyfield;
+    }
+}
 
-push(@INC,$dpkglibdir);
-require 'controllib.pl';
+scalar keys %exec || usageerr(_g("need at least one executable"));
 
-textdomain("dpkg-dev");
+my %dependencies;
+my %shlibs;
+
+my $cur_field;
+foreach my $file (keys %exec) {
+    $cur_field = $exec{$file};
+    print "Scanning $file (for $cur_field field)\n" if $debug;
 
-#use strict;
-#use warnings;
+    my $obj = Dpkg::Shlibs::Objdump::Object->new($file);
+    my @sonames = $obj->get_needed_libraries;
+
+    # Load symbols files for all needed libraries (identified by SONAME)
+    my %libfiles;
+    foreach my $soname (@sonames) {
+	my $lib = my_find_library($soname, $obj->{RPATH}, $obj->{format}, $file);
+	failure(sprintf(_g("couldn't find library %s (note: only packages with 'shlibs' files are looked into)."), $soname)) unless defined($lib);
+	$libfiles{$lib} = $soname if defined($lib);
+    }
+    my $file2pkg = find_packages(keys %libfiles);
+    my $symfile = Dpkg::Shlibs::SymbolFile->new();
+    my $dumplibs_wo_symfile = Dpkg::Shlibs::Objdump->new();
+    my @soname_wo_symfile;
+    foreach my $lib (keys %libfiles) {
+	my $soname = $libfiles{$lib};
+	if (not exists $file2pkg->{$lib}) {
+	    # If the library is not available in an installed package,
+	    # it's because it's in the process of being built
+	    # Empty package name will lead to consideration of symbols
+	    # file from the package being built only
+	    $file2pkg->{$lib} = [""];
+	}
+
+	# Load symbols/shlibs files from packages providing libraries
+	foreach my $pkg (@{$file2pkg->{$lib}}) {
+	    my $dpkg_symfile;
+	    if ($packagetype eq "deb") {
+		# Use fine-grained dependencies only on real deb
+		$dpkg_symfile = find_symbols_file($pkg, $soname);
+		if (defined $dpkg_symfile) {
+		    # Load symbol information
+		    print "Using symbols file $dpkg_symfile for $soname\n" if $debug;
+		    $symfile->load($dpkg_symfile);
+		}
+	    }
+	    if (defined($dpkg_symfile) && $symfile->has_object($soname)) {
+		# Initialize dependencies as an unversioned dependency
+		my $dep = $symfile->get_dependency($soname);
+		foreach my $subdep (split /\s*,\s*/, $dep) {
+		    if (not exists $dependencies{$cur_field}{$subdep}) {
+			$dependencies{$cur_field}{$subdep} = '';
+		    }
+		}
+	    } else {
+		# No symbol file found, fall back to standard shlibs
+		my $id = $dumplibs_wo_symfile->parse($lib);
+		push @soname_wo_symfile, $soname;
+		my $libobj = $dumplibs_wo_symfile->get_object($id);
+		# Only try to generate a dependency for libraries with a SONAME
+		if ($libobj->is_public_library() and not add_shlibs_dep($soname, $pkg)) {
+		    failure(sprintf(
+			_g("No dependency information found for %s (used by %s)."),
+			$soname, $file)) unless $ignore_missing_info;
+		}
+	    }
+	}
+    }
+
+    # Scan all undefined symbols of the binary and resolve to a
+    # dependency
+    my %used_sonames = map { $_ => 0 } @sonames;
+    foreach my $sym ($obj->get_undefined_dynamic_symbols()) {
+	my $name = $sym->{name};
+	if ($sym->{version}) {
+	    $name .= "\@$sym->{version}";
+	} else {
+	    $name .= "\@Base";
+	}
+	my $symdep = $symfile->lookup_symbol($name, \@sonames);
+	if (defined($symdep)) {
+	    my ($d, $m) = ($symdep->{depends}, $symdep->{minver});
+	    $used_sonames{$symdep->{soname}}++;
+	    foreach my $subdep (split /\s*,\s*/, $d) {
+		if (exists $dependencies{$cur_field}{$subdep} and
+		    defined($dependencies{$cur_field}{$subdep}))
+		{
+		    if ($dependencies{$cur_field}{$subdep} eq '' or
+			vercmp($m, $dependencies{$cur_field}{$subdep}) > 0)
+		    {
+			$dependencies{$cur_field}{$subdep} = $m;
+		    }
+		} else {
+		    $dependencies{$cur_field}{$subdep} = $m;
+		}
+	    }
+	} else {
+	    my $syminfo = $dumplibs_wo_symfile->locate_symbol($name);
+	    if (not defined($syminfo)) {
+		# Complain about missing symbols only for executables
+		# and public libraries
+		if ($obj->is_executable() or $obj->is_public_library()) {
+		    my $print_name = $name;
+		    # Drop the default suffix for readability
+		    $print_name =~ s/\@Base$//;
+		    warning(sprintf(
+			_g("symbol %s used by %s found in none of the libraries."),
+			$print_name, $file)) unless $sym->{weak};
+		}
+	    } else {
+		$used_sonames{$syminfo->{soname}}++;
+	    }
+	}
+    }
+    # Warn about un-NEEDED libraries
+    foreach my $soname (@sonames) {
+	unless ($used_sonames{$soname}) {
+	    warning(sprintf(
+		_g("%s shouldn't be linked with %s (it uses none of its symbols)."),
+		$file, $soname));
+	}
+    }
+}
+
+# Open substvars file
+my $fh;
+if ($stdout) {
+    $fh = \*STDOUT;
+} else {
+    open(NEW, ">", "$varlistfile.new") ||
+	syserr(sprintf(_g("open new substvars file \`%s'"), "$varlistfile.new"));
+    if (-e $varlistfile) {
+	open(OLD, "<", $varlistfile) ||
+	    syserr(sprintf(_g("open old varlist file \`%s' for reading"), $varlistfile));
+	foreach my $entry (grep { not m/^\Q$varnameprefix\E:/ } (<OLD>)) {
+	    print(NEW $entry) ||
+		syserr(sprintf(_g("copy old entry to new varlist file \`%s'"), "$varlistfile.new"));
+	}
+	close(OLD);
+    }
+    $fh = \*NEW;
+}
+
+# Write out the shlibs substvars
+my %depseen;
+
+sub filter_deps {
+    my ($dep, $field) = @_;
+    # Skip dependencies on excluded packages
+    foreach my $exc (@exclude) {
+	return 0 if $dep =~ /^\s*\Q$exc\E\b/;
+    }
+    # Don't include dependencies if they are already
+    # mentionned in a higher priority field
+    if (not defined($depseen{$dep})) {
+	$depseen{$dep} = $dependencies{$field}{$dep};
+	return 1;
+    } else {
+	# Since dependencies can be versionned, we have to
+	# verify if the dependency is stronger than the
+	# previously seen one
+	if (vercmp($depseen{$dep}, $dependencies{$field}{$dep}) > 0) {
+	    return 0;
+	} else {
+	    $depseen{$dep} = $dependencies{$field}{$dep};
+	    return 1;
+	}
+    }
+}
+
+foreach my $field (reverse @depfields) {
+    my $dep = "";
+    if (exists $dependencies{$field} and scalar keys %{$dependencies{$field}}) {
+	$dep = join ", ",
+	    map {
+		# Translate dependency templates into real dependencies
+		if ($dependencies{$field}{$_}) {
+		    s/#MINVER#/(>= $dependencies{$field}{$_})/g;
+		} else {
+		    s/#MINVER#//g;
+		}
+		s/\s+/ /g;
+		$_;
+	    } grep { filter_deps($_, $field) }
+	    keys %{$dependencies{$field}};
+    }
+    if ($dep) {
+	print $fh "$varnameprefix:$field=$dep\n";
+    }
+}
+
+# Replace old file by new one
+if (!$stdout) {
+    close($fh);
+    rename("$varlistfile.new",$varlistfile) ||
+	syserr(sprintf(_g("install new varlist file \`%s'"), $varlistfile));
+}
+
+##
+## Functions
+##
 
 sub version {
     printf _g("Debian %s version %s.\n"), $progname, $version;
@@ -39,7 +289,9 @@ sub version {
     printf _g("
 Copyright (C) 1996 Ian Jackson.
 Copyright (C) 2000 Wichert Akkerman.
-Copyright (C) 2006 Frank Lichtenheld.");
+Copyright (C) 2006 Frank Lichtenheld.
+Copyright (C) 2007 Raphael Hertzog.
+");
 
     printf _g("
 This is free software; see the GNU General Public Licence version 2 or
@@ -62,6 +314,7 @@ Options:
   -L<localshlibsfile>      shlibs override file, not debian/shlibs.local.
   -T<varlistfile>          update variables here, not debian/substvars.
   -t<type>                 set package type (default is deb).
+  -x<package>              exclude package from the generated dependencies.
   --admindir=<directory>   change the administrative directory.
   -h, --help               show this help message.
       --version            show the version.
@@ -71,376 +324,156 @@ Dependency fields recognised are:
 "), $progname, join("/",@depfields);
 }
 
-my ($stdout, @exec, @execfield);
-foreach (@ARGV) {
-    if (m/^-T/) {
-	$varlistfile= $POSTMATCH;
-    } elsif (m/^-p(\w[-:0-9A-Za-z]*)$/) {
-	$varnameprefix= $1;
-    } elsif (m/^-L/) {
-	$shlibslocal= $POSTMATCH;
-    } elsif (m/^-O$/) {
-	$stdout= 1;
-    } elsif (m/^-(h|-help)$/) {
-	usage; exit(0);
-    } elsif (m/^--version$/) {
-	version; exit(0);
-    } elsif (m/^--admindir=/) {
-	$admindir = $POSTMATCH;
-	-d $admindir ||
-	    error(sprintf(_g("administrative directory '%s' does not exist"),
-			     $admindir));
-    } elsif (m/^-d/) {
-	$dependencyfield= capit($POSTMATCH);
-	defined($depstrength{$dependencyfield}) ||
-	    warning(sprintf(_g("unrecognised dependency field '%s'"), $dependencyfield));
-    } elsif (m/^-e/) {
-	push(@exec,$POSTMATCH); push(@execfield,$dependencyfield);
-    } elsif (m/^-t/) {
-	$packagetype= $POSTMATCH;
-    } elsif (m/^-/) {
-	usageerr(sprintf(_g("unknown option \`%s'"), $_));
-    } else {
-	push(@exec,$_); push(@execfield,$dependencyfield);
+sub add_shlibs_dep {
+    my ($soname, $pkg) = @_;
+    foreach my $file ($shlibslocal, $shlibsoverride, @pkg_shlibs,
+			"$admindir/info/$pkg.shlibs",
+			$shlibsdefault)
+    {
+	next if not -e $file;
+	my $dep = extract_from_shlibs($soname, $file);
+	if (defined($dep)) {
+	    foreach (split(/,\s*/, $dep)) {
+		$dependencies{$cur_field}{$_} = 1;
+	    }
+	    return 1;
+	}
     }
+    return 0;
 }
 
-$shlibsppdir = "$admindir/info";
-
-@exec || usageerr(_g("need at least one executable"));
-
-sub isbin {
-    open (F, $_[0]) || die(sprintf(_g("unable to open '%s' for test"), $_[0]));
-    my $d;
-    if (read (F, $d, 4) != 4) {
-       die (sprintf(_g("unable to read first four bytes of '%s' as magic number"), $_[0]));
-    }
-    if ($d =~ /^\177ELF$/) { # ELF binary
-       return 1;
-    } elsif (unpack ('N', $d) == 0x8086010B) { # obsd dyn bin
-       return 1;
-    } elsif (unpack ('N', $d) ==   0x86010B) { # obsd stat bin
-       return 1;
-    } elsif ($d =~ /^\#\!..$/) { # shell script
-       return 0;
-    } elsif (unpack ('N', $d) == 0xcafebabe) { # JAVA binary
-       return 0;
+sub extract_from_shlibs {
+    my ($soname, $shlibfile) = @_;
+    my ($libname, $libversion);
+    # Split soname in name/version
+    if ($soname =~ /^(.*)\.so\.(.*)$/) {
+	$libname = $1; $libversion = $2;
+    } elsif ($soname =~ /^(.*)-(.*)\.so$/) {
+	$libname = $1; $libversion = $2;
     } else {
-       die(sprintf(_g("unrecognized file type for '%s'"), $_[0]));
+	warning(sprintf(_g("Can't extract name and version from library name \`%s'"), $soname));
+	return;
     }
-}
-
-my @librarypaths = qw( /lib /usr/lib /lib32 /usr/lib32 /lib64 /usr/lib64
-		       /emul/ia32-linux/lib /emul/ia32-linux/usr/lib );
-my %librarypaths = map { $_ => 'default' } @librarypaths;
-
-if ($ENV{LD_LIBRARY_PATH}) {
-    foreach (reverse split( /:/, $ENV{LD_LIBRARY_PATH} )) {
-	s,/+$,,;
-	unless (exists $librarypaths{$_}) {
-	    $librarypaths{$_} = 'env';
-	    unshift @librarypaths, $_;
+    # Open shlibs file
+    $shlibfile = "./$shlibfile" if $shlibfile =~ m/^\s/;
+    open(SHLIBS, "<", $shlibfile)
+	|| syserr(sprintf(_g("unable to open shared libs info file \`%s'"), $shlibfile));
+    my $dep;
+    while (<SHLIBS>) {
+	s/\s*\n$//;
+	next if m/^\#/;
+	if (!m/^\s*(?:(\S+):\s+)?(\S+)\s+(\S+)\s+(\S.*\S)\s*$/) {
+	    warning(sprintf(_g("shared libs info file \`%s' line %d: bad line \`%s'"), $shlibfile, $., $_));
+	    next;
 	}
-    }
-}
-
-# Support system library directories.
-my $ldconfigdir = '/lib/ldconfig';
-if (opendir(DIR, $ldconfigdir)) {
-    my @dirents = readdir(DIR);
-    closedir(DIR);
-
-    for (@dirents) {
-	next if /^\./;
-	my $d = `readlink -f $ldconfigdir/$_`;
-	chomp $d;
-	unless (exists $librarypaths{$d}) {
-	    $librarypaths{$d} = 'ldconfig';
-	    push @librarypaths, $d;
+	if (($libname eq $2) && ($libversion eq $3)) {
+	    # Define dep and end here if the package type explicitely
+	    # matches. Otherwise if the packagetype is not specified, use
+	    # the dep only as a default that can be overriden by a later
+	    # line
+	    if (defined($1)) {
+		if ($1 eq $packagetype) {
+		    $dep = $4;
+		    last;
+		}
+	    } else {
+		$dep = $4 unless defined $dep;
+	    }
 	}
     }
+    close(SHLIBS);
+    return $dep;
 }
 
-open CONF, '</etc/ld.so.conf' or
-    warning(sprintf(_g("couldn't open /etc/ld.so.conf: %s"), $!));
-while( <CONF> ) {
-    next if /^\s*$/;
-    chomp;
-    s,/+$,,;
-    unless (exists $librarypaths{$_}) {
-	$librarypaths{$_} = 'conf';
-	push @librarypaths, $_;
-    }
-}
-close CONF;
-
-my (%rpaths, %format);
-my (@libfiles, @libname, @libsoname, @libfield, @libexec);
-for ($i=0;$i<=$#exec;$i++) {
-    if (!isbin ($exec[$i])) { next; }
-
-    # Now we get the direct deps of the program
-    defined(my $c= open(P,"-|")) || syserr(_g("cannot fork for objdump"));
-    if (!$c) {
-	exec("objdump", "-p", "--", $exec[$i]) or
-	    syserr(_g("cannot exec objdump"));
-    }
-    while (<P>) {
-	chomp;
-	if (/^\s*\S+:\s*file\s+format\s+(\S+)\s*$/) {
-	    $format{$exec[$i]} = $1;
-	} elsif (m,^\s*NEEDED\s+,) {
-	    if (m,^\s*NEEDED\s+((\S+)\.so\.(\S+))$,) {
-		push(@libname,$2); push(@libsoname,$3);
-		push(@libfield,$execfield[$i]);
-		push(@libfiles,$1);
-		push(@libexec,$exec[$i]);
-	    } elsif (m,^\s*NEEDED\s+((\S+)-(\S+)\.so)$,) {
-		push(@libname,$2); push(@libsoname,$3);
-		push(@libfield,$execfield[$i]);
-		push(@libfiles,$1);
-		push(@libexec,$exec[$i]);
-	    } else {
-		m,^\s*NEEDED\s+(\S+)$,;
-		warning(sprintf(_g("format of 'NEEDED %s' not recognized"), $1));
-	    }
-	} elsif (/^\s*RPATH\s+(\S+)\s*$/) {
-	    push @{$rpaths{$exec[$i]}}, split(/:/, $1);
+sub find_symbols_file {
+    my ($pkg, $soname) = @_;
+    foreach my $file (@pkg_symbols,
+	"/etc/dpkg/symbols/$pkg.symbols.$host_arch",
+	"/etc/dpkg/symbols/$pkg.symbols",
+	"$admindir/info/$pkg.symbols")
+    {
+	if (-e $file and symfile_has_soname($file, $soname)) {
+	    return $file;
 	}
     }
-    close(P) or subprocerr(sprintf(_g("objdump on \`%s'"), $exec[$i]));
+    return undef;
 }
 
-# Now: See if it is in this package.  See if it is in any other package.
-my @curshlibs;
-sub searchdir {
-    my $dir = shift;
-    if(opendir(DIR, $dir)) {
-	my @dirents = readdir(DIR);
-	closedir(DIR);
-	for (@dirents) {
-	    if ( -f "$dir/$_/DEBIAN/shlibs" ) {
-		push(@curshlibs, "$dir/$_/DEBIAN/shlibs");
-		next;
-	    } elsif ( $_ !~ /^\./ && ! -e "$dir/$_/DEBIAN" &&
-		      -d "$dir/$_" && ! -l "$dir/$_" ) {
-		&searchdir("$dir/$_");
-	    }
+sub symfile_has_soname {
+    my ($file, $soname) = @_;
+    open(SYM_FILE, "<", $file)
+	|| syserr(sprintf(_g("cannot open file %s"), $file));
+    my $result = 0;
+    while (<SYM_FILE>) {
+	if (/^\Q$soname\E /) {
+	    $result = 1;
+	    last;
 	}
     }
+    close(SYM_FILE);
+    return $result;
 }
 
-my $searchdir = $exec[0];
-my $curpackdir = "debian/tmp";
-do { $searchdir =~ s,/[^/]*$,,; } while($searchdir =~ m,/,
-					&& ! -d "$searchdir/DEBIAN");
-if ($searchdir =~ m,/,) {
-    $curpackdir = $searchdir;
-    $searchdir =~ s,/[^/]*,,;
-    &searchdir($searchdir);
-}
+# find_library ($soname, \@rpath, $format)
+sub my_find_library {
+    my ($lib, $rpath, $format, $execfile) = @_;
+    my $file;
+
+    # Create real RPATH in case $ORIGIN is used
+    # Note: ld.so also supports $PLATFORM and $LIB but they are
+    # used in real case (yet)
+    my $origin = "/" . relative_to_pkg_root($execfile);
+    $origin =~ s{/+[^/]*$}{};
+    my @RPATH = ();
+    foreach my $path (@{$rpath}) {
+	$path =~ s/\$ORIGIN/$origin/g;
+	$path =~ s/\$\{ORIGIN\}/$origin/g;
+	push @RPATH, $path;
+    }
 
-if (1 || $#curshlibs >= 0) {
-  PRELIB:
-    for ($i=0;$i<=$#libname;$i++) {
-	if(scanshlibsfile($shlibslocal,$libname[$i],$libsoname[$i],$libfield[$i])
-	   || scanshlibsfile($shlibsoverride,$libname[$i],$libsoname[$i],$libfield[$i])) {
-	    splice(@libname, $i, 1);
-	    splice(@libsoname, $i, 1);
-	    splice(@libfield, $i, 1);
-	    splice(@libfiles, $i, 1);
-	    splice(@libexec, $i, 1);
-	    $i--;
-	    next PRELIB;
-	}
-	for my $shlibsfile (@curshlibs) {
-	    if(scanshlibsfile($shlibsfile, $libname[$i], $libsoname[$i], $libfield[$i])) {
-		splice(@libname, $i, 1);
-		splice(@libsoname, $i, 1);
-		splice(@libfield, $i, 1);
-		splice(@libfiles, $i, 1);
-		splice(@libexec, $i, 1);
-		$i--;
-		next PRELIB;
-	    }
-	}
+    # Look into the packages we're currently building (but only those
+    # that provides shlibs file...)
+    # TODO: we should probably replace that by a cleaner way to look into
+    # the various temporary build directories...
+    foreach my $builddir (map { s{/DEBIAN/shlibs$}{}; $_ } @pkg_shlibs) {
+	$file = find_library($lib, \@RPATH, $format, $builddir);
+	return $file if defined($file);
     }
-}
 
-my %pathpackages;
-if ($#libfiles >= 0) {
-    grep(s/\[\?\*/\\$&/g, @libname);
-    defined(my $c= open(P,"-|")) || syserr(_g("cannot fork for dpkg --search"));
-    if (!$c) {
-	my %seen_libfiles;
-	my @uniq_libfiles = grep !$seen_libfiles{$_}++, @libfiles;
+    # Fallback in the root directory if we have not found what we were
+    # looking for in the packages
+    $file = find_library($lib, \@RPATH, $format, "");
+    return $file if defined($file);
+
+    return undef;
+}
 
-	close STDERR; # we don't need to see dpkg's errors
-	open STDERR, "> /dev/null";
+sub find_packages {
+    my @files = (@_);
+    my $pkgmatch = {};
+    my $pid = open(DPKG, "-|");
+    syserr(_g("cannot fork for dpkg --search")) unless defined($pid);
+    if (!$pid) {
+	# Child process running dpkg --search and discarding errors
+	close STDERR;
+	open STDERR, ">", "/dev/null";
 	$ENV{LC_ALL} = "C";
-	exec("dpkg", "--search", "--", @uniq_libfiles) or
-	    syserr(_g("cannot exec dpkg"));
+	exec("dpkg", "--search", "--", @files)
+	    || syserr(_g("cannot exec dpkg"));
     }
-    while (<P>) {
-	chomp;
+    while(defined($_ = <DPKG>)) {
+	chomp($_);
 	if (m/^local diversion |^diversion by/) {
 	    warning(_g("diversions involved - output may be incorrect"));
-	    print(STDERR " $_\n") || syserr(_g("write diversion info to stderr"));
-	} elsif (m=^(\S+(, \S+)*): (\S+)$=) {
-	    push @{$pathpackages{$LAST_PAREN_MATCH}}, split(/, /, $1);
+	    print(STDERR " $_\n")
+		|| syserr(_g("write diversion info to stderr"));
+	} elsif (m/^([^:]+): (\S+)$/) {
+	    $pkgmatch->{$2} = [ split(/, /, $1) ];
 	} else {
 	    warning(sprintf(_g("unknown output from dpkg --search: '%s'"), $_));
 	}
     }
-    close(P);
+    close(DPKG);
+    return $pkgmatch;
 }
 
- LIB:
-    for ($i=0;$i<=$#libname;$i++) {
-	my $file = $libfiles[$i];
-	my @packages;
-	foreach my $rpath (@{$rpaths{$libexec[$i]}}) {
-	    if (exists $pathpackages{"$rpath/$file"}
-		&& format_matches($libexec[$i],"$rpath/$file")) {
-		push @packages, @{$pathpackages{"$rpath/$file"}};
-	    }
-	}
-	foreach my $path (@librarypaths) {
-	    if (exists $pathpackages{"$path/$file"}
-		&& format_matches($libexec[$i],"$path/$file")) {
-		push @packages, @{$pathpackages{"$path/$file"}};
-	    }
-	}
-	if (!@packages) {
-	    warning(sprintf(_g("could not find any packages for %s"), $libfiles[$i]));
-	} else {
-	    for my $p (@packages) {
-		scanshlibsfile("$shlibsppdir/$p$shlibsppext",
-			       $libname[$i],$libsoname[$i],$libfield[$i])
-		    && next LIB;
-	    }
-	}
-	scanshlibsfile($shlibsdefault,$libname[$i],$libsoname[$i],$libfield[$i])
-	    && next;
-	warning(sprintf(_g("unable to find dependency information for ".
-	                   "shared library %s (soname %s, ".
-	                   "path %s, dependency field %s)"),
-	                $libname[$i], $libsoname[$i],
-	                $libfiles[$i], $libfield[$i]));
-    }
-
-sub format_matches {
-    my ($file1, $file2) = @_;
-    my ($format1, $format2) = (get_format($file1),get_format($file2));
-    return $format1 eq $format2;
-}
-
-sub get_format {
-    my ($file) = @_;
-
-    if ($format{$file}) {
-	return $format{$file};
-    } else {
-	defined(my $c= open(P,"-|")) || syserr(_g("cannot fork for objdump"));
-	if (!$c) {
-	    exec("objdump", "-a", "--", $file) or
-		syserr(_g("cannot exec objdump"));
-	}
-	while (<P>) {
-	    chomp;
-	    if (/^\s*\S+:\s*file\s+format\s+(\S+)\s*$/) {
-		$format{$file} = $1;
-		return $format{$file};
-	    }
-	}
-	close(P) or subprocerr(sprintf(_g("objdump on \`%s'"), $file));
-    }
-}
-
-my (%predefdepfdep, %unkdepfdone, %unkdepf);
-sub scanshlibsfile {
-    my ($fn,$ln,$lsn,$lf) = @_;
-    my ($da,$dk);
-    $fn= "./$fn" if $fn =~ m/^\s/;
-    if (!open(SLF,"< $fn")) {
-        $! == ENOENT || syserr(sprintf(_g("unable to open shared libs info file \`%s'"), $fn));
-        return 0;
-    }
-
-    while (<SLF>) {
-        s/\s*\n$//; next if m/^\#/;
-        if (!m/^\s*(?:(\S+):\s+)?(\S+)\s+(\S+)/) {
-	    warning(sprintf(_g("shared libs info file '%s' line %d: bad line '%s'"), $fn, $., $_));
-            next;
-        }
-        next if defined $1 && $1 ne $packagetype;
-        next if $2 ne $ln || $3 ne $lsn;
-        return 1 if $fn eq "$curpackdir/DEBIAN/shlibs";
-        $da= $POSTMATCH;
-        last if defined $1; # exact match, otherwise keep looking
-    }
-    close(SLF);
-
-    return 0 unless defined $da;
-
-    for my $dv (split(/,/,$da)) {
-        $dv =~ s/^\s+//; $dv =~ s/\s+$//;
-        if (defined($depstrength{$lf})) {
-            if (!defined($predefdepfdep{$dv}) ||
-                $depstrength{$predefdepfdep{$dv}} < $depstrength{$lf}) {
-                $predefdepfdep{$dv}= $lf;
-            }
-        } else {
-            $dk= "$lf: $dv";
-            if (!defined($unkdepfdone{$dk})) {
-                $unkdepfdone{$dk}= 1;
-                $unkdepf{$lf} .= ', ' if defined($unkdepf{$lf});
-                $unkdepf{$lf}.= $dv;
-            }
-        }
-    }
-    return 1;
-}
-
-my $fh;
-if (!$stdout) {
-    open(Y,"> $varlistfile.new") ||
-        syserr(sprintf(_g("open new substvars file \`%s'"), "$varlistfile.new"));
-    unless ($REAL_USER_ID) {
-	chown(getfowner(), "$varlistfile.new") ||
-	    syserr(sprintf(_g("chown of \`%s'"), "$varlistfile.new"));
-    }
-    if (open(X,"< $varlistfile")) {
-        while (<X>) {
-            s/\n$//;
-            next if m/^(\w[-:0-9A-Za-z]*):/ && $1 eq $varnameprefix;
-            print(Y "$_\n") ||
-                syserr(sprintf(_g("copy old entry to new varlist file \`%s'"), "$varlistfile.new"));
-        }
-    } elsif ($! != ENOENT) {
-        syserr(sprintf(_g("open old varlist file \`%s' for reading"), $varlistfile));
-    }
-    $fh = \*Y;
-} else {
-    $fh = \*STDOUT;
-}
-my %defdepf;
-for my $dv (sort keys %predefdepfdep) {
-    my $lf= $predefdepfdep{$dv};
-    $defdepf{$lf} .= ', ' if defined($defdepf{$lf});
-    $defdepf{$lf}.= $dv;
-}
-for my $lf (reverse @depfields) {
-    next unless defined($defdepf{$lf});
-    print($fh "$varnameprefix:$lf=$defdepf{$lf}\n")
-        || syserr(_g("write output entry"));
-}
-for my $lf (sort keys %unkdepf) {
-    print($fh "$varnameprefix:$lf=$unkdepf{$lf}\n")
-        || syserr(_g("write userdef output entry"));
-}
-close($fh) || syserr(_g("close output"));
-if (!$stdout) {
-    rename("$varlistfile.new",$varlistfile) ||
-        syserr(sprintf(_g("install new varlist file \`%s'"), $varlistfile));
-}

+ 1 - 1
scripts/dpkg-source.pl

@@ -289,7 +289,7 @@ if ($opmode eq 'build') {
 	    }
 	    elsif (m/^Uploaders$/i) { ($f{$_}= $v) =~ s/[\r\n]//g; }
 	    elsif (m/^Build-(Depends|Conflicts)(-Indep)?$/i) {
-		my $dep = parsedep(substvars($v),1);
+		my $dep = parsedep($v, 1);
 		&error(sprintf(_g("error occurred while parsing %s"), $_)) unless defined $dep;
 		$f{$_}= showdep($dep, 1);
 	    }

+ 6 - 1
scripts/po/POTFILES.in

@@ -8,10 +8,15 @@ scripts/dpkg-checkbuilddeps.pl
 scripts/dpkg-distaddfile.pl
 scripts/dpkg-genchanges.pl
 scripts/dpkg-gencontrol.pl
+scripts/dpkg-gensymbols.pl
 scripts/dpkg-parsechangelog.pl
 scripts/dpkg-scanpackages.pl
 scripts/dpkg-scansources.pl
 scripts/dpkg-shlibdeps.pl
 scripts/dpkg-source.pl
 scripts/changelog/debian.pl
-
+scripts/Dpkg/Shlibs.pm
+scripts/Dpkg/Shlibs/Objdump.pm
+scripts/Dpkg/Shlibs/SymbolFile.pm
+scripts/Dpkg/Version.pm
+scripts/Dpkg/ErrorHandling.pm

+ 11 - 0
scripts/t/000_pod.t

@@ -0,0 +1,11 @@
+# -*- mode: cperl;-*-
+
+use Test::More;
+
+use strict;
+use warnings;
+
+eval "use Test::Pod 1.00";
+plan skip_all => "Test::Pod 1.00 required for testing POD" if $@;
+my @poddirs = ( $ENV{srcdir} || '.' );
+all_pod_files_ok( all_pod_files( @poddirs ) );

+ 80 - 0
scripts/t/100_Dpkg_Version.t

@@ -0,0 +1,80 @@
+# -*- mode: cperl;-*-
+
+use Test::More;
+
+use warnings;
+use strict;
+
+# Default cmp '>'
+my @versions = ({a      => '1.0-1',
+		 b      => '2.0-2',
+		 result => -1,
+		 relation => 'lt',
+		},
+		{a      => '2.2~rc-4',
+		 b      => '2.2-1',
+		 result => -1,
+		 relation => 'lt',
+		},
+		{a      => '2.2-1',
+		 b      => '2.2~rc-4',
+		 result => 1,
+		 relation => 'gt',
+		},
+		{a      => '1.0000-1',
+		 b      => '1.0-1',
+		 result => 0,
+		 relation => 'eq',
+		},
+		{a      => '1.0000-1',
+		 b      => '1.0-1',
+		 result => 0,
+		 relation => 'ge',
+		},
+		{a      => '1',
+		 b      => '0:1',
+		 result => 0,
+		 relation => 'eq',
+		},
+		{a      => '2:2.5',
+		 b      => '1:7.5',
+		 result => 1,
+		 relation => 'gt',
+		},
+	       );
+my @test_failure = ({a      => '1.0-1',
+		     b      => '2.0-2',
+		     relation => 'gt',
+		    },
+		    {a      => '2.2~rc-4',
+		     b      => '2.2-1',
+		     relation => 'eq',
+		    },
+		   );
+
+plan tests => @versions * 3 + @test_failure * 2 + 1;
+
+sub dpkg_vercmp{
+     my ($a,$b,$cmp) = @_;
+     $cmp = 'gt' if not defined $cmp;
+     return system('dpkg','--compare-versions',$a,$cmp,$b) == 0;
+}
+
+
+use_ok('Dpkg::Version');
+
+for my $version_cmp (@versions) {
+     ok(Dpkg::Version::vercmp($$version_cmp{a},$$version_cmp{b}) == $$version_cmp{result},
+	"vercmp: Version $$version_cmp{a} $$version_cmp{relation} $$version_cmp{b} ok");
+     ok(Dpkg::Version::compare_versions($$version_cmp{a},$$version_cmp{relation},$$version_cmp{b}),
+       "compare_versions: Version $$version_cmp{a} $$version_cmp{relation} $$version_cmp{b} ok");
+     ok(dpkg_vercmp($$version_cmp{a},$$version_cmp{b},$$version_cmp{relation}),
+	"Dpkg concures: Version $$version_cmp{a} $$version_cmp{relation} $$version_cmp{b}");
+}
+
+for my $version_cmp (@test_failure) {
+     ok(!Dpkg::Version::compare_versions($$version_cmp{a},$$version_cmp{relation},$$version_cmp{b}),
+       "compare_versions: Version $$version_cmp{a} $$version_cmp{relation} $$version_cmp{b} false");
+     ok(!dpkg_vercmp($$version_cmp{a},$$version_cmp{b},$$version_cmp{relation}),
+	"Dpkg concures: Version $$version_cmp{a} $$version_cmp{relation} $$version_cmp{b}");
+}

+ 148 - 0
scripts/t/200_Dpkg_Shlibs.t

@@ -0,0 +1,148 @@
+# -*- mode: cperl;-*-
+
+use Test::More tests => 27;
+
+use strict;
+use warnings;
+
+use_ok('Dpkg::Shlibs');
+
+my @save_paths = @Dpkg::Shlibs::librarypaths;
+@Dpkg::Shlibs::librarypaths = ();
+
+my $srcdir = $ENV{srcdir} || '.';
+$srcdir .= '/t/200_Dpkg_Shlibs';
+
+Dpkg::Shlibs::parse_ldso_conf("t.tmp/ld.so.conf");
+
+use Data::Dumper;
+is_deeply([qw(/nonexistant32 /nonexistant/lib64
+	     /usr/local/lib /nonexistant/lib128 )],
+	  \@Dpkg::Shlibs::librarypaths, "parsed library paths");
+
+use_ok('Dpkg::Shlibs::Objdump');
+
+my $obj = Dpkg::Shlibs::Objdump::Object->new;
+
+open my $objdump, '<', "$srcdir/objdump.libc6-2.6"
+  or die "$srcdir/objdump.libc6-2.6: $!";
+$obj->_parse($objdump);
+close $objdump;
+
+is($obj->{SONAME}, 'libc.so.6', 'SONAME');
+is($obj->{HASH}, '0x13d99c', 'HASH');
+is($obj->{GNU_HASH}, '0x194', 'GNU_HASH');
+is($obj->{format}, 'elf32-i386', 'format');
+is_deeply($obj->{flags}, { DYNAMIC => 1, HAS_SYMS => 1, D_PAGED => 1 }, 'flags');
+is_deeply($obj->{NEEDED}, [ 'ld-linux.so.2' ], 'NEEDED');
+is_deeply([ $obj->get_needed_libraries ], [ 'ld-linux.so.2' ], 'NEEDED');
+
+my $sym = $obj->get_symbol('_sys_nerr@GLIBC_2.3');
+is_deeply( $sym, { name => '_sys_nerr', version => 'GLIBC_2.3',
+		   soname => 'libc.so.6', section => '.rodata', dynamic => 1,
+		   debug => '', type => 'O', weak => '',
+		   local => '', global => 1, visibility => '',
+		   hidden => 1, defined => 1 }, 'Symbol' );
+$sym = $obj->get_symbol('_IO_stdin_used');
+is_deeply( $sym, { name => '_IO_stdin_used', version => '',
+		   soname => 'libc.so.6', section => '*UND*', dynamic => 1,
+		   debug => '', type => ' ', weak => 1,
+		   local => '', global => '', visibility => '',   
+		   hidden => '', defined => '' }, 'Symbol 2' );
+
+my @syms = $obj->get_exported_dynamic_symbols;
+is( scalar @syms, 2231, 'defined && dynamic' );
+@syms = $obj->get_undefined_dynamic_symbols;
+is( scalar @syms, 9, 'undefined && dynamic' );
+
+
+my $obj_old = Dpkg::Shlibs::Objdump::Object->new;
+
+open $objdump, '<', "$srcdir/objdump.libc6-2.3"
+  or die "$srcdir/objdump.libc6-2.3: $!";
+$obj_old->_parse($objdump);
+close $objdump;
+
+
+use_ok('Dpkg::Shlibs::SymbolFile');
+
+my $sym_file = Dpkg::Shlibs::SymbolFile->new("$srcdir/symbol_file.tmp");
+my $sym_file_dup = Dpkg::Shlibs::SymbolFile->new("$srcdir/symbol_file.tmp");
+my $sym_file_old = Dpkg::Shlibs::SymbolFile->new("$srcdir/symbol_file.tmp");
+
+$sym_file->merge_symbols($obj_old, "2.3.6.ds1-13");
+$sym_file_old->merge_symbols($obj_old, "2.3.6.ds1-13");
+
+ok( $sym_file->has_object('libc.so.6'), 'SONAME in sym file' );
+
+$sym_file->merge_symbols($obj, "2.6-1");
+
+ok( $sym_file->has_new_symbols($sym_file_old), 'has new symbols' );
+ok( $sym_file_old->has_lost_symbols($sym_file), 'has lost symbols' );
+
+is( $sym_file_old->lookup_symbol('__bss_start@Base', ['libc.so.6']),
+    undef, 'internal symbols are blacklisted');
+
+$sym = $sym_file->lookup_symbol('_errno@GLIBC_2.0', ['libc.so.6'], 1);
+is_deeply($sym, { 'minver' => '2.3.6.ds1-13', 'dep_id' => 0, 
+		  'deprecated' => '2.6-1', 'depends' => '', 
+		  'soname' => 'libc.so.6' }, 'deprecated symbol');
+
+use File::Temp;
+
+my $save_file = new File::Temp;
+
+$sym_file->save($save_file->filename);
+
+$sym_file_dup->load($save_file->filename);
+$sym_file_dup->{file} = "$srcdir/symbol_file.tmp";
+
+is_deeply($sym_file_dup, $sym_file, 'save -> load' );
+
+# Test include mechanism of SymbolFile
+$sym_file = Dpkg::Shlibs::SymbolFile->new("$srcdir/symbols.include-1");
+
+$sym = $sym_file->lookup_symbol('symbol_before@Base', ['libfake.so.1']);
+is_deeply($sym, { 'minver' => '0.9', 'dep_id' => 0, 'deprecated' => 0,
+		  'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, 
+	    'symbol before include not lost');
+
+$sym = $sym_file->lookup_symbol('symbol_after@Base', ['libfake.so.1']);
+is_deeply($sym, {'minver' => '1.1', 'dep_id' => 0, 'deprecated' => 0, 
+		  'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, 
+	    'symbol after include not lost');
+
+$sym = $sym_file->lookup_symbol('symbol1_fake1@Base', ['libfake.so.1']);
+is_deeply($sym, {'minver' => '1.0', 'dep_id' => 0, 'deprecated' => 0, 
+		  'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, 
+	    'overrides order with #include');
+
+$sym = $sym_file->lookup_symbol('symbol3_fake1@Base', ['libfake.so.1']);
+is_deeply($sym, { 'minver' => '1.1', 'dep_id' => 0, 'deprecated' => 0,
+		  'depends' => 'libfake1 #MINVER#', 'soname' => 'libfake.so.1' }, 
+	    'overrides order with #include');
+
+$sym_file = Dpkg::Shlibs::SymbolFile->new("$srcdir/symbols.include-2");
+
+$sym = $sym_file->lookup_symbol('symbol1_fake2@Base', ['libfake.so.1']);
+is_deeply($sym, { 'minver' => '1.0', 'dep_id' => 1, 'deprecated' => 0,
+		  'depends' => 'libvirtualfake', 'soname' => 'libfake.so.1' }, 
+	    'overrides order with circular #include');
+
+# Check parsing of objdump output on ia64 (local symbols
+# without versions and with visibility attribute)
+$obj = Dpkg::Shlibs::Objdump::Object->new;
+
+open $objdump, '<', "$srcdir/objdump.glib-ia64"
+  or die "$srcdir/objdump.glib-ia64: $!";
+$obj->_parse($objdump);
+close $objdump;
+
+$sym = $obj->get_symbol('IA__g_free');
+is_deeply( $sym, { name => 'IA__g_free', version => '',
+		   soname => 'libglib-2.0.so.0', section => '.text', dynamic => 1,
+		   debug => '', type => 'F', weak => '',
+		   local => 1, global => '', visibility => 'hidden',
+		   hidden => '', defined => 1 }, 
+		   'symbol with visibility without version' );
+

+ 9 - 0
scripts/t/200_Dpkg_Shlibs/ld.so.conf

@@ -0,0 +1,9 @@
+# Comment and empty line
+
+# Paths
+/nonexistant32
+/nonexistant/lib64
+
+include /nonexistant/*.conf
+include t.tmp/ld.so.conf.d/*.conf
+

+ 1 - 0
scripts/t/200_Dpkg_Shlibs/ld.so.conf.d/inf_recurse.conf

@@ -0,0 +1 @@
+include t.tmp/ld.so.conf

+ 1 - 0
scripts/t/200_Dpkg_Shlibs/ld.so.conf.d/normal.conf

@@ -0,0 +1 @@
+/usr/local/lib/

+ 1 - 0
scripts/t/200_Dpkg_Shlibs/ld.so.conf.d/recursive.conf

@@ -0,0 +1 @@
+include t.tmp/ld.so.conf_2

+ 1 - 0
scripts/t/200_Dpkg_Shlibs/ld.so.conf_2

@@ -0,0 +1 @@
+/nonexistant/lib128

+ 350 - 0
scripts/t/200_Dpkg_Shlibs/objdump.glib-ia64

@@ -0,0 +1,350 @@
+
+/usr/lib/libglib-2.0.so.0:     file format elf64-little
+architecture: ia64-elf64, flags 0x00000150:
+HAS_SYMS, DYNAMIC, D_PAGED
+start address 0x000000000002dc40
+
+Program Header:
+    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**16
+         filesz 0x0000000000158820 memsz 0x0000000000158820 flags r-x
+    LOAD off    0x0000000000158820 vaddr 0x0000000000168820 paddr 0x0000000000168820 align 2**16
+         filesz 0x0000000000001498 memsz 0x0000000000001a90 flags rw-
+ DYNAMIC off    0x0000000000158948 vaddr 0x0000000000168948 paddr 0x0000000000168948 align 2**3
+         filesz 0x00000000000001f0 memsz 0x00000000000001f0 flags rw-
+   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**3
+         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
+0x70000001 off    0x0000000000150e28 vaddr 0x0000000000150e28 paddr 0x0000000000150e28 align 2**3
+         filesz 0x00000000000079f8 memsz 0x00000000000079f8 flags r--
+
+Dynamic Section:
+  NEEDED      libc.so.6.1
+  SONAME      libglib-2.0.so.0
+  INIT        0x15070
+  FINI        0x106360
+  INIT_ARRAY  0x168820
+  INIT_ARRAYSZ 0x18
+  FINI_ARRAY  0x168838
+  FINI_ARRAYSZ 0x8
+  HASH        0x158
+  GNU_HASH    0x25c8
+  STRTAB      0xc4c0
+  SYMTAB      0x4a38
+  STRSZ       0x5deb
+  SYMENT      0x18
+  0x70000000  0x168dd8
+  PLTGOT      0x168dd8
+  PLTRELSZ    0xcd8
+  PLTREL      0x7
+  JMPREL      0x14398
+  RELA        0x12d18
+  RELASZ      0x1680
+  RELAENT     0x18
+  VERNEED     0x12ce8
+  VERNEEDNUM  0x1
+  VERSYM      0x122ac
+  RELACOUNT   0x60
+
+Version References:
+  required from libc.so.6.1:
+    0x0d696913 0x00 03 GLIBC_2.3
+    0x0d696912 0x00 02 GLIBC_2.2
+
+DYNAMIC SYMBOL TABLE:
+00000000000bbaa0 l    DF .text	00000000000006b0              .hidden IA__g_thread_pool_new
+000000000007b730 l    DF .text	0000000000000200              .hidden IA__g_option_group_free
+00000000000b2f30 l    DF .text	0000000000000060              .hidden IA__g_str_equal
+00000000000cd0c0 l    DF .text	0000000000000010              .hidden IA__g_direct_hash
+0000000000095660 l    DF .text	00000000000001d0              .hidden IA__g_scanner_warn
+00000000001062e0 l    DF .text	0000000000000080              .hidden __do_global_ctors_aux
+0000000000071fe0 l    DF .text	00000000000000f0              .hidden IA__g_free
+0000000000074a30 l    DF .text	0000000000000370              .hidden _g_log_fallback_handler
+0000000000077080 l    DF .text	0000000000000a20              .hidden IA__g_log_default_handler
+00000000000afc90 l    DF .text	0000000000000090              .hidden IA__g_str_hash
+0000000000095830 l    DF .text	00000000000001f0              .hidden IA__g_scanner_error
+00000000000d4d60 l    DF .text	0000000000000290              g_io_unix_get_flags
+00000000000d4a60 l    DF .text	0000000000000120              g_io_unix_set_flags
+00000000000d4b80 l    DF .text	0000000000000020              g_io_unix_free
+00000000000d4ba0 l    DF .text	00000000000000c0              g_io_unix_create_watch
+00000000000d4c60 l    DF .text	0000000000000100              g_io_unix_close
+00000000000d4ff0 l    DF .text	00000000000001f0              g_io_unix_seek
+00000000000d51e0 l    DF .text	0000000000000150              g_io_unix_write
+00000000000d5330 l    DF .text	0000000000000180              g_io_unix_read
+00000000000d4820 l    DF .text	0000000000000030              g_io_unix_finalize
+00000000000d4950 l    DF .text	0000000000000110              g_io_unix_dispatch
+00000000000d4850 l    DF .text	0000000000000080              g_io_unix_check
+00000000000d48d0 l    DF .text	0000000000000080              g_io_unix_prepare
+00000000000cd720 l    DF .text	0000000000000090              language_names_cache_free
+00000000000c89f0 l    DF .text	0000000000000090              charset_cache_free
+00000000000c20f0 l    DF .text	0000000000000050              interval_compare
+00000000000bb270 l    DF .text	0000000000000830              g_thread_pool_thread_proxy
+00000000000b3360 l    DF .text	0000000000000050              g_thread_fail
+00000000000b33b0 l    DF .text	00000000000000c0              gettime
+00000000000b8c70 l    DF .text	00000000000004a0              g_thread_cleanup
+00000000000b6790 l    DF .text	00000000000003b0              g_thread_create_proxy
+00000000000a37a0 l    DF .text	0000000000000320              private_thread_memory_cleanup
+000000000009a7d0 l    DF .text	00000000000000e0              iter_compare
+0000000000094c10 l    DF .text	0000000000000060              g_scanner_destroy_symbol_table_entry
+0000000000095f50 l    DF .text	00000000000001b0              g_scanner_msg_handler
+0000000000096100 l    DF .text	00000000000000a0              g_scanner_key_equal
+0000000000093210 l    DF .text	0000000000000080              g_scanner_key_hash
+0000000000093290 l    DF .text	00000000000000c0              g_scanner_foreach_internal
+0000000000092510 l    DF .text	00000000000004a0              interpolate_replacement
+000000000008cd60 l    DF .text	0000000000000050              literal_replacement
+000000000008cd00 l    DF .text	0000000000000060              free_interpolation_data
+0000000000089190 l    DF .text	0000000000000040              relation_delete_value_tuple
+0000000000089c20 l    DF .text	0000000000000030              g_relation_free_array
+0000000000089690 l    DF .text	0000000000000210              g_relation_delete_tuple
+00000000000895a0 l    DF .text	00000000000000f0              g_relation_select_tuple
+0000000000088c30 l    DF .text	00000000000000a0              g_relation_print_index
+0000000000088cd0 l    DF .text	0000000000000170              g_relation_print_one
+00000000000889a0 l    DF .text	0000000000000020              tuple_hash_2
+0000000000088940 l    DF .text	0000000000000060              tuple_equal_2
+000000000007bc50 l    DF .text	0000000000000050              dgettext_swapped
+00000000000787b0 l    DF .text	0000000000000040              g_node_find_func
+0000000000071570 l    DF .text	0000000000000200              profiler_try_realloc
+0000000000071770 l    DF .text	0000000000000150              profiler_try_malloc
+0000000000073410 l    DF .text	0000000000000190              profiler_calloc
+00000000000718c0 l    DF .text	00000000000001c0              profiler_free
+0000000000073380 l    DF .text	0000000000000090              profiler_realloc
+00000000000735a0 l    DF .text	0000000000000090              profiler_malloc
+0000000000071a80 l    DF .text	00000000000000d0              fallback_calloc
+000000000005a2b0 l    DF .text	0000000000000040              g_source_callback_get
+000000000005d650 l    DF .text	00000000000000e0              g_source_callback_unref
+000000000005a290 l    DF .text	0000000000000020              g_source_callback_ref
+000000000005a340 l    DF .text	00000000000000c0              g_idle_dispatch
+000000000005a330 l    DF .text	0000000000000010              g_idle_check
+000000000005a310 l    DF .text	0000000000000020              g_idle_prepare
+000000000005a400 l    DF .text	00000000000000c0              g_child_watch_dispatch
+000000000005a5c0 l    DF .text	0000000000000020              g_child_watch_check
+000000000005a5e0 l    DF .text	0000000000000030              g_child_watch_prepare
+0000000000060390 l    DF .text	0000000000000160              g_timeout_dispatch
+00000000000604f0 l    DF .text	00000000000000f0              g_timeout_check
+00000000000605e0 l    DF .text	0000000000000310              g_timeout_prepare
+000000000005cc20 l    DF .text	0000000000000030              g_main_dispatch_free
+000000000005b130 l    DF .text	00000000000000b0              g_child_watch_signal_handler
+00000000000619f0 l    DF .text	00000000000002e0              child_watch_helper_thread
+000000000004d830 l    DF .text	00000000000000b0              g_key_file_key_value_pair_free
+0000000000041860 l    DF .text	0000000000000090              default_finalize_hook
+000000000002b370 l    DF .text	0000000000000090              filename_charset_cache_free
+000000000001fe80 l    DF .text	0000000000000440              text_raw_cb
+0000000000020660 l    DF .text	0000000000000480              end_element_raw_cb
+0000000000026110 l    DF .text	0000000000001cf0              start_element_raw_cb
+000000000001e790 l    DF .text	0000000000000060              parse_data_free
+000000000001e6e0 l    DF .text	00000000000000b0              bookmark_app_info_free
+000000000001e960 l    DF .text	0000000000000260              bookmark_item_free
+000000000001c300 l    DF .text	0000000000000020              stack_trace_sigchld
+0000000000019a00 l    DF .text	0000000000000070              g_async_queue_invert_compare
+0000000000016be0 l    DF .text	0000000000000080              __do_jv_register_classes
+0000000000016b20 l    DF .text	00000000000000b0              __do_global_dtors_aux
+0000000000016aa0 l    DF .text	0000000000000070              gmon_initializer
+0000000000000000      DF *UND*	0000000000000370  GLIBC_2.2   getpwuid
+0000000000000000      DF *UND*	0000000000000550  GLIBC_2.2   freopen
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   __strtod_internal
+0000000000000000      DF *UND*	0000000000000240  GLIBC_2.2   feof
+0000000000000000      DF *UND*	0000000000000450  GLIBC_2.2   localeconv
+0000000000000000      DF *UND*	00000000000001e0  GLIBC_2.2   strcpy
+0000000000000000      DF *UND*	0000000000000200  GLIBC_2.2   raise
+0000000000000000      DO *UND*	0000000000000008  GLIBC_2.2   environ
+0000000000000000      DF *UND*	0000000000000030  GLIBC_2.2   getuid
+0000000000000000      DF *UND*	0000000000000180  GLIBC_2.2   waitpid
+0000000000000000      DF *UND*	0000000000000100  GLIBC_2.2   strcasecmp
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   select
+0000000000000000      DF *UND*	0000000000000110  GLIBC_2.2   closedir
+0000000000000000      DF *UND*	0000000000000440  GLIBC_2.2   fwrite
+0000000000000000      DF *UND*	00000000000001d0  GLIBC_2.2   rewinddir
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   close
+0000000000000000      DF *UND*	0000000000000280  GLIBC_2.2   strstr
+0000000000000000      DF *UND*	0000000000000080  GLIBC_2.2   time
+0000000000000000      DF *UND*	0000000000000520  GLIBC_2.2   fdopen
+0000000000000000  w   D  *UND*	0000000000000000              __gmon_start__
+0000000000000000  w   D  *UND*	0000000000000000              _Jv_RegisterClasses
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   wcsxfrm
+0000000000000000      DF *UND*	00000000000000c0  GLIBC_2.2   strncasecmp
+0000000000000000      DF *UND*	00000000000000d0  GLIBC_2.2   remove
+0000000000000000      DF *UND*	00000000000004f0  GLIBC_2.2   malloc
+0000000000000000      DF *UND*	0000000000000080  GLIBC_2.2   execve
+0000000000000000      DF *UND*	00000000000000b0  GLIBC_2.2   fprintf
+0000000000000000      DF *UND*	0000000000000200  GLIBC_2.2   setpwent
+0000000000000000      DF *UND*	0000000000000100  GLIBC_2.2   nl_langinfo
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   chdir
+0000000000000000      DF *UND*	0000000000000100  GLIBC_2.2   gethostname
+0000000000000000  w   DO *UND*	0000000000000008  GLIBC_2.2   _environ
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   rmdir
+0000000000000000      DF *UND*	0000000000000390  GLIBC_2.2   fputc
+0000000000000000      DF *UND*	0000000000000170  GLIBC_2.2   poll
+0000000000000000      DF *UND*	00000000000003e0  GLIBC_2.2   getcwd
+0000000000000000      DO *UND*	0000000000000008  GLIBC_2.2   stdin
+0000000000000000      DF *UND*	00000000000004f0  GLIBC_2.2   getpwnam_r
+0000000000000000      DF *UND*	0000000000000520  GLIBC_2.2   memmove
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   __strtoul_internal
+0000000000000000      DO *UND*	0000000000000008  GLIBC_2.2   stdout
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   strncmp
+0000000000000000      DF *UND*	0000000000000320  GLIBC_2.2   vasprintf
+0000000000000000      DF *UND*	0000000000000210  GLIBC_2.2   endpwent
+0000000000000000      DF *UND*	00000000000001f0  GLIBC_2.2   fcntl
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   dup2
+0000000000000000      DF *UND*	00000000000007e0  GLIBC_2.2   fork
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   gmtime
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   readlink
+0000000000000000      DF *UND*	0000000000000080  GLIBC_2.3   __ctype_toupper_loc
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   lseek
+0000000000000000      DF *UND*	00000000000000c0  GLIBC_2.2   __fxstat
+0000000000000000      DF *UND*	00000000000000b0  GLIBC_2.2   fscanf
+0000000000000000      DO *UND*	0000000000000008  GLIBC_2.2   __environ
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   munmap
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   strftime
+0000000000000000      DF *UND*	00000000000003a0  GLIBC_2.2   fread
+0000000000000000      DF *UND*	0000000000007090  GLIBC_2.2   vfprintf
+0000000000000000      DF *UND*	00000000000000b0  GLIBC_2.2   snprintf
+0000000000000000      DF *UND*	0000000000000330  GLIBC_2.2   iconv_open
+0000000000000000      DF *UND*	0000000000000080  GLIBC_2.3   __ctype_b_loc
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   nanosleep
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   pipe
+0000000000000000      DF *UND*	0000000000000090  GLIBC_2.2   strpbrk
+0000000000000000      DF *UND*	0000000000000640  GLIBC_2.2   realloc
+0000000000000000      DF *UND*	0000000000000240  GLIBC_2.2   ferror
+0000000000000000      DF *UND*	00000000000004f0  GLIBC_2.2   getpwuid_r
+0000000000000000      DF *UND*	0000000000000030  GLIBC_2.2   strcmp
+0000000000000000      DF *UND*	00000000000000e0  GLIBC_2.2   setenv
+0000000000000000      DF *UND*	0000000000000650  GLIBC_2.2   fclose
+0000000000000000  w   DF *UND*	0000000000000220  GLIBC_2.2   __cxa_finalize
+0000000000000000      DF *UND*	0000000000000020  GLIBC_2.2   __errno_location
+0000000000000000      DF *UND*	00000000000002c0  GLIBC_2.2   exit
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   open
+0000000000000000      DF *UND*	0000000000000590  GLIBC_2.2   abort
+0000000000000000      DF *UND*	0000000000000400  GLIBC_2.2   fputs
+0000000000000000      DF *UND*	00000000000000a0  GLIBC_2.2   sigemptyset
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   localtime_r
+0000000000000000      DF *UND*	00000000000000b0  GLIBC_2.2   sprintf
+0000000000000000      DF *UND*	00000000000002c0  GLIBC_2.2   unsetenv
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   mmap
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   mkdir
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   creat
+0000000000000000      DF *UND*	00000000000000d0  GLIBC_2.2   getpid
+0000000000000000      DF *UND*	0000000000000170  GLIBC_2.2   strerror
+0000000000000000      DF *UND*	0000000000000220  GLIBC_2.2   memcmp
+0000000000000000      DF *UND*	0000000000000320  GLIBC_2.2   qsort
+0000000000000000      DF *UND*	0000000000000c70  GLIBC_2.2   sysconf
+0000000000000000      DF *UND*	0000000000000190  GLIBC_2.2   bsearch
+0000000000000000      DF *UND*	00000000000001b0  GLIBC_2.2   signal
+0000000000000000      DF *UND*	00000000000000c0  GLIBC_2.2   __xstat
+0000000000000000      DF *UND*	00000000000000c0  GLIBC_2.2   __lxstat
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   wcscoll
+0000000000000000      DF *UND*	0000000000000160  GLIBC_2.2   vsprintf
+0000000000000000      DF *UND*	0000000000000130  GLIBC_2.2   vsnprintf
+0000000000000000      DF *UND*	00000000000003e0  GLIBC_2.2   strncpy
+0000000000000000      DF *UND*	00000000000002e0  GLIBC_2.2   getenv
+0000000000000000      DF *UND*	0000000000000120  GLIBC_2.2   strchr
+0000000000000000      DF *UND*	00000000000008c0  GLIBC_2.2   calloc
+0000000000000000      DF *UND*	00000000000000a0  GLIBC_2.2   __cxa_atexit
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   write
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   stpcpy
+0000000000000000      DF *UND*	0000000000000450  GLIBC_2.2   fgets
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   rename
+0000000000000000      DF *UND*	0000000000000310  GLIBC_2.2   __uflow
+0000000000000000      DF *UND*	0000000000000410  GLIBC_2.2   memset
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   fopen
+0000000000000000      DF *UND*	0000000000000050  GLIBC_2.2   __strtol_internal
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   unlink
+0000000000000000      DF *UND*	0000000000000430  GLIBC_2.2   iconv
+0000000000000000      DF *UND*	00000000000001b0  GLIBC_2.2   perror
+0000000000000000      DF *UND*	0000000000000880  GLIBC_2.2   execvp
+0000000000000000      DF *UND*	0000000000000330  GLIBC_2.2   ungetc
+0000000000000000      DF *UND*	0000000000000140  GLIBC_2.2   _exit
+0000000000000000      DF *UND*	0000000000000080  GLIBC_2.3   __ctype_tolower_loc
+0000000000000000      DF *UND*	0000000000000070  GLIBC_2.2   bindtextdomain
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   chmod
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   timegm
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   read
+0000000000000000      DF *UND*	0000000000000300  GLIBC_2.2   readdir
+0000000000000000      DF *UND*	0000000000000300  GLIBC_2.2   free
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   dcgettext
+0000000000000000      DF *UND*	00000000000000e0  GLIBC_2.2   strrchr
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   access
+0000000000000000      DF *UND*	0000000000000390  GLIBC_2.2   fflush
+0000000000000000      DF *UND*	0000000000000070  GLIBC_2.2   bind_textdomain_codeset
+0000000000000000      DF *UND*	00000000000001c0  GLIBC_2.2   opendir
+0000000000000000      DF *UND*	0000000000000530  GLIBC_2.2   strsignal
+0000000000000000      DF *UND*	0000000000000070  GLIBC_2.2   isatty
+0000000000000000      DF *UND*	0000000000000130  GLIBC_2.2   posix_memalign
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   gettimeofday
+0000000000000000      DF *UND*	00000000000000a0  GLIBC_2.2   iconv_close
+0000000000000000      DF *UND*	0000000000000040  GLIBC_2.2   dup
+0000000000000000      DF *UND*	0000000000000540  GLIBC_2.2   memcpy
+0000000000000000      DO *UND*	0000000000000008  GLIBC_2.2   stderr
+0000000000000000      DF *UND*	0000000000000030  GLIBC_2.2   getppid
+0000000000000000      DF *UND*	0000000000000100  GLIBC_2.2   strlen
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   execv
+0000000000000000      DF *UND*	0000000000000f50  GLIBC_2.2   setlocale
+0000000000000000      DF *UND*	0000000000000060  GLIBC_2.2   sigaction
+00000000000909e0 g    DF .text	0000000000000310  Base        g_regex_match_full
+0000000000038400 g    DF .text	0000000000000660  Base        g_date_strftime
+0000000000017530 g    DF .text	00000000000000f0  Base        g_ptr_array_add
+00000000000c6930 g    DF .text	00000000000001e0  Base        g_utf8_strreverse
+0000000000039650 g    DF .text	0000000000000030  Base        g_date_set_time
+00000000000cab10 g    DF .text	0000000000000710  Base        g_utf8_collate_key_for_filename
+00000000000c26f0 g    DF .text	0000000000000160  Base        g_unichar_type
+000000000002a930 g    DF .text	0000000000000430  Base        g_uri_list_extract_uris
+00000000000cf850 g    DF .text	0000000000000350  Base        g_get_system_data_dirs
+000000000008b450 g    DF .text	0000000000000070  Base        g_rand_new_with_seed_array
+00000000000a7410 g    DF .text	0000000000000080  Base        g_slist_concat
+0000000000033c50 g    DF .text	0000000000000020  Base        g_date_valid_weekday
+000000000003f090 g    DF .text	0000000000000190  Base        g_hash_table_get_values
+0000000000058710 g    DF .text	0000000000000010  Base        g_list_pop_allocator
+000000000008c9a0 g    DF .text	00000000000000b0  Base        g_match_info_is_partial_match
+00000000000d3620 g    DF .text	0000000000000290  Base        g_get_user_name
+00000000000a84d0 g    DF .text	0000000000000030  Base        g_slist_free_1
+00000000000cccc0 g    DF .text	00000000000002b0  Base        g_unicode_canonical_decomposition
+00000000000656e0 g    DF .text	0000000000000550  Base        g_main_context_unref
+00000000000d42b0 g    DF .text	0000000000000100  Base        g_vsprintf
+0000000000079f90 g    DF .text	00000000000000e0  Base        g_node_get_root
+0000000000016df0 g    DF .text	0000000000000130  Base        g_ptr_array_remove_index_fast
+000000000007b3b0 g    DF .text	0000000000000080  Base        g_option_group_set_parse_hooks
+00000000000b2c80 g    DF .text	0000000000000170  Base        g_string_chunk_clear
+0000000000021620 g    DF .text	0000000000000040  Base        g_bookmark_file_error_quark
+0000000000088490 g    DF .text	0000000000000110  Base        g_queue_sort
+00000000000c7c00 g    DF .text	0000000000000530  Base        g_utf16_to_utf8
+00000000000197e0 g    DF .text	0000000000000050  Base        g_byte_array_prepend
+0000000000053510 g    DF .text	0000000000000580  Base        g_key_file_get_string_list
+0000000000169a40 g    DO .sdata	0000000000000008  Base        glib_mem_profiler_table
+00000000000a8760 g    DF .text	00000000000000d0  Base        g_slist_remove_link
+00000000000a8130 g    DF .text	0000000000000060  Base        g_slist_prepend
+0000000000063bf0 g    DF .text	0000000000000390  Base        g_main_context_find_source_by_user_data
+000000000005c540 g    DF .text	00000000000000d0  Base        g_main_loop_is_running
+000000000003c5e0 g    DF .text	0000000000000030  Base        g_mkstemp
+00000000000b0440 g    DF .text	0000000000000140  Base        g_string_set_size
+0000000000088160 g    DF .text	0000000000000110  Base        g_queue_insert_after
+00000000000738a0 g    DF .text	0000000000000150  Base        g_log_set_default_handler
+0000000000059c30 g    DF .text	00000000000000b0  Base        g_list_delete_link
+0000000000058a10 g    DF .text	0000000000000090  Base        g_list_position
+0000000000059110 g    DF .text	0000000000000100  Base        g_list_find_custom
+00000000000b0990 g    DF .text	00000000000000f0  Base        g_string_ascii_down
+00000000000629a0 g    DF .text	0000000000000130  Base        g_main_loop_new
+000000000005acb0 g    DF .text	00000000000000b0  Base        g_source_get_context
+0000000000033c00 g    DF .text	0000000000000020  Base        g_date_valid_year
+00000000000a7d90 g    DF .text	0000000000000030  Base        g_slist_insert_sorted
+000000000009f6a0 g    DF .text	0000000000000f20  Base        g_shell_parse_argv
+00000000000bca30 g    DF .text	00000000000000f0  Base        g_timer_stop
+0000000000099ec0 g    DF .text	0000000000000120  Base        g_scanner_peek_next_token
+000000000002d5a0 g    DF .text	00000000000000f0  Base        g_filename_display_basename
+00000000000305c0 g    DF .text	0000000000000580  Base        g_dataset_id_get_data
+0000000000064a50 g    DF .text	0000000000000480  Base        g_source_attach
+000000000003e5d0 g    DF .text	0000000000000360  Base        g_mkdir_with_parents
+000000000001de50 g    DF .text	0000000000000110  Base        g_bookmark_file_has_item
+0000000000065050 g    DF .text	00000000000001c0  Base        g_child_watch_add_full
+00000000000a8830 g    DF .text	0000000000000050  Base        g_freopen
+00000000000a8730 g    DF .text	0000000000000030  Base        g_slist_alloc
+0000000000054a60 g    DF .text	0000000000000480  Base        g_key_file_get_locale_string
+0000000000094fd0 g    DF .text	00000000000001b0  Base        g_scanner_input_file
+0000000000093660 g    DF .text	00000000000000a0  Base        g_scanner_set_scope
+0000000000022780 g    DF .text	0000000000000180  Base        g_bookmark_file_get_visited
+000000000002f280 g    DF .text	00000000000003a0  Base        g_datalist_id_get_data
+0000000000040000 g    DF .text	00000000000000e0  Base        g_hash_table_new_full
+00000000000d2f40 g    DF .text	0000000000000260  Base        g_get_user_config_dir
+0000000000059700 g    DF .text	0000000000000280  Base        g_list_insert_before
+0000000000079270 g    DF .text	00000000000000f0  Base        g_node_n_children
+00000000000d0680 g    DF .text	0000000000000460  Base        g_get_user_cache_dir
+000000000006a5a0 g    DF .text	00000000000000d0  Base        g_markup_parse_context_get_element
+00000000000aefe0 g    DF .text	00000000000000a0  Base        g_strndup
+
+

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2276 - 0
scripts/t/200_Dpkg_Shlibs/objdump.libc6-2.3


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2345 - 0
scripts/t/200_Dpkg_Shlibs/objdump.libc6-2.6


+ 4 - 0
scripts/t/200_Dpkg_Shlibs/symbols.fake-1

@@ -0,0 +1,4 @@
+libfake.so.1 libfake1 #MINVER#
+ symbol1_fake1@Base 1.0
+ symbol2_fake1@Base 1.0
+ symbol3_fake1@Base 1.0

+ 8 - 0
scripts/t/200_Dpkg_Shlibs/symbols.fake-2

@@ -0,0 +1,8 @@
+#include "symbols.include-2"
+# This is just a comment
+libfake.so.1 libfake1 #MINVER#
+# The alternate dependency is below
+| libvirtualfake
+ symbol1_fake2@Base 1.0 1
+ symbol2_fake2@Base 1.0
+ symbol3_fake2@Base 1.0

+ 7 - 0
scripts/t/200_Dpkg_Shlibs/symbols.include-1

@@ -0,0 +1,7 @@
+libfake.so.1 libfake1
+ symbol1_fake1@Base 0.9
+ symbol2_fake1@Base 0.9
+ symbol_before@Base 0.9
+#include "symbols.fake-1"
+ symbol3_fake1@Base 1.1
+ symbol_after@Base 1.1

+ 3 - 0
scripts/t/200_Dpkg_Shlibs/symbols.include-2

@@ -0,0 +1,3 @@
+libfake.so.1 libfake1
+ symbol1_fake2@Base 0.5
+#include "symbols.fake-2"