[Reproducible-builds] [debhelper] 02/07: dh_strip: normalize ar file headers for reproducible builds
Jérémy Bobbio
lunar at moszumanska.debian.org
Sun Aug 31 03:46:51 UTC 2014
This is an automated email from the git hooks/post-receive script.
lunar pushed a commit to branch pu/reproducible_builds
in repository debhelper.
commit 99adaf58da5f63065076d21818ce03ac3c7537a4
Author: Jérémy Bobbio <lunar at debian.org>
Date: Sat Aug 30 02:24:57 2014 +0000
dh_strip: normalize ar file headers for reproducible builds
User id, group id, timestamps and file modes can get captured when creating
static libraries. While this information is not useful while building software,
it prevents build to be reproducible. Let's replace the data by what is
written when `ar` is used in "deterministic" mode.
Thanks to Niko Tyni for the Perl code.
---
dh_strip | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/dh_strip b/dh_strip
index 516b6f2..c55f10f 100755
--- a/dh_strip
+++ b/dh_strip
@@ -8,6 +8,7 @@ dh_strip - strip executables, shared libraries, and some static libraries
use strict;
use File::Find;
+use Fcntl q/SEEK_SET/;
use Debian::Debhelper::Dh_Lib;
=head1 SYNOPSIS
@@ -28,6 +29,9 @@ strips each as much as is possible. (Which is not at all for debugging
libraries.) In general it seems to make very good guesses, and will do the
right thing in almost all cases.
+For static libraries, it will also normalize user id, group id, timestamp and
+file mode of the archive members to enable build reproducibility.
+
Since it is very hard to automatically guess if a file is a
module, and hard to determine how to strip a module, B<dh_strip> does not
currently deal with stripping binary modules such as F<.o> files.
@@ -190,6 +194,61 @@ sub attach_debug {
doit($objcopy, "--add-gnu-debuglink", $debug_path, $file);
}
+sub normalize_ar {
+ my $file=shift;
+
+ my $GLOBAL_HEADER= "!<arch>\n";
+ my $GLOBAL_HEADER_LENGTH=length $GLOBAL_HEADER;
+
+ my $FILE_HEADER_LENGTH=60;
+ my $FILE_MAGIC="`\n";
+
+ my $buf;
+
+ open(F, '+<', $file)
+ or die("failed to open $file for read+write: $!");
+
+ read F, $buf, $GLOBAL_HEADER_LENGTH;
+ die("Unable to find global header") if $buf ne $GLOBAL_HEADER;
+
+ while (1) {
+ my $file_header_start=tell F;
+ my $count=read F, $buf, $FILE_HEADER_LENGTH;
+ die "reading $file failed: $!" if !defined $count;
+ last if $count == 0;
+
+ # http://en.wikipedia.org/wiki/Ar_(Unix)
+ #from to Name Format
+ #0 15 File name ASCII
+ #16 27 File modification date Decimal
+ #28 33 Owner ID Decimal
+ #34 39 Group ID Decimal
+ #40 47 File mode Octal
+ #48 57 File size in bytes Decimal
+ #58 59 File magic \140\012
+
+ die "Incorrect header length"
+ if length $buf != $FILE_HEADER_LENGTH;
+ die "Incorrect file magic"
+ if substr($buf, 58, length($FILE_MAGIC)) ne $FILE_MAGIC;
+
+ my $file_size = substr($buf, 48, 10);
+ seek F, $file_header_start + 16, SEEK_SET;
+
+ # mtime
+ syswrite F, sprintf("%-12d", 0);
+ # owner
+ syswrite F, sprintf("%-6d", 0);
+ # group
+ syswrite F, sprintf("%-6d", 0);
+ # file mode
+ syswrite F, sprintf("%-8o", 0644);
+
+ # move to next member
+ seek F, $file_header_start + $FILE_HEADER_LENGTH + $file_size, SEEK_SET;
+ }
+}
+
foreach my $package (@{$dh{DOPACKAGES}}) {
my $tmp=tmpdir($package);
@@ -236,6 +295,7 @@ foreach my $package (@{$dh{DOPACKAGES}}) {
foreach (@static_libs) {
doit($strip,"--strip-debug",$_);
+ normalize_ar($_);
}
}
@@ -248,5 +308,6 @@ This program is a part of debhelper.
=head1 AUTHOR
Joey Hess <joeyh at debian.org>
+Niko Tyni <ntyni at debian.org>
=cut
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/reproducible/debhelper.git
More information about the Reproducible-builds
mailing list