[clang] 58288c6 - [driver] Search for compatible Android runtime directories
Shoaib Meenai via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 18 16:25:05 PDT 2023
Author: Shoaib Meenai
Date: 2023-09-18T16:14:18-07:00
New Revision: 58288c6c1214f8a3a0e32e003406437652e098bd
URL: https://github.com/llvm/llvm-project/commit/58288c6c1214f8a3a0e32e003406437652e098bd
DIFF: https://github.com/llvm/llvm-project/commit/58288c6c1214f8a3a0e32e003406437652e098bd.diff
LOG: [driver] Search for compatible Android runtime directories
Android triples include a version number, which makes direct triple
comparisons for per-target runtime directory searching not always work.
Instead, look for the triple with the highest compatible version number
and use that per-target runtime directory instead. This maintains the
existing fallback to a triple without any version number, but I'm hoping
we can remove that in the future. https://discourse.llvm.org/t/62717
discusses this further.
The one remaining triple mismatch after this is that Android armv7
triples usually have an environment of `androideabi`, which Clang
normalizes to `android`. If you use the `androideabi` triple when
building the runtimes with a per-target runtimes dir, the directory will
get created with `androideabi` in its name, but Clang's triple search
uses the normalized triple and will look for an `android` directory
instead. https://reviews.llvm.org/D140925 will fix that by normalizing
triples when creating the per-target runtimes directories as well.
Reviewed By: phosek, pirama
Differential Revision: https://reviews.llvm.org/D158476
Added:
clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android23/libc++.so
clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android29/libc++.so
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android23/libclang_rt.builtins.a
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android29/libclang_rt.builtins.a
clang/test/Driver/android-unversioned-fallback-warning.cpp
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticDriverKinds.td
clang/include/clang/Driver/ToolChain.h
clang/lib/Driver/ToolChain.cpp
clang/test/Driver/android-installed-libcxx.cpp
clang/test/Driver/linux-per-target-runtime-dir.c
Removed:
clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android21/libc++.so
clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/libclang_rt.builtins.a
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d48bcb24e74ddb8..130dbe870f26d9a 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -341,6 +341,23 @@ X86 Support
Arm and AArch64 Support
^^^^^^^^^^^^^^^^^^^^^^^
+Android Support
+^^^^^^^^^^^^^^^
+
+- Android target triples are usually suffixed with a version. Clang searches for
+ target-specific runtime and standard libraries in directories named after the
+ target (e.g. if you're building with ``-target aarch64-none-linux-android21``,
+ Clang will look for ``lib/aarch64-none-linux-android21`` under its resource
+ directory to find runtime libraries). If an exact match isn't found, Clang
+ would previously fall back to a directory without any version (which would be
+ ``lib/aarch64-none-linux-android`` in our example). Clang will now look for
+ directories for lower versions and use the newest version it finds instead,
+ e.g. if you have ``lib/aarch64-none-linux-android21`` and
+ ``lib/aarch64-none-linux-android29``, ``-target aarch64-none-linux-android23``
+ will use the former and ``-target aarch64-none-linux-android30`` will use the
+ latter. Falling back to a versionless directory will now emit a warning, and
+ the fallback will be removed in Clang 19.
+
Windows Support
^^^^^^^^^^^^^^^
- Fixed an assertion failure that occurred due to a failure to propagate
diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td
index 9349ff85ca8a1d3..61ac792d6fda46a 100644
--- a/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -749,4 +749,10 @@ def warn_drv_missing_multilib : Warning<
InGroup<DiagGroup<"missing-multilib">>;
def note_drv_available_multilibs : Note<
"available multilibs are:%0">;
+
+def warn_android_unversioned_fallback : Warning<
+ "Using unversioned Android target directory %0 for target %1. Unversioned"
+ " directories will not be used in Clang 19. Provide a versioned directory"
+ " for the target version or lower instead.">,
+ InGroup<DiagGroup<"android-unversioned-fallback">>;
}
diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h
index 96d76c2384a9aa6..2d0c1f826c1728a 100644
--- a/clang/include/clang/Driver/ToolChain.h
+++ b/clang/include/clang/Driver/ToolChain.h
@@ -182,6 +182,9 @@ class ToolChain {
EffectiveTriple = std::move(ET);
}
+ std::optional<std::string>
+ getFallbackAndroidTargetPath(StringRef BaseDir) const;
+
mutable std::optional<CXXStdlibType> cxxStdlibType;
mutable std::optional<RuntimeLibType> runtimeLibType;
mutable std::optional<UnwindLibType> unwindLibType;
diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp
index 3a7e90e6b637707..31245964c4baab3 100644
--- a/clang/lib/Driver/ToolChain.cpp
+++ b/clang/lib/Driver/ToolChain.cpp
@@ -677,6 +677,50 @@ const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
return Args.MakeArgString(getCompilerRT(Args, Component, Type));
}
+// Android target triples contain a target version. If we don't have libraries
+// for the exact target version, we should fall back to the next newest version
+// or a versionless path, if any.
+std::optional<std::string>
+ToolChain::getFallbackAndroidTargetPath(StringRef BaseDir) const {
+ llvm::Triple TripleWithoutLevel(getTriple());
+ TripleWithoutLevel.setEnvironmentName("android"); // remove any version number
+ const std::string &TripleWithoutLevelStr = TripleWithoutLevel.str();
+ unsigned TripleVersion = getTriple().getEnvironmentVersion().getMajor();
+ unsigned BestVersion = 0;
+
+ SmallString<32> TripleDir;
+ bool UsingUnversionedDir = false;
+ std::error_code EC;
+ for (llvm::vfs::directory_iterator LI = getVFS().dir_begin(BaseDir, EC), LE;
+ !EC && LI != LE; LI = LI.increment(EC)) {
+ StringRef DirName = llvm::sys::path::filename(LI->path());
+ StringRef DirNameSuffix = DirName;
+ if (DirNameSuffix.consume_front(TripleWithoutLevelStr)) {
+ if (DirNameSuffix.empty() && TripleDir.empty()) {
+ TripleDir = DirName;
+ UsingUnversionedDir = true;
+ } else {
+ unsigned Version;
+ if (!DirNameSuffix.getAsInteger(10, Version) && Version > BestVersion &&
+ Version < TripleVersion) {
+ BestVersion = Version;
+ TripleDir = DirName;
+ UsingUnversionedDir = false;
+ }
+ }
+ }
+ }
+
+ if (TripleDir.empty())
+ return {};
+
+ SmallString<128> P(BaseDir);
+ llvm::sys::path::append(P, TripleDir);
+ if (UsingUnversionedDir)
+ D.Diag(diag::warn_android_unversioned_fallback) << P << getTripleString();
+ return std::string(P);
+}
+
std::optional<std::string>
ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
auto getPathForTriple =
@@ -713,15 +757,8 @@ ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
return *Path;
}
- // Android targets may include an API level at the end. We still want to fall
- // back on a path without the API level.
- if (getTriple().isAndroid() &&
- getTriple().getEnvironmentName() != "android") {
- llvm::Triple TripleWithoutLevel = getTriple();
- TripleWithoutLevel.setEnvironmentName("android");
- if (auto Path = getPathForTriple(TripleWithoutLevel))
- return *Path;
- }
+ if (getTriple().isAndroid())
+ return getFallbackAndroidTargetPath(BaseDir);
return {};
}
diff --git a/clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android21/libc++.so b/clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android23/libc++.so
similarity index 100%
rename from clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android21/libc++.so
rename to clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android23/libc++.so
diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/libclang_rt.builtins.a b/clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android29/libc++.so
similarity index 100%
rename from clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android21/libclang_rt.builtins.a
rename to clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android29/libc++.so
diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android23/libclang_rt.builtins.a b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android23/libclang_rt.builtins.a
new file mode 100644
index 000000000000000..e69de29bb2d1d64
diff --git a/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android29/libclang_rt.builtins.a b/clang/test/Driver/Inputs/resource_dir_with_per_target_subdir/lib/aarch64-unknown-linux-android29/libclang_rt.builtins.a
new file mode 100644
index 000000000000000..e69de29bb2d1d64
diff --git a/clang/test/Driver/android-installed-libcxx.cpp b/clang/test/Driver/android-installed-libcxx.cpp
index 4d139a1fb3693e6..14856e26e273074 100644
--- a/clang/test/Driver/android-installed-libcxx.cpp
+++ b/clang/test/Driver/android-installed-libcxx.cpp
@@ -13,6 +13,7 @@
// RUN: mkdir -p %t2/include/c++/v1
// RUN: mkdir -p %t2/sysroot
// RUN: mkdir -p %t2/include/aarch64-none-linux-android/c++/v1
+// RUN: mkdir -p %t2/include/aarch64-none-linux-android23/c++/v1
// RUN: %clang -target aarch64-none-linux-android -ccc-install-dir %/t2/bin \
// RUN: --sysroot=%t2/sysroot -stdlib=libc++ -fsyntax-only \
@@ -24,3 +25,14 @@
// ANDROID-DIR: "-internal-isystem" "[[DIR]][[SEP:/|\\\\]]..[[SEP]]include[[SEP]]aarch64-none-linux-android[[SEP]]c++[[SEP]]v1"
// ANDROID-DIR-SAME: "-internal-isystem" "[[DIR]][[SEP]]..[[SEP]]include[[SEP]]c++[[SEP]]v1"
+
+// RUN: %clang -target aarch64-none-linux-android23 -ccc-install-dir %/t2/bin \
+// RUN: --sysroot=%t2/sysroot -stdlib=libc++ -fsyntax-only \
+// RUN: %s -### 2>&1 | FileCheck --check-prefix=ANDROID23-DIR -DDIR=%/t2/bin %s
+
+// RUN: %clang -target aarch64-none-linux-android28 -ccc-install-dir %/t2/bin \
+// RUN: --sysroot=%t2/sysroot -stdlib=libc++ -fsyntax-only \
+// RUN: %s -### 2>&1 | FileCheck --check-prefix=ANDROID23-DIR -DDIR=%/t2/bin %s
+
+// ANDROID23-DIR: "-internal-isystem" "[[DIR]][[SEP:/|\\\\]]..[[SEP]]include[[SEP]]aarch64-none-linux-android23[[SEP]]c++[[SEP]]v1"
+// ANDROID23-DIR-SAME: "-internal-isystem" "[[DIR]][[SEP]]..[[SEP]]include[[SEP]]c++[[SEP]]v1"
diff --git a/clang/test/Driver/android-unversioned-fallback-warning.cpp b/clang/test/Driver/android-unversioned-fallback-warning.cpp
new file mode 100644
index 000000000000000..c6c21d63fd41313
--- /dev/null
+++ b/clang/test/Driver/android-unversioned-fallback-warning.cpp
@@ -0,0 +1,33 @@
+// Check that we emit warnings for using unversioned Android target directories
+// as appropriate.
+
+// RUN: mkdir -p %t/bin
+// RUN: mkdir -p %t/include/aarch64-none-linux-android/c++/v1
+// RUN: mkdir -p %t/include/aarch64-none-linux-android23/c++/v1
+// RUN: mkdir -p %t/include/c++/v1
+// RUN: mkdir -p %t/lib/aarch64-none-linux-android
+// RUN: mkdir -p %t/lib/aarch64-none-linux-android23
+// RUN: mkdir -p %t/resource/lib/aarch64-none-linux-android
+// RUN: mkdir -p %t/resource/lib/aarch64-none-linux-android23
+
+// Using an unversioned directory for an unversioned triple isn't a warning.
+// RUN: %clang -target aarch64-none-linux-android -ccc-install-dir %t/bin \
+// RUN: -resource-dir %t/resource -### -c %s 2>&1 | \
+// RUN: FileCheck --check-prefix=NO-WARNING %s
+// NO-WARNING-NOT: Using unversioned Android target directory
+
+// RUN: %clang -target aarch64-none-linux-android21 -ccc-install-dir %t/bin \
+// RUN: -resource-dir %t/resource -### -c %s 2>&1 | \
+// RUN: FileCheck --check-prefix=ANDROID21 -DDIR=%t -DSEP=%{fs-sep} %s
+// ANDROID21-DAG: Using unversioned Android target directory [[DIR]]/bin[[SEP]]..[[SEP]]include[[SEP]]aarch64-none-linux-android
+// ANDROID21-DAG: Using unversioned Android target directory [[DIR]]/bin[[SEP]]..[[SEP]]lib[[SEP]]aarch64-none-linux-android
+// ANDROID21-DAG: Using unversioned Android target directory [[DIR]]/resource[[SEP]]lib[[SEP]]aarch64-none-linux-android
+
+// 23 or newer should use the versioned directory
+// RUN: %clang -target aarch64-none-linux-android23 -ccc-install-dir %t/bin \
+// RUN: -resource-dir %t/resource -### -c %s 2>&1 | \
+// RUN: FileCheck --check-prefix=NO-WARNING %s
+
+// RUN: %clang -target aarch64-none-linux-android28 -ccc-install-dir %t/bin \
+// RUN: -resource-dir %t/resource -### -c %s 2>&1 | \
+// RUN: FileCheck --check-prefix=NO-WARNING %s
diff --git a/clang/test/Driver/linux-per-target-runtime-dir.c b/clang/test/Driver/linux-per-target-runtime-dir.c
index c5c871236044b27..8c721d82821f6ad 100644
--- a/clang/test/Driver/linux-per-target-runtime-dir.c
+++ b/clang/test/Driver/linux-per-target-runtime-dir.c
@@ -17,12 +17,25 @@
// RUN: %clang --target=aarch64-unknown-linux-android21 -print-file-name=libc++.so 2>&1 \
// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \
// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID21 %s
-// CHECK-LIBCXX-ANDROID21: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android21{{/|\\}}libc++.so
+// CHECK-LIBCXX-ANDROID21: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libc++.so
// RUN: %clang --target=aarch64-unknown-linux-android23 -print-file-name=libc++.so 2>&1 \
// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \
// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID23 %s
-// CHECK-LIBCXX-ANDROID23: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libc++.so
+// CHECK-LIBCXX-ANDROID23: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android23{{/|\\}}libc++.so
+
+// RUN: %clang --target=aarch64-unknown-linux-android26 -print-file-name=libc++.so 2>&1 \
+// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \
+// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID23 %s
+
+// RUN: %clang --target=aarch64-unknown-linux-android29 -print-file-name=libc++.so 2>&1 \
+// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \
+// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID29 %s
+// CHECK-LIBCXX-ANDROID29: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android29{{/|\\}}libc++.so
+
+// RUN: %clang --target=aarch64-unknown-linux-android31 -print-file-name=libc++.so 2>&1 \
+// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \
+// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID29 %s
// RUN: %clang --target=aarch64-unknown-linux-android -print-file-name=libc++.so 2>&1 \
// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \
@@ -45,13 +58,29 @@
// RUN: --target=aarch64-unknown-linux-android21 \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
// RUN: | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID21 %s
-// CHECK-FILE-NAME-ANDROID21: lib{{/|\\}}aarch64-unknown-linux-android21{{/|\\}}libclang_rt.builtins.a
+// CHECK-FILE-NAME-ANDROID21: lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libclang_rt.builtins.a
// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
// RUN: --target=aarch64-unknown-linux-android23 \
// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
// RUN: | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID23 %s
-// CHECK-FILE-NAME-ANDROID23: lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libclang_rt.builtins.a
+// CHECK-FILE-NAME-ANDROID23: lib{{/|\\}}aarch64-unknown-linux-android23{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android26 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID23 %s
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android29 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID29 %s
+// CHECK-FILE-NAME-ANDROID29: lib{{/|\\}}aarch64-unknown-linux-android29{{/|\\}}libclang_rt.builtins.a
+
+// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
+// RUN: --target=aarch64-unknown-linux-android31 \
+// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \
+// RUN: | FileCheck --check-prefix=CHECK-FILE-NAME-ANDROID29 %s
// RUN: %clang -rtlib=compiler-rt -print-file-name=libclang_rt.builtins.a 2>&1 \
// RUN: --target=aarch64-unknown-linux-android \
More information about the cfe-commits
mailing list