diff options
author | Marc Espie <espie@cvs.openbsd.org> | 2012-07-13 11:56:14 +0000 |
---|---|---|
committer | Marc Espie <espie@cvs.openbsd.org> | 2012-07-13 11:56:14 +0000 |
commit | d5682b5365c31c5f8bdffd7309f3e48a32684ab8 (patch) | |
tree | 33f5fd7e9ec69041989e8d0ba9b46faa2d04ec73 /usr.bin/libtool/LT | |
parent | f2eeda3c7c3c63c21432abb225e9d36773e89121 (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.pm | 141 | ||||
-rw-r--r-- | usr.bin/libtool/LT/Library.pm | 20 | ||||
-rw-r--r-- | usr.bin/libtool/LT/Linker.pm | 103 | ||||
-rw-r--r-- | usr.bin/libtool/LT/Mode/Link.pm | 115 | ||||
-rw-r--r-- | usr.bin/libtool/LT/Mode/Link/Library.pm | 162 | ||||
-rw-r--r-- | usr.bin/libtool/LT/Mode/Link/Program.pm | 132 | ||||
-rw-r--r-- | usr.bin/libtool/LT/Program.pm | 113 |
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; |