Renaming `Glibc` to `bionic` on android

Hello android developers,

As the android support matures, many things which initially made sense or were done for expediency start to stick out as problem areas. One area that I would like to address is the system libc inclusion. Currently, the system libc on android is imported as glibc as the module name is swiftGlibc. However, android's libc implementation is bionic, which is not particularly compatible with glibc, and has sufficient differences that the module map for the library is even split out.

I think that things are now in a place where it would be possible to rename the module from glibc to bionic. The one problem that crops up is that this would be a source compatibility break on android. Fortunately (or unfortunately?) we do not have any stability guarantees on non-Darwin platforms.

For those that think that android would be the odd platform in this case, I will point out that Windows uses ucrt for the module name as per the name of the system libc.

The question that comes up though, are there packages that we could not update for this and thus we need to provide some sort of staging or if we can just break compatibility with the next major release? That is where the input of other android folks would be useful.

CC: @drodriguez @Geordie_J

5 Likes

This would be fine for our own code of course but we do depend on some external libraries that “just work” on Android because they rely on #canImport Glibc. I think @johnno1962 is doing something similar from memory.

To me the best way forward would be “deprecating” import Glibc and printing a warning that support for this will be removed. In the meantime we could alias Glibc to reference the new Bionic module. I’m not sure if either of these is technically possible without significant changes though..

bionic may be a better name than Glibc but perhaps they should all have been called POSIX and this wouldn’t crop up. For me, the real solution is to have the system library as an @_exported import inside Foundation so you only ever need to import Foundation but from memory this created other problems.

POSIX would be incorrect - there are no guarantees about POSIX when you import the system C library. In fact, ucrt is not POSIX compliant at all.

Foundation already does the @_exported import in NSSwiftRuntime.swift. This would obviously be altered if it were to be renamed so that it would import bionic on Android

It really might be worth pushing on the generic "Platform" module idea before making this change, so that people only have to change once.

3 Likes

Even if it does sound slightly “over generous” and Python-y, I’d be fine with the Platform naming if its (cross-platform) contents stick to a well-documented meaning going forward.

What does spring to mind though: what we’re naming here, as @compnerd mentions, is the system C library. I guess libc sounds too much like Glibc, and maybe bionic and the windows variant literally aren’t libc. Would it be crazy to just import C?

1 Like

The one question that comes to mind, what does "platform" mean? I'm fine with the name, just want to know what it really means. On Windows, we have ucrt (usually imported as MSVCRT) and WinSDK. The difference is that WinSDK actually has a HUGE number of things it pulls in (effectively the entire system is made available - WinSock, LDAP, Explorer - yes, the file explorer, MSHTML - yes, the browser, etc). Would platform do the same thing on Darwin? That is, would importing Platform mean that you have WebView available on Darwin? Or does Platform just supposed to be synonymous with libSystem?

I love the name C for the import, and is what I had proposed earlier though it never ended up going anywhere because the bikeshedding came up and everyone had opinions on what the name should be and what it should cover.

I'm going to keep out of the other topics in the thread, but I am going to give my opinion on the original question from Saleem.

I don't know how much to keep it, but I think the best way of making this work for third party developers that also depend on third party code, is have "virtual" modules for Glibc (and maybe SwiftGlibc in case someone is being tricky) that contains something like the following:

#if canImport(bionic)
#warning("Glibc module is deprecated in Android platforms. Please start using #import bionic and canImport(bionic) for Android.")
@_exported import bionic
#else
#error("Glibc cannot find bionic module.")
#endif

After a reasonable time that #warning can be changed to #error, and after another reasonable time, the "virtual" module can be removed completly.

I also want to say that I don't use that much 3rd party code, or Glibc in Android that much, so the opinions of anyone that actually make use of those should have more weight than mine.

I think if we all find that solution to be sensible, it might be the moment to implement it, since the 5.1 train is leaving soon, and otherwise the workarounds will have to be kept longer.

2 Likes

Cool, this is what I had in mind with the “deprecation”. I forgot about these new warning and error flags (which aren’t at all that new any more :slight_smile:)

Was the naming confusion over this exact use case? I think there may be scope for both Platform and C (which would be a part of Platform, as it is with Darwin?). In my somewhat inexperienced opinion though I think C is a little more obvious as to what it should and shouldn’t contain.

If we have a well-defined set of things that should be in there, there may be scope for “filling in the gaps” in the long term on platforms that are missing certain C functionality. But maybe we should start another discussion for this topic.

I’m not sure what the best way forward is- if people are against “C” I can imagine even more controversy over what goes into “Platform”. Maybe the discussion should be framed very clearly in this way- that we’re looking for a pragmatic solution to naming the base-level C functionality that should be expected to work the same (to the extent that C is) across all supported platforms. One that only needs to be implemented (by devs and library devs) once.

2 Likes

I think Platform has to be "the thing that provides libc" and not make any more promises than that. On Apple platforms, that's all of "Darwin"…but not Dispatch. It's not really a great answer, but the alternative seems (to me) to be to say "these platforms are fundamentally different", which is the place we're in today, and it isn't even true given how many programs have #if os only around this one import.

@ddunbar, I remember you were a big proponent of this for a while. Did we have any names other than "Platform" in mind? "Libc" seems too limited for something that brings in Darwin.

I don't think we ever had a good name. Its a giant mess because of how conflated/confusing exactly what would be in "libc" is.

Why don't we just call it OS like sensible people, and have it bring in "all the low level junk you probably want if you want low level junk" within it, it can have finer grained modules if people need the control.

1 Like

I kind of see this as the other way around. Darwin is a superset and would itself import (and export) C. From memory this is the functionality that currently lives in Darwin.System but I’m not at my Mac right now to check.

Is it possible to define a minimal set of things that C should contain? Or is that just as difficult as defining what OS or Platform should contain? FWIW OS would be ok for me but it’s a little hand wavey - maybe it has to be though.

I'm not going to say it's impossible, but finding a subset of Darwin that could be split out into its own module is probably beyond the scope of this effort, and would involve liaising with other teams at Apple.* We should stick to something that just requires changes in Swift.

* Swift doesn't really handle Clang submodules; it just papers over them, and fails to do so for any modules with an overlay. So we really would need a separate top-level module.

I definitely would be against OS as the name. There is no guarantee that the OS even provides a C library.

I think that having something similar in between is really nice - Platform which does an @_exported import C to re-expose the C standard interfaces, and anything else which the platform wants to expose. By having the Platform layer we can protect the users from the issue and continue to create the more reasonable structure for the modules as we go forward.

I’ll stay out of the specifics because it’s not my area. Just wanted to throw one possible name of System into the mix, although it’s probably easier to guess what Platform would contain.

System is confusing, particularly when you are on Darwin. Is that going to be just libSystem? Well, libSystem has a number of re-exported libraries, which make this even more confusing (libSystem has a LC_REEXPORT for libDispatch.dylib IIRC), which means that System would end up including other things that we may not be able to do on Linux - Windows could actually do the re-exporting.