Open andrewrk opened 3 years ago
The only downside of this I can see is additional complexity, for what could be argued is an obscure use case.
only?
link_libc
dynamic means means a lot of code bloat, you now have to ship code that calls the libc and the self-hosted implementation,link_libc
may be true the whole stdlib will require the libc to be linked in, how do you explain you may not call any part of it to the linker? Opening all the symbols with dlopen/dlsym is definitely bonkers,posixCallMainAndExit
is tailored for Zig's startup, if the libc expects something more/less/different you're screwed (at runtime)My two cents: the number of people working on Zig is already small and the project scope is already enormous (a language, a compiler, a hopefully better compiler written in Zig, an intermediate representation, a bunch of code-generator backends, three or four linkers, a standard library), it would be better to focus on something more practical than this.
I'm new to Zig, just starting actually... but I wanted to confirm what Andrew already told -> "portable Linux binaries that work on any distribution, that are capable of doing dlopen and therefore pop up a window and do graphics drivers stuff". Yup. This is it. Right know with c/c++ vis&sim/games/etc You either have to build per distro/distro version or target really old compiler/libc so you can run on newer systems and just dlopen everything else like vulkan/opengl/other stuff. It's costly and usually makes supporting Linux a non option. On Windows it'a amazing that you can just import loadlibrary from kernel dll and without ever touching libc get everything that You need to get going, even if it's vulkan/opengl/directx etc. So I think this is a huge use case. Ps. Thanks Andrew for the sample. (zig-window). I will take a look and post results from my Fedora 33 system.
I finally managed to spend some time with Zig, both on my main Fedora 33 system as well as on Win10 (VM with GPU passthrough). I've background mostly in C/Go and is really nice to work with it and I've been productive after just 15 minutes and setting up ZLS. Also mostly just wanted to confirm that the binary from https://andrewkelley.me/temp/static-window9 works on my Fedora 33 system. Ps. Latest master also works fine on F33: $ zig build -Dtarget=x86_64-linux -Drelease-fast=true $ patchelf --remove-needed libdummy.so.0 zig-cache/bin/static-window $ zig-cache/bin/static-window
This is now additionally complicated by glibc completely breaking this use-case for ld.so. zig-window's trick is really clever, but also so obscure that dynamic linker implementations may break it at any point in time.
Here's my idea. Change
std.builtin.link_libc
to be an enum:Most applications would be
never
oralways
. To getruntime
you would need to ask for it with a special compiler flag, such as:-fruntime-libc
. Then we introduce a new decl,std.process.link_libc
:This is interesting because it is always a
bool
, but it could be comptime or runtime known. Most that currently usesstd.builtin.link_libc
would be updated to use this value instead.The start code:
There would be some other code that would need to be changed in response to this, but most code would already work just fine - what would happen is when the value is runtime known, the other fallback code for when the code is not linked with libc would get included in the binary in addition to the libc path, and it would turn into a runtime check.
The main use case for this would be to create portable Linux binaries that work on any distribution, that are capable of doing
dlopen
and therefore pop up a window and do graphics drivers stuff, as well as other stuff that only works when you interact with the system libc. I have a proof-of-concept of this over in https://github.com/andrewrk/zig-window.@LemonBoy pointed out in https://github.com/ziglang/zig/commit/479f259ea4799583f4062b2dffb7d9a289f7e18b#commitcomment-44519027 that the proof-of-concept was flawed because if it ever tried to do threads or thread-local-storage, it would cause UB. This proposal is what it would look like to solve the problem in a robust way. The only downside of this I can see is additional complexity, for what could be argued is an obscure use case. And now, maybe I'm getting too big for my britches here, but it seems to me that gaming on Linux being an obscure use case might have something to do with how non-portable binaries are. I personally think it's a very exciting use case, something I haven't seen ever done before, that could bring a lot of value to game developers and players alike. There are also use cases beyond gaming; essentially what this opens up is the ability to create portable binary distributions of complex applications.
The breaking change that would affect everyone who doesn't care about this use case would be to simply update all your
std.builtin.link_libc
tostd.process.link_libc
.