xref: /openbsd-src/usr.bin/libtool/LT/Mode/Link/Program.pm (revision 9761804b54a27882267d629875396c3dfba4a388)
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