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

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

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