2 # Wrapper around LLVM tools to generate a native .o from llvm-gxx using an
3 # LLVM back-end (CBE by default).
11 chomp ($ProgramName = `basename $0`);
14 print "\e[1m", @_, "\e[0m";
17 # process command-line options.
18 # most of these are passed on to llvm-gxx.
20 for ($i = 0; $i <= $#ARGV; ++$i) {
21 if ($ARGV[$i] =~ /-mllvm-backend=([a-z0-9]*)/) {
23 if ($ProgramName =~ /llvm-native-gxx/) {
24 splice (@ARGV, $i, 1);
27 } elsif ($ARGV[$i] eq "-E") {
29 } elsif ($ARGV[$i] eq "-c") {
30 $GCCOptions .= " " . $ARGV[$i];
32 } elsif ($ARGV[$i] eq "-v") {
33 $GCCOptions .= " " . $ARGV[$i];
35 } elsif ($ARGV[$i] eq "-o") {
36 $OutputFile = $ARGV[$i + 1];
37 } elsif ($ARGV[$i] eq "-save-temps") {
38 $GCCOptions .= " " . $ARGV[$i];
40 } elsif ($ARGV[$i] =~ /\.bc$/) {
41 push (@BytecodeFiles, $ARGV[$i]);
42 } elsif ($ARGV[$i] =~ /^-L/) {
43 $GCCOptions .= " " . $ARGV[$i];
44 push (@LibDirs, $ARGV[$i]);
45 } elsif ($ARGV[$i] =~ /^-l/) {
46 $GCCOptions .= " " . $ARGV[$i];
47 push (@Libs, $ARGV[$i]);
48 } elsif ($ARGV[$i] =~ /\.(c|cpp|cc|i|ii|C)$/) {
49 $LastCFile = $ARGV[$i];
53 sub GetDefaultOutputFileName
{
54 my $DefaultOutputFileBase;
56 if ($ProgramName =~ /llvm-native-gxx/) {
57 $DefaultOutputFileBase = $LastCFile;
58 } elsif ($ProgramName =~ /native-build/) {
59 $DefaultOutputFileBase = $BytecodeFiles[0];
62 my $def = $DefaultOutputFileBase;
64 die "Can't figure out name of output file.\n"
65 unless $DefaultOutputFileBase
66 && (($ProgramName !~ /native-build/)
67 || $#BytecodeFiles == 0);
69 print "Warning: defaulting output file name ",
70 "based on '$DefaultOutputFileBase'\n" if $Verbose;
72 if ($ProgramName =~ /llvm-native-gxx/) {
73 $def =~ s/\.(c|cpp|cc|i|ii|C)$/.o/;
74 } elsif ($ProgramName =~ /native-build/) {
75 $def =~ s/\.bc$/.$Backend/;
76 if ($CompileDontLink) {
84 # run a command, optionally echoing, and quitting if it fails:
86 my $command = join(" ", @_);
87 print "$command\n" if $Verbose;
88 $command =~ s/\"/\\\"/g;
89 system $command and die "$0: $command failed";
92 sub LinkBytecodeFilesIntoTemporary
{
93 my $FinalOutputFileName = shift @_;
94 my @BytecodeFiles = @_;
96 my $BCFiles = join (" ", @BytecodeFiles);
99 $LinkedBCFile = "${FinalOutputFileName}.llvm.bc";
101 $LinkedBCFile = "/tmp/nativebuild-$$.llvm.bc";
103 run
"llvm-link -o $LinkedBCFile $BCFiles";
104 return $LinkedBCFile;
107 sub CompileBytecodeToNative
{
108 my ($BCFile, $Backend, $OutputFile) = @_;
111 if ($Backend eq 'cbe') {
113 $GeneratedCode = "${OutputFile}.c";
115 $GeneratedCode = "/tmp/nativebuild-$$.c";
117 run
"llc -march=c -f -o $GeneratedCode $BCFile";
118 } elsif ($Backend eq 'llc') {
120 $GeneratedCode = "${OutputFile}.s";
122 $GeneratedCode = "/tmp/nativebuild-$$.s";
124 run
"llc -f -o $GeneratedCode $BCFile";
126 my $LibDirs = join (" ", @LibDirs);
127 my $Libs = join (" ", @Libs);
128 run
"gcc $GCCOptions $GeneratedCode -o $OutputFile $LibDirs $Libs";
129 run
"rm $BCFile $GeneratedCode"
133 sub CompileCToNative
{
134 my ($LLVMGCCCommand, $Backend, $OutputFile) = @_;
136 if ($PreprocessOnly) {
139 my $BCFile = "${OutputFile}.llvm.bc";
140 if ($CompileDontLink) {
141 run
"mv ${OutputFile} $BCFile";
142 } else { # gccld messes with the output file name
143 run
"mv ${OutputFile}.bc $BCFile";
146 if ($Backend eq 'cbe') {
147 $GeneratedCode = "${OutputFile}.cbe.c";
148 run
"llc -march=c -f -o $GeneratedCode $BCFile";
149 } elsif ($Backend eq 'llc') {
150 $GeneratedCode = "${OutputFile}.llc.s";
151 run
"llc -f -o $GeneratedCode $BCFile";
153 my $NativeGCCOptions = "";
154 if ($CompileDontLink) {
155 $NativeGCCOptions = "-c";
157 run
"gcc $NativeGCCOptions $GeneratedCode -o $OutputFile";
158 run
"rm ${OutputFile}.llvm.bc $GeneratedCode"
162 # guess the name of the output file, if -o was not specified.
163 $OutputFile = GetDefaultOutputFileName
() unless $OutputFile;
164 print "Output file is $OutputFile\n" if $Verbose;
165 # do all the dirty work:
166 if ($ProgramName eq /native-build/) {
167 my $LinkedBCFile = LinkBytecodeFilesIntoTemporary
(@BytecodeFiles);
168 CompileBytecodeToNative
($LinkedBCFile, $Backend, $OutputFile);
169 } elsif ($ProgramName =~ /llvm-native-gxx/) {
170 # build the llvm-gxx command line.
171 $LLVMGCCCommand = join (" ", ("llvm-g++", @ARGV));
172 CompileCToNative
($LLVMGCCCommand, $Backend, $OutputFile);
188 llvm-native-g++ [OPTIONS...] FILE
190 native-build [OPTIONS...] FILE
194 llvm-native-g++ is a wrapper around the LLVM command-line tools which generates
195 a native object (.o) file by compiling FILE with llvm-g++, and then running
196 an LLVM back-end (CBE by default) over the resulting bytecode, and then
197 compiling the resulting code to a native object file.
199 If called as "native-build", it compiles bytecode to native code, and takes
204 llvm-native-g++ takes the same options as llvm-gcc. All options
205 except -mllvm-backend=... are passed on to llvm-g++.
209 =item -mllvm-backend=BACKEND
211 Use BACKEND for native code generation.
215 Print command lines that llvm-native-g++ runs.
219 llvm-native-g++ tries to guess the name of the llvm-g++ output file by looking
220 for this option in the command line. If it can't find it, it finds the last C
221 or C++ source file named on the command line, and turns its suffix into .o. See
226 Save temporary files used by llvm-native-g++ (and llvm-g++, and g++).
232 llvm-native-g++ only handles the case where llvm-g++ compiles a single
233 file per invocation. llvm-native-g++ has weak command-line argument
234 parsing and is a poor substitute for making g++/g++.c do this stuff.
236 This manual page does not adequately document native-build mode.
238 llvm-native-g++ is pretty gross because it represents the blind merging of two
239 other scripts that predated it. It could use some code clean-up.