1# ex:ts=8 sw=4: 2# $OpenBSD: Compile.pm,v 1.13 2014/04/16 14:39:06 zhuk Exp $ 3# 4# Copyright (c) 2007-2010 Steven Mestdagh <steven@openbsd.org> 5# Copyright (c) 2012 Marc Espie <espie@openbsd.org> 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. 18use strict; 19use warnings; 20 21package LT::Mode::Compile; 22our @ISA = qw(LT::Mode); 23 24use File::Basename; 25use LT::LoFile; 26use LT::Util; 27use LT::Trace; 28 29sub help 30{ 31 print <<"EOH"; 32 33Usage: $0 --mode=compile COMPILE-COMMAND [opts] SOURCE 34Compile source file into library object 35 36 -o OUTPUT-FILE 37EOH 38} 39 40my @valid_src = qw(asm c cc cpp cxx f s); 41sub run 42{ 43 my ($class, $ltprog, $gp, $ltconfig) = @_; 44 my $lofile = LT::LoFile->new; 45 46 my $pic = !$ltconfig->noshared; 47 my $nonpic = 1; 48 if ($gp->has_tag('disable-shared')) { 49 $pic = 0; 50 } 51 if ($gp->has_tag('disable-static') && $pic) { 52 $nonpic = 0; 53 } 54 55 my $pic_mode = 0; 56 57 my @pie_flags = (); 58 59 $gp->handle_permuted_options('o:!@', 60 qr{\-Wc\,(.*)}, 61 sub { 62 $gp->keep_for_later(split(/\,/, shift)); 63 }, 64 'Xcompiler:', 65 sub { 66 $gp->keep_for_later($_[2]); 67 }, 68 'pie|fpie|fPIE', 69 sub { 70 push(@pie_flags, $_[3]); 71 }, 72 'no-suppress', # we just ignore that one 73 'prefer-pic', sub { $pic_mode = 1; }, 74 'prefer-non-pic', sub { $pic_mode = 0; }, 75 'static', 76 sub { 77 $pic = 0; 78 $nonpic = 1; 79 }, 80 'shared', 81 sub { 82 if (!$pic) { 83 shortdie "bad configuration: can't build shared library"; 84 } 85 $nonpic = 0; 86 }); 87 88 my ($outfile, $odir, $ofile, $srcfile, $srcext); 89 # XXX check whether -c flag is present and if not, die? 90 if ($gp->o) { 91 if ($gp->o > 1) { 92 shortdie "Can't specify -o more than once\n"; 93 } 94 # fix extension if needed 95 ($outfile = ($gp->o)[0]) =~ s/\.o$/.lo/; 96 $odir = dirname($outfile); 97 $ofile = basename($outfile); 98 } else { 99 # XXX sometimes no -o flag is present and we need another way 100 my $srcre = join '|', @valid_src; 101 my $found = 0; 102 foreach my $a (@main::ARGV) { 103 if ($a =~ m/\.($srcre)$/i) { 104 $srcfile = $a; 105 $srcext = $1; 106 $found = 1; 107 last; 108 } 109 } 110 $found or die "Cannot find source file in command\n"; 111 # the output file ends up in the current directory 112 $odir = '.'; 113 ($ofile = basename($srcfile)) =~ s/\.($srcext)$/.lo/i; 114 $outfile = "$odir/$ofile"; 115 } 116 tsay {"srcfile = $srcfile"} if $srcfile; 117 tsay {"outfile = $outfile"}; 118 (my $nonpicobj = $ofile) =~ s/\.lo$/.o/; 119 my $picobj = "$ltdir/$nonpicobj"; 120 121 $lofile->{picobj} = $picobj if $pic; 122 $lofile->{nonpicobj} = $nonpicobj if $nonpic; 123 $lofile->{picflags} = $ltconfig->picflags; 124 if ($pic_mode) { 125 $lofile->{nonpicflags} = $ltconfig->picflags; 126 } else { 127 $lofile->{nonpicflags} = \@pie_flags; 128 } 129 $lofile->compile($ltprog, $odir, \@ARGV); 130 $lofile->write($outfile); 131} 132 1331; 134