summaryrefslogtreecommitdiff
path: root/usr.bin/libtool/LT
diff options
context:
space:
mode:
authorMarc Espie <espie@cvs.openbsd.org>2012-07-13 11:56:14 +0000
committerMarc Espie <espie@cvs.openbsd.org>2012-07-13 11:56:14 +0000
commitd5682b5365c31c5f8bdffd7309f3e48a32684ab8 (patch)
tree33f5fd7e9ec69041989e8d0ba9b46faa2d04ec73 /usr.bin/libtool/LT
parentf2eeda3c7c3c63c21432abb225e9d36773e89121 (diff)
move stuff around some more, do not load link parts unless we are actually
linking. (and always load basic linker class when we're actually linking) Start making a proper "library stash class".
Diffstat (limited to 'usr.bin/libtool/LT')
-rw-r--r--usr.bin/libtool/LT/LaFile.pm141
-rw-r--r--usr.bin/libtool/LT/Library.pm20
-rw-r--r--usr.bin/libtool/LT/Linker.pm103
-rw-r--r--usr.bin/libtool/LT/Mode/Link.pm115
-rw-r--r--usr.bin/libtool/LT/Mode/Link/Library.pm162
-rw-r--r--usr.bin/libtool/LT/Mode/Link/Program.pm132
-rw-r--r--usr.bin/libtool/LT/Program.pm113
7 files changed, 406 insertions, 380 deletions
diff --git a/usr.bin/libtool/LT/LaFile.pm b/usr.bin/libtool/LT/LaFile.pm
index df80e4bdf8b..54c5e757492 100644
--- a/usr.bin/libtool/LT/LaFile.pm
+++ b/usr.bin/libtool/LT/LaFile.pm
@@ -1,4 +1,4 @@
-# $OpenBSD: LaFile.pm,v 1.16 2012/07/12 19:21:00 espie Exp $
+# $OpenBSD: LaFile.pm,v 1.17 2012/07/13 11:56:12 espie Exp $
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
@@ -149,12 +149,6 @@ sub find
return 0;
}
-sub link
-{
- require LT::Linker;
- return LT::Linker::LaFile->new->link(@_);
-}
-
sub install
{
my ($class, $src, $dstdir, $instprog, $instopts, $strip) = @_;
@@ -204,137 +198,4 @@ sub install
}
}
-
-package LT::Linker::LaFile;
-our @ISA = qw(LT::Linker);
-
-use LT::Util;
-use LT::Trace;
-use File::Basename;
-
-sub link
-{
- my ($linker, $self, $ltprog, $ltconfig, $la, $fname, $odir, $shared,
- $objs, $dirs, $libs, $deplibs, $libdirs, $parser, $gp) = @_;
-
- tsay {"creating link command for library (linked ",
- ($shared) ? "dynamically" : "statically", ")"};
-
- my @libflags;
- my @cmd;
- my $dst = ($odir eq '.') ? "$ltdir/$fname" : "$odir/$ltdir/$fname";
- if ($la =~ m/\.a$/) {
- # probably just a convenience library
- $dst = ($odir eq '.') ? "$fname" : "$odir/$fname";
- }
- my $symlinkdir = $ltdir;
- if ($odir ne '.') {
- $symlinkdir = "$odir/$ltdir";
- }
- mkdir $symlinkdir if ! -d $symlinkdir;
-
- my ($staticlibs, $finalorderedlibs, $args) =
- $linker->common1($parser, $gp, $deplibs, $libdirs, $dirs, $libs);
-
- # static linking
- if (!$shared) {
- @cmd = ('ar', 'cru', $dst);
- foreach my $a (@$staticlibs) {
- if ($a =~ m/\.a$/ && $a !~ m/_pic\.a/) {
- # extract objects from archive
- my $libfile = basename($a);
- my $xdir = "$odir/$ltdir/${la}x/$libfile";
- LT::Archive->extract($xdir, $a);
- my @kobjs = LT::Archive->get_objlist($a);
- map { $_ = "$xdir/$_"; } @kobjs;
- push @libflags, @kobjs;
- }
- }
- foreach my $k (@$finalorderedlibs) {
- my $l = $libs->{$k};
- # XXX improve test
- # this has to be done probably only with
- # convenience libraries
- next if !defined $l->{lafile};
- my $lainfo = LT::LaFile->parse($l->{lafile});
- next if ($lainfo->stringize('dlname') ne '');
- $l->resolve_library($dirs, 0, 0, ref($self));
- my $a = $l->{fullpath};
- if ($a =~ m/\.a$/ && $a !~ m/_pic\.a/) {
- # extract objects from archive
- my $libfile = basename $a;
- my $xdir = "$odir/$ltdir/${la}x/$libfile";
- LT::Archive->extract($xdir, $a);
- my @kobjs = LT::Archive->get_objlist($a);
- map { $_ = "$xdir/$_"; } @kobjs;
- push @libflags, @kobjs;
- }
- }
- push @cmd, @libflags if @libflags;
- push @cmd, @$objs if @$objs;
- LT::Exec->link(@cmd);
- LT::Exec->link('ranlib', $dst);
- return;
- }
-
- # dynamic linking
- my $symbolsfile;
- if ($gp->export_symbols) {
- $symbolsfile = $gp->export_symbols;
- } elsif ($gp->export_symbols_regex) {
- ($symbolsfile = "$odir/$ltdir/$la") =~ s/\.la$/.exp/;
- LT::Archive->get_symbollist($symbolsfile, $gp->export_symbols_regex, $objs);
- }
- my $tmp = [];
- while (my $k = shift @$finalorderedlibs) {
- my $l = $libs->{$k};
- $l->resolve_library($dirs, 1, $gp->static, ref($self));
- if ($l->{dropped}) {
- # remove library if dependency on it has been dropped
- delete $libs->{$k};
- } else {
- push(@$tmp, $k);
- }
- }
- $finalorderedlibs = $tmp;
-
- my @libobjects = values %$libs;
- tsay {"libs:\n", join("\n", (keys %$libs))};
- tsay {"libfiles:\n",
- join("\n", map { $_->{fullpath}//'UNDEF' } @libobjects) };
-
- $linker->create_symlinks($symlinkdir, $libs);
- my $prev_was_archive = 0;
- my $libcounter = 0;
- foreach my $k (@$finalorderedlibs) {
- my $a = $libs->{$k}->{fullpath} || die "Link error: $k not found in \$libs\n";
- if ($a =~ m/\.a$/) {
- # don't make a -lfoo out of a static library
- push @libflags, '-Wl,-whole-archive' unless $prev_was_archive;
- push @libflags, $a;
- if ($libcounter == @$finalorderedlibs - 1) {
- push @libflags, '-Wl,-no-whole-archive';
- }
- $prev_was_archive = 1;
- } else {
- push @libflags, '-Wl,-no-whole-archive' if $prev_was_archive;
- $prev_was_archive = 0;
- push @libflags, $linker->infer_libparameter($a, $k);
- }
- $libcounter++;
- }
-
- @cmd = @$ltprog;
- push @cmd, $ltconfig->sharedflag, @{$ltconfig->picflags};
- push @cmd, '-o', $dst;
- push @cmd, '-pthread' if $parser->{pthread};
- push @cmd, @$args if $args;
- push @cmd, @$objs if @$objs;
- push @cmd, '-Wl,-whole-archive', @$staticlibs, '-Wl,-no-whole-archive'
- if @$staticlibs;
- push @cmd, "-L$symlinkdir", @libflags if @libflags;
- push @cmd, "-Wl,-retain-symbols-file,$symbolsfile" if $symbolsfile;
- LT::Exec->link(@cmd);
-}
-
1;
diff --git a/usr.bin/libtool/LT/Library.pm b/usr.bin/libtool/LT/Library.pm
index 7a1581d43a1..40661426d69 100644
--- a/usr.bin/libtool/LT/Library.pm
+++ b/usr.bin/libtool/LT/Library.pm
@@ -1,4 +1,4 @@
-# $OpenBSD: Library.pm,v 1.7 2012/07/13 08:44:20 espie Exp $
+# $OpenBSD: Library.pm,v 1.8 2012/07/13 11:56:12 espie Exp $
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
@@ -19,6 +19,24 @@ use strict;
use warnings;
use feature qw(say switch state);
+package LT::Library::Stash;
+
+sub new
+{
+ my $class = shift;
+
+ bless {}, $class;
+}
+
+sub create
+{
+ my ($self, $key) = @_;
+ if (!exists $self->{$key}) {
+ $self->{$key} = LT::Library->new($key);
+ }
+ return $self->{$key};
+}
+
package LT::Library;
use LT::Util;
diff --git a/usr.bin/libtool/LT/Linker.pm b/usr.bin/libtool/LT/Linker.pm
deleted file mode 100644
index 93b1da58a37..00000000000
--- a/usr.bin/libtool/LT/Linker.pm
+++ /dev/null
@@ -1,103 +0,0 @@
-# $OpenBSD: Linker.pm,v 1.5 2012/07/12 19:21:00 espie Exp $
-
-# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
-# Copyright (c) 2012 Marc Espie <espie@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);
-
-package LT::Linker;
-use LT::Trace;
-use LT::Util;
-use File::Basename;
-use Cwd qw(abs_path);
-
-sub new
-{
- my $class = shift;
- bless {}, $class;
-}
-
-sub create_symlinks
-{
- my ($self, $dir, $libs) = @_;
- if (! -d $dir) {
- mkdir($dir) or die "Cannot mkdir($dir) : $!\n";
- }
-
- foreach my $l (values %$libs) {
- my $f = $l->{fullpath};
- next if !defined $f;
- next if $f =~ m/\.a$/;
- my $libnames = [];
- 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);
- } else {
- push @$libnames, basename($f);
- }
- foreach my $libfile (@$libnames) {
- my $link = "$dir/$libfile";
- tsay {"ln -s $f $link"};
- next if -f $link;
- my $p = abs_path($f);
- if (!symlink($p, $link)) {
- die "Cannot create symlink($p, $link): $!\n"
- unless $!{EEXIST};
- }
- }
- }
- return $dir;
-}
-
-sub common1
-{
- my ($self, $parser, $gp, $deplibs, $libdirs, $dirs, $libs) = @_;
-
- $parser->resolve_la($deplibs, $libdirs);
- my $orderedlibs = [];
- 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);
-}
-
-sub infer_libparameter
-{
- my ($self, $a, $k) = @_;
- my $lib = basename($a);
- if ($lib =~ m/^lib(.*)\.so(\.\d+){2}$/) {
- $lib = $1;
- } elsif ($lib =~ m/^lib(.*)\.so$/) {
- say "warning: library filename $a has no version number";
- $lib = $1;
- } else {
- say "warning: cannot derive -l flag from library filename $a, assuming hash key -l$k";
- $lib = $k;
- }
- return "-l$lib";
-}
-
-1;
-
-
diff --git a/usr.bin/libtool/LT/Mode/Link.pm b/usr.bin/libtool/LT/Mode/Link.pm
index 6ce80dc155b..ba9cb6c2ac9 100644
--- a/usr.bin/libtool/LT/Mode/Link.pm
+++ b/usr.bin/libtool/LT/Mode/Link.pm
@@ -1,5 +1,5 @@
# ex:ts=8 sw=4:
-# $OpenBSD: Link.pm,v 1.17 2012/07/12 17:07:12 espie Exp $
+# $OpenBSD: Link.pm,v 1.18 2012/07/13 11:56:12 espie Exp $
#
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
@@ -93,6 +93,7 @@ our @ISA = qw(LT::Mode);
use LT::Util;
use LT::Trace;
+use LT::Library;
use File::Basename;
use constant {
@@ -120,7 +121,7 @@ sub run
my $noshared = $ltconfig->noshared;
my $cmd;
my $libdirs = []; # list of libdirs
- my $libs = {}; # libraries
+ my $libs = LT::Library::Stash->new; # libraries
my $dirs = {}; # paths to find libraries
# put a priority in the dir hash
# always look here
@@ -206,7 +207,7 @@ sub run
my $parser = LT::Parser->new(\@ARGV);
if ($linkmode == PROGRAM) {
- require LT::Program;
+ require LT::Mode::Link::Program;
my $program = LT::Program->new;
$program->{outfilepath} = $outfile;
# XXX give higher priority to dirs of not installed libs
@@ -235,7 +236,7 @@ sub run
$program->link($ltprog, $ltconfig, $dirs, $libs, $deplibs, $libdirs, $parser, $gp);
} elsif ($linkmode == LIBRARY) {
my $convenience = 0;
- require LT::LaFile;
+ require LT::Mode::Link::Library;
my $lainfo = LT::LaFile->new;
$shared = 1 if ($gp->version_info ||
@@ -445,7 +446,6 @@ package LT::Parser;
use File::Basename;
use Cwd qw(abs_path);
use LT::Util;
-use LT::Library;
use LT::Trace;
my $calls = 0;
@@ -565,7 +565,7 @@ sub internal_parse_linkargs1
my @largs = ();
my $key = $1;
if (!exists $libs->{$key}) {
- $libs->{$key} = LT::Library->new($key);
+ $libs->create($key);
require LT::LaFile;
my $lafile = LT::LaFile->find($key, $dirs);
if ($lafile) {
@@ -595,11 +595,8 @@ sub internal_parse_linkargs1
$libs, \@largs, $level+1) if @largs;
} elsif (m/(\S+\/)*(\S+)\.a$/) {
(my $key = $2) =~ s/^lib//;
- if (!exists $libs->{$key}) {
- $libs->{$key} = LT::Library->new($key);
- }
$dirs->{abs_dir($_)} = 1;
- $libs->{$key}->{fullpath} = $_;
+ $libs->create($key)->{fullpath} = $_;
push(@$result, $_);
} elsif (m/(\S+\/)*(\S+)\.la$/) {
(my $key = $2) =~ s/^lib//;
@@ -612,8 +609,7 @@ sub internal_parse_linkargs1
my $libdir = $lainfo->{'libdir'};
if ($dlname ne '') {
if (!exists $libs->{$key}) {
- $libs->{$key} = LT::Library->new($key);
- $libs->{$key}->{lafile} = $fulla;
+ $libs->create($key)->{lafile} = $fulla;
}
}
push(@$result, $_);
@@ -621,9 +617,7 @@ sub internal_parse_linkargs1
} elsif (m/(\S+\/)*(\S+)\.so(\.\d+){2}/) {
(my $key = $2) =~ s/^lib//;
$dirs->{abs_dir($_)} = 1;
- if (!exists $libs->{$key}) {
- $libs->{$key} = LT::Library->new($key);
- }
+ $libs->create($key);
# not really normal argument
# -lfoo should be used instead, so convert it
push(@$result, "-l$key");
@@ -682,16 +676,11 @@ sub parse_linkargs2
} elsif (m/^-l(.*)/) {
my @largs = ();
my $key = $1;
- if (!exists $libs->{$key}) {
- $libs->{$key} = LT::Library->new($key);
- }
+ $libs->create($key);
push @$orderedlibs, $key;
} elsif (m/(\S+\/)*(\S+)\.a$/) {
(my $key = $2) =~ s/^lib//;
- if (!exists $libs->{$key}) {
- $libs->{$key} = LT::Library->new($key);
- }
- $libs->{$key}->{fullpath} = $_;
+ $libs->create($key)->{fullpath} = $_;
push(@$staticlibs, $_);
} elsif (m/(\S+\/)*(\S+)\.la$/) {
(my $key = $2) =~ s/^lib//;
@@ -711,8 +700,7 @@ sub parse_linkargs2
push @$staticlibs, "$d/$ltdir/$oldlib";
} else {
if (!exists $libs->{$key}) {
- $libs->{$key} = LT::Library->new($key);
- $libs->{$key}->{lafile} = $fulla;
+ $libs->create($key)->{lafile} = $fulla;
}
push @$orderedlibs, $key;
}
@@ -738,5 +726,84 @@ sub new
bless { args => $args, pthread => 0 }, $class;
}
+package LT::Linker;
+use LT::Trace;
+use LT::Util;
+use File::Basename;
+use Cwd qw(abs_path);
+
+sub new
+{
+ my $class = shift;
+ bless {}, $class;
+}
+
+sub create_symlinks
+{
+ my ($self, $dir, $libs) = @_;
+ if (! -d $dir) {
+ mkdir($dir) or die "Cannot mkdir($dir) : $!\n";
+ }
+
+ foreach my $l (values %$libs) {
+ my $f = $l->{fullpath};
+ next if !defined $f;
+ next if $f =~ m/\.a$/;
+ my $libnames = [];
+ 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);
+ } else {
+ push @$libnames, basename($f);
+ }
+ foreach my $libfile (@$libnames) {
+ my $link = "$dir/$libfile";
+ tsay {"ln -s $f $link"};
+ next if -f $link;
+ my $p = abs_path($f);
+ if (!symlink($p, $link)) {
+ die "Cannot create symlink($p, $link): $!\n"
+ unless $!{EEXIST};
+ }
+ }
+ }
+ return $dir;
+}
+
+sub common1
+{
+ my ($self, $parser, $gp, $deplibs, $libdirs, $dirs, $libs) = @_;
+
+ $parser->resolve_la($deplibs, $libdirs);
+ my $orderedlibs = [];
+ 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);
+}
+
+sub infer_libparameter
+{
+ my ($self, $a, $k) = @_;
+ my $lib = basename($a);
+ if ($lib =~ m/^lib(.*)\.so(\.\d+){2}$/) {
+ $lib = $1;
+ } elsif ($lib =~ m/^lib(.*)\.so$/) {
+ say "warning: library filename $a has no version number";
+ $lib = $1;
+ } else {
+ say "warning: cannot derive -l flag from library filename $a, assuming hash key -l$k";
+ $lib = $k;
+ }
+ return "-l$lib";
+}
+
1;
diff --git a/usr.bin/libtool/LT/Mode/Link/Library.pm b/usr.bin/libtool/LT/Mode/Link/Library.pm
new file mode 100644
index 00000000000..62a32a49c6b
--- /dev/null
+++ b/usr.bin/libtool/LT/Mode/Link/Library.pm
@@ -0,0 +1,162 @@
+# $OpenBSD: Library.pm,v 1.1 2012/07/13 11:56:13 espie Exp $
+
+# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
+# Copyright (c) 2012 Marc Espie <espie@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);
+
+use LT::LaFile;
+
+package LT::LaFile;
+sub link
+{
+ return LT::Linker::LaFile->new->link(@_);
+}
+
+package LT::Linker::LaFile;
+our @ISA = qw(LT::Linker);
+
+use LT::Util;
+use LT::Trace;
+use File::Basename;
+
+sub link
+{
+ my ($linker, $self, $ltprog, $ltconfig, $la, $fname, $odir, $shared,
+ $objs, $dirs, $libs, $deplibs, $libdirs, $parser, $gp) = @_;
+
+ tsay {"creating link command for library (linked ",
+ ($shared) ? "dynamically" : "statically", ")"};
+
+ my @libflags;
+ my @cmd;
+ my $dst = ($odir eq '.') ? "$ltdir/$fname" : "$odir/$ltdir/$fname";
+ if ($la =~ m/\.a$/) {
+ # probably just a convenience library
+ $dst = ($odir eq '.') ? "$fname" : "$odir/$fname";
+ }
+ my $symlinkdir = $ltdir;
+ if ($odir ne '.') {
+ $symlinkdir = "$odir/$ltdir";
+ }
+ mkdir $symlinkdir if ! -d $symlinkdir;
+
+ my ($staticlibs, $finalorderedlibs, $args) =
+ $linker->common1($parser, $gp, $deplibs, $libdirs, $dirs, $libs);
+
+ # static linking
+ if (!$shared) {
+ @cmd = ('ar', 'cru', $dst);
+ foreach my $a (@$staticlibs) {
+ if ($a =~ m/\.a$/ && $a !~ m/_pic\.a/) {
+ # extract objects from archive
+ my $libfile = basename($a);
+ my $xdir = "$odir/$ltdir/${la}x/$libfile";
+ LT::Archive->extract($xdir, $a);
+ my @kobjs = LT::Archive->get_objlist($a);
+ map { $_ = "$xdir/$_"; } @kobjs;
+ push @libflags, @kobjs;
+ }
+ }
+ foreach my $k (@$finalorderedlibs) {
+ my $l = $libs->{$k};
+ # XXX improve test
+ # this has to be done probably only with
+ # convenience libraries
+ next if !defined $l->{lafile};
+ my $lainfo = LT::LaFile->parse($l->{lafile});
+ next if ($lainfo->stringize('dlname') ne '');
+ $l->resolve_library($dirs, 0, 0, ref($self));
+ my $a = $l->{fullpath};
+ if ($a =~ m/\.a$/ && $a !~ m/_pic\.a/) {
+ # extract objects from archive
+ my $libfile = basename $a;
+ my $xdir = "$odir/$ltdir/${la}x/$libfile";
+ LT::Archive->extract($xdir, $a);
+ my @kobjs = LT::Archive->get_objlist($a);
+ map { $_ = "$xdir/$_"; } @kobjs;
+ push @libflags, @kobjs;
+ }
+ }
+ push @cmd, @libflags if @libflags;
+ push @cmd, @$objs if @$objs;
+ LT::Exec->link(@cmd);
+ LT::Exec->link('ranlib', $dst);
+ return;
+ }
+
+ # dynamic linking
+ my $symbolsfile;
+ if ($gp->export_symbols) {
+ $symbolsfile = $gp->export_symbols;
+ } elsif ($gp->export_symbols_regex) {
+ ($symbolsfile = "$odir/$ltdir/$la") =~ s/\.la$/.exp/;
+ LT::Archive->get_symbollist($symbolsfile, $gp->export_symbols_regex, $objs);
+ }
+ my $tmp = [];
+ while (my $k = shift @$finalorderedlibs) {
+ my $l = $libs->{$k};
+ $l->resolve_library($dirs, 1, $gp->static, ref($self));
+ if ($l->{dropped}) {
+ # remove library if dependency on it has been dropped
+ delete $libs->{$k};
+ } else {
+ push(@$tmp, $k);
+ }
+ }
+ $finalorderedlibs = $tmp;
+
+ my @libobjects = values %$libs;
+ tsay {"libs:\n", join("\n", (keys %$libs))};
+ tsay {"libfiles:\n",
+ join("\n", map { $_->{fullpath}//'UNDEF' } @libobjects) };
+
+ $linker->create_symlinks($symlinkdir, $libs);
+ my $prev_was_archive = 0;
+ my $libcounter = 0;
+ foreach my $k (@$finalorderedlibs) {
+ my $a = $libs->{$k}->{fullpath} || die "Link error: $k not found in \$libs\n";
+ if ($a =~ m/\.a$/) {
+ # don't make a -lfoo out of a static library
+ push @libflags, '-Wl,-whole-archive' unless $prev_was_archive;
+ push @libflags, $a;
+ if ($libcounter == @$finalorderedlibs - 1) {
+ push @libflags, '-Wl,-no-whole-archive';
+ }
+ $prev_was_archive = 1;
+ } else {
+ push @libflags, '-Wl,-no-whole-archive' if $prev_was_archive;
+ $prev_was_archive = 0;
+ push @libflags, $linker->infer_libparameter($a, $k);
+ }
+ $libcounter++;
+ }
+
+ @cmd = @$ltprog;
+ push @cmd, $ltconfig->sharedflag, @{$ltconfig->picflags};
+ push @cmd, '-o', $dst;
+ push @cmd, '-pthread' if $parser->{pthread};
+ push @cmd, @$args if $args;
+ push @cmd, @$objs if @$objs;
+ push @cmd, '-Wl,-whole-archive', @$staticlibs, '-Wl,-no-whole-archive'
+ if @$staticlibs;
+ push @cmd, "-L$symlinkdir", @libflags if @libflags;
+ push @cmd, "-Wl,-retain-symbols-file,$symbolsfile" if $symbolsfile;
+ LT::Exec->link(@cmd);
+}
+
+1;
diff --git a/usr.bin/libtool/LT/Mode/Link/Program.pm b/usr.bin/libtool/LT/Mode/Link/Program.pm
new file mode 100644
index 00000000000..22987868b68
--- /dev/null
+++ b/usr.bin/libtool/LT/Mode/Link/Program.pm
@@ -0,0 +1,132 @@
+# $OpenBSD: Program.pm,v 1.1 2012/07/13 11:56:13 espie Exp $
+
+# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
+# Copyright (c) 2012 Marc Espie <espie@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);
+
+use LT::Program;
+
+package LT::Program;
+
+sub link
+{
+ return LT::Linker::Program->new->link(@_);
+}
+
+package LT::Linker::Program;
+our @ISA = qw(LT::Linker);
+
+use LT::Trace;
+use LT::Util;
+use File::Basename;
+
+sub link
+{
+ my ($linker, $self, $ltprog, $ltconfig, $dirs, $libs, $deplibs,
+ $libdirs, $parser, $gp) = @_;
+
+ tsay {"linking program (", ($gp->static ? "not " : ""),
+ "dynamically linking not-installed libtool libraries)"};
+
+ my $fpath = $self->{outfilepath};
+ my $RPdirs = $self->{RPdirs};
+
+ my $odir = dirname($fpath);
+ my $fname = basename($fpath);
+
+ my @libflags;
+ my @cmd;
+ my $dst;
+
+ my ($staticlibs, $finalorderedlibs, $args) =
+ $linker->common1($parser, $gp, $deplibs, $libdirs, $dirs, $libs);
+
+ my $symlinkdir = $ltdir;
+ if ($odir ne '.') {
+ $symlinkdir = "$odir/$ltdir";
+ }
+ mkdir $symlinkdir if ! -d $symlinkdir;
+ if ($parser->{seen_la_shared}) {
+ $dst = ($odir eq '.') ? "$ltdir/$fname" : "$odir/$ltdir/$fname";
+ $self->write_wrapper;
+ } else {
+ $dst = ($odir eq '.') ? $fname : "$odir/$fname";
+ }
+
+ my $symbolsfile;
+ if ($gp->export_symbols) {
+ $symbolsfile = $gp->export_symbols;
+ } elsif ($gp->export_symbols_regex) {
+ ($symbolsfile = "$odir/$ltdir/$fname") =~ s/\.la$/.exp/;
+ LT::Archive->get_symbollist($symbolsfile, $gp->export_symbols_regex, $self->{objlist});
+ }
+ $libdirs = reverse_zap_duplicates_ref($libdirs);
+ my $rpath_link = {};
+ # 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;
+ } else {
+ push @$RPdirs, $l;
+ }
+ }
+ $RPdirs = reverse_zap_duplicates_ref($RPdirs);
+ foreach my $k (keys %$libs) {
+ tprint {"key = $k - "};
+ my $r = ref($libs->{$k});
+ tsay {"ref = $r"};
+ $libs->create($k)->resolve_library($dirs, 1, $gp->static,
+ ref($self));
+ }
+
+ my @libobjects = values %$libs;
+ tsay {"libs:\n", join("\n", keys %$libs)};
+ tsay {"libfiles:\n", join("\n", map { $_->{fullpath} } @libobjects)};
+
+ $linker->create_symlinks($symlinkdir, $libs);
+ foreach my $k (@$finalorderedlibs) {
+ my $a = $libs->{$k}->{fullpath} || die "Link error: $k not found in \$libs\n";
+ if ($a =~ m/\.a$/) {
+ # don't make a -lfoo out of a static library
+ push @libflags, $a;
+ } else {
+ push @libflags, $linker->infer_libparameter($a, $k);
+ }
+ }
+
+ my @linkeropts = ();
+ for my $d (@$RPdirs) {
+ push(@linkeropts, '-rpath', $d);
+ }
+ for my $d (keys %$rpath_link) {
+ push(@linkeropts, '-rpath-link', $d);
+ }
+ if ($symbolsfile) {
+ push(@linkeropts, '-retain-symbols-file', $symbolsfile);
+ }
+ @cmd = @$ltprog;
+ push @cmd, '-o', $dst;
+ push @cmd, '-pthread' if $parser->{pthread};
+ push @cmd, @$args if $args;
+ push @cmd, @{$self->{objlist}} if @{$self->{objlist}};
+ push @cmd, @$staticlibs if @$staticlibs;
+ push @cmd, "-L$symlinkdir", @libflags if @libflags;
+ push @cmd, '-Wl,'. join(',', @linkeropts) if @linkeropts;
+ LT::Exec->link(@cmd);
+}
+1;
diff --git a/usr.bin/libtool/LT/Program.pm b/usr.bin/libtool/LT/Program.pm
index 009f08f5a7e..d49dffc3160 100644
--- a/usr.bin/libtool/LT/Program.pm
+++ b/usr.bin/libtool/LT/Program.pm
@@ -1,4 +1,4 @@
-# $OpenBSD: Program.pm,v 1.18 2012/07/12 19:21:00 espie Exp $
+# $OpenBSD: Program.pm,v 1.19 2012/07/13 11:56:12 espie Exp $
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
# Copyright (c) 2012 Marc Espie <espie@openbsd.org>
@@ -78,115 +78,4 @@ sub install
LT::Exec->install(@$instprog, @$instopts, $realpath, $dst);
}
-sub link
-{
- require LT::Linker;
- return LT::Linker::Program->new->link(@_);
-}
-
-package LT::Linker::Program;
-our @ISA = qw(LT::Linker);
-
-use LT::Trace;
-use LT::Util;
-use File::Basename;
-
-sub link
-{
- my ($linker, $self, $ltprog, $ltconfig, $dirs, $libs, $deplibs,
- $libdirs, $parser, $gp) = @_;
-
- tsay {"linking program (", ($gp->static ? "not " : ""),
- "dynamically linking not-installed libtool libraries)"};
-
- my $fpath = $self->{outfilepath};
- my $RPdirs = $self->{RPdirs};
-
- my $odir = dirname($fpath);
- my $fname = basename($fpath);
-
- my @libflags;
- my @cmd;
- my $dst;
-
- my ($staticlibs, $finalorderedlibs, $args) =
- $linker->common1($parser, $gp, $deplibs, $libdirs, $dirs, $libs);
-
- my $symlinkdir = $ltdir;
- if ($odir ne '.') {
- $symlinkdir = "$odir/$ltdir";
- }
- mkdir $symlinkdir if ! -d $symlinkdir;
- if ($parser->{seen_la_shared}) {
- $dst = ($odir eq '.') ? "$ltdir/$fname" : "$odir/$ltdir/$fname";
- $self->write_wrapper;
- } else {
- $dst = ($odir eq '.') ? $fname : "$odir/$fname";
- }
-
- my $symbolsfile;
- if ($gp->export_symbols) {
- $symbolsfile = $gp->export_symbols;
- } elsif ($gp->export_symbols_regex) {
- ($symbolsfile = "$odir/$ltdir/$fname") =~ s/\.la$/.exp/;
- LT::Archive->get_symbollist($symbolsfile, $gp->export_symbols_regex, $self->{objlist});
- }
- $libdirs = reverse_zap_duplicates_ref($libdirs);
- my $rpath_link = {};
- # 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;
- } else {
- push @$RPdirs, $l;
- }
- }
- $RPdirs = reverse_zap_duplicates_ref($RPdirs);
- foreach my $k (keys %$libs) {
- tprint {"key = $k - "};
- my $r = ref($libs->{$k});
- tsay {"ref = $r"};
- if (!defined $libs->{$k}) {
- tsay {"creating library object for $k"};
- require LT::Library;
- $libs->{$k} = LT::Library->new($k);
- }
- $libs->{$k}->resolve_library($dirs, 1, $gp->static, ref($self));
- }
-
- my @libobjects = values %$libs;
- tsay {"libs:\n", join("\n", keys %$libs)};
- tsay {"libfiles:\n", join("\n", map { $_->{fullpath} } @libobjects)};
-
- $linker->create_symlinks($symlinkdir, $libs);
- foreach my $k (@$finalorderedlibs) {
- my $a = $libs->{$k}->{fullpath} || die "Link error: $k not found in \$libs\n";
- if ($a =~ m/\.a$/) {
- # don't make a -lfoo out of a static library
- push @libflags, $a;
- } else {
- push @libflags, $linker->infer_libparameter($a, $k);
- }
- }
-
- my @linkeropts = ();
- for my $d (@$RPdirs) {
- push(@linkeropts, '-rpath', $d);
- }
- for my $d (keys %$rpath_link) {
- push(@linkeropts, '-rpath-link', $d);
- }
- if ($symbolsfile) {
- push(@linkeropts, '-retain-symbols-file', $symbolsfile);
- }
- @cmd = @$ltprog;
- push @cmd, '-o', $dst;
- push @cmd, '-pthread' if $parser->{pthread};
- push @cmd, @$args if $args;
- push @cmd, @{$self->{objlist}} if @{$self->{objlist}};
- push @cmd, @$staticlibs if @$staticlibs;
- push @cmd, "-L$symlinkdir", @libflags if @libflags;
- push @cmd, '-Wl,'. join(',', @linkeropts) if @linkeropts;
- LT::Exec->link(@cmd);
-}
1;