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