[BACK]Return to libtool CVS log [TXT][DIR] Up to [local] / src / usr.bin / libtool

Annotation of src/usr.bin/libtool/libtool, Revision 1.39

1.1       espie       1: #!/usr/bin/perl
1.39    ! brad        2: # $OpenBSD: libtool,v 1.38 2012/10/27 10:11:23 espie Exp $
1.1       espie       3:
                      4: # Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org>
1.13      espie       5: # Copyright (c) 2012 Marc Espie <espie@openbsd.org>
1.1       espie       6: #
                      7: # Permission to use, copy, modify, and distribute this software for any
                      8: # purpose with or without fee is hereby granted, provided that the above
                      9: # copyright notice and this permission notice appear in all copies.
                     10: #
                     11: # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     12: # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     13: # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     14: # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     15: # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     16: # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     17: # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     18:
                     19: use strict;
                     20: use warnings;
                     21: use feature qw(say switch state);
1.23      espie      22: use Cwd qw(getcwd);
1.1       espie      23: use File::Glob ':glob';
1.3       espie      24:
1.1       espie      25: use LT::Trace;
                     26: use LT::Exec;
                     27: use LT::Util;
1.23      espie      28: use LT::Getopt;
1.1       espie      29:
1.3       espie      30: $SIG{__DIE__} = sub {
                     31:        require Carp;
                     32:
                     33:        my $_ = pop @_;
                     34:        s/(.*)( at .*? line .*?\n$)/$1/s;
                     35:        push @_, $_;
                     36:        die &Carp::longmess;
                     37: };
                     38:
1.16      jasper     39: package LT::OSConfig;
                     40:
                     41: use Config;
1.18      jasper     42: use LT::Util;
1.16      jasper     43:
1.35      espie      44: my @picflags =qw(-fPIC -DPIC);
                     45:
1.16      jasper     46: sub new
                     47: {
1.35      espie      48:            my $class = shift;
                     49:            # XXX: incomplete
1.37      espie      50:            my $self = bless {
1.35      espie      51:                machine_arch => $Config{ARCH},
                     52:                ltdir => $ltdir,
                     53:                version => $version,
                     54:                objdir => $ltdir,
                     55:                build_old_libs => 'yes',
                     56:                pic_flags => join(' ', @picflags),
1.37      espie      57:            }, $class;
1.35      espie      58:            ($self->{gnu_arch} = $self->{machine_arch}) =~ s/amd64/x86_64/;
                     59:
1.39    ! brad       60:            if (grep { $_ eq $self->{machine_arch} } qw(vax)) {
1.35      espie      61:                $self->{build_libtool_libs} = 'yes';
                     62:                $self->{noshared} = 1;
                     63:            } else {
                     64:                $self->{build_libtool_libs} = 'no';
                     65:                $self->{noshared} = 0;
1.38      espie      66:            }
1.39    ! brad       67:            if (grep { $_ eq $self->{machine_arch} } qw(m68k vax)) {
1.38      espie      68:                $self->{elf} = 0;
                     69:            } else {
                     70:                $self->{elf} = 1;
1.35      espie      71:            }
                     72:
1.37      espie      73:            return $self;
1.35      espie      74: }
1.22      jasper     75:
1.35      espie      76: sub noshared
                     77: {
                     78:        my $self = shift;
                     79:        return $self->{noshared};
                     80: }
                     81:
                     82: sub host
                     83: {
                     84:        my $self = shift;
                     85:        if (!defined $self->{osversion}) {
                     86:                chomp($self->{osversion} = `uname -r`);
                     87:        }
                     88:        return "$self->{gnu_arch}-unknown-openbsd$self->{osversion}";
                     89: }
                     90:
                     91: # XXX
                     92: sub picflags
                     93: {
                     94:        my $self = shift;
                     95:        return \@picflags;
                     96: }
                     97:
                     98: sub sharedflag
                     99: {
                    100:        return '-shared';
                    101: }
                    102:
                    103: sub version
                    104: {
                    105:        my $self = shift;
                    106:        return $self->{version};
1.16      jasper    107: }
                    108:
1.20      jasper    109: sub dump
                    110: {
                    111:        my $self = shift;
1.34      espie     112:        for my $key (sort keys %$self) {
                    113:                say "$key=$self->{$key}";
1.20      jasper    114:        }
                    115: }
                    116:
1.19      espie     117: package LT::Mode;
1.23      espie     118: use LT::Util;
1.19      espie     119:
                    120: sub new
                    121: {
                    122:        my ($class, $origin) = @_;
                    123:        bless {origin => $origin }, $class;
                    124: }
                    125:
1.30      espie     126: sub load_subclass
                    127: {
                    128:        my ($self, $class) = @_;
                    129:        local $SIG{__DIE__} = 'DEFAULT';
                    130:        eval "require $class;";
                    131:        if ($@) {
                    132:                unless ($@ =~ m/^Can't locate .* in \@INC/) {
                    133:                        say STDERR $@;
                    134:                        exit 1;
                    135:                }
                    136:        }
                    137: }
                    138:
1.19      espie     139: my $mode_maker = { compile => 'LT::Mode::Compile',
                    140:        clean => 'LT::Mode::Clean',
                    141:        execute => 'LT::Mode::Execute',
                    142:        finish => 'LT::Mode::Finish',
                    143:        install => 'LT::Mode::Install',
                    144:        link => 'LT::Mode::Link',
                    145:        uninstall => 'LT::Mode::Uninstall' };
                    146:
                    147: sub factory
                    148: {
                    149:        my ($class, $mode, $origin) = @_;
1.30      espie     150:        my $s = $mode_maker->{$mode};
                    151:        if ($s) {
                    152:                $class->load_subclass($s);
                    153:                return $s->new($origin);
1.19      espie     154:        } else {
1.23      espie     155:                shortdie "Mode=$mode not implemented yet.\n";
1.19      espie     156:        }
                    157: }
                    158:
1.26      espie     159: sub help
                    160: {
                    161: }
                    162:
                    163: sub help_all
                    164: {
1.30      espie     165:        my $class = shift;
                    166:        for my $s (sort values %$mode_maker) {
                    167:                $class->load_subclass($s);
                    168:                $s->help;
1.26      espie     169:        }
                    170: }
                    171:
1.19      espie     172: package LT::Mode::Empty;
                    173: our @ISA = qw(LT::Mode);
                    174: sub run
                    175: {
                    176:        exit 0;
                    177: }
                    178:
                    179: package LT::Mode::Clean;
                    180: our @ISA = qw(LT::Mode::Empty);
1.27      espie     181: sub help
                    182: {
                    183:        print <<"EOH";
                    184:
                    185: Usage: $0 --mode=clean RM [RM-Option]... FILE...
                    186: has not been implemented.
                    187: It should remove files from the build directory.
                    188: EOH
                    189: }
                    190:
1.19      espie     191: package LT::Mode::Execute;
                    192: our @ISA = qw(LT::Mode);
                    193: sub run
                    194: {
1.35      espie     195:        my ($class, $ltprog, $gp, $ltconfig) = @_;
1.19      espie     196:        # XXX check whether this is right
                    197:        LT::Exec->silent_run;
                    198:        LT::Exec->execute(@$ltprog, @main::ARGV);
                    199: }
                    200:
1.27      espie     201: sub help
                    202: {
                    203:        print <<"EOH";
                    204:
                    205: Usage: $0 --mode=execute COMMAND  [ARGS...]
                    206: Run a program after setting correct library path.
                    207: EOH
                    208: }
                    209:
                    210:
1.19      espie     211: package LT::Mode::Finish;
                    212: our @ISA = qw(LT::Mode::Empty);
1.27      espie     213: sub help
                    214: {
                    215:        print <<"EOH";
                    216:
                    217: Usage: $0 --mode=finish [LIBDIR}...
                    218: Complete the installation of libtool libraries.
                    219: Not needed for our usage.
                    220: EOH
                    221: }
1.19      espie     222:
                    223: package LT::Mode::Uninstall;
                    224: our @ISA = qw(LT::Mode::Empty);
1.27      espie     225: sub help
                    226: {
                    227:        print <<"EOH";
                    228:
                    229: Usage: $0 --mode=uninstall RM [RM-OPTION]... FILE...
                    230: has not been implemented
                    231: It should remove libraries from an installation directory.
                    232: EOH
                    233: }
1.19      espie     234:
1.10      espie     235: package LT::Options;
1.23      espie     236: use LT::Util;
                    237: our @ISA = qw(LT::Getopt);
1.10      espie     238:
                    239: my @valid_modes = qw(compile clean execute finish install link uninstall);
1.19      espie     240:
1.10      espie     241: my @known_tags = qw(disable-shared disable-static CC CXX F77 FC GO GCJ RC);
                    242:
                    243: sub new
                    244: {
                    245:        my $class = shift;
1.32      espie     246:        my $o = bless {}, $class;
1.10      espie     247:        return $o;
                    248: }
                    249:
                    250: sub add_tag
                    251: {
                    252:        my ($self, $value) = @_;
                    253:        if ($value =~ m/[^\-\w,\/]/) {
1.23      espie     254:                shortdie "invalid tag name: $value";
1.10      espie     255:                exit 1;
                    256:        }
                    257:        if (grep {$value eq $_} @known_tags) {
                    258:                $self->{tags}{$value} = 1;
                    259:        } else {
                    260:                say STDERR "ignoring unknown tag: $value";
                    261:        }
                    262: }
                    263:
                    264: sub has_tag
                    265: {
                    266:        my ($self, $tag) = @_;
                    267:        return defined $self->{tags}{$tag};
                    268: }
                    269:
                    270: sub is_abreviated_mode
                    271: {
                    272:        my ($self, $arg) = @_;
1.15      jasper    273:        return undef if !$arg;
1.10      espie     274:        for my $m (@valid_modes) {
                    275:                next if length $arg > length $m;
                    276:                if ($arg eq substr($m, 0, length $arg)) {
1.19      espie     277:                        return LT::Mode->factory($m, $arg);
1.10      espie     278:                }
                    279:        }
                    280:        return undef;
                    281: }
                    282:
                    283: # XXX this should always fail if we are libtool2 !
                    284: # try to guess libtool mode when it is not specified
                    285: sub guess_implicit_mode
                    286: {
                    287:        my ($self, $ltprog) = @_;
                    288:        my $m;
                    289:        for my $a (@$ltprog) {
                    290:           if ($a =~ m/(install([.-]sh)?|cp)$/) {
1.29      espie     291:                $m = LT::Mode->factory('install', "implicit $a");
1.10      espie     292:           } elsif ($a =~ m/cc|c\+\+/) {        # XXX improve test
                    293:                if (grep { $_ eq '-c' } @ARGV) {
1.29      espie     294:                        $m = LT::Mode->factory('compile', "implicit");
1.10      espie     295:                } else {
1.29      espie     296:                        $m = LT::Mode->factory('link',  "implicit");
1.10      espie     297:                }
                    298:           }
                    299:        }
                    300:        return $m;
                    301: }
                    302:
                    303: sub valid_modes
                    304: {
                    305:        my $self = shift;
                    306:        return join(' ', @valid_modes);
                    307: }
                    308:
                    309: package main;
1.1       espie     310:
1.17      espie     311: my $ltconfig = LT::OSConfig->new;
1.1       espie     312: my $cwd = getcwd();
                    313: my $mode;
                    314: my $verbose = 1;
1.26      espie     315: my $help = 0;
1.1       espie     316:
1.31      espie     317:
                    318: # XXX compat game to satisfy both libtool 1 and libtool 2
                    319: unless ($ARGV[0] eq 'install' && $ARGV[1] =~ m/^-[bcCdpSsBfgmo]/) {
                    320:        if ($mode = LT::Options->is_abreviated_mode($ARGV[0])) {
                    321:                shift @ARGV;
                    322:        }
                    323: }
                    324:
1.1       espie     325: # just to be clear:
                    326: # when building a library:
                    327: #      * -R libdir records libdir in dependency_libs
                    328: #      * -rpath is the path where the (shared) library will be installed
                    329: # when building a program:
                    330: #      * both -R libdir and -rpath libdir add libdir to the run-time path
                    331: # -Wl,-rpath,libdir will bypass libtool.
                    332:
1.10      espie     333: my $gp = LT::Options->new;
1.25      espie     334: $gp->handle_options(
                    335:     '-config' => \&config,
                    336:     '-debug|x' => sub {
                    337:                    LT::Trace->set(1);
                    338:                    LT::Exec->verbose_run;
                    339:                },
                    340:     '-dry-run|-dryrun|n' => sub { LT::Exec->dry_run; },
                    341:     '-features' => sub {
1.35      espie     342:                say "host: ", $ltconfig->host;
                    343:                say "enable shared libraries" unless $ltconfig->noshared;
1.25      espie     344:                say "enable static libraries";
                    345:                exit 0;
                    346:            },
1.29      espie     347:     '-finish' => sub { $mode = LT::Mode->factory('finish', '--finish'); },
1.26      espie     348:     '-help|?|h' => sub { $help = 1; },
                    349:     '-help-all' => sub { basic_help(); LT::Mode->help_all; exit 0; },
1.25      espie     350:     '-mode=' => sub {
                    351:                    $mode = LT::Mode->factory($_[2], "--mode=$_[2]");
                    352:                },
                    353:     '-quiet|-silent|-no-verbose' => sub { $verbose = 0; },
                    354:     '-verbose|-no-silent|-no-quiet|v' => sub {$verbose = 1;},
                    355:     '-tag=' => sub { $gp->add_tag($_[2]); },
                    356:     '-version' => sub {
1.35      espie     357:                    say "libtool (not (GNU libtool)) ", $ltconfig->version;
1.25      espie     358:                    exit 0;
                    359:                },
1.26      espie     360:     '-no-warning|-no-warn' => sub {},
1.28      espie     361:     # ignored
                    362:     '-preserve-dup-deps',
                    363:     '-dlopen=|dlopen=@',
1.25      espie     364: );
1.1       espie     365:
1.26      espie     366: if ($help) {
                    367:        basic_help();
                    368:        if ($mode) {
                    369:                $mode->help;
                    370:        }
                    371:        exit 0;
                    372: }
1.10      espie     373: if ($verbose) {
1.1       espie     374:        LT::Exec->verbose_run;
                    375: }
1.10      espie     376:
1.1       espie     377: # what are we going to run (cc, c++, ...)
                    378: my $ltprog = [];
                    379: # deal with multi-arg ltprog
1.10      espie     380: tsay {"ARGV = \"@ARGV\""};
1.1       espie     381: while (@ARGV) {
                    382:        # just read arguments until the next option...
                    383:        if ($ARGV[0] =~ m/^\-/) { last; }
                    384:        # XXX improve checks
                    385:        if ($ARGV[0] =~ m/^\S+\.la/) { last; }
                    386:        my $arg = shift @ARGV;
                    387:        push @$ltprog, $arg;
1.10      espie     388:        tsay {"arg = \"$arg\""};
1.1       espie     389:        # if the current argument is an install program, stop immediately
                    390:        if ($arg =~ /cp$/) { last; }
                    391:        if ($arg =~ /install([-.]sh)?$/) { last; }
                    392: }
1.10      espie     393: tsay {"ltprog = \"@$ltprog\""};
1.14      espie     394:
                    395: # XXX compat game to satisfy both libtool 1 and libtool 2
                    396: # let libtool install work as both libtool 1 and libtool 2
1.19      espie     397: if (@$ltprog == 0 && defined $mode && $mode->{origin} eq 'install') {
                    398:        $ltprog = [ 'install' ];
1.14      espie     399: }
1.31      espie     400:
1.6       jasper    401: if (@$ltprog == 0) { die "No libtool command given.\n" .
                    402:                         "Use `libtool --help' for more information.\n" };
1.1       espie     403: # make ltprog a list of elements without whitespace (prevent exec errors)
                    404: my @tmp_ltprog = @$ltprog;
                    405: @$ltprog = ();
                    406: for my $el (@tmp_ltprog) {
                    407:        my @parts = split /\s+/, $el;
                    408:        push @$ltprog, @parts;
                    409: }
                    410:
1.10      espie     411: if (!defined $mode) {
                    412:        $mode = $gp->guess_implicit_mode($ltprog);
1.19      espie     413:        tsay {"implicit mode: ", $mode->{origin}} if $mode;
1.28      espie     414: }
                    415:
                    416: if (!defined $mode) {
                    417:        shortdie "no explicit mode, couldn't figure out implicit mode\n";
                    418: }
                    419:
                    420: if (!$mode->isa("LT::Mode::Execute")) {
1.29      espie     421:        if ($gp->dlopen)  {
1.28      espie     422:                shortdie "Error: -dlopen FILE  in generic libtool options is an error in non execute mode";
                    423:        }
1.1       espie     424: }
                    425:
                    426: # from here, options may be intermixed with arguments
                    427:
1.35      espie     428: $mode->run($ltprog, $gp, $ltconfig);
1.1       espie     429:
                    430: if (LT::Exec->performed == 0) {
                    431:        die "No commands to execute.\n"
                    432: }
                    433:
                    434: ###########################################################################
                    435:
1.26      espie     436: sub basic_help
1.1       espie     437: {
                    438:        print <<EOF
                    439: Usage: $0 [options]
                    440: --config - print configuration
                    441: --debug - turn on debugging output
                    442: --dry-run - don't do anything, only show what would be done
                    443: --help - this message
                    444: --mode=MODE - use operation mode MODE
                    445: --quiet - do not print informational messages
                    446: --silent - same as `--quiet'
1.5       jasper    447: --tag=TAG - specify a configuration variable TAG
1.1       espie     448: --version - print version of libtool
                    449: EOF
                    450: ;
                    451: }
                    452:
                    453: sub config
                    454: {
1.20      jasper    455:        $ltconfig->dump;
1.1       espie     456:        exit 0;
                    457: }
                    458: