From 9f85ab647c8c9f47a1523f99facdf15fc34797a0 Mon Sep 17 00:00:00 2001 From: Fred Hornsey Date: Tue, 17 Nov 2020 22:20:43 -0600 Subject: 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 Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/13694) --- Configurations/15-android.conf | 84 ++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/Configurations/15-android.conf b/Configurations/15-android.conf index 4616394f8c..fd5cd3f478 100644 --- a/Configurations/15-android.conf +++ b/Configurations/15-android.conf @@ -29,18 +29,18 @@ $ndk = $ENV{$ndk_var}; last if defined $ndk; } - die "\$ANDROID_NDK_HOME is not defined" if (!$ndk); - if (!-d "$ndk/platforms" && !-f "$ndk/AndroidVersion.txt") { - # $ndk/platforms is traditional "all-inclusive" NDK, while - # $ndk/AndroidVersion.txt is so-called standalone toolchain - # tailored for specific target down to API level. + die "\$ANDROID_NDK_HOME is not defined" if (!$ndk); + my $is_standalone_toolchain = -f "$ndk/AndroidVersion.txt"; + my $ndk_src_props = "$ndk/source.properties"; + my $is_ndk = -f $ndk_src_props; + if ($is_ndk == $is_standalone_toolchain) { die "\$ANDROID_NDK_HOME=$ndk is invalid"; } $ndk = canonpath($ndk); my $ndkver = undef; - if (open my $fh, "<$ndk/source.properties") { + if (open my $fh, "<$ndk_src_props") { local $_; while(<$fh>) { if (m|Pkg\.Revision\s*=\s*([0-9]+)|) { @@ -59,7 +59,7 @@ if ($sysroot = $ENV{CROSS_SYSROOT}) { $sysroot =~ m|/android-([0-9]+)/arch-(\w+)/?$|; ($api, $arch) = ($1, $2); - } elsif (-f "$ndk/AndroidVersion.txt") { + } elsif ($is_standalone_toolchain) { $sysroot = "$ndk/sysroot"; } else { $api = "*"; @@ -72,17 +72,31 @@ } } - # list available platforms (numerically) - my @platforms = sort { $a =~ m/-([0-9]+)$/; my $aa = $1; - $b =~ m/-([0-9]+)$/; $aa <=> $1; - } glob("$ndk/platforms/android-$api"); - die "no $ndk/platforms/android-$api" if ($#platforms < 0); + if (-d "$ndk/platforms") { + # list available platforms (numerically) + my @platforms = sort { $a =~ m/-([0-9]+)$/; my $aa = $1; + $b =~ m/-([0-9]+)$/; $aa <=> $1; + } glob("$ndk/platforms/android-$api"); + die "no $ndk/platforms/android-$api" if ($#platforms < 0); - $sysroot = "@platforms[$#platforms]/arch-$arch"; - $sysroot =~ m|/android-([0-9]+)/arch-$arch|; - $api = $1; + $sysroot = "@platforms[$#platforms]/arch-$arch"; + $sysroot =~ m|/android-([0-9]+)/arch-$arch|; + $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; + } + } + close $fh; + } + die "Could not get default API Level" if ($api eq "*"); } - die "no sysroot=$sysroot" if (!-d $sysroot); + die "no sysroot=$sysroot" if (length $sysroot && !-d $sysroot); my $triarch = $triplet{$arch}; my $cflags; @@ -95,17 +109,21 @@ my $arm = $ndkver > 16 ? "armv7a" : "armv5te"; (my $tridefault = $triarch) =~ s/^arm-/$arm-/; (my $tritools = $triarch) =~ s/(?:x|i6)86(_64)?-.*/x86$1/; - $cflags .= " -target $tridefault " - . "-gcc-toolchain \$($ndk_var)/toolchains" - . "/$tritools-4.9/prebuilt/$host"; - $user{CC} = "clang" if ($user{CC} !~ m|clang|); + if (length $sysroot) { + $cflags .= " -target $tridefault " + . "-gcc-toolchain \$($ndk_var)/toolchains" + . "/$tritools-4.9/prebuilt/$host"; + $user{CC} = "clang" if ($user{CC} !~ m|clang|); + } else { + $user{CC} = "$tridefault$api-clang"; + } $user{CROSS_COMPILE} = undef; if (which("llvm-ar") =~ m|^$ndk/.*/prebuilt/([^/]+)/|) { $user{AR} = "llvm-ar"; $user{ARFLAGS} = [ "rs" ]; $user{RANLIB} = ":"; } - } elsif (-f "$ndk/AndroidVersion.txt") { #"standalone toolchain" + } elsif ($is_standalone_toolchain) { my $cc = $user{CC} // "clang"; # One can probably argue that both clang and gcc should be # probed, but support for "standalone toolchain" was added @@ -127,19 +145,21 @@ $user{CROSS_COMPILE} = "$triarch-"; } - if (!-d "$sysroot/usr/include") { - my $incroot = "$ndk/sysroot/usr/include"; - die "no $incroot" if (!-d $incroot); - die "no $incroot/$triarch" if (!-d "$incroot/$triarch"); - $incroot =~ s|^$ndk/||; - $cppflags = "-D__ANDROID_API__=$api"; - $cppflags .= " -isystem \$($ndk_var)/$incroot/$triarch"; - $cppflags .= " -isystem \$($ndk_var)/$incroot"; + if (length $sysroot) { + if (!-d "$sysroot/usr/include") { + my $incroot = "$ndk/sysroot/usr/include"; + die "no $incroot" if (!-d $incroot); + die "no $incroot/$triarch" if (!-d "$incroot/$triarch"); + $incroot =~ s|^$ndk/||; + $cppflags = "-D__ANDROID_API__=$api"; + $cppflags .= " -isystem \$($ndk_var)/$incroot/$triarch"; + $cppflags .= " -isystem \$($ndk_var)/$incroot"; + } + $sysroot =~ s|^$ndk/||; + $sysroot = " --sysroot=\$($ndk_var)/$sysroot"; } - - $sysroot =~ s|^$ndk/||; $android_ndk = { - cflags => "$cflags --sysroot=\$($ndk_var)/$sysroot", + cflags => $cflags . $sysroot, cppflags => $cppflags, bn_ops => $arch =~ m/64$/ ? "SIXTY_FOUR_BIT_LONG" : "BN_LLONG", -- cgit v1.2.3