1*9761804bSzhuk# $OpenBSD: Program.pm,v 1.6 2014/04/20 17:34:26 zhuk Exp $ 2ce8e7994Sespie 3ce8e7994Sespie# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org> 4ce8e7994Sespie# Copyright (c) 2012 Marc Espie <espie@openbsd.org> 5ce8e7994Sespie# 6ce8e7994Sespie# Permission to use, copy, modify, and distribute this software for any 7ce8e7994Sespie# purpose with or without fee is hereby granted, provided that the above 8ce8e7994Sespie# copyright notice and this permission notice appear in all copies. 9ce8e7994Sespie# 10ce8e7994Sespie# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11ce8e7994Sespie# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12ce8e7994Sespie# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13ce8e7994Sespie# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14ce8e7994Sespie# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15ce8e7994Sespie# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16ce8e7994Sespie# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17ce8e7994Sespie 18ce8e7994Sespieuse strict; 19ce8e7994Sespieuse warnings; 20ce8e7994Sespieuse feature qw(say); 21ce8e7994Sespie 22ce8e7994Sespieuse LT::Program; 23ce8e7994Sespie 24ce8e7994Sespiepackage LT::Program; 25ce8e7994Sespie 26ce8e7994Sespiesub link 27ce8e7994Sespie{ 28ce8e7994Sespie return LT::Linker::Program->new->link(@_); 29ce8e7994Sespie} 30ce8e7994Sespie 31ce8e7994Sespiepackage LT::Linker::Program; 32ce8e7994Sespieour @ISA = qw(LT::Linker); 33ce8e7994Sespie 34ce8e7994Sespieuse LT::Trace; 35ce8e7994Sespieuse LT::Util; 36ce8e7994Sespieuse File::Basename; 37ce8e7994Sespie 38ce8e7994Sespiesub link 39ce8e7994Sespie{ 40ce8e7994Sespie my ($linker, $self, $ltprog, $ltconfig, $dirs, $libs, $deplibs, 41ce8e7994Sespie $libdirs, $parser, $gp) = @_; 42ce8e7994Sespie 43ce8e7994Sespie tsay {"linking program (", ($gp->static ? "not " : ""), 44ce8e7994Sespie "dynamically linking not-installed libtool libraries)"}; 45ce8e7994Sespie 46ce8e7994Sespie my $fpath = $self->{outfilepath}; 47ce8e7994Sespie my $RPdirs = $self->{RPdirs}; 48ce8e7994Sespie 49ce8e7994Sespie my $odir = dirname($fpath); 50ce8e7994Sespie my $fname = basename($fpath); 51ce8e7994Sespie 52ce8e7994Sespie my @libflags; 53ce8e7994Sespie my @cmd; 54ce8e7994Sespie my $dst; 55ce8e7994Sespie 56ce8e7994Sespie my ($staticlibs, $finalorderedlibs, $args) = 57ce8e7994Sespie $linker->common1($parser, $gp, $deplibs, $libdirs, $dirs, $libs); 58ce8e7994Sespie 59ce8e7994Sespie my $symlinkdir = $ltdir; 60ce8e7994Sespie if ($odir ne '.') { 61ce8e7994Sespie $symlinkdir = "$odir/$ltdir"; 62ce8e7994Sespie } 63ce8e7994Sespie mkdir $symlinkdir if ! -d $symlinkdir; 64ce8e7994Sespie if ($parser->{seen_la_shared}) { 65ce8e7994Sespie $dst = ($odir eq '.') ? "$ltdir/$fname" : "$odir/$ltdir/$fname"; 66ce8e7994Sespie $self->write_wrapper; 67ce8e7994Sespie } else { 68ce8e7994Sespie $dst = ($odir eq '.') ? $fname : "$odir/$fname"; 69ce8e7994Sespie } 70ce8e7994Sespie 71*9761804bSzhuk my $rpath_link = LT::UList->new; 72ce8e7994Sespie # add libdirs to rpath if they are not in standard lib path 73ce8e7994Sespie for my $l (@$libdirs) { 74ce8e7994Sespie if (LT::OSConfig->is_search_dir($l)) { 75*9761804bSzhuk push @$rpath_link, $l; 76ce8e7994Sespie } else { 77ce8e7994Sespie push @$RPdirs, $l; 78ce8e7994Sespie } 79ce8e7994Sespie } 80ce8e7994Sespie foreach my $k (keys %$libs) { 81ce8e7994Sespie tprint {"key = $k - "}; 82ce8e7994Sespie my $r = ref($libs->{$k}); 83ce8e7994Sespie tsay {"ref = $r"}; 84ce8e7994Sespie $libs->create($k)->resolve_library($dirs, 1, $gp->static, 85ce8e7994Sespie ref($self)); 86ce8e7994Sespie } 87ce8e7994Sespie 88ce8e7994Sespie my @libobjects = values %$libs; 89ce8e7994Sespie tsay {"libs:\n", join("\n", keys %$libs)}; 90ce8e7994Sespie tsay {"libfiles:\n", join("\n", map { $_->{fullpath} } @libobjects)}; 91ce8e7994Sespie 92ce8e7994Sespie $linker->create_symlinks($symlinkdir, $libs); 93ce8e7994Sespie foreach my $k (@$finalorderedlibs) { 94ce8e7994Sespie my $a = $libs->{$k}->{fullpath} || die "Link error: $k not found in \$libs\n"; 95ce8e7994Sespie if ($a =~ m/\.a$/) { 96ce8e7994Sespie # don't make a -lfoo out of a static library 97ce8e7994Sespie push @libflags, $a; 98ce8e7994Sespie } else { 99ce8e7994Sespie push @libflags, $linker->infer_libparameter($a, $k); 100ce8e7994Sespie } 101ce8e7994Sespie } 102ce8e7994Sespie 103ce8e7994Sespie my @linkeropts = (); 1041d4b672eSespie if (!$ltconfig->noshared) { 105ce8e7994Sespie for my $d (@$RPdirs) { 106ce8e7994Sespie push(@linkeropts, '-rpath', $d); 107ce8e7994Sespie } 108*9761804bSzhuk for my $d (@$rpath_link) { 109ce8e7994Sespie push(@linkeropts, '-rpath-link', $d); 110ce8e7994Sespie } 1111d4b672eSespie } 112c15864b4Sespie 113c15864b4Sespie push(@linkeropts, $linker->export_symbols($ltconfig, 114c15864b4Sespie "$odir/$ltdir/$fname", $gp, @{$self->{objlist}}, @$staticlibs)); 115c15864b4Sespie 116ce8e7994Sespie @cmd = @$ltprog; 117ce8e7994Sespie push @cmd, '-o', $dst; 118ce8e7994Sespie push @cmd, '-pthread' if $parser->{pthread}; 119ce8e7994Sespie push @cmd, @$args if $args; 120ce8e7994Sespie push @cmd, @{$self->{objlist}} if @{$self->{objlist}}; 121ce8e7994Sespie push @cmd, @$staticlibs if @$staticlibs; 122ce8e7994Sespie push @cmd, "-L$symlinkdir", @libflags if @libflags; 123c15864b4Sespie push @cmd, join(',', '-Wl', @linkeropts) if @linkeropts; 124ce8e7994Sespie LT::Exec->link(@cmd); 125ce8e7994Sespie} 126ce8e7994Sespie1; 127