[HN Gopher] Zig cc: A drop-in replacement for GCC/Clang (2020)
       ___________________________________________________________________
        
       Zig cc: A drop-in replacement for GCC/Clang (2020)
        
       Author : AlexeyBrin
       Score  : 256 points
       Date   : 2021-07-18 13:04 UTC (9 hours ago)
        
 (HTM) web link (andrewkelley.me)
 (TXT) w3m dump (andrewkelley.me)
        
       | manish_gill wrote:
       | I literally started learning Zig today after watching a talk on
       | youtube by Andrew Kelly. The drop-in C compiler replacement lured
       | me.
       | 
       | But what surprised me immediately and the thing I'm absolutely
       | loving is the error handling
       | (https://twitter.com/mgill25/status/1416720958988210177) and the
       | comptime features.
       | 
       | I've done Rust and while I love what it's doing, getting into
       | low-level C-world without the overhead of a language like Rust
       | feels liberating.
        
         | coder543 wrote:
         | The thing I dislike about Zig error handling is that there's no
         | way to associate informational context with an error. Bubbling
         | the errors up, you'll eventually print out a string to the
         | console that says "error: AccessDenied". The sysadmin/user
         | running your software will be left baffled. Access denied...
         | _to what?!_
         | 
         | Zig is 90% of the way there with error handling, but it is
         | extremely obvious to me that you need to be able to have error
         | context carried with the error... it is apparently not obvious
         | to the core Zig team[0], and this is a major impediment to my
         | interest.
         | 
         | Sure, if you're compiling to a microcontroller, maybe you're
         | willing to sacrifice usability to avoid error values ever
         | allocating... but most developers can spare an allocation for
         | errors, especially given that error handling is generally not
         | the hot path.
         | 
         | [0]: https://github.com/ziglang/zig/issues/2647 (among other
         | issues)
        
           | kristoff_it wrote:
           | > it is apparently not obvious to the core Zig team
           | 
           | I think it really is not obvious once you start thinking
           | about all the implications. Right now the recommended way of
           | reporting extra information alongside errors is by using a
           | "diagnostics" struct.
           | 
           | You can see an extremely effective example of that in zig-
           | clap, for example.
           | 
           | https://github.com/Hejsil/zig-clap
           | 
           | Also this pattern was also mentioned in the issue you
           | mentioned: https://github.com/ziglang/zig/issues/2647#issueco
           | mment-5898...
           | 
           | The advantage of this system is that the caller can decide
           | whether error diagnostics are desirable or not. If they're
           | not, then zig-clap doesn't waste cycles nor memory keeping
           | track of the context in which an error happened. It's the
           | best of both worlds in my opinion.
        
             | coder543 wrote:
             | To add one more comment... you should study the
             | distribution of votes in that thread. Take a poll of the
             | developers using Zig. Anywhere you look, I'm sure you will
             | see that most people want error handling to include context
             | by default.
             | 
             | 84 upvotes for the initial issue is substantial in a
             | community the size of Zig.
        
             | coder543 wrote:
             | > I think it really is not obvious once you start thinking
             | about all the implications.
             | 
             | No... it _really is_ obvious. I 've written quite a bit of
             | C, C++, and Rust over the years, in addition to all sorts
             | of garbage collected languages. I'm not writing this as an
             | off-the-cuff thought. I've even written a similar comment
             | before on HN about Zig's error handling. I've thought about
             | this for a long time. It is just as obvious now as it was
             | on day one.
             | 
             | The fact that the Zig team keeps resisting this is just
             | mind blowing to me. "Penny wise, pound foolish" is my
             | opinion. The actual runtime cost here would be _so
             | entirely_ negligible, but its absence is a major
             | limitation.
             | 
             | > The advantage of this system is that the caller can
             | decide whether error diagnostics are desirable or not. If
             | they're not, then zig-clap doesn't waste cycles nor memory
             | keeping track of the context in which an error happened.
             | It's the best of both worlds in my opinion.
             | 
             | Instead, _the developer_ has to waste mental cycles and
             | memory keeping track of the context on every single
             | function call. Strongly disagree on it being the best of
             | both worlds.
             | 
             | For starters, every library has to decide whether they will
             | support it or not. If the language doesn't make this a
             | built-in part of the core error handling, then spoiler:
             | they won't. They'll throw away all useful error context,
             | leaving no option for the application developer to add it
             | back. Once the context is gone, _it 's gone for good._ You
             | can't know what a library did to cause an AccessDenied
             | error... you can't reach into the library and pull that
             | context out of thin air. If every library is implementing
             | this diagnostics pattern, then that's an equally strong
             | argument for it to be supported at the language level.
             | Either context is being irrevocably lost or developers are
             | wasting time writing convoluted code. Either way, this is
             | not the optimal solution.
             | 
             | I have experience writing code in a lot of languages...
             | error context is extremely important, and the "waste" of
             | CPU cycles and memory is extremely minimal for the benefit
             | gained.
             | 
             | As I have hinted before, a compile-time switch to throw
             | this information away could be a valid solution for the
             | extremely-difficult-to-imagine situations where great error
             | handling is unacceptably costly on performance... then it
             | would be like Zig's "async" support, where the library
             | developer doesn't have to color their functions based on
             | how the end user will use it. They should return all the
             | error information all the time, and the compiler decides
             | whether to keep the context or throw it away and provide
             | only the error "name". Yes, this would bring its own
             | challenges, but seriously, this option to discard the
             | context is completely unnecessary outside of like 8-bit
             | microcontrollers, and probably isn't worth implementing.
             | _Just provide context all the time_. Please... it 's such a
             | small ask.
             | 
             | Looking at the links you've provided, which you have also
             | provided in past discussions here, that pattern is
             | extremely painful. I cannot overstate how much worse that
             | usability is compared to the regular error handling Zig
             | provides, and so _obviously_ no one will _ever_ use it. It
             | serves as a pattern for the most desperate situations, and
             | as a way to handwave the lack of language-level support for
             | error context, in my opinion.
        
               | kristoff_it wrote:
               | I'm still not convinced, but at the same time it's not up
               | to me to decide. If you haven't done so already, I
               | recommend you make your case in the relevant issue.
        
           | dilap wrote:
           | Totally agree; it's _almost_ perfect, but this is defnly
           | needed to get to full perfection.
           | 
           | While you can argue (as people do on that issue) that there
           | are workarounds to carry error payload, the truth is if you
           | don't make it ergonomic, many libraries will not do it, and
           | that will filter down into software using those libraries,
           | thus hurting the final resulting software.
           | 
           | I'm hopeful this feature will eventually get added.
           | 
           | (See also https://news.ycombinator.com/item?id=25798578)
        
       | tempodox wrote:
       | Previous discussion:
       | 
       | https://news.ycombinator.com/item?id=22679138
        
       | arusahni wrote:
       | Another thing that's really cool, here: they've published the
       | language (and toolchain) to PyPi. So, with a simple
       | pip install ziglang
       | 
       | You can do                   python3 -m ziglang cc my_c_prog.c -o
       | my_c_prog         ./my_c_prog
       | 
       | A great way to do compilation on a system without needing to get
       | a C toolchain installed, if you already have Python available
        
       | IgorPartola wrote:
       | I looked at Zig a little while ago. What I really liked was some
       | of the clever features of the language and thr C interop. What
       | made me not pursue it for now is that I mostly use C for embedded
       | development and Zig doesn't have meaningful support for the
       | ESP8266 platform. Also, not fully memory safe which obviously not
       | the end of the world for me but if I'm going to switch away from
       | C then I kind of want that as a thing.
        
       | ksec wrote:
       | From Release Note 0.8 Roadmap [1],
       | 
       | >The major theme of the 0.9.0 release cycle will be stabilizing
       | the language, creating a first draft of the language
       | specification, and self-hosting the compiler.
       | 
       | So I am guessing we could see 1.0 release within 12 months time?
       | Or will there be 0.10 or 0.11 after that?
       | 
       | I am just eager to hear people's comments and opinions for using
       | it in production within their context and edge cases.
       | 
       | And as a sort of side note, I quite like the momentum and the way
       | Andrew has been handling Zig's PR. I just hope and pray HN keep
       | that tradition, dont over hype it.
       | 
       | [1] https://ziglang.org/download/0.8.0/release-
       | notes.html#Roadma...
        
         | kristoff_it wrote:
         | > So I am guessing we could see 1.0 release within 12 months
         | time? Or will there be 0.10 or 0.11 after that?
         | 
         | 1.0 is going to take a lot longer than that.
        
         | geodel wrote:
         | I guess at least 2 major things after 0.9 would be package
         | manager, library standardization and cleanup which would take
         | many releases and perhaps need to be done before 1.0
        
       | vlovich123 wrote:
       | Can it be used for c++ code? Also we build LLVM tip of tree from
       | scratch. Is it easy to get the version of zig cc built against
       | the newer version or does one have to wait for the project
       | authors to update to the latest (I'm assuming my it's a non-
       | trivial amount of work?)
        
         | O_H_E wrote:
         | > Can it be used for c++ code?
         | 
         | Yup!
         | https://github.com/ziglang/zig/commit/db17c0d88c44183b306099...
         | 
         | > Also we build LLVM tip of tree from scratch...
         | 
         | I would have also thought it would be non-trivial (Julia uses
         | LLVM and has some non-backwards compatible patches) but this
         | paragraph intrigued me:
         | 
         | >> At the time of this writing, LLVM 10 was just released two
         | hours ago. It will take days or weeks for it to become
         | available in various system package managers. But you can
         | already download a master branch build of Zig and play with the
         | new features of Clang/LLVM 10. For example, improved RISC-V
         | support!
         | 
         | I found this for LLVM 12 (released April 14)
         | https://github.com/ziglang/zig/commit/5a3ea9beced660c9cc463b...
         | https://github.com/ziglang/zig/commit/e248de93a07fd6a7f48581...
         | https://github.com/ziglang/zig/commit/6a7f21d1b8ca5c082c804e...
         | https://github.com/ziglang/zig/commit/1438c324a460789f1004a3...
         | 
         | Andrew seem to be following along their release pretty closely.
         | 
         | Disclaimer: I don't know squat what I'm talking about
        
       | flohofwoe wrote:
       | What's usually not mentioned is that zig cc is also an
       | ObjC/ObjC++ compiler, which is important on macOS to talk to
       | system framework APIs. Zig 0.8.0 still has some warts on macOS
       | (for instance one needs to tell Zig to use the Apple system
       | linker), but those will be fixed in 0.9.0 (AFAIK it already works
       | in the main branch).
        
       | lou1306 wrote:
       | It does look impressive! Does anyone know if Zig exposes some
       | APIs to extract/manipulate/analyze the AST of the C program? It
       | might be a nice alternative to LLVM, which I find a little
       | overwhelming.
        
         | bionade24 wrote:
         | zig cc uses LLVM under the hood.
        
           | msingle wrote:
           | right now - my understanding is once the self-hosted compiler
           | is done, LLVM will be optional.
        
             | adamdusty wrote:
             | I think LLVM will still be required for release builds.
        
       | fractalb wrote:
       | `zcc` would be even better.
        
         | Andoryuuta wrote:
         | Having "cc" as a sub-command with a space has caused some
         | issues with Go (cgo), make, autotools, etc [0].
         | 
         | The latest proposal from andrewrk is a new zig subcommand which
         | would automatically generate wrappers ("zig-cc", "zig-c++",
         | etc) for for the target, then set them in the current env
         | ("CC=zig-cc", "CXX=zig-c++") [1].
         | 
         | [0]: https://github.com/ziglang/zig/issues/8716
         | 
         | [1]: https://github.com/ziglang/zig/issues/8973
        
         | tempodox wrote:
         | $ alias zcc='zig cc'
         | 
         | Only works interactively, though.
        
           | makeworld wrote:
           | shopt -s expand_aliases
           | 
           | Put that at the top of your bash scripts and aliases will
           | work there too.
        
       | O_H_E wrote:
       | interesting paragraph on why the builds are so small.
       | 
       | > You can download a 45 MiB tarball, unpack it, and you're done.
       | You can even have multiple versions at the same time, no
       | problem......Compare this to downloading Clang, which has 380 MiB
       | Linux-distribution-specific tarballs. Zig's Linux tarballs are
       | fully statically linked, and therefore work correctly on all
       | Linux distributions. The size difference here comes because the
       | Clang tarball ships with more utilities than a C compiler, as
       | well as pre-compiled static libraries for both LLVM and Clang.
       | Zig does not ship with any pre-compiled libraries; instead it
       | ships with source code, and builds what it needs on-the-fly.
        
       | linux2647 wrote:
       | > Take a moment to appreciate what just happened here - I
       | downloaded a Windows build of Zig, ran it in Wine, using it to
       | cross compile for Linux, and then ran the binary natively.
       | Computers are fun!
        
       | _benj wrote:
       | I've been learning Zig for a few months now and what I'm in love
       | with is the ability to just use Zig to interact with whatever C
       | libraries I want, but doing so with the conveniences that Zig
       | offers.
       | 
       | I want to use SDL2 and cairo and pango? No problem! GTK4, easy
       | peasy! There's a C lib that comes as a single .c file that makes
       | it easier to interact with SDL? Drop it on the project folder and
       | compile it with Zig along all the other .zig files!
       | 
       | As somebody that has been avoiding C as much as I can, I'm loving
       | this approach since it has open the doors to the world of C for
       | me without having to learn autotools, make, valgrind, et al
        
         | skohan wrote:
         | This is one of the things I really liked about working with
         | Swift. You just got 50 years of C libraries for free, with high
         | level features on top of it, which means there is _a lot_ you
         | can do.
        
         | rhn_mk1 wrote:
         | Note that none of autotools, make, and valgrind are required
         | for C. You could be building with meson and ninja.
         | 
         | Valgrind is also more useful than just for C, although
         | admittedly it's most useful for binaries that have parts
         | written in unchecked languages like C.
        
           | tialaramex wrote:
           | Right. Even in an entirely _safe_ language you can have
           | leaks, and valgrind is an effective way to find those leaks
           | if you can afford the virtualisation overhead.
           | 
           | If you _can 't_ afford the virtualisation overhead, and you
           | need to find leaks you should try what Raymond Chen suggests
           | in "The poor man's way of identifying memory leaks" (not
           | bothering to link since Microsoft will only move it anyway,
           | they have several times since I read it). If you are too lazy
           | to do it by hand, or find the technique works but wish it
           | less manual, this is what Leakdice does:
           | 
           | https://github.com/tialaramex/leakdice OR
           | https://github.com/tialaramex/leakdice-rust
        
             | unilynx wrote:
             | http://bytepointer.com/resources/old_new_thing/20050815_224
             | _...
             | 
             | (a site that tries to keep a proper backup of the ever
             | moving writings of Chen)
        
         | pjmlp wrote:
         | As much as I dislike C from safety point or view, all of that
         | is also easy peasy with C.
        
         | klyrs wrote:
         | Omg, skip the rest but valgrind is _amazing_ and requires
         | almost zero learning to use. Build your code with debug
         | symbols, find inputs that trigger a segfault, then run it under
         | valgrind. It then reports out of bounds memory access, with a
         | full stacktrace. It 's got a billion more uses, but at the most
         | basic, that one use-case will keep you from wasting time
         | futzing with a debugger or print-debugging 99% of segfaults and
         | memory leaks.
        
           | jcalvinowens wrote:
           | Have you tried ASAN? If you like valgrind, you will be in
           | _love_ with ASAN, it 's really surpassed it at this point
           | IMHO.
        
             | klyrs wrote:
             | I have tried ASAN, and I'm fully prepared to love it, but
             | last time I tried to use it with Cython, it was pretty
             | fidgety to configure my build system to get it running --
             | unlike valgrind, you need to understand how programs are
             | compiled and linked. If you want ASAN to see into the
             | Python that's calling/consuming your Cython, you need to
             | build a custom Python. It's certainly a sharper tool, but
             | valgrind has the learning curve of a hammer.
        
             | jedisct1 wrote:
             | Be careful with ASAN on cryptographic code, though. It can
             | introduce side channels.
        
               | skeetmtp wrote:
               | ASAN is not meant to be used in production though. Or I
               | missed something in your comment.
        
               | chrsig wrote:
               | I've seen it advised to periodically release to
               | production with ASAN/UBSAN/TSAN enabled, with the
               | intention that it's only 1/nth of a deployment, and even
               | then, only deployed for enough time to collect
               | instrumentation. I don't have a citation to share, so
               | take with as many grains of salt as you feel appropriate.
               | 
               | If nothing else, I appreciate the advisement that it can
               | have security implications.
        
               | wizzwizz4 wrote:
               | > _with the intention that it 's only 1/nth of a
               | deployment, and even then, only deployed for enough time
               | to collect instrumentation_
               | 
               | You can't unleak secrets.
        
               | chrsig wrote:
               | I agree with you, but I don't understand intent of your
               | comment.
        
               | wizzwizz4 wrote:
               | If you leak all the secrets 1% of the time, that's not
               | leaking 1% of the secrets. All of the secrets have been
               | leaked, albeit over a short stretch of time.
        
           | _benj wrote:
           | ok, I'm down!
           | 
           | Using zig I finally decided to try GDB and it is amazing!
        
       | jedisct1 wrote:
       | `zig cc` is also amazing to compile C and C++ code to
       | WebAssembly. For standalone WebAssembly or WASI.
       | 
       | No need to install yet another toolchain, this is just another
       | target Zig can compile to, out of the box.
        
         | pjmlp wrote:
         | Actually you can do the same with clang.
         | 
         | Emscripten just installs a bunch of stuff to make it easier to
         | use existing libraries.
         | 
         | If you just want to use standard library, no need for extra
         | stuff.
         | 
         | https://surma.dev/things/c-to-webassembly/
        
           | jedisct1 wrote:
           | Only for freestanding webassembly. In order to target WASI,
           | you have to install the builtins
           | (https://github.com/jedisct1/libclang_rt.builtins-wasm32.a),
           | as well as the WASI libc, and fiddle with `---sysroot`.
           | 
           | Zig can target both without having to install anything else.
        
             | pjmlp wrote:
             | Assuming that you even need them.
             | 
             | Zig packages them, naturally you don't need to install them
             | a second time.
        
       | gigatexal wrote:
       | Zig looks really compelling. Anyone use it in production?
        
         | ifreund wrote:
         | This person has been for many months now:
         | https://www.youtube.com/watch?v=124wdTckHNY
         | 
         | We hope to be using TigerBeetle which is written in zig in
         | production in 2022: https://github.com/coilhq/tigerbeetle
        
       | pornel wrote:
       | I really like what they've done for cross-compilation.
       | Automatically selecting appropriate libc/crt implementation is
       | such a relief.
       | 
       | Compared to Zig, cross-compilation in C/C++/Rust seems downright
       | user-hostile: you have to obtain the correct cross-sdk, but it
       | won't tell you which one, or how to get it (some combos don't
       | even exist), or even where to put it. If you don't guess
       | everything correctly, it will fail with inscrutable errors, or
       | worse, only fail at runtime on the target machine.
        
         | pjmlp wrote:
         | What this kind of stories always miss is that the host platform
         | needs all system libraries for the target platform for anything
         | beyond the basic examples using the standard library.
         | 
         | E.g. try to cross compile Metal shading example for iOS from
         | Linux with zig, or do a Win2D UWP rendering application from
         | Linux with zig.
        
           | pcwalton wrote:
           | Right. Are you going to ship all Windows headers and import
           | libraries to everyone, including DirectX, etc.? Are you going
           | to keep them up to date with every new version of a Windows
           | component? Are you going to ship parts of the macOS, or iOS
           | SDKs?
           | 
           | I don't see shipping all targets all the time to be a
           | particularly scalable solution in general. When you start
           | including all libraries necessary to develop actual apps, the
           | download size will eventually get so big that people will
           | complain. Just make it easy for developers to get the targets
           | they need, but don't ship everything by default.
        
             | slimsag wrote:
             | I'd argue it's less about what the compiler does by
             | default, but rather what it (and the community) enable.
             | 
             | For Mach (the Zig game engine I'm working on), I have a Zig
             | build script which fetches the required parts of the macOS
             | and iOS SDKs from GitHub to enable cross compilation from
             | Windows/Linux -> macOS. Zig's linker, zld, enables that to
             | work easily.[0]
             | 
             | For SDL.zig, they have also achieved cross compilation for
             | most targets out of the box[1].
             | 
             | Contrast this to say, Go or Rust, where most GLFW and SDL
             | bindings require mucking around with the system
             | dependencies. It doesn't just work out of the box, I think
             | that's really unfortunate and hope other languages work
             | more towards painless installation of C-binding
             | dependencies.
             | 
             | [0] https://twitter.com/slimsag/status/1413770578494775298
             | 
             | [1] https://github.com/MasterQ32/SDL.zig#support-matrix
        
             | p0nce wrote:
             | > Just make it easy for developers to get the targets they
             | need, but don't ship everything by default.
             | 
             | It seems to be what Flutter is doing, and it must be a ton
             | of work.
        
             | flohofwoe wrote:
             | I'd guess once Zig gets its package manager many target-
             | specific packages can move out of the default installation.
        
               | pcwalton wrote:
               | Absolutely, which is exactly what I'm arguing for. :)
        
           | flohofwoe wrote:
           | The Metal shader compiler is an unfortunate special case,
           | because the bytecode and the Metal compiler tools are
           | proprietary and locked up by Apple (there are precompiled
           | binaries of the Metal compiler for Windows, but not Linux).
           | The ball is definitely in Apple's court here, there's nothing
           | any language project can do, except illegally reverse
           | engineering Metal bytecode, which obviously isn't a good
           | idea.
           | 
           | The system API problem can be solved by shipping
           | automatically generated API bindings (similar to what
           | Microsoft does with the Rust bindings to the Windows APIs, a
           | similar project for Zig is underway). Once those bindings
           | exist, no Windows SDK is needed anymore and cross-compiling
           | should "just work".
           | 
           | PS: Zig actually ships with the mingw headers in the default
           | installation (e.g. windows.h, d3d11.h, dxgi.h etc are all
           | there), I haven't actually tried to cross-compile a Windows
           | executable using the Win32 APIs though, but it looks like it
           | should work already.
        
             | pcwalton wrote:
             | So does every new release of any Windows component require
             | a new version of Zig? That doesn't seem sustainable.
        
               | flohofwoe wrote:
               | I don't actually know what Windows components mingw
               | supports in detail and how often mingw is updated because
               | of that, but I guess that the important Win32 APIs are
               | stable. I suppose that the new APIs which are highly in
               | flux could be supported by separate packages, like this:
               | https://github.com/marlersoft/zigwin32)
        
             | kevin_thibedeau wrote:
             | > illegally reverse engineering Metal bytecode
             | 
             | Reverse engineering is legal in the US (unless bound by
             | contract).
        
           | zamadatix wrote:
           | I'm not sure what's really "missed", if you call a library
           | other than the stdlib of course you're going to need to
           | provide the appropriate headers/libraries for that as that's
           | got nothing to do with a C compiler.
        
             | pjmlp wrote:
             | In general, it isn't so clear when these kinds of examples
             | are posted.
             | 
             | And to go back to my examples, headers and libraries alone
             | won't make it, without the remaining toolchain to create
             | the appropriate package.
        
               | zamadatix wrote:
               | Well for your particular examples UWP is C++/C#/a few
               | others but it has no direct c binding and iOS APIs are
               | all defined for Objective-C and Swift so sure, you're not
               | going to get far with a C compiler before you even start
               | thinking about a c cross compiler.
               | 
               | If you want to cross compile C stuff e.g. a Win32 GUI app
               | with Direct X or get OpenGL bindings for SDL though those
               | all work just fine if you provide the SDK files same as
               | you would compiling natively. The advantage being now you
               | can do all builds from a single build instance just by
               | feeding it the libraries and a target platform.
        
         | skohan wrote:
         | I don't know much about cross compilation, but in terms of the
         | Rust case, could part of it be the relative complexity of the
         | language compared to Zig?
        
           | woogley wrote:
           | `zig cc` cross-compiles C, not Zig.
        
             | skohan wrote:
             | No but I mean why the Zig cross compilation story is better
             | than Rust according to this thread
        
               | steveklabnik wrote:
               | Nothing about 'zig cc' is related to language semantics,
               | it is entirely a toolchain feature. Language semantics do
               | have some bearing on cross compiler difficulty, but IMHO
               | it's not a major factor, especially within the sorts of
               | languages that Rust and Zig are. The largest factor I can
               | think of (compile-time code execution) exists in both Zig
               | and Rust. It's possible I'm forgetting something, though.
               | 
               | It doesn't exist in Rust because nobody has proposed it
               | or implemented it, simple as that.
        
               | sobeston wrote:
               | I think Zig does cross compilation (ignoring for the
               | moment, projects with C dependencies) better because it
               | comes out-of-the-box with the libraries and headers
               | needed to target a lot of systems. In Rust, you typically
               | get additional toolchains via rustup, whereas Zig works
               | on all of the targets with a single install.
        
               | steveklabnik wrote:
               | Absolutely, hence a toolchain thing.
        
               | pcwalton wrote:
               | Are you sure that we should be shipping all targets by
               | default into one monster download? This doesn't seem
               | particularly scalable.
        
               | steveklabnik wrote:
               | 100% sure? No. Mind you, I'm on MSVC, where I already
               | need an extra ~1gb download to get the system linker.
               | 
               | We could still do a few different things to make this
               | story better for users, even if it's not literally
               | identical.
        
               | coder543 wrote:
               | The whole toolchain for Zig, which appears to include
               | complete cross compilation, is less than 40MB
               | compressed[0]. I would _hardly_ call that a  "monster
               | download".
               | 
               | I think developers can spare that much space. Besides,
               | storage space is scaling much faster than the number of
               | available targets, so I don't see how this could be "not
               | particularly scalable" unless you either have a weird
               | definition of "target" or predict there's going to be a
               | sudden explosion in the number of targets.
               | 
               | Go also makes cross compilation to any supported target a
               | breeze in the default toolchain download, and it is an
               | incredible convenience for the developer.
               | 
               | [0]: https://ziglang.org/download/
        
               | pcwalton wrote:
               | The Xcode download, which is the only officially-
               | supported way to develop native apps on macOS and iOS, is
               | 9.8 GB and gets larger with every update. The Windows 10
               | SDK is 4 GB and likewise is only getting larger. Sure,
               | you can develop some apps with only a subset of the SDK.
               | But, as a language project, do you really want to be in
               | the business of optimizing and subsetting every single OS
               | SDK?
               | 
               | I think a lot of the issue here comes down to targeting
               | server workloads and command-line tools vs. apps using
               | more of the OS libraries. In practice, Go focuses on the
               | former kinds of apps, so shipping all targets is a more
               | viable approach for them. But when you start getting into
               | apps that want to use a larger swath of the platform
               | facilities, then the size of the platform SDKs starts to
               | become an issue.
        
               | coder543 wrote:
               | No one (that I've seen) is suggesting to include those
               | SDKs, which you probably don't even have the rights to
               | redistribute anyways.
               | 
               | I provided both Zig and Go as examples of what people are
               | looking for, and their downloads are neither obscenely
               | large nor do they include those massive SDKs.
               | 
               | So yes, you have a weird definition of "target" that no
               | one else here is using, and it is disingenuous for the
               | conversation. rustup can already add additional targets
               | after installation, are you suggesting this downloads
               | 10GB SDKs? Definitely not, and that sounds irrelevant.
               | (Even once you do this, the toolchain experience is not
               | as good as what Zig or Go offer.)
               | 
               | Compare what Zig and Go do to what Rust does, not some
               | strawman argument that would require users to download
               | 10GB of SDK with the Rust toolchain. Alternatively, find
               | me someone who is saying they think these multi-gigabyte
               | SDKs should be included, because I don't see that
               | _anywhere_ in this conversation.
               | 
               | People here are complimenting what Zig _currently_ does,
               | which takes less than 40MB compressed. Zig can cross
               | compile to Windows just fine. There are limitations to
               | everything, but what Zig and Go offer is strictly better
               | than what Rust offers in terms of the out-of-box cross
               | compilation experience, and it isn 't unduly burdensome
               | on the developers like your proposed 10GB download.
        
               | pcwalton wrote:
               | My nightly-x86_64-unknown-linux-gnu lib directory is
               | 148MB. This is because it includes several libraries in
               | both rlib and so format (static vs. dynamic linking),
               | asan/lsan/msan/tsan variants, and so forth. You could
               | easily imagine that ballooning to 1GB if we shipped all
               | tier 1 targets. This is what I mean by shipping all
               | targets not being scalable: it might have seemed so in
               | the early days when the libraries were smaller and the
               | targets fewer, but not now.
        
               | coder543 wrote:
               | Yes, the Zig (and Go) developers have clearly put a lot
               | of effort into ensuring the size of their toolchain
               | remains reasonable. I fully believe the Rust developers
               | could achieve similar results as well, if they really
               | wanted.
               | 
               | Until then, the lack of a great cross compilation
               | experience out of the box is just a limitation of the
               | Rust toolchain. It's an _acceptable_ limitation in many
               | situations, but I don 't buy your repeated arguments on
               | this HN discussion that it is unclear that this is
               | desirable to fix. Clearly many people in this discussion
               | alone disagree with your position, and my own anecdotal
               | discussions with other developers in real life aligns
               | with this discussion. YMMV, obviously.
        
               | pcwalton wrote:
               | > Yes, the Zig (and Go) developers have clearly put a lot
               | of effort into ensuring the size of their toolchain
               | remains reasonable. I fully believe the Rust developers
               | could achieve similar results as well, if they really
               | wanted.
               | 
               | I strongly disagree. These are different languages. Rust
               | leans heavily on generics and monomorphization. It
               | implements most language operations, like ptr::offset, in
               | the language itself, increasing the size of library
               | metadata. It supports tools like the sanitizers. It has a
               | rich serializable MIR format so that generics can be
               | embedded at a higher level than just machine code and a
               | lower level than source.
               | 
               | It is absolutely not true that nobody "really wants"
               | smaller binaries. Rust already did a fair bit of
               | experimentation with running crate metadata through gzip,
               | etc. years ago (turns out there are some thorny tradeoffs
               | around compilation time vs. on-disk storage when you go
               | that route). I can't speak to Zig, knowing less about it,
               | but with Go there were conscious _language_ design
               | decisions that favor binary size over runtime performance
               | (e.g. hash table lookups all going through a single
               | function instead of being specialized). This is fine! But
               | it 's contrary to the idea that Rust could achieve
               | smaller binary sizes if we "really" wanted to.
               | 
               | > Until then, the lack of a great cross compilation
               | experience out of the box is just a limitation of the
               | Rust toolchain.
               | 
               | Rust has a great cross-compilation experience. It's as
               | simple as:                   $ rustup target add arm-
               | linux-androideabi         $ cargo build --target=arm-
               | linux-androideabi
               | 
               | That's it. One more command than Zig or Go, to install
               | the toolchain you need, and then you're off to the races.
        
               | [deleted]
        
               | burntsushi wrote:
               | The difference is really not just one command. I suggest
               | you go out and actually try Zig cross compilation or at
               | least read more about it. Andrew Kelley has written a lot
               | about it. The work impressed me so much that it was one
               | of the things that provoked me to become a financial
               | supporter of Zig. (Even though I haven't written a line
               | of Zig yet.)
               | 
               | Cross compilation in Rust is better than C or C++. But
               | it's still a big pain.
               | 
               | I really think you are underestimating what the Zig folks
               | are doing. Please investigate more deeply.
               | 
               | In particular: "Zig does not ship with any pre-compiled
               | libraries; instead it ships with source code, and builds
               | what it needs on-the-fly."
        
               | coder543 wrote:
               | > That's it. One more command than Zig or Go, to install
               | the toolchain you need, and then you're off to the races.
               | 
               | Except it's not the same. Zig also cross-compiles C code
               | beautifully, and lots of Rust code depends on C
               | libraries. That "one additional command" does not solve
               | cross compilation to an equivalent degree as Zig.
               | 
               | Go code tends to avoid C because of the heavy penalty
               | that CGo imposes, so the cross compiliation experience is
               | usually good there, but for different reasons than Zig.
        
               | woogley wrote:
               | I see. I'll let the real experts add some insight but I
               | don't think language complexity has much to do with it,
               | considering Rust compiles to an IR first anyway. And I
               | would say Rust has a good cross-compilation story as it
               | is. In 2016 (!) I managed to get Rust to compile my SDL2
               | game to a mipsel device that used a custom GCC toolchain
               | (http://www.gcw-zero.com/develop)
        
         | wyldfire wrote:
         | > Compared to Zig, cross-compilation in C/C++/Rust seems
         | downright user-hostile:
         | 
         | This has been the status quo for so very long. Usually these
         | projects are maintained by different teams. IMO musl is more
         | accessible than glibc and that's part of what makes it easier
         | to distribute. Arm and x86 coexisting for as long as they have
         | is a factor, and so is Kelley's ambition to make this use case
         | well-supported. nostdlib is also well-supported by Zig btw.
        
         | vvanders wrote:
         | I would not include Rust in that list, in my experience rustup
         | and cargo are miles ahead of C/C++ when cross compiling.
        
           | [deleted]
        
           | [deleted]
        
           | steveklabnik wrote:
           | Personally, I see it in three tiers: Rust improved upon those
           | experiences, but I still wish someone would implement what
           | Zig has in rustc.
        
             | pcwalton wrote:
             | I don't. We could approximate it by shipping all targets by
             | default, but few really want that and the few who do can
             | just install those targets with rustup.
        
               | steveklabnik wrote:
               | Sure, like many things, I bet you could pick three or
               | four and get 90% of the default coverage. That still
               | helps 90% of the users.
               | 
               | I also think you're really missing out on the "compile C
               | code easily too" thing. That isn't very pleasant at all
               | in Rust today.
               | 
               | (Finally, one reason it's so big is that we ship
               | binaries. This ships source. std-aware cargo could really
               | help here.)
        
               | nicoburns wrote:
               | Is it really few who want that? Anybody developing server
               | software on windows or mac and deploying on linux could
               | use this. Anybody developing cross-platform client
               | software could use it.
               | 
               | I'd guess that a lot of Rust developers currently do
               | development on their target platform, but that's because
               | cross compiling is such a pain. If it were as easy as zig
               | or go then things might well be differen.
        
               | pcwalton wrote:
               | My x86_64 Rust libraries directory is 86MB. `rustup
               | target list | wc -l` spits out 84 for me. The math
               | doesn't add up.
        
             | vvanders wrote:
             | Yup, fully agreed Zig stands above others here. Cross
             | compiling C/C++ is just a special kind of hell. Each target
             | always has some sort of bespoke toolchain and build
             | environment constraint that add so much unneeded
             | complexity.
        
         | DrBazza wrote:
         | It's always a bit harsh comparing a 36 year old language with
         | more-or-less full backwards compatibility, with a new language
         | designed with the benefit of hindsight.
         | 
         | That's not to say that it's impossible to do something like
         | that in a C++ compiler but it's going to be more work than
         | there is benefit. Tangentially related:
         | https://twitter.com/__phantomderp/status/1416108650809241601
         | 
         | C++ also tries to bring in modern programming research when it
         | makes sense, but that also explains why it's like an octopus
         | with extra legs nailed on.
        
           | tialaramex wrote:
           | The octopus analogy seems especially appropriate. The thing
           | about the legs on an actual octopus is that there's a bunch
           | of local compute substrate in them, if you were to nail extra
           | legs onto the octopus those are _rubbish_ compared to its
           | real legs which can think.
           | 
           | For example, move semantics are a peg leg for the octopus.
           | Should an octopus have a peg leg? I'm not a biologist of any
           | sort, but my guess is "No". I can see why C++ wanted to add
           | move (without this performance in some scenarios is just
           | awful) and yet since C++ didn't start out having move
           | semantics and can't give up backward compatibility it has to
           | shoehorn them in with this awkward "hollowed out object"
           | idea. The result is performance still isn't where it could be
           | _and_ the feature is unergonomic.
        
         | zajio1am wrote:
         | > cross-compilation in C/C++/Rust seems downright user-hostile:
         | you have to obtain the correct cross-sdk, but it won't tell you
         | which one, or how to get it (some combos don't even exist), or
         | even where to put it.
         | 
         | Since advent of multiarch, crosscompilation does not seem
         | harder than regular compilation. Just install package with gcc
         | for target arch and required libraries for target arch (using
         | the same way as gcc and libraries for host arch).
        
         | sm_ts wrote:
         | I've had to compile only a few times C/++ programs, and the
         | experience can't be really compared to Rust (probably, to any
         | other language :)).
         | 
         | Lately I've cross-compiled a few times Linux/Windows programs,
         | and the only thing I had to do (assuming that the underlying
         | crates are compatible, and that the development libraries are
         | in place, which is required for any language) was:
         | rustup target add x86_64-pc-windows-gnu       rustup toolchain
         | install stable-x86_64-pc-windows-gnu
         | 
         | That's all. Then one can compile with:                 cargo
         | build --target x86_64-pc-windows-gnu
         | 
         | I've also compiled for RISC-V, and it was the same procedure.
         | 
         | There are surely issues with individual crates, and possibly
         | with lower-tier targets, but to characterize this procedure as
         | "user-hostile" doesn't make sense.
        
           | pornel wrote:
           | That's true only for static libraries and pure-Rust projects.
           | For executables and dynamic libraries Rust relies on system-
           | provided linker (except nightly that can enable lld) and
           | target libc already present on the OS (the nice part zig has,
           | but Rust doesn't).
           | 
           | Rust totally craps out if you try to make a binary or dylib
           | and you don't already have cross-compilation toolchain on
           | your OS. It's doable from a Linux distro that has cross
           | packages and a GNU target. It's a PITA for anything else,
           | including anything from Windows and macOS hosts.
           | 
           | `zig cc` is actually useful even for cross-compiling Rust
           | projects, because some Rust crates depend on C libraries.
        
       | WalterBright wrote:
       | D is taking a different approach. D is getting a builtin C
       | compiler (called ImportC) that is a from scratch C compiler, now
       | in prototype form.
       | 
       | https://dlang.org/spec/importc.html
       | 
       | It works by having an extra module called cparse.d
       | 
       | https://github.com/dlang/dmd/blob/master/src/dmd/cparse.d
       | 
       | which parses Standard C. The lexer and semantic routines of the D
       | compiler are then tweaked to support C semantics. The same
       | optimizer and code generator is used.
       | 
       | As a side effect of using the D compiler's innards, ImportC can
       | do things like handle forward references, and even execute C code
       | at compile time!
        
         | Quekid5 wrote:
         | This is getting super-weird, love it!
         | 
         | One assumes it is because C is so hard to rid ourselves of
         | because POSIX (etc) that you're even entertaining this idea?
         | 
         | I mean, "it's fun" could also work as motivation, I guess.
         | 
         | I'm just curious!
        
           | WalterBright wrote:
           | I admit it's been fun! My old C compiler (Datalight C) works
           | well, but its coding practices are severely outdated. I
           | wanted to see how it would look using modern practices.
           | 
           | P.S. I wouldn't be in the business if it wasn't fun.
        
           | mhh__ wrote:
           | A decent subset of D programmers have used C and have been
           | majorly bitten by it before, so it's definitely not a
           | marriage of love put it that way. ImportC is, in my view,
           | about optics and a little convenience - using C with D is
           | already trivial if you understand how C works, ImportC just
           | makes it offensively easy to do.
           | 
           | There are some less theoretical things too, i.e. no more
           | keeping kernel headers up to date (apart from ones that use
           | inline ASM that we have to be careful with).
           | 
           | With ImportC, D will be one of the better and non-hackier
           | ways to interface C with other languages - i.e. introspection
           | and metaprogramming but in a real language rather than some
           | brain-dead DSL
        
             | WalterBright wrote:
             | The reasons for ImportC are:
             | 
             | 1. It's no longer necessary to translate .h files to D to
             | interface with C. While doing the translations isn't hard,
             | it is tedious, and if there are a lot of .h files it
             | becomes a barrier.
             | 
             | 2. .h files get updated over time, and correspondingly
             | updating the D files is error prone. It's much more
             | effective to just compile the new .h files.
             | 
             | 3. It is not necessary to even create a .h file - just
             | compile the .c file with ImportC and D will access it just
             | like any other module. D will even inline the C functions
             | in it.
             | 
             | 4. Use it as a standalone, small and fast, C compiler.
        
         | msoucy wrote:
         | I miss playing with D. It looks like you've done a lot of neat
         | stuff recently, but I just don't have a project that I can use
         | it for. I remember being thoroughly impressed with its
         | metaprogramming capabilities in college when I was working on
         | dproto.
        
       | gus_massa wrote:
       | I don't understand the difference. Is "zig cc" more smart to find
       | included files than the other compilers?
        
         | wffurr wrote:
         | The article goes into great detail of the differences.
        
         | wyldfire wrote:
         | zig distributes critical stuff like C library headers and libs.
         | So it's not smarter, just more convenient. Built in support for
         | several OS/architecture combos.
        
           | notaplumber wrote:
           | Although as mentioned in the article, this won't work on
           | systems like *BSD, Solaris or macOS.
        
           | jlarocco wrote:
           | When you put it that way, this is an unfair comparison and
           | the downsides are more obvious.
           | 
           | With GCC and Clang, I only pay for cross compilation if I
           | need it, so for a fair comparison, the cross-compiler
           | libraries should be installed for GCC and Clang. Also with
           | GCC and Clang, I don't have to worry about a third party (the
           | Zig team) incorporating bug and security fixes from upstream.
           | And with GCC I get support for more platforms.
           | 
           | If I _have_ chosen to use cross-compilation, building for
           | alternative architectures is just as easy as for Zig.
        
           | azakai wrote:
           | In addition, zig cc uses a remarkable compile+cache
           | mechanism, which makes it possible to distribute a single
           | build that can be used to cross-compile anything. It will
           | cross-compile the necessary files as you need them,
           | transparently - without downloading a new toolchain for each
           | target, and quickly.
           | 
           | zig cc is really, really cool, and it's incredibly generous
           | that it provides zig's benefits to users of C and C++ as
           | well.
        
       ___________________________________________________________________
       (page generated 2021-07-18 23:01 UTC)