]>
Commit | Line | Data |
---|---|---|
ebea0f30 AP |
1 | #### Android... |
2 | # | |
df3a1551 | 3 | # See NOTES.ANDROID for details, and don't miss platform-specific |
f39276fd | 4 | # comments below... |
ebea0f30 AP |
5 | |
6 | { | |
18174ba8 RL |
7 | use File::Spec::Functions; |
8 | ||
ebea0f30 AP |
9 | my $android_ndk = {}; |
10 | my %triplet = ( | |
11 | arm => "arm-linux-androideabi", | |
12 | arm64 => "aarch64-linux-android", | |
13 | mips => "mipsel-linux-android", | |
14 | mips64 => "mips64el-linux-android", | |
15 | x86 => "i686-linux-android", | |
16 | x86_64 => "x86_64-linux-android", | |
17 | ); | |
18 | ||
19 | sub android_ndk { | |
20 | unless (%$android_ndk) { | |
f770d75b AP |
21 | if ($now_printing =~ m|^android|) { |
22 | return $android_ndk = { bn_ops => "BN_AUTO" }; | |
23 | } | |
24 | ||
6b4f9892 RL |
25 | my $ndk_var; |
26 | my $ndk; | |
453eccd6 | 27 | foreach (qw(ANDROID_NDK_HOME ANDROID_NDK)) { |
28 | $ndk_var = $_; | |
6b4f9892 RL |
29 | $ndk = $ENV{$ndk_var}; |
30 | last if defined $ndk; | |
31 | } | |
32 | die "\$ANDROID_NDK_HOME is not defined" if (!$ndk); | |
a66c361a AP |
33 | if (!-d "$ndk/platforms" && !-f "$ndk/AndroidVersion.txt") { |
34 | # $ndk/platforms is traditional "all-inclusive" NDK, while | |
35 | # $ndk/AndroidVersion.txt is so-called standalone toolchain | |
36 | # tailored for specific target down to API level. | |
6b4f9892 | 37 | die "\$ANDROID_NDK_HOME=$ndk is invalid"; |
a66c361a | 38 | } |
9f9a7d60 | 39 | $ndk = canonpath($ndk); |
ebea0f30 | 40 | |
df3a1551 AP |
41 | my $ndkver = undef; |
42 | ||
43 | if (open my $fh, "<$ndk/source.properties") { | |
44 | local $_; | |
45 | while(<$fh>) { | |
46 | if (m|Pkg\.Revision\s*=\s*([0-9]+)|) { | |
47 | $ndkver = $1; | |
48 | last; | |
49 | } | |
50 | } | |
51 | close $fh; | |
52 | } | |
53 | ||
a66c361a AP |
54 | my ($sysroot, $api, $arch); |
55 | ||
56 | $config{target} =~ m|[^-]+-([^-]+)$|; # split on dash | |
57 | $arch = $1; | |
ebea0f30 | 58 | |
a66c361a AP |
59 | if ($sysroot = $ENV{CROSS_SYSROOT}) { |
60 | $sysroot =~ m|/android-([0-9]+)/arch-(\w+)/?$|; | |
61 | ($api, $arch) = ($1, $2); | |
62 | } elsif (-f "$ndk/AndroidVersion.txt") { | |
63 | $sysroot = "$ndk/sysroot"; | |
64 | } else { | |
65 | $api = "*"; | |
ebea0f30 AP |
66 | |
67 | # see if user passed -D__ANDROID_API__=N | |
df3a1551 | 68 | foreach (@{$useradd{CPPDEFINES}}, @{$user{CPPFLAGS}}) { |
ebea0f30 AP |
69 | if (m|__ANDROID_API__=([0-9]+)|) { |
70 | $api = $1; | |
71 | last; | |
72 | } | |
73 | } | |
74 | ||
f39276fd | 75 | # list available platforms (numerically) |
ebea0f30 AP |
76 | my @platforms = sort { $a =~ m/-([0-9]+)$/; my $aa = $1; |
77 | $b =~ m/-([0-9]+)$/; $aa <=> $1; | |
78 | } glob("$ndk/platforms/android-$api"); | |
79 | die "no $ndk/platforms/android-$api" if ($#platforms < 0); | |
80 | ||
a66c361a | 81 | $sysroot = "@platforms[$#platforms]/arch-$arch"; |
3453dbde AP |
82 | $sysroot =~ m|/android-([0-9]+)/arch-$arch|; |
83 | $api = $1; | |
ebea0f30 AP |
84 | } |
85 | die "no sysroot=$sysroot" if (!-d $sysroot); | |
86 | ||
ebea0f30 | 87 | my $triarch = $triplet{$arch}; |
0ad4078c | 88 | my $cflags; |
ebea0f30 AP |
89 | my $cppflags; |
90 | ||
a66c361a | 91 | # see if there is NDK clang on $PATH, "universal" or "standalone" |
df3a1551 | 92 | if (which("clang") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) { |
f41c8674 | 93 | my $host=$1; |
ebea0f30 | 94 | # harmonize with gcc default |
df3a1551 AP |
95 | my $arm = $ndkver > 16 ? "armv7a" : "armv5te"; |
96 | (my $tridefault = $triarch) =~ s/^arm-/$arm-/; | |
f41c8674 AP |
97 | (my $tritools = $triarch) =~ s/(?:x|i6)86(_64)?-.*/x86$1/; |
98 | $cflags .= " -target $tridefault " | |
6b4f9892 | 99 | . "-gcc-toolchain \$($ndk_var)/toolchains" |
f41c8674 | 100 | . "/$tritools-4.9/prebuilt/$host"; |
df3a1551 | 101 | $user{CC} = "clang" if ($user{CC} !~ m|clang|); |
ebea0f30 | 102 | $user{CROSS_COMPILE} = undef; |
3b1928fe AP |
103 | if (which("llvm-ar") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) { |
104 | $user{AR} = "llvm-ar"; | |
105 | $user{ARFLAGS} = [ "rs" ]; | |
106 | $user{RANLIB} = ":"; | |
107 | } | |
a66c361a AP |
108 | } elsif (-f "$ndk/AndroidVersion.txt") { #"standalone toolchain" |
109 | my $cc = $user{CC} // "clang"; | |
110 | # One can probably argue that both clang and gcc should be | |
111 | # probed, but support for "standalone toolchain" was added | |
112 | # *after* announcement that gcc is being phased out, so | |
113 | # favouring clang is considered adequate. Those who insist | |
114 | # have option to enforce test for gcc with CC=gcc. | |
115 | if (which("$triarch-$cc") !~ m|^$ndk|) { | |
116 | die "no NDK $triarch-$cc on \$PATH"; | |
117 | } | |
118 | $user{CC} = $cc; | |
119 | $user{CROSS_COMPILE} = "$triarch-"; | |
df3a1551 AP |
120 | } elsif ($user{CC} eq "clang") { |
121 | die "no NDK clang on \$PATH"; | |
ebea0f30 | 122 | } else { |
df3a1551 AP |
123 | if (which("$triarch-gcc") !~ m|^$ndk/.*/prebuilt/([^/]+)/|) { |
124 | die "no NDK $triarch-gcc on \$PATH"; | |
125 | } | |
ebea0f30 AP |
126 | $cflags .= " -mandroid"; |
127 | $user{CROSS_COMPILE} = "$triarch-"; | |
128 | } | |
129 | ||
130 | if (!-d "$sysroot/usr/include") { | |
131 | my $incroot = "$ndk/sysroot/usr/include"; | |
132 | die "no $incroot" if (!-d $incroot); | |
133 | die "no $incroot/$triarch" if (!-d "$incroot/$triarch"); | |
134 | $incroot =~ s|^$ndk/||; | |
135 | $cppflags = "-D__ANDROID_API__=$api"; | |
6b4f9892 RL |
136 | $cppflags .= " -isystem \$($ndk_var)/$incroot/$triarch"; |
137 | $cppflags .= " -isystem \$($ndk_var)/$incroot"; | |
ebea0f30 AP |
138 | } |
139 | ||
140 | $sysroot =~ s|^$ndk/||; | |
141 | $android_ndk = { | |
6b4f9892 | 142 | cflags => "$cflags --sysroot=\$($ndk_var)/$sysroot", |
ebea0f30 AP |
143 | cppflags => $cppflags, |
144 | bn_ops => $arch =~ m/64$/ ? "SIXTY_FOUR_BIT_LONG" | |
145 | : "BN_LLONG", | |
146 | }; | |
147 | } | |
148 | ||
149 | return $android_ndk; | |
150 | } | |
151 | } | |
152 | ||
153 | my %targets = ( | |
154 | "android" => { | |
155 | inherit_from => [ "linux-generic32" ], | |
156 | template => 1, | |
157 | ################################################################ | |
158 | # Special note about -pie. The underlying reason is that | |
159 | # Lollipop refuses to run non-PIE. But what about older systems | |
160 | # and NDKs? -fPIC was never problem, so the only concern is -pie. | |
161 | # Older toolchains, e.g. r4, appear to handle it and binaries | |
162 | # turn out mostly functional. "Mostly" means that oldest | |
163 | # Androids, such as Froyo, fail to handle executable, but newer | |
164 | # systems are perfectly capable of executing binaries targeting | |
165 | # Froyo. Keep in mind that in the nutshell Android builds are | |
166 | # about JNI, i.e. shared libraries, not applications. | |
167 | cflags => add(sub { android_ndk()->{cflags} }), | |
168 | cppflags => add(sub { android_ndk()->{cppflags} }), | |
169 | cxxflags => add(sub { android_ndk()->{cflags} }), | |
170 | bn_ops => sub { android_ndk()->{bn_ops} }, | |
171 | bin_cflags => "-pie", | |
ac98d386 | 172 | enable => [ ], |
ebea0f30 AP |
173 | }, |
174 | "android-arm" => { | |
175 | ################################################################ | |
176 | # Contemporary Android applications can provide multiple JNI | |
177 | # providers in .apk, targeting multiple architectures. Among | |
178 | # them there is "place" for two ARM flavours: generic eabi and | |
179 | # armv7-a/hard-float. However, it should be noted that OpenSSL's | |
180 | # ability to engage NEON is not constrained by ABI choice, nor | |
181 | # is your ability to call OpenSSL from your application code | |
182 | # compiled with floating-point ABI other than default 'soft'. | |
f39276fd | 183 | # (Latter thanks to __attribute__((pcs("aapcs"))) declaration.) |
ebea0f30 AP |
184 | # This means that choice of ARM libraries you provide in .apk |
185 | # is driven by application needs. For example if application | |
186 | # itself benefits from NEON or is floating-point intensive, then | |
187 | # it might be appropriate to provide both libraries. Otherwise | |
188 | # just generic eabi would do. But in latter case it would be | |
189 | # appropriate to | |
190 | # | |
191 | # ./Configure android-arm -D__ARM_MAX_ARCH__=8 | |
192 | # | |
193 | # in order to build "universal" binary and allow OpenSSL take | |
194 | # advantage of NEON when it's available. | |
195 | # | |
f39276fd | 196 | # Keep in mind that (just like with linux-armv4) we rely on |
ebea0f30 AP |
197 | # compiler defaults, which is not necessarily what you had |
198 | # in mind, in which case you would have to pass additional | |
199 | # -march and/or -mfloat-abi flags. NDK defaults to armv5te. | |
df3a1551 | 200 | # Newer NDK versions reportedly require additional -latomic. |
ebea0f30 AP |
201 | # |
202 | inherit_from => [ "android", asm("armv4_asm") ], | |
87ba25ee | 203 | bn_ops => add("RC4_CHAR"), |
ebea0f30 AP |
204 | }, |
205 | "android-arm64" => { | |
206 | inherit_from => [ "android", asm("aarch64_asm") ], | |
87ba25ee | 207 | bn_ops => add("RC4_CHAR"), |
ebea0f30 AP |
208 | perlasm_scheme => "linux64", |
209 | }, | |
210 | ||
211 | "android-mips" => { | |
212 | inherit_from => [ "android", asm("mips32_asm") ], | |
87ba25ee | 213 | bn_ops => add("RC4_CHAR"), |
ebea0f30 AP |
214 | perlasm_scheme => "o32", |
215 | }, | |
216 | "android-mips64" => { | |
217 | ################################################################ | |
218 | # You are more than likely have to specify target processor | |
219 | # on ./Configure command line. Trouble is that toolchain's | |
220 | # default is MIPS64r6 (at least in r10d), but there are no | |
221 | # such processors around (or they are too rare to spot one). | |
222 | # Actual problem is that MIPS64r6 is binary incompatible | |
223 | # with previous MIPS ISA versions, in sense that unlike | |
224 | # prior versions original MIPS binary code will fail. | |
225 | # | |
226 | inherit_from => [ "android", asm("mips64_asm") ], | |
87ba25ee | 227 | bn_ops => add("RC4_CHAR"), |
ebea0f30 AP |
228 | perlasm_scheme => "64", |
229 | }, | |
230 | ||
231 | "android-x86" => { | |
232 | inherit_from => [ "android", asm("x86_asm") ], | |
233 | CFLAGS => add(picker(release => "-fomit-frame-pointer")), | |
234 | bn_ops => add("RC4_INT"), | |
235 | perlasm_scheme => "android", | |
236 | }, | |
237 | "android-x86_64" => { | |
238 | inherit_from => [ "android", asm("x86_64_asm") ], | |
239 | bn_ops => add("RC4_INT"), | |
240 | perlasm_scheme => "elf", | |
241 | }, | |
242 | ||
243 | #################################################################### | |
0f68b771 | 244 | # Backward compatible targets, (might) require $CROSS_SYSROOT |
ebea0f30 AP |
245 | # |
246 | "android-armeabi" => { | |
247 | inherit_from => [ "android-arm" ], | |
248 | }, | |
249 | "android64" => { | |
250 | inherit_from => [ "android" ], | |
251 | }, | |
252 | "android64-aarch64" => { | |
253 | inherit_from => [ "android-arm64" ], | |
254 | }, | |
255 | "android64-x86_64" => { | |
256 | inherit_from => [ "android-x86_64" ], | |
257 | }, | |
258 | "android64-mips64" => { | |
259 | inherit_from => [ "android-mips64" ], | |
260 | }, | |
261 | ); |