| ... | @@ -0,0 +1,85 @@ |
| 1 | # Zig GNU C Library ("glibc") Support |
| 2 | |
| 3 | *Date*: November, 2023 |
| 4 | |
| 5 | Zig supports building binaries that will dynamically link against the |
| 6 | [GNU C Library ("glibc")](https://www.gnu.org/software/libc/) when run. |
| 7 | This support extends across a range of glibc versions. |
| 8 | |
| 9 | By default, Zig binaries will not depend on any external C library, but |
| 10 | they can be linked against one with the `-lc` option. The compilation |
| 11 | target defines which C library: `musl` for the |
| 12 | [musl C library](https://musl.libc.org/) or `gnu` for the GNU C library. |
| 13 | |
| 14 | A specific GNU C library version can be chosen with an appropriate |
| 15 | `-target`. For example, `-target native-native-gnu.2.19` will use the |
| 16 | default CPU and OS targets, but will link in a run-time dependency on |
| 17 | glibc v2.19 (or later). Use `zig env` to show the default target and |
| 18 | version. |
| 19 | |
| 20 | Glibc symbols are defined in the `std.c.` namespace in Zig, though the |
| 21 | `std.os.` namespace is generally what should be used to access C-library |
| 22 | APIs in Zig code (it is defined depending on the linked C library). |
| 23 | |
| 24 | See `src/glibc.zig` for how Zig will build the glibc components. The |
| 25 | generated shared object files are sufficient only for compile-time |
| 26 | linking. They are stub libraries that only indicate that which symbols |
| 27 | will be present at run-time, along with their type and size. The symbols |
| 28 | do not reference an actual implementation. |
| 29 | |
| 30 | ## Targets |
| 31 | |
| 32 | The GNU C Library supports a very wide set of platforms and architectures. |
| 33 | The current Zig support for glibc only supports Linux. |
| 34 | |
| 35 | Zig supports glibc versions back to v2.17 (2012) as the Zig standard |
| 36 | library depends on symbols that were introduced in 2.17. |
| 37 | |
| 38 | ## Glibc stubs |
| 39 | |
| 40 | The file `lib/libc/glibc/abilist` is a Zig-specific binary blob that |
| 41 | defines the supported glibc versions and the set of symbols each version |
| 42 | must define. See https://github.com/ziglang/glibc-abi-tool for the |
| 43 | tooling to generate this blob. The code in `glibc.zig` parses the abilist |
| 44 | to build version-specific stub libraries on demand. |
| 45 | |
| 46 | The generated stub library is used for compile-time linking, with the |
| 47 | expectation that at run-time the real glibc library will provide the |
| 48 | actual symbol implementations. |
| 49 | |
| 50 | ### Public Headers |
| 51 | |
| 52 | The glibc headers are in `lib/libc/include/generic-glibc/`. These are |
| 53 | customized and have a couple Zig-specific `#ifdef`s to make the single set |
| 54 | of headers represent any of the supported glibc versions. There are |
| 55 | currently a handful of patches to these headers to represent new features |
| 56 | (e.g. `reallocarray`) or changes in implementation (e.g., the `stat()` |
| 57 | family of functions). |
| 58 | |
| 59 | The related Zig https://github.com/ziglang/universal-headers is a project |
| 60 | designed to more robustly build multi-version header files suitable for |
| 61 | compliation across a variety of target C library versions. |
| 62 | |
| 63 | ## Glibc static C-Runtime object files and libraries |
| 64 | |
| 65 | Linking against glibc also implies linking against several, generally |
| 66 | "invisible" glibc C Runtime libraries: `crti.o`, `crtn.o`, `Scrt1.o` and |
| 67 | `libc_nonshared.a`. These objects are linked into generated Zig binaries |
| 68 | and are not run-time linking dependencies. Generally they provide |
| 69 | bootstrapping, initialization, and mapping of un-versioned public APIs to |
| 70 | glibc-private versioned APIs. |
| 71 | |
| 72 | Like the public headers, these files contain a couple customiziations for |
| 73 | Zig to be able to build for any supported glibc version. E.g., for glibc |
| 74 | versions before v2.32, `libc_nonshared.a` contained stubs that directed |
| 75 | the `fstat()` call to a versioned `__fxstat()` call. |
| 76 | |
| 77 | These files used for these objects are in `lib/libc/glibc`. See the |
| 78 | `tools/update_glibc.zig` tool for updating content in here from the |
| 79 | upstream glibc. |
| 80 | |
| 81 | # More Information |
| 82 | |
| 83 | See |
| 84 | https://github.com/ziglang/zig/commit/2314051acaad37dd5630dd7eca08571d620d6496 |
| 85 | for an example commit that updates glibc (to v2.38). |