Skip to content

Android API level needs to be visible in Swift #76671

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
grynspan opened this issue Sep 24, 2024 · 17 comments
Open

Android API level needs to be visible in Swift #76671

grynspan opened this issue Sep 24, 2024 · 17 comments
Labels
Android Platform: Android availability The @available attribute and availability checking in general compiler control statements Feature: compiler control statements feature A feature request or implementation #if Feature → compiler control statements: Conditional compilation blocks

Comments

@grynspan
Copy link
Contributor

Motivation

In Android, new API is guarded by API level. For instance, timespec_get() was introduced with Android API level 29. API level can be determined by checking the value of __ANDROID_API__ defined in the system header <android/api-level.h>.

This value is not visible to Swift, meaning that code that is conditionally dependent on the availability of some API needs to check for it (and provide a fallback path!) in C or C++ rather than in Swift.

Proposed solution

I propose we teach the compiler, when targetting Android, to expose the API level similar to how the Swift language mode and compiler version are exposed:

var ts = timespec()
#if _apiLevel(>=29)
timespec_get(&ts, TIME_UTC)
#else
clock_gettime(CLOCK_REALTIME, &ts)
#endif
return ts

Alternatives considered

  • Exposing the API level as a macro would result in it being evaluated too late and the compiler wouldn't be able to ignore the API usage.
  • Exposing the API level as the de facto OS version (#available(Android 29, *)) would have a similar problem.
  • "Just do it in C" is generally not the solution we want for Swift projects.

Additional information

No response

@grynspan grynspan added feature A feature request or implementation Android Platform: Android triage needed This issue needs more specific labels labels Sep 24, 2024
@grynspan
Copy link
Contributor Author

@finagolfin @compnerd Could use your thoughts here. :)

@compnerd
Copy link
Member

There's another option of mapping OS release to API level, but that isn't very precise either. The difference between the iOS and Android here is that the information is statically available for Android. IIRC the OS check on Darwin was static with mmin-macosx-version was specified and dynamic if the availability was indeterminate. For Android, something like that with a weak linkage in the indeterminate case would be really nice.

@grynspan
Copy link
Contributor Author

There's another option of mapping OS release to API level, but that isn't very precise either.

See my "alternatives" section, yeah. #available would potentially be evaluated too late to be useful unless Android has weak linking support à la Darwin.

@bc-lee
Copy link
Contributor

bc-lee commented Sep 25, 2024

For Android, something like that with a weak linkage in the indeterminate case would be really nice.

It is possible. The macro __ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__ is specifically designed for this purpose. When defined, the NDK treats all symbols unavailable on the current platform as weak, similar to how it's done on Darwin.

For more information, see this guide and refer to the implementation details in android/versioning.h and time.h.

@grynspan
Copy link
Contributor Author

We'd need some way for the underlying machinery of #available() to query the API level for the running system (i.e. a runtime value, not a compile-time constant.) I think the system property "ro.build.version.sdk" gives us that value?

@finagolfin
Copy link
Member

It's something Android porters like @drodriguez have talked about for years, but nobody got around to adding. Since Android usually builds with the API version in the build triple, it should be easy to pass in at compile time to Swift code, just as it is currently passed in by SwiftPM when compiling C/C++ code with clang and Swift's ClangImporter, which then invoke this code that sets it in clang. So only Swift code is currently oblivious of the Android API used, past time that was remedied.

@finagolfin
Copy link
Member

We should assign somebody to work on this: @compnerd, is this something you Browser Company people would add? It all depends on who needs it, whether @marcprux for Skip or you guys or somebody else entirely.

@finagolfin finagolfin added #if Feature → compiler control statements: Conditional compilation blocks and removed triage needed This issue needs more specific labels labels Jan 16, 2025
@compnerd
Copy link
Member

This is definitely something that would be nice to have. This is similar to the long standing feature request on Windows for availability support. I think that would allow us to surface both of these in the best way possible, but that isn't something that we can take on just right now with the other items that are outstanding.

@compnerd compnerd added availability The @available attribute and availability checking in general #available Feature → statements: Availability condition and removed #if Feature → compiler control statements: Conditional compilation blocks labels Jan 16, 2025
@grynspan
Copy link
Contributor Author

I think we would also want the PSG to chime in if we were ready to pursue a change here for any given platform.

@finagolfin
Copy link
Member

@al45tair, would Jon's _apiLevel() idea above or Android @/#available annotations need to be pitched on the forum through PSG? Let us know how we move this forward.

@marcprux, given your Android toolchain, is this something you Skip people would want to add?

@marcprux
Copy link
Contributor

@marcprux, given your Android toolchain, is this something you Skip people would want to add?

While I agree it would be very useful, we unfortunately don't have the bandwidth to tackle it anytime in the near future.

@finagolfin
Copy link
Member

Ok, for me personally, this is a nice to have feature but not a priority, so I'm sounding the community out to see who is willing to put the time in to implement and push this through. Just for completeness, pinging @ephemer and @mstokercricut to see if either of you have any input.

@ephemer
Copy link

ephemer commented Jan 18, 2025

Thanks for the ping. We would also like to see this, but it's not something we actively have a current use-case for.

@AnthonyLatsis AnthonyLatsis added incremental compilation #if Feature → compiler control statements: Conditional compilation blocks compiler control statements Feature: compiler control statements and removed #available Feature → statements: Availability condition incremental compilation labels Jan 19, 2025
@al45tair
Copy link
Contributor

Yes, I think this is potentially something PSG is interested in. Personally I'd rather see @/#available used for this if at all possible, instead of adding a whole new thing, and then we could use the Android version number as part of the target perhaps, in a similar way to the way Darwin systems do?

@grynspan
Copy link
Contributor Author

I specifically suggested _apiLevel() on the assumption it was a static condition rather than something we could solve with weak linking, but I've since been schooled. So yes, I think it'd be great to align it directly to @/#available if it's technically feasible.

@finagolfin
Copy link
Member

Alright, looks like this is just waiting on someone to pitch and implement it then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Android Platform: Android availability The @available attribute and availability checking in general compiler control statements Feature: compiler control statements feature A feature request or implementation #if Feature → compiler control statements: Conditional compilation blocks
Projects
Status: Todo
Development

No branches or pull requests

8 participants