agcc: agcc

File agcc, 6.0 KB (added by admin, 13 years ago)
Line 
1#!/usr/bin/perl -w
2use strict;
3
4# Copyright 2008, Andrew Ross andy@plausible.org
5# Distributable under the terms of the GNU GPL, see COPYING for details
6
7# The Android toolchain is ... rough.  Rather than try to manage the
8# complexity directly, this script wraps the tools into an "agcc" that
9# works a lot like a gcc command line does for a native platform or a
10# properly integrated cross-compiler.  It accepts arbitrary arguments,
11# but interprets the following specially:
12#
13# -E/-S/-c/-shared - Enable needed arguments (linker flags, include
14#                    directories, runtime startup objects...) for the
15#                    specified compilation mode when building under
16#                    android.
17#
18# -O<any> - Turn on the optimizer flags used by the Dalvik build.  No
19#           control is provided over low-level optimizer flags.
20#
21# -W<any> - Turn on the warning flags used by the Dalvik build.  No
22#           control is provided over specific gcc warning flags.
23#
24# Notes:
25# + The prebuilt arm-eabi-gcc from a built (!) android source
26#   directory must be on your PATH.
27# + All files are compiled with -fPIC to an ARMv5TE target.  No
28#   support is provided for thumb.
29# + No need to pass a "-Wl,-soname" argument when linking with
30#   -shared, it uses the file name always (so don't pass a directory in
31#   the output path for a shared library!)
32
33# Dance around to find the actual android toolchain path (it's very
34# deep, so links on $PATH are going to be common.
35my $GCC = `which arm-eabi-gcc`;
36$GCC = qx(cd `dirname $GCC`; /bin/pwd);
37chomp $GCC;
38die "bad arm-eabi-gcc path" if $GCC !~ /(.*)\/prebuilt\//;
39my $DROID = $1;
40
41my $ALIB = "$DROID/out/target/product/vision/obj/lib";
42my $TOOLCHAIN = "$DROID/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1";
43
44my @include_paths = (
45    "-I$DROID/system/core/include",
46    "-I$DROID/hardware/libhardware/include",
47    "-I$DROID/hardware/ril/include",
48    "-I$DROID/dalvik/libnativehelper/include",
49    "-I$DROID/frameworks/base/include",
50    "-I$DROID/external/skia/include",
51    "-I$DROID/out/target/product/vision/obj/include",
52    "-I$DROID/bionic/libc/arch-arm/include",
53    "-I$DROID/bionic/libc/include",
54    "-I$DROID/bionic/libstdc++/include",
55    "-I$DROID/bionic/libc/kernel/common",
56    "-I$DROID/bionic/libc/kernel/arch-arm",
57    "-I$DROID/bionic/libm/include",
58    "-I$DROID/bionic/libm/include/arch/arm",
59    "-I$DROID/bionic/libthread_db/include",
60    "-I$DROID/bionic/libm/arm",
61    "-I$DROID/bionic/libm",
62    "-I$DROID/out/target/product/vision/obj/SHARED_LIBRARIES/libm_intermediates");
63
64my @preprocess_args = (
65    "-D__ARM_ARCH_5__",
66    "-D__ARM_ARCH_5T__",
67    "-D__ARM_ARCH_5E__",
68    "-D__ARM_ARCH_5TE__", # Already defined by toolchain
69    "-DANDROID",
70    "-DSK_RELEASE",
71    "-DNDEBUG",
72    "-include", "$DROID/system/core/include/arch/linux-arm/AndroidConfig.h",
73    "-UDEBUG");
74
75my @warn_args = (
76    "-Wall",
77    "-Wno-unused", # why?
78    "-Wno-multichar", # why?
79    "-Wstrict-aliasing=2"); # Implicit in -Wall per texinfo
80
81my @compile_args = (
82    "-march=armv5te",
83    "-mtune=xscale",
84    "-msoft-float",
85    "-mthumb-interwork",
86    "-fpic",
87    "-fno-exceptions",
88    "-ffunction-sections",
89    "-funwind-tables", # static exception-like tables
90    "-fstack-protector", # check guard variable before return
91    "-fmessage-length=0"); # No line length limit to error messages
92
93my @optimize_args = (
94    "-O2",
95    "-finline-functions",
96    "-finline-limit=300",
97    "-fno-inline-functions-called-once",
98    "-fgcse-after-reload",
99    "-frerun-cse-after-loop", # Implicit in -O2 per texinfo
100    "-frename-registers",
101    "-fomit-frame-pointer",
102    "-fstrict-aliasing", # Implicit in -O2 per texinfo
103    "-funswitch-loops");
104
105my @link_args = (
106    "-Bdynamic",
107    "-Wl,-T,$DROID/build/core/armelf.x",
108    "-Wl,-dynamic-linker,/system/bin/linker",
109    "-Wl,--gc-sections",
110    "-Wl,-z,nocopyreloc",
111    "-Wl,--no-undefined",
112    "-Wl,-rpath-link=$ALIB",
113    "-L$ALIB",
114    "-nostdlib",
115    "$ALIB/crtend_android.o",
116    "$ALIB/crtbegin_dynamic.o",
117    "$TOOLCHAIN/lib/gcc/arm-eabi/4.3.1/interwork/libgcc.a",
118    "-lc",
119    "-lm");
120   
121# Also need: -Wl,-soname,libXXXX.so
122my @shared_args = (
123    "-nostdlib",
124    "-Wl,-T,$DROID/build/core/armelf.xsc",
125    "-Wl,--gc-sections",
126    "-Wl,-shared,-Bsymbolic",
127    "-L$ALIB",
128    "-Wl,--no-whole-archive",
129    "-lc",
130    "-lm",
131    "-Wl,--no-undefined",
132    "$TOOLCHAIN/lib/gcc/arm-eabi/4.3.1/interwork/libgcc.a",
133    "-Wl,--whole-archive"); # .a, .o input files go *after* here
134
135# Now implement a quick parser for a gcc-like command line
136
137my %MODES = ("-E"=>1, "-c"=>1, "-S"=>1, "-shared"=>1);
138
139my $mode = "DEFAULT";
140my $out;
141my $warn = 0;
142my $opt = 0;
143my @args = ();
144my $have_src = 0;
145while(@ARGV) {
146    my $a = shift;
147    if(defined $MODES{$a}) {
148        die "Can't specify $a and $mode" if $mode ne "DEFAULT";
149        $mode = $a;
150    } elsif($a eq "-o") {
151        die "Missing -o argument" if !@ARGV;
152        die "Duplicate -o argument" if defined $out;
153        $out = shift;
154    } elsif($a =~ /^-W.*/) {
155        $warn = 1;
156    } elsif($a =~ /^-O.*/) {
157        $opt = 1;
158    } else {
159        if($a =~ /\.(c|cpp|cxx)$/i) { $have_src = 1; }
160        push @args, $a;
161    }
162}
163
164my $need_cpp = 0;
165my $need_compile = 0;
166my $need_link = 0;
167my $need_shlink = 0;
168if($mode eq "DEFAULT") { $need_cpp = $need_compile = $need_link = 1; }
169if($mode eq "-E") { $need_cpp = 1; }
170if($mode eq "-c") { $need_cpp = $need_compile = 1; }
171if($mode eq "-S") { $need_cpp = $need_compile = 1; }
172if($mode eq "-shared") { $need_shlink = 1; }
173
174if($have_src and $mode ne "-E") { $need_cpp = $need_compile = 1; }
175
176# Assemble the command:
177my @cmd = ("arm-eabi-gcc");
178if($mode ne "DEFAULT") { @cmd = (@cmd, $mode); }
179if(defined $out) { @cmd = (@cmd, "-o", $out); }
180if($need_cpp) { @cmd = (@cmd, @include_paths, @preprocess_args); }
181if($need_compile){
182    @cmd = (@cmd, @compile_args);
183    if($warn) { @cmd = (@cmd, @warn_args); }
184    if($opt) { @cmd = (@cmd, @optimize_args); }
185}
186if($need_link) { @cmd = (@cmd, @link_args); }
187if($need_shlink) { @cmd = (@cmd, @shared_args); }
188@cmd = (@cmd, @args);
189
190#print join(" ", @cmd), "\n"; # Spit it out if you're curious
191exec(@cmd);