ajacoutot@, me and probably others were seeing. No fallout in bulk build.
Input from espie@ and ajacoutot@.
Prodding by ajacoutot@
Bulk test by jasper@
-# $OpenBSD: Archive.pm,v 1.5 2012/11/09 10:51:47 espie Exp $
+# $OpenBSD: Archive.pm,v 1.6 2014/04/16 10:31:27 zhuk Exp $
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
package LT::Archive;
use LT::Trace;
use LT::Exec;
+use LT::UList;
use LT::Util;
use File::Path;
tsay {"generating symbol list in file: $filepath"};
tsay {"object list is @$objlist" };
my $symbols = [];
+ tie (@$symbols, 'LT::UList');
open(my $sh, '-|', 'nm', '--', @$objlist) or
die "Error running nm on object list @$objlist\n";
my $c = 0;
}
$c++;
}
- $symbols = reverse_zap_duplicates_ref($symbols);
- @$symbols = sort @$symbols;
open(my $fh, '>', $filepath) or die "Cannot open $filepath\n";
- print $fh map { "$_\n" } @$symbols;
+ print $fh map { "$_\n" } sort @$symbols;
}
1;
-# $OpenBSD: LaFile.pm,v 1.20 2014/03/06 08:58:43 ajacoutot Exp $
+# $OpenBSD: LaFile.pm,v 1.21 2014/04/16 10:31:27 zhuk Exp $
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
{
my ($self, $l, $dirs) = @_;
- # sort dir search order by priority
- # XXX not fully correct yet
- my @sdirs = sort { $dirs->{$b} <=> $dirs->{$a} } keys %$dirs;
# search in cwd as well
- unshift @sdirs, '.';
+ unshift @$dirs, '.';
tsay {"searching .la for $l"};
- tsay {"search path= ", join(':', @sdirs)};
- foreach my $d (@sdirs) {
+ tsay {"search path= ", join(':', @$dirs)};
+ foreach my $d (@$dirs) {
foreach my $la_candidate ("$d/lib$l.la", "$d/$l.la") {
if (-f $la_candidate) {
tsay {"found $la_candidate"};
-# $OpenBSD: Library.pm,v 1.9 2014/03/19 02:16:22 afresh1 Exp $
+# $OpenBSD: Library.pm,v 1.10 2014/04/16 10:31:27 zhuk Exp $
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
"points to nonexistent file ", $libfile, " !"};
}
} else {
- # otherwise, search the filesystem
- # sort dir search order by priority
- # XXX not fully correct yet
- my @sdirs = sort { $dirs->{$b} <=> $dirs->{$a} } keys %$dirs;
# search in .libs when priority is high
- map { $_ = "$_/$ltdir" if (exists $dirs->{$_} && $dirs->{$_} > 3) } @sdirs;
- push @sdirs, $gp->libsearchdirs if $gp;
+ push @$dirs, $gp->libsearchdirs if $gp;
tsay {"searching for $libtofind"};
- tsay {"search path= ", join(':', @sdirs)};
+ tsay {"search path= ", join(':', @$dirs)};
tsay {"search type= ", $shared ? 'shared' : 'static'};
- foreach my $sd (@sdirs) {
+ foreach my $sd (@$dirs) {
if ($shared) {
# select correct library by sorting by version number only
my $bestlib = $self->findbest($sd, $libtofind);
# ex:ts=8 sw=4:
-# $OpenBSD: Link.pm,v 1.25 2014/03/19 02:16:22 afresh1 Exp $
+# $OpenBSD: Link.pm,v 1.26 2014/04/16 10:31:27 zhuk Exp $
#
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
# supplement OSConfig with stuff needed.
package LT::OSConfig;
+require LT::UList;
+
+my $search_dir_obj = tie(my @search_dir_list, 'LT::UList');
-my ($search_dir_hash, $search_dir_list);
sub fillup_search_dirs
{
- return if defined $search_dir_list;
- $search_dir_list = [];
- $search_dir_hash = {};
+ return if @search_dir_list;
open(my $fh, '-|', '/sbin/ldconfig -r');
if (!defined $fh) {
die "Can't run ldconfig\n";
}
while (<$fh>) {
if (m/^\s*search directories:\s*(.*?)\s*$/o) {
- foreach my $d (split(/\:/o, $1)) {
- push @$search_dir_list, $d;
- $search_dir_hash->{$d} = 1;
- }
+ push @search_dir_list, split(/\:/o, $1);
last;
}
}
{
my $self = shift;
$self->fillup_search_dirs;
- return @$search_dir_list;
+ return @search_dir_list;
}
sub is_search_dir
{
my ($self, $dir) = @_;
$self->fillup_search_dirs;
- return $search_dir_hash->{$dir};
+ return $search_dir_obj->exists($dir);
}
my $noshared = $ltconfig->noshared;
my $cmd;
- my $libdirs = []; # list of libdirs
- my $libs = LT::Library::Stash->new; # libraries
- my $dirs = {}; # paths to find libraries
- # put a priority in the dir hash
- # always look here
- $dirs->{'/usr/lib'} = 3;
+ my $libdirs = []; # list of libdirs
+ tie (@$libdirs, 'LT::UList');
+ my $libs = LT::Library::Stash->new; # libraries
+ my $dirs = []; # paths to find libraries
+ tie (@$dirs, 'LT::UList', '/usr/lib'); # always look here
$gp->handle_permuted_options(
'all-static',
tsay {"sobjs = @sobjs"};
my $deplibs = []; # list of dependent libraries (both -L and -l flags)
+ tie (@$deplibs, 'LT::UList');
my $parser = LT::Parser->new(\@ARGV);
if ($linkmode == PROGRAM) {
tsay {"hoping for real objects in ARGV..."};
}
}
- my $RPdirs = [];
- @$RPdirs = (@Ropts, @RPopts, $gp->Rresolved);
+ tie(my @temp, 'LT::UList', @Ropts, @RPopts, $gp->Rresolved);
+ my $RPdirs = \@temp;
$program->{RPdirs} = $RPdirs;
$program->link($ltprog, $ltconfig, $dirs, $libs, $deplibs, $libdirs, $parser, $gp);
map { $_ = "-R$_" } @Ropts;
unshift @$deplibs, @Ropts if @Ropts;
tsay {"deplibs = @$deplibs"};
- my $finaldeplibs = reverse_zap_duplicates_ref($deplibs);
- tsay {"finaldeplibs = @$finaldeplibs"};
- $lainfo->set('dependency_libs', "@$finaldeplibs");
+ $lainfo->set('dependency_libs', "@$deplibs");
if (@RPopts) {
if (@RPopts > 1) {
tsay {"more than 1 -rpath option given, ",
}
my $lai = "$odir/$ltdir/$ofile".'i';
if ($shared) {
- my $pdeplibs = process_deplibs($finaldeplibs);
+ my $pdeplibs = process_deplibs($deplibs);
if (defined $pdeplibs) {
$lainfo->set('dependency_libs', "@$pdeplibs");
}
# XXX improve checks when adding to deplibs
say "warning: $lf dropped from deplibs";
} else {
- $lf = $libdir.'/'.$lafile;
- push @$result, $lf;
+ push @$result, $libdir.'/'.$lafile;
}
} else {
push @$result, $lf;
package LT::Parser;
use File::Basename;
use Cwd qw(abs_path);
+use LT::UList;
use LT::Util;
use LT::Trace;
{
my ($self, $lainfo, $level) = @_;
my $o = $lainfo->{cached} = {
- deplibs => [], libdirs => [], result => []};
+ deplibs => [], libdirs => [], result => [] };
+ tie @{$o->{deplibs}}, 'LT::UList';
+ tie @{$o->{libdirs}}, 'LT::UList';
+ tie @{$o->{result}}, 'LT::UList';
$self->internal_resolve_la($o, $lainfo->deplib_list,
$level+1);
push(@{$o->{deplibs}}, @{$lainfo->deplib_list});
if ($lainfo->{libdir} ne '') {
push(@{$o->{libdirs}}, $lainfo->{libdir});
}
- for my $e (qw(deplibs libdirs result)) {
- if (@{$o->{$e}} > 50) {
- $o->{$e} = reverse_zap_duplicates_ref($o->{$e});
- }
- }
}
sub internal_resolve_la
tsay {"resolve level: $level"};
$o->{pthread} = 0;
foreach my $arg (@$args) {
+# XXX still needed?
if ($arg eq '-pthread') {
$o->{pthread}++;
next;
}
$o->{pthread} += $lainfo->{cached}{pthread};
for my $e (qw(deplibs libdirs result)) {
+LT::Trace::print { "Calls to resolve_la: $calls\n" } if $calls;
push(@{$o->{$e}}, @{$lainfo->{cached}{$e}});
}
}
my $o = { result => [], deplibs => $deplibs, libdirs => $libdirs};
$self->internal_resolve_la($o, $self->{args});
+
+# XXX still needed?
if ($o->{pthread}) {
unshift(@{$o->{result}}, '-pthread');
unshift(@{$o->{deplibs}}, '-pthread');
# first read all directories where we can search libraries
foreach my $arg (@$args) {
if ($arg =~ m/^-L(.*)/) {
- if (!exists $dirs->{$1}) {
- $dirs->{$1} = 1;
- tsay {" adding $arg to deplibs"}
- if $level == 0;
- push(@$deplibs, $arg);
- }
+ push(@$dirs, $1);
+ # XXX could be not adding actually, this is UList
+ tsay {" adding $_ to deplibs"}
+ if $level == 0;
+ push(@$deplibs, $arg);
}
}
foreach my $arg (@$args) {
$libs, \@largs, $level+1) if @largs;
} elsif ($arg =~ m/(\S+\/)*(\S+)\.a$/) {
(my $key = $2) =~ s/^lib//;
- $dirs->{abs_dir($arg)} = 1;
+ push(@$dirs, abs_dir($arg));
$libs->create($key)->{fullpath} = $arg;
push(@$result, $arg);
} elsif ($arg =~ m/(\S+\/)*(\S+)\.la$/) {
(my $key = $2) =~ s/^lib//;
- $dirs->{abs_dir($arg)} = 1;
+ push(@$dirs, abs_dir($arg));
my $fulla = abs_path($arg);
require LT::LaFile;
my $lainfo = LT::LaFile->parse($fulla);
push(@$deplibs, $fulla) if $libdir ne '';
} elsif ($arg =~ m/(\S+\/)*(\S+)\.so(\.\d+){2}/) {
(my $key = $2) =~ s/^lib//;
- $dirs->{abs_dir($arg)} = 1;
+ push(@$dirs, abs_dir($arg));
$libs->create($key);
# not really normal argument
# -lfoo should be used instead, so convert it
} elsif ($arg eq '-pthread') {
$self->{pthread} = 1;
} elsif ($arg =~ m/^-L(.*)/) {
- if (!exists $dirs->{$1}) {
- $dirs->{$1} = 1;
- }
+ push(@$dirs, $1);
} elsif ($arg =~ m/^-R(.*)/) {
# -R options originating from .la resolution
# those from @ARGV are in @Ropts
} elsif ($arg =~ m/(\S+\/)*(\S+)\.la$/) {
(my $key = $2) =~ s/^lib//;
my $d = abs_dir($arg);
- $dirs->{$d} = 1;
+ push(@$dirs, $d);
my $fulla = abs_path($arg);
require LT::LaFile;
my $lainfo = LT::LaFile->parse($fulla);
next if !defined $f;
next if $f =~ m/\.a$/;
my $libnames = [];
+ tie (@$libnames, 'LT::UList');
if (defined $l->{lafile}) {
require LT::LaFile;
my $lainfo = LT::LaFile->parse($l->{lafile});
my $librarynames = $lainfo->stringize('library_names');
- @$libnames = split /\s/, $librarynames;
- $libnames = reverse_zap_duplicates_ref($libnames);
+ push @$libnames, split(/\s/, $librarynames);
} else {
push @$libnames, basename($f);
}
$parser->resolve_la($deplibs, $libdirs);
my $orderedlibs = [];
+ tie(@$orderedlibs, 'LT::UList');
my $staticlibs = [];
my $args = $parser->parse_linkargs2($gp, $orderedlibs, $staticlibs, $dirs,
$libs);
tsay {"staticlibs = \n", join("\n", @$staticlibs)};
tsay {"orderedlibs = @$orderedlibs"};
- $orderedlibs = reverse_zap_duplicates_ref($orderedlibs);
- tsay {"final orderedlibs = @$orderedlibs"};
return ($staticlibs, $orderedlibs, $args);
}
-# $OpenBSD: Library.pm,v 1.3 2014/03/31 13:44:04 ajacoutot Exp $
+# $OpenBSD: Library.pm,v 1.4 2014/04/16 10:31:27 zhuk Exp $
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
$libcounter++;
}
- $libdirs = reverse_zap_duplicates_ref($libdirs);
# add libdirs to rpath if they are not in standard lib path
for my $l (@$libdirs) {
if (!LT::OSConfig->is_search_dir($l)) {
push @$RPdirs, $l;
}
}
- $RPdirs = reverse_zap_duplicates_ref($RPdirs) if $RPdirs;
my @linkeropts = ();
if (!$ltconfig->noshared) {
-# $OpenBSD: Program.pm,v 1.3 2012/11/09 10:55:01 espie Exp $
+# $OpenBSD: Program.pm,v 1.4 2014/04/16 10:31:27 zhuk Exp $
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
$dst = ($odir eq '.') ? $fname : "$odir/$fname";
}
- $libdirs = reverse_zap_duplicates_ref($libdirs);
- my $rpath_link = {};
+ tie(my @rpath_link, 'LT::UList');
# add libdirs to rpath if they are not in standard lib path
for my $l (@$libdirs) {
if (LT::OSConfig->is_search_dir($l)) {
- $rpath_link->{$l} = 1;
+ push @rpath_link, $l;
} else {
push @$RPdirs, $l;
}
}
- $RPdirs = reverse_zap_duplicates_ref($RPdirs);
foreach my $k (keys %$libs) {
tprint {"key = $k - "};
my $r = ref($libs->{$k});
for my $d (@$RPdirs) {
push(@linkeropts, '-rpath', $d);
}
- for my $d (keys %$rpath_link) {
+ for my $d (@rpath_link) {
push(@linkeropts, '-rpath-link', $d);
}
}
--- /dev/null
+# ex:ts=8 sw=4:
+# $OpenBSD: UList.pm,v 1.1 2014/04/16 10:31:27 zhuk Exp $
+#
+# Copyright (c) 2013 Vadim Zhukov <zhuk@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use strict;
+use warnings;
+use feature qw(say);
+
+# Hash that preserves order of adding items and avoids duplicates.
+# Also, some additional restrictions are applied to make sure
+# the usage of this list is straightforward.
+
+package LT::UList;
+require Tie::Array;
+
+our @ISA = qw(Tie::Array);
+
+sub _translate_num_key($$;$) {
+ if ($_[1] < 0) {
+ $_[1] = @{$_[0]} - (-$_[1]);
+ die "invalid index" if $_[1] < 1;
+ } else {
+ $_[1] += 1;
+ }
+ die "invalid index" if $_[1] - int($_[2] // 0) >= @{$_[0]};
+}
+
+# Given we have successfully added N directories:
+# self->[0] = { directory => 1 }
+# self->[1 .. N] = directories in the order of addition, represented as 0..N-1
+
+sub TIEARRAY {
+ my $class = shift;
+ my $self = bless [ {} ], $class;
+ $self->PUSH(@_);
+ return $self;
+}
+
+# Unfortunately, exists() checks for the value being integer even in the
+# case we have EXISTS() outta there. So if you really need to check the
+# presence of particular item, call the method below on the reference
+# returned by tie() or tied() instead.
+sub exists { return exists $_[0]->[0]->{$_[1]}; }
+
+sub FETCHSIZE { return scalar(@{$_[0]}) - 1; }
+
+# not needed
+sub STORE { die "unimplemented and should not be used"; }
+sub DELETE { die "unimplemented and should not be used"; }
+sub EXTEND { }
+
+sub FETCH
+{
+ my ($self, $key) = (shift, shift);
+
+ # ignore?
+ die "undef given instead of directory or index" unless defined $key;
+
+ $self->_translate_num_key($key);
+ return $self->[$key];
+}
+
+sub STORESIZE
+{
+ my ($self, $newsz) = (shift, shift() + 2);
+ my $sz = @$self;
+
+ if ($newsz > $sz) {
+ # XXX any better way to grow?
+ $self->[$newsz - 1] = undef;
+ } elsif ($newsz < $sz) {
+ $self->POP() for $newsz .. $sz - 1;
+ }
+}
+
+sub PUSH
+{
+ my $self = shift;
+ for (@_) {
+ next if exists $self->[0]->{$_};
+ $self->[0]->{$_} = @$self;
+ push(@$self, $_);
+ }
+}
+
+sub POP
+{
+ my $self = shift;
+ return undef if @$self < 2;
+ my $key = pop @$self;
+ delete $self->[0]->{$key};
+ return $key;
+}
+
+sub SHIFT
+{
+ my $self = shift;
+ return undef if @$self < 2;
+ my $key = splice(@$self, 1, 1);
+ delete $self->[0]->{$key};
+ return $key;
+}
+
+sub UNSHIFT
+{
+ my $self = shift;
+ $self->SPLICE(0, 0, @_);
+}
+
+sub SPLICE
+{
+ my $self = shift;
+
+ my $offset = shift // 0;
+ $self->_translate_num_key($offset, 1);
+ my $maxrm = @$self - $offset;
+
+ my $length = shift;
+ if (defined $length) {
+ $length = $maxrm - (-$length) if $length < 0;
+ $length = $maxrm if $length > $maxrm;
+ } else {
+ $length = $maxrm;
+ }
+
+ # do not ever dream of adding items here
+ my @ret = splice(@$self, $offset, $length);
+
+ for (@ret) {
+ delete $self->[0]->{$_};
+ }
+ for ($offset .. scalar(@$self) - 1) {
+ $self->[0]->{$self->[$_]} -= $length;
+ }
+
+ return @ret unless scalar(@_);
+
+ if ($length == $maxrm) {
+ # simply add items to the end
+ $self->PUSH(@_);
+ return @ret;
+ }
+
+ my $newpos = $offset;
+ for (@_) {
+ my $index = $self->[0]->{$_};
+ if (defined $index) {
+ if ($index < $offset) {
+ # skip current item totally
+ continue;
+ } elsif ($index == $offset) {
+ # skip adding but act as if added
+ $self->[0]->{$_} += $newpos - $offset;
+ $newpos++;
+ next;
+ }
+ splice(@$self, $index, 1);
+ }
+ splice(@$self, $newpos, 0, $_);
+ $self->[0]->{$_} = $newpos++;
+ }
+ for ($newpos .. scalar(@$self) - 1) {
+ $self->[0]->{$self->[$_]} += $newpos - $offset;
+ }
+ return @ret;
+}
+
+
+=head1 test
+package main;
+
+my $r = ['/path0', '/path1'];
+tie(@$r, 'LT::UList');
+#push(@$r, '/path0');
+#push(@$r, '/path1');
+push(@$r, '/path2');
+push(@$r, '/path3');
+push(@$r, '/path4');
+push(@$r, '/path3');
+push(@$r, '/path1');
+push(@$r, '/path5');
+say "spliced: ".join(", ", splice(@$r, 2, 2, '/pathAdd1', '/pathAdd2', '/pathAdd1'));
+#say "a: ".join(", ", @a);
+say "r: ".join(", ", @$r);
+#say "r2: ".join(", ", @$r2);
+=cut
-# $OpenBSD: Util.pm,v 1.5 2012/07/10 12:24:45 espie Exp $
+# $OpenBSD: Util.pm,v 1.6 2014/04/16 10:31:27 zhuk Exp $
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
package LT::Util;
require Exporter;
our @ISA = qw(Exporter);
-our @EXPORT = qw(reverse_zap_duplicates_ref abs_dir $ltdir $version shortdie);
+our @EXPORT = qw(abs_dir $ltdir $version shortdie);
use File::Basename;
use Cwd;
our $ltdir = '.libs';
our $version = '1.5.26'; # pretend to be this version of libtool
-# walk a list from back to front, removing any duplicates
-# this should make sure a library's dependencies are behind the library itself
-sub reverse_zap_duplicates_ref
-{
- my $arglist = shift;
- my $h = {};
- my $r = [];
- for my $el (reverse @$arglist) {
- next if defined $h->{$el};
- unshift @$r, $el;
- $h->{$el} = 1;
- }
- return $r;
-}
-
sub abs_dir
{
my $a = shift;
-# $OpenBSD: Makefile,v 1.6 2012/07/13 11:56:12 espie Exp $
+# $OpenBSD: Makefile,v 1.7 2014/04/16 10:31:27 zhuk Exp $
.include <bsd.own.mk>
LT/Mode/Link/Library.pm \
LT/Program.pm \
LT/Trace.pm \
+ LT/UList.pm \
LT/Util.pm
LIBBASE=/usr/libdata/perl5