summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr.bin/libtool/LT/Mode/Compile.pm83
-rw-r--r--usr.bin/libtool/LT/Mode/Install.pm97
-rw-r--r--usr.bin/libtool/LT/Mode/Link.pm387
-rw-r--r--usr.bin/libtool/Makefile7
-rwxr-xr-xusr.bin/libtool/libtool497
5 files changed, 593 insertions, 478 deletions
diff --git a/usr.bin/libtool/LT/Mode/Compile.pm b/usr.bin/libtool/LT/Mode/Compile.pm
new file mode 100644
index 00000000000..bb367f21e34
--- /dev/null
+++ b/usr.bin/libtool/LT/Mode/Compile.pm
@@ -0,0 +1,83 @@
+# ex:ts=8 sw=4:
+# $OpenBSD: Compile.pm,v 1.1 2012/06/24 13:44:53 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;
+package LT::Mode::Compile;
+
+use File::Basename;
+use LT::LoFile;
+use LT::Util;
+
+my @valid_src = qw(asm c cc cpp cxx f s);
+my %opts;
+sub run
+{
+ my ($class, $ltprog, $gp, $tags, $noshared) = @_;
+ my $lofile = LT::LoFile->new;
+
+ $gp->getoptions('o=s' => \$opts{'o'},
+ 'prefer-pic' => \$opts{'prefer-pic'},
+ 'prefer-non-pic'=> \$opts{'prefer-non-pic'},
+ 'static' => \$opts{'static'},
+ );
+ # XXX options ignored: -prefer-pic and -prefer-non-pic
+ my $pic = 0;
+ my $nonpic = 1;
+ # assume we need to build pic objects
+ $pic = 1 if (!$noshared);
+ $nonpic = 0 if ($pic && grep { $_ eq 'disable-static' } @$tags);
+ $pic = 0 if ($nonpic && grep { $_ eq 'disable-shared' } @$tags);
+ $nonpic = 1 if ($opts{'static'});
+
+ my ($outfile, $odir, $ofile, $srcfile, $srcext);
+ # XXX check whether -c flag is present and if not, die?
+ if ($opts{'o'}) {
+ # fix extension if needed
+ ($outfile = $opts{'o'}) =~ s/\.o$/.lo/;
+ $odir = dirname($outfile);
+ $ofile = basename($outfile);
+ } else {
+ # XXX sometimes no -o flag is present and we need another way
+ my $srcre = join '|', @valid_src;
+ my $found = 0;
+ foreach my $a (@ARGV) {
+ if ($a =~ m/\.($srcre)$/i) {
+ $srcfile = $a;
+ $srcext = $1;
+ $found = 1;
+ last;
+ }
+ }
+ $found or die "Cannot find source file in command\n";
+ # the output file ends up in the current directory
+ $odir = '.';
+ ($ofile = basename $srcfile) =~ s/\.($srcext)$/.lo/i;
+ $outfile = "$odir/$ofile";
+ }
+ LT::Trace::debug {"srcfile = $srcfile\n"} if $srcfile;
+ LT::Trace::debug {"outfile = $outfile\n"};
+ (my $nonpicobj = $ofile) =~ s/\.lo$/.o/;
+ my $picobj = "$ltdir/$nonpicobj";
+
+ $lofile->{picobj} = $picobj if $pic;
+ $lofile->{nonpicobj} = $nonpicobj if $nonpic;
+ $lofile->compile($ltprog, $odir, \@ARGV);
+ $lofile->write($outfile);
+}
+
+1;
diff --git a/usr.bin/libtool/LT/Mode/Install.pm b/usr.bin/libtool/LT/Mode/Install.pm
new file mode 100644
index 00000000000..8ab9558fb4d
--- /dev/null
+++ b/usr.bin/libtool/LT/Mode/Install.pm
@@ -0,0 +1,97 @@
+# ex:ts=8 sw=4:
+# $OpenBSD: Install.pm,v 1.1 2012/06/24 13:44:53 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;
+
+package LT::Mode::Install;
+
+use LT::Util;
+use Getopt::Std;
+use File::Basename;
+
+sub run
+{
+ my ($class, $ltprog) = @_;
+ # we just parse the options in order to find the actual arguments
+ my @argvcopy = @ARGV;
+ my %install_opts;
+ LT::Trace::debug {"ltprog[-1] = $$ltprog[-1]\n"};
+ if ($$ltprog[-1] =~ m/install([.-]sh)?$/) {
+ getopts('BbCcdf:g:m:o:pSs', \%install_opts);
+ if (@ARGV < 2 && (!defined $install_opts{'d'} && @ARGV == 1)) {
+ die "Wrong number of arguments for install\n";
+ }
+ } elsif ($$ltprog[-1] =~ m/cp$/) {
+ getopts('HLPRfipr', \%install_opts);
+ if (@ARGV < 2) {
+ die "Wrong number of arguments for install\n";
+ }
+ } else {
+ die "Unsupported install program $$ltprog[-1]\n";
+ }
+ my @instopts = @argvcopy[0 .. (@argvcopy - @ARGV - 1)];
+ my $dst = pop @ARGV;
+ my @src = @ARGV;
+ my $dstdir;
+ if (-d $dst) {
+ $dstdir = $dst;
+ } else {
+ # dst is not a directory, i.e. a file
+ if (@src > 1) {
+ # XXX not really libtool's task to check this
+ die "Multiple source files combined with file destination.\n";
+ } else {
+ $dstdir = dirname $dst;
+ }
+ }
+ foreach my $s (@src) {
+ my $dstfile = basename $s;
+ # resolve symbolic links, so we don't try to test later
+ # whether the symlink is a program wrapper etc.
+ if (-l $s) {
+ $s = readlink($s) or die "Cannot readlink $s: $!\n";
+ }
+ my $srcdir = dirname $s;
+ my $srcfile = basename $s;
+ LT::Trace::debug {"srcdir = $srcdir\nsrcfile = $srcfile\n"};
+ LT::Trace::debug {"dstdir = $dstdir\ndstfile = $dstfile\n"};
+ if ($srcfile =~ m/^\S+\.la$/) {
+ require LT::LaFile;
+ LT::LaFile->install($s, $dstdir, $ltprog, \@instopts, $install_opts{'s'});
+ } elsif (-f "$srcdir/$ltdir/$srcfile" && is_wrapper($s)) {
+ require LT::Program;
+ LT::Program->install($s, $dst, $ltprog, \@instopts);
+ } else {
+ LT::Exec->install(@$ltprog, @instopts, $s, $dst);
+ }
+ }
+ if (defined $install_opts{'d'}) {
+ LT::Exec->install(@$ltprog, @instopts, @ARGV);
+ }
+}
+
+sub is_wrapper
+{
+# my $self = shift;
+ my $program = shift;
+
+ open(my $pw, '<', $program) or die "Cannot open $program: $!\n";
+ return grep { m/wrapper\sfor/ } <$pw>;
+}
+
+1;
diff --git a/usr.bin/libtool/LT/Mode/Link.pm b/usr.bin/libtool/LT/Mode/Link.pm
new file mode 100644
index 00000000000..a4ef6eddf29
--- /dev/null
+++ b/usr.bin/libtool/LT/Mode/Link.pm
@@ -0,0 +1,387 @@
+# ex:ts=8 sw=4:
+# $OpenBSD: Link.pm,v 1.1 2012/06/24 13:44:53 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::Mode::Link;
+use LT::Util;
+use LT::Parser;
+use File::Basename;
+
+use constant {
+ OBJECT => 0, # unused ?
+ LIBRARY => 1,
+ PROGRAM => 2,
+};
+
+
+our %opts;
+my $shared = 0;
+my $static = 1;
+my @libsearchdirs;
+
+sub run
+{
+ my ($class, $ltprog, $gp, $tags, $noshared) = @_;
+
+ my $cmd;
+ my @Ropts; # -R options on the command line
+ my @Rresolved; # -R options originating from .la resolution
+ my @RPopts; # -rpath options
+ my $libdirs = []; # list of libdirs
+ my $libs = {}; # libraries
+ my $dirs = {}; # paths to find libraries
+ # put a priority in the dir hash
+ # always look here
+ $dirs->{'/usr/lib'} = 3;
+
+ $gp->getoptions('all-static' => \$opts{'all-static'},
+ 'avoid-version' => \$opts{'avoid-version'},
+ 'dlopen=s{1}' => \$opts{'dlopen'},
+ 'dlpreopen=s{1}' => \$opts{'dlpreopen'},
+ 'export-dynamic' => \$opts{'export-dynamic'},
+ 'export-symbols=s' => \$opts{'export-symbols'},
+ 'export-symbols-regex=s'=> \$opts{'export-symbols-regex'},
+ 'module' => \$opts{'module'},
+ 'no-fast-install' => \$opts{'no-fast-install'},
+ 'no-install' => \$opts{'no-install'},
+ 'no-undefined' => \$opts{'no-undefined'},
+ 'o=s' => \$opts{'o'},
+ 'objectlist=s' => \$opts{'objectlist'},
+ 'precious-files-regex=s'=> \$opts{'precious-files-regex'},
+ 'prefer-pic' => \$opts{'prefer-pic'},
+ 'prefer-non-pic' => \$opts{'prefer-non-pic'},
+ 'release=s' => \$opts{'release'},
+ 'rpath=s' => \@RPopts,
+ 'R=s' => \@Ropts,
+ 'shrext=s' => \$opts{'shrext'},
+ 'static' => \$opts{'static'},
+ 'thread-safe' => \$opts{'thread-safe'},
+ 'version-info=s{1}' => \$opts{'version-info'},
+ 'version_info=s{1}' => \$opts{'version-info'},
+ 'version-number=s{1}' => \$opts{'version-info'},
+ );
+ # XXX options ignored: dlopen, dlpreopen, no-fast-install,
+ # no-install, no-undefined, precious-files-regex,
+ # shrext, thread-safe, prefer-pic, prefer-non-pic
+
+ @libsearchdirs = get_search_dirs();
+ # add the .libs dir as well in case people try to link directly
+ # with the real library instead of the .la library
+ push @libsearchdirs, './.libs';
+
+ my $outfile = $opts{'o'};
+ if (!$outfile) {
+ die "No output file given.\n";
+ }
+ LT::Trace::debug {"outfile = $outfile\n"};
+ my $odir = dirname($outfile);
+ my $ofile = basename($outfile);
+
+ # what are we linking?
+ my $linkmode = PROGRAM;
+ if ($ofile =~ m/\.l?a$/) {
+ $linkmode = LIBRARY;
+ }
+ LT::Trace::debug {"linkmode: $linkmode\n"};
+
+ # eat multiple version-info arguments, we only accept the first.
+ map { $_ = '' if ($_ =~ m/\d+:\d+:\d+/); } @ARGV;
+
+ my @objs;
+ my @sobjs;
+ if ($opts{'objectlist'}) {
+ my $objectlist = $opts{'objectlist'};
+ open(my $ol, '<', $objectlist) or die "Cannot open $objectlist: $!\n";
+ my @objlist = <$ol>;
+ for (@objlist) { chomp; }
+ generate_objlist(\@objs, \@sobjs, \@objlist);
+ } else {
+ generate_objlist(\@objs, \@sobjs, \@ARGV);
+ }
+ LT::Trace::debug {"objs = @objs\n"};
+ LT::Trace::debug {"sobjs = @sobjs\n"};
+
+ my $deplibs = []; # list of dependent libraries (both -L and -l flags)
+ my $parser = LT::Parser->new(\@ARGV);
+ $parser->{result} = [];
+
+
+ if ($linkmode == PROGRAM) {
+ require LT::Program;
+ my $program = LT::Program->new;
+ $program->{outfilepath} = $outfile;
+ # XXX give higher priority to dirs of not installed libs
+ if ($opts{'export-dynamic'}) {
+ push(@{$parser->{args}}, "-Wl,-E");
+ }
+
+ $parser->parse_linkargs1($deplibs, \@Rresolved, \@libsearchdirs,
+ $dirs, $libs, $parser->{args}, 0);
+ $parser->{args} = $parser->{result};
+ LT::Trace::debug {"end parse_linkargs1\n"};
+ LT::Trace::debug {"deplibs = @$deplibs\n"};
+
+ $program->{objlist} = \@objs;
+ if (@objs == 0) {
+ if (@sobjs > 0) {
+ LT::Trace::debug {"no non-pic libtool objects found, trying pic objects...\n"};
+ $program->{objlist} = \@sobjs;
+ } elsif (@sobjs == 0) {
+ LT::Trace::debug {"no libtool objects of any kind found\n"};
+ LT::Trace::debug {"hoping for real objects in ARGV...\n"};
+ }
+ }
+ my $RPdirs = [];
+ @$RPdirs = (@Ropts, @RPopts, @Rresolved);
+ $program->{RPdirs} = $RPdirs;
+
+ $program->link($ltprog, $dirs, $libs, $deplibs, $libdirs, $parser, \%opts);
+ } elsif ($linkmode == LIBRARY) {
+ my $convenience = 0;
+ require LT::LaFile;
+ my $lainfo = LT::LaFile->new;
+
+ $shared = 1 if ($opts{'version-info'} ||
+ $opts{'avoid-version'} ||
+ $opts{module});
+ if (!@RPopts) {
+ $convenience = 1;
+ $noshared = 1;
+ $static = 1;
+ $shared = 0;
+ } else {
+ $shared = 1;
+ }
+ if ($ofile =~ m/\.a$/ && !$convenience) {
+ $ofile =~ s/\.a$/.la/;
+ $outfile =~ s/\.a$/.la/;
+ }
+ (my $libname = $ofile) =~ s/\.l?a$//; # remove extension
+ my $staticlib = $libname.'.a';
+ my $sharedlib = $libname.'.so';
+ my $sharedlib_symlink;
+
+ if ($opts{'static'} || $opts{'all-static'}) {
+ $shared = 0;
+ $static = 1;
+ }
+ $shared = 0 if $noshared;
+
+ $parser->parse_linkargs1($deplibs, \@Rresolved, \@libsearchdirs,
+ $dirs, $libs, $parser->{args}, 0);
+ $parser->{args} = $parser->{result};
+ LT::Trace::debug {"end parse_linkargs1\n"};
+ LT::Trace::debug {"deplibs = @$deplibs\n"};
+
+ my $sover = '0.0';
+ my $origver = 'unknown';
+ # environment overrides -version-info
+ (my $envlibname = $libname) =~ s/[.+-]/_/g;
+ my ($current, $revision, $age) = (0, 0, 0);
+ if ($opts{'version-info'}) {
+ ($current, $revision, $age) = parse_version_info($opts{'version-info'});
+ $origver = "$current.$revision";
+ $sover = $origver;
+ }
+ if ($ENV{"${envlibname}_ltversion"}) {
+ # this takes priority over the previous
+ $sover = $ENV{"${envlibname}_ltversion"};
+ ($current, $revision) = split /\./, $sover;
+ $age = 0;
+ }
+ if (defined $opts{release}) {
+ $sharedlib_symlink = $sharedlib;
+ $sharedlib = $libname.'-'.$opts{release}.'.so';
+ }
+ if ($opts{'avoid-version'} ||
+ (defined $opts{release} && !$opts{'version-info'})) {
+ # don't add a version in these cases
+ } else {
+ $sharedlib .= ".$sover";
+ if (defined $opts{release}) {
+ $sharedlib_symlink .= ".$sover";
+ }
+ }
+
+ # XXX add error condition somewhere...
+ $static = 0 if ($shared && grep { $_ eq 'disable-static' } @$tags);
+ $shared = 0 if ($static && grep { $_ eq 'disable-shared' } @$tags);
+
+ LT::Trace::debug {"SHARED: $shared\nSTATIC: $static\n"};
+
+ $lainfo->{'libname'} = $libname;
+ if ($shared) {
+ $lainfo->{'dlname'} = $sharedlib;
+ $lainfo->{'library_names'} = $sharedlib;
+ $lainfo->{'library_names'} .= " $sharedlib_symlink"
+ if (defined $opts{release});
+ $lainfo->link($ltprog, $ofile, $sharedlib, $odir, 1, \@sobjs, $dirs, $libs, $deplibs, $libdirs, $parser, \%opts);
+ LT::Trace::debug {"sharedlib: $sharedlib\n"};
+ $lainfo->{'current'} = $current;
+ $lainfo->{'revision'} = $revision;
+ $lainfo->{'age'} = $age;
+ }
+ if ($static) {
+ $lainfo->{'old_library'} = $staticlib;
+ $lainfo->link($ltprog, $ofile, $staticlib, $odir, 0, ($convenience && @sobjs > 0) ? \@sobjs : \@objs, $dirs, $libs, $deplibs, $libdirs, $parser, \%opts);
+ LT::Trace::debug {($convenience ? "convenience" : "static")." lib: $staticlib\n"};
+ }
+ $lainfo->{installed} = 'no';
+ $lainfo->{shouldnotlink} = $opts{module} ? 'yes' : 'no';
+ map { $_ = "-R$_" } @Ropts;
+ unshift @$deplibs, @Ropts if (@Ropts);
+ LT::Trace::debug {"deplibs = @$deplibs\n"};
+ my $finaldeplibs = reverse_zap_duplicates_ref($deplibs);
+ LT::Trace::debug {"finaldeplibs = @$finaldeplibs\n"};
+ $lainfo->set('dependency_libs', "@$finaldeplibs");
+ if (@RPopts) {
+ if (@RPopts > 1) {
+ LT::Trace::debug {"more than 1 -rpath option given, taking the first: ", $RPopts[0], "\n"};
+ }
+ $lainfo->{'libdir'} = $RPopts[0];
+ }
+ if (!($convenience && $ofile =~ m/\.a$/)) {
+ $lainfo->write($outfile, $ofile);
+ unlink("$odir/$ltdir/$ofile");
+ symlink("../$ofile", "$odir/$ltdir/$ofile");
+ }
+ my $lai = "$odir/$ltdir/$ofile".'i';
+ if ($shared) {
+ my $pdeplibs = process_deplibs($finaldeplibs);
+ if (defined $pdeplibs) {
+ $lainfo->set('dependency_libs', "@$pdeplibs");
+ }
+ if (! $opts{module}) {
+ $lainfo->write_shared_libs_log($origver);
+ }
+ }
+ $lainfo->{'installed'} = 'yes';
+ # write .lai file (.la file that will be installed)
+ $lainfo->write($lai, $ofile);
+ }
+}
+
+# XXX reuse code from SharedLibs.pm instead
+sub get_search_dirs
+{
+ my @libsearchdirs;
+ open(my $fh, '-|', '/sbin/ldconfig -r');
+ if (defined $fh) {
+ while (<$fh>) {
+ if (m/^\s*search directories:\s*(.*?)\s*$/o) {
+ foreach my $d (split(/\:/o, $1)) {
+ push @libsearchdirs, $d;
+ }
+ last;
+ }
+ }
+ close($fh);
+ } else {
+ die "Can't run ldconfig\n";
+ }
+ return @libsearchdirs;
+}
+
+# populate arrays of non-pic and pic objects and remove these from @ARGV
+sub generate_objlist
+{
+ my $objs = shift;
+ my $sobjs = shift;
+ my $objsource = shift;
+
+ my $result = [];
+ foreach my $a (@$objsource) {
+ if ($a =~ m/\S+\.lo$/) {
+ require LT::LoFile;
+ my $ofile = basename $a;
+ my $odir = dirname $a;
+ my $loinfo = LT::LoFile->parse($a);
+ if ($loinfo->{'non_pic_object'}) {
+ my $o;
+ $o .= "$odir/" if ($odir ne '.');
+ $o .= $loinfo->{'non_pic_object'};
+ push @$objs, $o;
+ }
+ if ($loinfo->{'pic_object'}) {
+ my $o;
+ $o .= "$odir/" if ($odir ne '.');
+ $o .= $loinfo->{'pic_object'};
+ push @$sobjs, $o;
+ }
+ } elsif ($a =~ m/\S+\.o$/) {
+ push @$objs, $a;
+ } else {
+ push @$result, $a;
+ }
+ }
+ @$objsource = @$result;
+}
+
+# convert 4:5:8 into a list of numbers
+sub parse_version_info
+{
+ my $vinfo = shift;
+
+ if ($vinfo =~ m/^(\d+):(\d+):(\d+)$/) {
+ return ($1, $2, $3);
+ } elsif ($vinfo =~ m/^(\d+):(\d+)$/) {
+ return ($1, $2, 0);
+ } elsif ($vinfo =~ m/^(\d+)$/) {
+ return ($1, 0, 0);
+ } else {
+ die "Error parsing -version-info $vinfo\n";
+ }
+}
+
+# prepare dependency_libs information for the .la file which is installed
+# i.e. remove any .libs directories and use the final libdir for all the
+# .la files
+sub process_deplibs
+{
+ my $linkflags = shift;
+
+ my $result;
+
+ foreach my $lf (@$linkflags) {
+ if ($lf =~ m/-L\S+\Q$ltdir\E$/) {
+ } elsif ($lf =~ m/-L\./) {
+ } elsif ($lf =~ m/\/\S+\/(\S+\.la)/) {
+ my $lafile = $1;
+ require LT::LaFile;
+ my $libdir = LT::LaFile->parse($lf)->{'libdir'};
+ if ($libdir eq '') {
+ # this drops libraries which will not be
+ # installed
+ # XXX improve checks when adding to deplibs
+ say "warning: $lf dropped from deplibs";
+ } else {
+ $lf = $libdir.'/'.$lafile;
+ push @$result, $lf;
+ }
+ } else {
+ push @$result, $lf;
+ }
+ }
+ return $result;
+}
+
+
+1;
+
diff --git a/usr.bin/libtool/Makefile b/usr.bin/libtool/Makefile
index eb85c7a60b6..70921f7e203 100644
--- a/usr.bin/libtool/Makefile
+++ b/usr.bin/libtool/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.1 2012/06/19 09:30:44 espie Exp $
+# $OpenBSD: Makefile,v 1.2 2012/06/24 13:44:53 espie Exp $
.include <bsd.own.mk>
@@ -12,6 +12,9 @@ PACKAGES= \
LT/LaLoFile.pm \
LT/Library.pm \
LT/LoFile.pm \
+ LT/Mode/Compile.pm \
+ LT/Mode/Install.pm \
+ LT/Mode/Link.pm \
LT/Parser.pm \
LT/Program.pm \
LT/Trace.pm \
@@ -22,6 +25,8 @@ LIBBASE=/usr/libdata/perl5
realinstall:
${INSTALL} -d -o ${LIBOWN} -g ${LIBGRP} -m ${DIRMODE} \
${DESTDIR}${LIBBASE}/LT
+ ${INSTALL} -d -o ${LIBOWN} -g ${LIBGRP} -m ${DIRMODE} \
+ ${DESTDIR}${LIBBASE}/LT/Mode
.for i in ${PACKAGES}
${INSTALL} ${INSTALL_COPY} -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \
${.CURDIR}/$i ${DESTDIR}${LIBBASE}/$i
diff --git a/usr.bin/libtool/libtool b/usr.bin/libtool/libtool
index a536dceb85c..4716272bae3 100755
--- a/usr.bin/libtool/libtool
+++ b/usr.bin/libtool/libtool
@@ -1,5 +1,5 @@
#!/usr/bin/perl
-# $OpenBSD: libtool,v 1.2 2012/06/19 18:56:07 espie Exp $
+# $OpenBSD: libtool,v 1.3 2012/06/24 13:44:53 espie Exp $
# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
#
@@ -23,44 +23,39 @@ use File::Basename;
use File::Glob ':glob';
use File::Path;
use Getopt::Long;
-use Getopt::Std;
+
use LT::Trace;
use LT::Exec;
-use LT::Parser;
use LT::Util;
package main;
+$SIG{__DIE__} = sub {
+ require Carp;
+
+ my $_ = pop @_;
+ s/(.*)( at .*? line .*?\n$)/$1/s;
+ push @_, $_;
+ die &Carp::longmess;
+};
+
use subs qw(
create_symlinks
- generate_objlist
- get_search_dirs
guess_implicit_mode
help
notyet
- parse_version_info
- process_deplibs
- is_wrapper
);
use Config;
-use constant {
- OBJECT => 0,
- LIBRARY => 1,
- PROGRAM => 2,
-};
-
my @no_shared_archs = qw(m88k vax);
my $machine_arch = $Config{'ARCH'};
(my $gnu_arch = $machine_arch) =~ s/amd64/x86_64/;
my @valid_modes = qw(clean compile execute finish install link uninstall);
-my @valid_src = qw(asm c cc cpp cxx f s);
my $cwd = getcwd();
my $instlibdir = '/usr/local/lib';
-my @libsearchdirs;
$instlibdir = $ENV{'LIBDIR'} if defined $ENV{'LIBDIR'};
my $mode;
@@ -79,9 +74,6 @@ my @tags; # list of --tag options passed to libtool
# -Wl,-rpath,libdir will bypass libtool.
# build static/shared objects?
-my $static = 1;
-my $shared = 0;
-my $convenience = 0;
my $noshared = 0;
if (grep { $_ eq $machine_arch } @no_shared_archs) {
$noshared = 1;
@@ -151,356 +143,22 @@ if (!($mode && grep { $_ eq $mode } @valid_modes)) {
$gp->configure('permute');
if ($mode eq 'compile') {
- require LT::LoFile;
- my $lofile = LT::LoFile->new;
-
- $gp->getoptions('o=s' => \$opts{'o'},
- 'prefer-pic' => \$opts{'prefer-pic'},
- 'prefer-non-pic'=> \$opts{'prefer-non-pic'},
- 'static' => \$opts{'static'},
- );
- # XXX options ignored: -prefer-pic and -prefer-non-pic
- my $pic = 0;
- my $nonpic = 1;
- # assume we need to build pic objects
- $pic = 1 if (!$noshared);
- $nonpic = 0 if ($pic && grep { $_ eq 'disable-static' } @tags);
- $pic = 0 if ($nonpic && grep { $_ eq 'disable-shared' } @tags);
- $nonpic = 1 if ($opts{'static'});
-
- my ($outfile, $odir, $ofile, $srcfile, $srcext);
- # XXX check whether -c flag is present and if not, die?
- if ($opts{'o'}) {
- # fix extension if needed
- ($outfile = $opts{'o'}) =~ s/\.o$/.lo/;
- $odir = dirname $outfile;
- $ofile = basename $outfile;
- } else {
- # XXX sometimes no -o flag is present and we need another way
- my $srcre = join '|', @valid_src;
- my $found = 0;
- foreach my $a (@ARGV) {
- if ($a =~ m/\.($srcre)$/i) {
- $srcfile = $a;
- $srcext = $1;
- $found = 1;
- last;
- }
- }
- $found or die "Cannot find source file in command\n";
- # the output file ends up in the current directory
- $odir = '.';
- ($ofile = basename $srcfile) =~ s/\.($srcext)$/.lo/i;
- $outfile = "$odir/$ofile";
- }
- LT::Trace::debug {"srcfile = $srcfile\n"} if $srcfile;
- LT::Trace::debug {"outfile = $outfile\n"};
- (my $nonpicobj = $ofile) =~ s/\.lo$/.o/;
- my $picobj = "$ltdir/$nonpicobj";
-
- $lofile->{picobj} = $picobj if $pic;
- $lofile->{nonpicobj} = $nonpicobj if $nonpic;
- $lofile->compile($ltprog, $odir, \@ARGV);
- $lofile->write($outfile);
+ require LT::Mode::Compile;
+ LT::Mode::Compile->run($ltprog, $gp, \@tags, $noshared);
} elsif ($mode eq 'install') {
- # we just parse the options in order to find the actual arguments
- my @argvcopy = @ARGV;
- my %install_opts;
- LT::Trace::debug {"ltprog[-1] = $$ltprog[-1]\n"};
- if ($$ltprog[-1] =~ m/install([.-]sh)?$/) {
- getopts('BbCcdf:g:m:o:pSs', \%install_opts);
- if (@ARGV < 2 && (!defined $install_opts{'d'} && @ARGV == 1)) {
- die "Wrong number of arguments for install\n";
- }
- } elsif ($$ltprog[-1] =~ m/cp$/) {
- getopts('HLPRfipr', \%install_opts);
- if (@ARGV < 2) {
- die "Wrong number of arguments for install\n";
- }
- } else {
- die "Unsupported install program $$ltprog[-1]\n";
- }
- my @instopts = @argvcopy[0 .. (@argvcopy - @ARGV - 1)];
- my $dst = pop @ARGV;
- my @src = @ARGV;
- my $dstdir;
- if (-d $dst) {
- $dstdir = $dst;
- } else {
- # dst is not a directory, i.e. a file
- if (@src > 1) {
- # XXX not really libtool's task to check this
- die "Multiple source files combined with file destination.\n";
- } else {
- $dstdir = dirname $dst;
- }
- }
- foreach my $s (@src) {
- my $dstfile = basename $s;
- # resolve symbolic links, so we don't try to test later
- # whether the symlink is a program wrapper etc.
- if (-l $s) {
- $s = readlink($s) or die "Cannot readlink $s: $!\n";
- }
- my $srcdir = dirname $s;
- my $srcfile = basename $s;
- LT::Trace::debug {"srcdir = $srcdir\nsrcfile = $srcfile\n"};
- LT::Trace::debug {"dstdir = $dstdir\ndstfile = $dstfile\n"};
- if ($srcfile =~ m/^\S+\.la$/) {
- require LT::LaFile;
- LT::LaFile->install($s, $dstdir, $ltprog, \@instopts, $install_opts{'s'});
- } elsif (-f "$srcdir/$ltdir/$srcfile" && is_wrapper($s)) {
- require LT::Program;
- LT::Program->install($s, $dst, $ltprog, \@instopts);
- } else {
- LT::Exec->$mode(@$ltprog, @instopts, $s, $dst);
- }
- }
- if (defined $install_opts{'d'}) {
- LT::Exec->$mode(@$ltprog, @instopts, @ARGV);
- }
-} elsif ($mode eq 'link') {
- my $cmd;
- my @Ropts; # -R options on the command line
- my @Rresolved; # -R options originating from .la resolution
- my @RPopts; # -rpath options
- my $deplibs = []; # list of dependent libraries (both -L and -l flags)
- my $libdirs = []; # list of libdirs
- my $libs = {}; # libraries
- my $dirs = {}; # paths to find libraries
- # put a priority in the dir hash
- # always look here
- $dirs->{'/usr/lib'} = 3;
+ require LT::Mode::Install;
+ LT::Mode::Install->run($ltprog);
- $gp->getoptions('all-static' => \$opts{'all-static'},
- 'avoid-version' => \$opts{'avoid-version'},
- 'dlopen=s{1}' => \$opts{'dlopen'},
- 'dlpreopen=s{1}' => \$opts{'dlpreopen'},
- 'export-dynamic' => \$opts{'export-dynamic'},
- 'export-symbols=s' => \$opts{'export-symbols'},
- 'export-symbols-regex=s'=> \$opts{'export-symbols-regex'},
- 'module' => \$opts{'module'},
- 'no-fast-install' => \$opts{'no-fast-install'},
- 'no-install' => \$opts{'no-install'},
- 'no-undefined' => \$opts{'no-undefined'},
- 'o=s' => \$opts{'o'},
- 'objectlist=s' => \$opts{'objectlist'},
- 'precious-files-regex=s'=> \$opts{'precious-files-regex'},
- 'prefer-pic' => \$opts{'prefer-pic'},
- 'prefer-non-pic' => \$opts{'prefer-non-pic'},
- 'release=s' => \$opts{'release'},
- 'rpath=s' => \@RPopts,
- 'R=s' => \@Ropts,
- 'shrext=s' => \$opts{'shrext'},
- 'static' => \$opts{'static'},
- 'thread-safe' => \$opts{'thread-safe'},
- 'version-info=s{1}' => \$opts{'version-info'},
- 'version_info=s{1}' => \$opts{'version-info'},
- 'version-number=s{1}' => \$opts{'version-info'},
- );
- # XXX options ignored: dlopen, dlpreopen, no-fast-install,
- # no-install, no-undefined, precious-files-regex,
- # shrext, thread-safe, prefer-pic, prefer-non-pic
-
- @libsearchdirs = get_search_dirs();
- # add the .libs dir as well in case people try to link directly
- # with the real library instead of the .la library
- push @libsearchdirs, './.libs';
-
- my $outfile = $opts{'o'};
- if (!$outfile) {
- die "No output file given.\n";
- }
- LT::Trace::debug {"outfile = $outfile\n"};
- my $odir = dirname $outfile;
- my $ofile = basename $outfile;
-
- # what are we linking?
- my $linkmode = PROGRAM;
- if ($ofile =~ m/\.l?a$/) {
- $linkmode = LIBRARY;
- }
- LT::Trace::debug {"linkmode: $linkmode\n"};
-
- # eat multiple version-info arguments, we only accept the first.
- map { $_ = '' if ($_ =~ m/\d+:\d+:\d+/); } @ARGV;
-
- my @objs;
- my @sobjs;
- if ($opts{'objectlist'}) {
- my $objectlist = $opts{'objectlist'};
- open(my $ol, '<', $objectlist) or die "Cannot open $objectlist: $!\n";
- my @objlist = <$ol>;
- for (@objlist) { chomp; }
- generate_objlist(\@objs, \@sobjs, \@objlist);
- } else {
- generate_objlist(\@objs, \@sobjs, \@ARGV);
- }
- LT::Trace::debug {"objs = @objs\n"};
- LT::Trace::debug {"sobjs = @sobjs\n"};
-
- my $parser = LT::Parser->new(\@ARGV);
- $parser->{result} = [];
-
- if ($linkmode == PROGRAM) {
- require LT::Program;
- my $program = LT::Program->new;
- $program->{outfilepath} = $outfile;
- # XXX give higher priority to dirs of not installed libs
- if ($opts{'export-dynamic'}) {
- push(@{$parser->{args}}, "-Wl,-E");
- }
-
- $parser->parse_linkargs1($deplibs, \@Rresolved, \@libsearchdirs,
- $dirs, $libs, $parser->{args}, 0);
- $parser->{args} = $parser->{result};
- LT::Trace::debug {"end parse_linkargs1\n"};
- LT::Trace::debug {"deplibs = @$deplibs\n"};
-
- $program->{objlist} = \@objs;
- if (@objs == 0) {
- if (@sobjs > 0) {
- LT::Trace::debug {"no non-pic libtool objects found, trying pic objects...\n"};
- $program->{objlist} = \@sobjs;
- } elsif (@sobjs == 0) {
- LT::Trace::debug {"no libtool objects of any kind found\n"};
- LT::Trace::debug {"hoping for real objects in ARGV...\n"};
- }
- }
- my $RPdirs = [];
- @$RPdirs = (@Ropts, @RPopts, @Rresolved);
- $program->{RPdirs} = $RPdirs;
-
- $program->link($ltprog, $dirs, $libs, $deplibs, $libdirs, $parser, \%opts);
- } elsif ($linkmode == LIBRARY) {
- require LT::LaFile;
- my $lainfo = LT::LaFile->new;
-
- $shared = 1 if ($opts{'version-info'} ||
- $opts{'avoid-version'} ||
- $opts{'module'});
- if (!@RPopts) {
- $convenience = 1;
- $noshared = 1;
- $static = 1;
- $shared = 0;
- } else {
- $shared = 1;
- }
- if ($ofile =~ m/\.a$/ && !$convenience) {
- $ofile =~ s/\.a$/.la/;
- $outfile =~ s/\.a$/.la/;
- }
- (my $libname = $ofile) =~ s/\.l?a$//; # remove extension
- my $staticlib = $libname.'.a';
- my $sharedlib = $libname.'.so';
- my $sharedlib_symlink;
-
- if ($opts{'static'} || $opts{'all-static'}) {
- $shared = 0;
- $static = 1;
- }
- $shared = 0 if $noshared;
-
- $parser->parse_linkargs1($deplibs, \@Rresolved, \@libsearchdirs,
- $dirs, $libs, $parser->{args}, 0);
- $parser->{args} = $parser->{result};
- LT::Trace::debug {"end parse_linkargs1\n"};
- LT::Trace::debug {"deplibs = @$deplibs\n"};
-
- my $sover = '0.0';
- my $origver = 'unknown';
- # environment overrides -version-info
- (my $envlibname = $libname) =~ s/[.+-]/_/g;
- my ($current, $revision, $age) = (0, 0, 0);
- if ($opts{'version-info'}) {
- ($current, $revision, $age) = parse_version_info($opts{'version-info'});
- $origver = "$current.$revision";
- $sover = $origver;
- }
- if ($ENV{"${envlibname}_ltversion"}) {
- # this takes priority over the previous
- $sover = $ENV{"${envlibname}_ltversion"};
- ($current, $revision) = split /\./, $sover;
- $age = 0;
- }
- if (defined $opts{'release'}) {
- $sharedlib_symlink = $sharedlib;
- $sharedlib = $libname.'-'.$opts{'release'}.'.so';
- }
- if ($opts{'avoid-version'} ||
- (defined $opts{'release'} && !$opts{'version-info'})) {
- # don't add a version in these cases
- } else {
- $sharedlib .= ".$sover";
- if (defined $opts{'release'}) {
- $sharedlib_symlink .= ".$sover";
- }
- }
-
- # XXX add error condition somewhere...
- $static = 0 if ($shared && grep { $_ eq 'disable-static' } @tags);
- $shared = 0 if ($static && grep { $_ eq 'disable-shared' } @tags);
-
- LT::Trace::debug {"SHARED: $shared\nSTATIC: $static\n"};
-
- $lainfo->{'libname'} = $libname;
- if ($shared) {
- $lainfo->{'dlname'} = $sharedlib;
- $lainfo->{'library_names'} = $sharedlib;
- $lainfo->{'library_names'} .= " $sharedlib_symlink"
- if (defined $opts{'release'});
- $lainfo->link($ltprog, $ofile, $sharedlib, $odir, 1, \@sobjs, $dirs, $libs, $deplibs, $libdirs, $parser, \%opts);
- LT::Trace::debug {"sharedlib: $sharedlib\n"};
- $lainfo->{'current'} = $current;
- $lainfo->{'revision'} = $revision;
- $lainfo->{'age'} = $age;
- }
- if ($static) {
- $lainfo->{'old_library'} = $staticlib;
- $lainfo->link($ltprog, $ofile, $staticlib, $odir, 0, ($convenience && @sobjs > 0) ? \@sobjs : \@objs, $dirs, $libs, $deplibs, $libdirs, $parser, \%opts);
- LT::Trace::debug {($convenience ? "convenience" : "static")." lib: $staticlib\n"};
- }
- $lainfo->{'installed'} = 'no';
- $lainfo->{'shouldnotlink'} = $opts{'module'} ? 'yes' : 'no';
- map { $_ = "-R$_" } @Ropts;
- unshift @$deplibs, @Ropts if (@Ropts);
- LT::Trace::debug {"deplibs = @$deplibs\n"};
- my $finaldeplibs = reverse_zap_duplicates_ref($deplibs);
- LT::Trace::debug {"finaldeplibs = @$finaldeplibs\n"};
- $lainfo->set('dependency_libs', "@$finaldeplibs");
- if (@RPopts) {
- if (@RPopts > 1) {
- LT::Trace::debug {"more than 1 -rpath option given, taking the first: ", $RPopts[0], "\n"};
- }
- $lainfo->{'libdir'} = $RPopts[0];
- }
- if (!($convenience && $ofile =~ m/\.a$/)) {
- $lainfo->write($outfile, $ofile);
- unlink("$odir/$ltdir/$ofile");
- symlink("../$ofile", "$odir/$ltdir/$ofile");
- }
- my $lai = "$odir/$ltdir/$ofile".'i';
- if ($shared) {
- my $pdeplibs = process_deplibs($finaldeplibs);
- if (defined $pdeplibs) {
- $lainfo->set('dependency_libs', "@$pdeplibs");
- }
- if (! $opts{'module'}) {
- $lainfo->write_shared_libs_log($origver);
- }
- }
- $lainfo->{'installed'} = 'yes';
- # write .lai file (.la file that will be installed)
- $lainfo->write($lai, $ofile);
- }
+} elsif ($mode eq 'link') {
+ require LT::Mode::Link;
+ LT::Mode::Link->run($ltprog, $gp, \@tags, $noshared);
} elsif ($mode eq 'finish' || $mode eq 'clean' || $mode eq 'uninstall') {
# don't do anything
exit 0;
} elsif ($mode eq 'execute') {
# XXX check whether this is right
LT::Exec->silent_run;
- LT::Exec->$mode(@$ltprog, @ARGV);
+ LT::Exec->execute(@$ltprog, @ARGV);
} else {
die "MODE=$mode not implemented yet.\n";
}
@@ -543,22 +201,6 @@ sub config
exit 0;
}
-# convert 4:5:8 into a list of numbers
-sub parse_version_info
-{
- my $vinfo = shift;
-
- if ($vinfo =~ m/^(\d+):(\d+):(\d+)$/) {
- return ($1, $2, $3);
- } elsif ($vinfo =~ m/^(\d+):(\d+)$/) {
- return ($1, $2, 0);
- } elsif ($vinfo =~ m/^(\d+)$/) {
- return ($1, 0, 0);
- } else {
- die "Error parsing -version-info $vinfo\n";
- }
-}
-
sub create_symlinks
{
my $dir = shift;
@@ -579,7 +221,7 @@ sub create_symlinks
@$libnames = split /\s/, $librarynames;
$libnames = reverse_zap_duplicates_ref($libnames);
} else {
- push @$libnames, basename $f;
+ push @$libnames, basename($f);
}
foreach my $libfile (@$libnames) {
LT::Trace::debug {"ln -s $f $dir/$libfile\n"};
@@ -590,95 +232,6 @@ sub create_symlinks
}
}
-# prepare dependency_libs information for the .la file which is installed
-# i.e. remove any .libs directories and use the final libdir for all the
-# .la files
-sub process_deplibs
-{
- my $linkflags = shift;
-
- my $result;
-
- foreach my $lf (@$linkflags) {
- if ($lf =~ m/-L\S+\Q$ltdir\E$/) {
- } elsif ($lf =~ m/-L\./) {
- } elsif ($lf =~ m/\/\S+\/(\S+\.la)/) {
- my $lafile = $1;
- require LT::LaFile;
- my $libdir = LT::LaFile->parse($lf)->{'libdir'};
- if ($libdir eq '') {
- # this drops libraries which will not be
- # installed
- # XXX improve checks when adding to deplibs
- say "warning: $lf dropped from deplibs";
- } else {
- $lf = $libdir.'/'.$lafile;
- push @$result, $lf;
- }
- } else {
- push @$result, $lf;
- }
- }
- return $result;
-}
-
-# populate arrays of non-pic and pic objects and remove these from @ARGV
-sub generate_objlist
-{
- my $objs = shift;
- my $sobjs = shift;
- my $objsource = shift;
-
- my $result = [];
- foreach my $a (@$objsource) {
- if ($a =~ m/\S+\.lo$/) {
- require LT::LoFile;
- my $ofile = basename $a;
- my $odir = dirname $a;
- my $loinfo = LT::LoFile->parse($a);
- if ($loinfo->{'non_pic_object'}) {
- my $o;
- $o .= "$odir/" if ($odir ne '.');
- $o .= $loinfo->{'non_pic_object'};
- push @$objs, $o;
- }
- if ($loinfo->{'pic_object'}) {
- my $o;
- $o .= "$odir/" if ($odir ne '.');
- $o .= $loinfo->{'pic_object'};
- push @$sobjs, $o;
- }
- } elsif ($a =~ m/\S+\.o$/) {
- push @$objs, $a;
- } else {
- push @$result, $a;
- }
- }
- @$objsource = @$result;
-}
-
-# XXX reuse code from SharedLibs.pm instead
-sub get_search_dirs
-{
- my @libsearchdirs;
- open(my $fh, '-|', '/sbin/ldconfig -r');
- if (defined $fh) {
- while (<$fh>) {
- if (m/^\s*search directories:\s*(.*?)\s*$/o) {
- foreach my $d (split(/\:/o, $1)) {
- push @libsearchdirs, $d;
- }
- last;
- }
- }
- close($fh);
- } else {
- die "Can't run ldconfig\n";
- }
- return @libsearchdirs;
-}
-
-
# try to guess libtool mode when it is not specified
sub guess_implicit_mode
{
@@ -697,13 +250,3 @@ sub guess_implicit_mode
}
return $m;
}
-
-sub is_wrapper
-{
-# my $self = shift;
- my $program = shift;
-
- open(my $pw, '<', $program) or die "Cannot open $program: $!\n";
- return grep { m/wrapper\sfor/ } <$pw>;
-}
-