ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.35k stars 2.43k forks source link

provide common implementations where applicable for libc functions #2879

Open andrewrk opened 5 years ago

andrewrk commented 5 years ago

Some libc functions can obviously share a common implementation. For example, right now, musl, mingw, the zig standard library all have independent implementations of the math functions, such as sqrt.

Instead, the canonical implementation should be in Zig, and even when providing musl or mingw libcs, the zig code should be built and used to fulfill those dependencies.

Other examples of functions would be memcpy and strcmp.

Functions that would be tricky to have common implementations would be, e.g. fopen. But that's worth investigating as well.

andrewrk commented 4 years ago

We now ship libc++ as well and it offers even more opportunities for this.

marcthe12 commented 4 years ago

I think we should focus on musl first especially stuff that does not rely on syscall. That should cover most targets easily as there are very few issues to to use does functions with ucrt for example.

LewisGaul commented 3 years ago

Is there anything that needs doing here that would be somewhat 'newcomer friendly'? Looking for an opportunity to get involved in something a bit bigger than zig fmt fixes :)

Mouvedia commented 3 years ago

@LewisGaul add *BSD libc issues?

2876 #2877 #2878

@nektro has a draft PR for FreeBSD: #8327

marcthe12 commented 3 years ago

I was looking at this for something similar recently. So I have some points so we can create a more concrete plan.

First thing, to what extend are we replacing the functions, are we only going to be doing only ones we have access to source or we can we do for one we only have headers or even no source at all? On nice thing if we can patch header is we can add functions not found in one libc but found in another one (annex k and complex numbers and C2x).

Unless we can do vardic functions in zig, we will not be able to stdio as printf family of function are vardic functions. Alot functions are simply wrapper here so we can share a lot of but it must implemented in c.

We should use the structure implemented in the libc and not reimplement it not to break the ABI. To us they should be an opaque structure. No need reimplement them.

Some stuff need state or a "runtime" like malloc and threads. Locale id the most annoying here. So unless we don't mind short circuiting locales, lets not touch those. We can still implementing supprising amount of functions though.

There are alot of function especially the math one which doesn't even need a libc itself. We really should start implementing this part first along with the wrappers in place like stdio. If done correctly we could even safety link some of these functions to any executable on any target.

nektro commented 2 years ago

is this with the intent to eventually remove some of the header files?

matu3ba commented 2 years ago

The "freestanding"/platform-independent bits are covered either by std.math or compiler-rt, see https://github.com/ziglang/zig/issues/7265.

What remains are smaller or bigger platform dependencies, which ideally have automatic abi tracking per platform or at least some test coverage for each supported platform.

Some of the shennanigans I did experience on trying to build a sane test system (it is not possible without user input for "non-standard platforms/freestanding"):

There are several things missing in the proposal to estimate the scope:

  1. Who is responsible to provide the correctly sized implementation with macro magic? Zig or the user? There is alot implementation defined behavior, ie char can be signed or unsigned.
  2. What is the scope of bending backwards backwards compatibility with all the macro shennanigans for usage?
  3. Which compilers are the target audience?

Technical side questions:

  1. How are abi sizes defined in clang and/or is there a query system in clang/other compilers we can use for all possible targets?
  2. How should sizes be communicated to the user for usability/no silent breakings? 2.1 One could either replace the header with a most accurate defined size type or/and 2.2 one could ship macro assertions with guards per target + a macro for the target selection. 2.3 Or should we make it like C to be mean and hide all the sizes from the user?

Related: https://github.com/marler8997/ziglibc/issues/1 Also related (to check if upstream breaks abi or allows abi breakage via build scripts etc): https://github.com/ziglang/zig/pull/11447 see posix_spawn as example, which can be platform defined (and for some reason glibc doesnt want to upstream the logic).

I played around with C macro introspection here and I believe that C code can not be sanely argued on without assumptions on how symbols may be retrieved for target triplet, all used types (typedefs offer no simple introspection) and a bunch of "platform specifiers" (super basic assumptions like function exit codes etc).