Support for Android NDK r22

This is a backport of #13434, Fixes #13685.

I think builds using standalone toolchain are fine so I left them alone,
but `Configure` will fail if using the NDK directly because the
`platforms` and `sysroot` directories were removed.

If `sysroot` is missing, omit the `--sysroot` and `-gcc-toolchain`
arguments and use the triplet form clang command.

Also since `platforms` was being used for the default API level, use
`meta/platforms.json` instead if needed.

Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/13694)
This commit is contained in:
Fred Hornsey 2020-11-17 22:20:43 -06:00 committed by Matt Caswell
parent 4b1be3c886
commit 9f85ab647c
1 changed files with 52 additions and 32 deletions

View File

@ -30,17 +30,17 @@
last if defined $ndk; last if defined $ndk;
} }
die "\$ANDROID_NDK_HOME is not defined" if (!$ndk); die "\$ANDROID_NDK_HOME is not defined" if (!$ndk);
if (!-d "$ndk/platforms" && !-f "$ndk/AndroidVersion.txt") { my $is_standalone_toolchain = -f "$ndk/AndroidVersion.txt";
# $ndk/platforms is traditional "all-inclusive" NDK, while my $ndk_src_props = "$ndk/source.properties";
# $ndk/AndroidVersion.txt is so-called standalone toolchain my $is_ndk = -f $ndk_src_props;
# tailored for specific target down to API level. if ($is_ndk == $is_standalone_toolchain) {
die "\$ANDROID_NDK_HOME=$ndk is invalid"; die "\$ANDROID_NDK_HOME=$ndk is invalid";
} }
$ndk = canonpath($ndk); $ndk = canonpath($ndk);
my $ndkver = undef; my $ndkver = undef;
if (open my $fh, "<$ndk/source.properties") { if (open my $fh, "<$ndk_src_props") {
local $_; local $_;
while(<$fh>) { while(<$fh>) {
if (m|Pkg\.Revision\s*=\s*([0-9]+)|) { if (m|Pkg\.Revision\s*=\s*([0-9]+)|) {
@ -59,7 +59,7 @@
if ($sysroot = $ENV{CROSS_SYSROOT}) { if ($sysroot = $ENV{CROSS_SYSROOT}) {
$sysroot =~ m|/android-([0-9]+)/arch-(\w+)/?$|; $sysroot =~ m|/android-([0-9]+)/arch-(\w+)/?$|;
($api, $arch) = ($1, $2); ($api, $arch) = ($1, $2);
} elsif (-f "$ndk/AndroidVersion.txt") { } elsif ($is_standalone_toolchain) {
$sysroot = "$ndk/sysroot"; $sysroot = "$ndk/sysroot";
} else { } else {
$api = "*"; $api = "*";
@ -72,6 +72,7 @@
} }
} }
if (-d "$ndk/platforms") {
# list available platforms (numerically) # list available platforms (numerically)
my @platforms = sort { $a =~ m/-([0-9]+)$/; my $aa = $1; my @platforms = sort { $a =~ m/-([0-9]+)$/; my $aa = $1;
$b =~ m/-([0-9]+)$/; $aa <=> $1; $b =~ m/-([0-9]+)$/; $aa <=> $1;
@ -81,8 +82,21 @@
$sysroot = "@platforms[$#platforms]/arch-$arch"; $sysroot = "@platforms[$#platforms]/arch-$arch";
$sysroot =~ m|/android-([0-9]+)/arch-$arch|; $sysroot =~ m|/android-([0-9]+)/arch-$arch|;
$api = $1; $api = $1;
} elsif ($api eq "*") {
# r22 Removed platforms dir, use this JSON file
my $path = "$ndk/meta/platforms.json";
open my $fh, $path or die "Could not open '$path' $!";
while (<$fh>) {
if (/"max": (\d+),/) {
$api = $1;
last;
} }
die "no sysroot=$sysroot" if (!-d $sysroot); }
close $fh;
}
die "Could not get default API Level" if ($api eq "*");
}
die "no sysroot=$sysroot" if (length $sysroot && !-d $sysroot);
my $triarch = $triplet{$arch}; my $triarch = $triplet{$arch};
my $cflags; my $cflags;
@ -95,17 +109,21 @@
my $arm = $ndkver > 16 ? "armv7a" : "armv5te"; my $arm = $ndkver > 16 ? "armv7a" : "armv5te";
(my $tridefault = $triarch) =~ s/^arm-/$arm-/; (my $tridefault = $triarch) =~ s/^arm-/$arm-/;
(my $tritools = $triarch) =~ s/(?:x|i6)86(_64)?-.*/x86$1/; (my $tritools = $triarch) =~ s/(?:x|i6)86(_64)?-.*/x86$1/;
if (length $sysroot) {
$cflags .= " -target $tridefault " $cflags .= " -target $tridefault "
. "-gcc-toolchain \$($ndk_var)/toolchains" . "-gcc-toolchain \$($ndk_var)/toolchains"
. "/$tritools-4.9/prebuilt/$host"; . "/$tritools-4.9/prebuilt/$host";
$user{CC} = "clang" if ($user{CC} !~ m|clang|); $user{CC} = "clang" if ($user{CC} !~ m|clang|);
} else {
$user{CC} = "$tridefault$api-clang";
}
$user{CROSS_COMPILE} = undef; $user{CROSS_COMPILE} = undef;
if (which("llvm-ar") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) { if (which("llvm-ar") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) {
$user{AR} = "llvm-ar"; $user{AR} = "llvm-ar";
$user{ARFLAGS} = [ "rs" ]; $user{ARFLAGS} = [ "rs" ];
$user{RANLIB} = ":"; $user{RANLIB} = ":";
} }
} elsif (-f "$ndk/AndroidVersion.txt") { #"standalone toolchain" } elsif ($is_standalone_toolchain) {
my $cc = $user{CC} // "clang"; my $cc = $user{CC} // "clang";
# One can probably argue that both clang and gcc should be # One can probably argue that both clang and gcc should be
# probed, but support for "standalone toolchain" was added # probed, but support for "standalone toolchain" was added
@ -127,6 +145,7 @@
$user{CROSS_COMPILE} = "$triarch-"; $user{CROSS_COMPILE} = "$triarch-";
} }
if (length $sysroot) {
if (!-d "$sysroot/usr/include") { if (!-d "$sysroot/usr/include") {
my $incroot = "$ndk/sysroot/usr/include"; my $incroot = "$ndk/sysroot/usr/include";
die "no $incroot" if (!-d $incroot); die "no $incroot" if (!-d $incroot);
@ -136,10 +155,11 @@
$cppflags .= " -isystem \$($ndk_var)/$incroot/$triarch"; $cppflags .= " -isystem \$($ndk_var)/$incroot/$triarch";
$cppflags .= " -isystem \$($ndk_var)/$incroot"; $cppflags .= " -isystem \$($ndk_var)/$incroot";
} }
$sysroot =~ s|^$ndk/||; $sysroot =~ s|^$ndk/||;
$sysroot = " --sysroot=\$($ndk_var)/$sysroot";
}
$android_ndk = { $android_ndk = {
cflags => "$cflags --sysroot=\$($ndk_var)/$sysroot", cflags => $cflags . $sysroot,
cppflags => $cppflags, cppflags => $cppflags,
bn_ops => $arch =~ m/64$/ ? "SIXTY_FOUR_BIT_LONG" bn_ops => $arch =~ m/64$/ ? "SIXTY_FOUR_BIT_LONG"
: "BN_LLONG", : "BN_LLONG",