这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@robertkirkman
Copy link
Member

@robertkirkman robertkirkman commented Aug 7, 2025

@robertkirkman robertkirkman changed the title fix(main/libllvm): Wrap all executables named after triplets with scr… fix(main/libllvm): Wrap all executables named after triplets with scripts that explicitly set the full target including the API level Aug 7, 2025
@robertkirkman robertkirkman changed the title fix(main/libllvm): Wrap all executables named after triplets with scripts that explicitly set the full target including the API level fix(main/libllvm): Implement all executables named after triplets with scripts that explicitly set the full target including the API level Aug 7, 2025
@fornwall
Copy link
Member

fornwall commented Aug 7, 2025

I think this makes sense.

The issue seems to come from NDK r27 having:

#if __ANDROID_API__ >= 24
int fileno_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
#endif /* __ANDROID_API__ >= 24 */

while NDK r28 updates to:

#if __BIONIC_AVAILABILITY_GUARD(24)
__nodiscard int fileno_unlocked(FILE* _Nonnull __fp) __INTRODUCED_IN(24);
#endif /* __BIONIC_AVAILABILITY_GUARD(24) */

Where the __BIONIC_AVAILABILITY_GUARD is defined in <android/versioning.h>:

#define __BIONIC_AVAILABILITY_GUARD(api_level) (__ANDROID_MIN_SDK_VERSION__ >= (api_level))

About __ANDROID_MINSDK_VERSION__ vs __ANDROID_API__, see https://developer.android.com/ndk/guides/sdk-versions:

The minSdkVersion of your application is made available to the preprocessor via the ANDROID_MIN_SDK_VERSION macro (the legacy ANDROID_API is identical, but prefer the former because its meaning is clearer). This macro is defined automatically by Clang, so no header needs to be included to use it. For NDK builds, this macro is always defined.

When invoked through a symlink without the api level (such as aarch64-linux-android-clang) clang will not define __ANDROID_MIN_SDK_VERSION__ or __ANDROID_API__ - see https://github.com/llvm/llvm-project/blob/main/clang/lib/Basic/Targets/OSTargets.h#L346-L351.

In Termux we do however get __ANDROID_API__ defined in <android/api-level.h> since we patch that file to contain:

#ifndef __ANDROID_API__
#define __ANDROID_API__ 24
#endif

We do not however get the more modern __ANDROID_MIN_SDK_VERSION__ macro defined there, which causes the breakage as NDK r28 switches to use that more modern variant.

But we shouldn't need to define that ourself there - clang should AFAIK define both __ANDROID_MIN_SDK_VERSION__ and __ANDROID_API__, and this PR makes that happen.

@robertkirkman
Copy link
Member Author

Thank you very much for writing a more detailed explanation of why the error started occurring only after the update to NDK r28c, and didn't happen with NDK r27c! I did not understand it to that level of detail, so it is very helpful.

@robertkirkman
Copy link
Member Author

robertkirkman commented Aug 7, 2025

When invoked through a symlink without the api level (such as aarch64-linux-android-clang) clang will not define __ANDROID_MIN_SDK_VERSION__ or __ANDROID_API__

I assume that specifically this condition is restricted to "symlinks that contain a triplet in their name", because clang is itself a symbolic link to clang-20, and when I tested the cc and gcc commands, which are also symbolic links, but which don't have a triplet in their names, they don't seem to be affected by the problem.

https://github.com/llvm/llvm-project/blob/main/clang/lib/Basic/Targets/OSTargets.h#L346-L351

Thank you for showing where this problem's root cause is inside the code of llvm!

While planning this PR, I thought about trying to do that as well, and whether or not I should try to fix the problem by editing code inside llvm rather than wrapper code, but It occurred to me that implementing this change using wrappers allows users to easily customize or remove the wrapper if they need to revert to the previous behavior, while if I were to edit this inside the code of llvm before recompiling it, it would be much more difficult for users to locally revert this change if they ever have to.

@robertkirkman
Copy link
Member Author

robertkirkman commented Aug 7, 2025

@licy183 I noticed now, after searching around for code that is similar to code that I'm editing in this PR, that you have implemented (from scratch by inventing Flang for Android?) the command aarch64-linux-android-flang-new, and you make this available for build-package.sh in termux_setup_flang(),

for host_plat in aarch64-linux-android armv7a-linux-androideabi i686-linux-android x86_64-linux-android; do
cat <<- EOF > $FLANG_FOLDER_TMP/bin/${host_plat}-flang-new
#!/usr/bin/env bash
if [ "\$1" != "-cpp" ] && [ "\$1" != "-fc1" ]; then
\`dirname \$0\`/flang-new --target=${host_plat}${TERMUX_PKG_API_LEVEL} -D__ANDROID_API__=$TERMUX_PKG_API_LEVEL "\$@"

however, what I noticed is that, unlike, for example, the command pkg install clang, the command pkg install flang does not provide a $PREFIX/bin/aarch64-linux-android-flang-new , only $PREFIX/bin/flang-new.

Do you think that providing $PREFIX/bin/aarch64-linux-android-flang-new with pkg install flang, and not only the one in ~/.termux-build/_cache/, is something that would be a good idea, or would it just be unnecessary in the case of Flang?

Unfortunately, I am very inexperienced with Fortran, so I don't know what is idiomatic for that language.

@licy183
Copy link
Member

licy183 commented Aug 8, 2025

There is no need to provide $PLATFORM_TRIPLE-flang-new for on-device build. It exists here just to make cmake happy. cmake will not work as intended without it when cross-compiling.

@robertkirkman
Copy link
Member Author

robertkirkman commented Aug 8, 2025

I was not sure at first whether this would be the best way to solve the problem, but it does appear to be and others have agreed that this makes sense, so I will merge this in 24 hours if no problems are found.

At first, I was slightly worried about my implementation of $PREFIX/bin/aarch64-linux-android-cpp not being quite exactly the same as ~/.termux-build/_cache/android-r28c-api-24-v1/bin/aarch64-linux-android-cpp (cpp --target=... instead of clang -E --target=...),

but I tested building grep on-device with this, which printed:

checking how to run the C preprocessor... aarch64-linux-android-cpp

and it seemed to build grep normally with no errors, so I think it is working completely fine.

@Heporis Heporis mentioned this pull request Aug 8, 2025
3 tasks
@robertkirkman robertkirkman marked this pull request as draft August 9, 2025 05:14
…h scripts

- Fixes termux#25622, which is an error that began occurring after the update to NDK r28c

- Also makes Termux's `clang` package behave more similarly to how Termux's `TERMUX_ON_DEVICE_BUILD=false` cross-compiling toolchain behaves
@robertkirkman robertkirkman force-pushed the libllvm-wrap-triplet-executables branch from bb96f11 to 9198163 Compare August 9, 2025 07:41
@robertkirkman robertkirkman changed the title fix(main/libllvm): Implement all executables named after triplets with scripts that explicitly set the full target including the API level fix(main/libllvm): Implement all executables named after triplets with scripts Aug 9, 2025
@robertkirkman
Copy link
Member Author

Biswa96 recommended that the commit message should be simplified, so I have revised it accordingly.

@robertkirkman robertkirkman marked this pull request as ready for review August 9, 2025 07:43
@robertkirkman robertkirkman merged commit e8e0dfa into termux:master Aug 9, 2025
11 checks passed
truboxl pushed a commit to truboxl/termux-packages that referenced this pull request Aug 23, 2025
…header patches

- Fixes termux#23401

- After termux#25627, it is believed that the custom definition of `__ANDROID_API__` is no longer needed, because:
  - There is no longer a way to reproduce any of the errors that it fixed before
  - Even if there were a way to, it would no longer be able to fix those errors by itself because of the update to NDK r28c (see termux#25622 for more details)
  - It is replaced with termux#25627, which does what it used to a different way that also fixes other erros and seems more reliable
robertkirkman added a commit that referenced this pull request Nov 4, 2025
…header patches

- Fixes #26838

- Fixes partly #23401

- After #25627, it is believed that the custom definition of `__ANDROID_API__` is no longer needed, because:
  - There is no longer a way to reproduce any of the errors that it fixed before
  - Even if there were a way to, it would no longer be able to fix those errors by itself because of the update to NDK r28c (see #25622 for more details)
  - It is replaced with #25627, which does what it used to a different way that also fixes other errors and seems more reliable
termux-pacman-bot added a commit to termux-pacman/termux-packages that referenced this pull request Nov 4, 2025
…header patches

- Fixes termux/termux-packages#26838

- Fixes partly termux/termux-packages#23401

- After termux/termux-packages#25627, it is believed that the custom definition of `__ANDROID_API__` is no longer needed, because:
  - There is no longer a way to reproduce any of the errors that it fixed before
  - Even if there were a way to, it would no longer be able to fix those errors by itself because of the update to NDK r28c (see termux/termux-packages#25622 for more details)
  - It is replaced with termux/termux-packages#25627, which does what it used to a different way that also fixes other errors and seems more reliable
robertkirkman added a commit that referenced this pull request Nov 16, 2025
- Fixes build with NDK r28c (after #25627)

- No longer necessary after fixing `gnustep-make` to not put `$TERMUX_PREFIX/bin` in `$PATH` or `$TERMUX_PREFIX/lib` in `$LD_LIBRARY_PATH`
termux-pacman-bot added a commit to termux-pacman/termux-packages that referenced this pull request Nov 16, 2025
- Fixes build with NDK r28c (after termux/termux-packages#25627)

- No longer necessary after fixing `gnustep-make` to not put `$TERMUX_PREFIX/bin` in `$PATH` or `$TERMUX_PREFIX/lib` in `$LD_LIBRARY_PATH`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] [NDK r28c] $PREFIX/bin/*-clang has different target API behavior from clang on all architectures except for 32-bit ARM

3 participants