Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

i'm following zig's project from HN and i often see cross-compilation and c/c++ mentionned.

Why is zig often mentionned in that context ? it seems that cross-compilation and C can be achieved using llvm/clang without a lot of problem ? What is zig accomplishing in that matter that makes it so special ?



Do you have experience cross compiling? If so, you’re likely familiar with the headache: getting the right tool chains, sysroots, compiler flags, libraries, etc. There are entire businesses and open source tools whose raison d'être is providing these tool chains and making the process simpler.

With Zig, that all goes away. It’s as simple as saying `zig build -Dtarget=aarch64-linux-gnu` or `zig build -Dtarget=riscv32-freestanding-none` and it just works. It’s pretty incredible.

Zig has set the bar for how cross compilation should be done and all other languages should be measured against it. Rust is close but is still a headache. The only other language that compares at the moment (IMO) is Go.


Huh. From what you said and then a quick peek at the docs Zig does seem great in that regard, but in my own experience I’ve definitely found Rust to be equally competent.

What about Zig would you say makes it better? Rust has `cargo build --target <triple>`


Cross compiling for the language itself is half of it, albeit a half Rust does decently well too, but Zig will also cross compile C/C++ for you just as easily. The latter part combined with Zig's focus on making it as 0 effort as possible to do either action is what results in it being talked about so much.


Admittedly I don’t have as much experience cross compiling with Rust, but my experience has not been so smooth. You need to install each target toolchain manually with rustup, and then some tool chains require different versions of Rust (e.g. the ESP32 RISC-V toolchain requires nightly). Another time I tried cross compiling on x86 Linux targeting Linux on ARM64, and I kept getting linking errors (or it couldn’t find an acceptable linker).

I certainly agree that Rust is much better than C/C++, but it’s not quite at Zig level, at least in my (limited) experience.


From what I've heard, for Rust the difficulty comes in when you're using a Rust wrapper of a C/C++ library and you need to crosscompile both into the binary.


I use Zig and cargo-zigbuild to cross-compile my Rust projects. It simply works, without Docker, if I want it to use older GLIBC symbols for an embedded Linux target running an ancient kernel/glibc version, or if I want to cross-compile to an M1 Mac from Linux. Of course, you still need to provide all the pkg-config/libraries/headers for the target platform, but that’s simple enough.


Best place to read more is probably on the Zig project website, specifically this section[1] on how/why Zig's compiler is also a C compiler and the benefits that provides.

[1] https://ziglang.org/learn/overview/#zig-is-also-a-c-compiler


So, I read that, and it is vague about whether the zig compiler itself compiles C, or whether it launches a C compiler (cc).

---

I will resist making the obvious reference despite having said both "launch" and "zig" in the same sentence.



The zig compiler itself (which is written in Zig) compiles C, `zig cc` just indicates to the zig compiler to parse C compiler options (`zig cc` has the same interface as Clang).


Here's the problem statement in a nutshell. Consider the following trivial C program:

    #include <stdio.h>
    #include <sys/random.h>
    int main(void) {
        unsigned char buf[10];
        ssize_t ret;
        ret = getrandom(buf, sizeof(buf), 0);
        if (ret != sizeof(buf))
            fprintf(stderr, "getrandom() failed\n");
        else
            fprintf(stderr, "getrandom() success\n");

        return ret != sizeof(buf);
    }
You have an x86_64 Linux machine running glibc 2.17. Your task is to compile the above program into a dynamically linked executable targeting glibc 2.28 on x86_64 Linux.

With Zig, it looks like this:

1) Download zig

2) `zig cc -target x86_64-linux-gnu.2.28 random.c`

What would those steps look like using llvm/clang?

Next, try doing it from Windows 8


It's simpler with clang.

  clang random.c
glibc 2.28 will work with binaries compiled against 2.17.


Unfortunately that won't compile against glibc 2.17 since getrandom(2) was only added to glibc in 2.25. See https://lwn.net/Articles/711013/ for background info,


nvm then


llvm/clang does not cross-compile "without a lot of problems". See this post from Zig's creator: https://andrewkelley.me/post/zig-cc-powerful-drop-in-replace...

zig cc uses clang under the hood, and Zig the language is also mostly based on LLVM, but zig cc ships a lot of versions of libc to ensure that it can properly compile to all platforms without weird linker errors.


TL;DR the hardest part of cross compilation is usually getting the tool gains set up to do so. Zig ships a bunch of libc's in a lightweight compressed format which makes cross compilation completely trivial, it handles most of the work behind the scenes.


How does it hande openssl ?


What do you mean? It can link against OpenSSL just like any other library. I don’t know if OpenSSL supports static builds, but if it does you can link it statically as well.


For cross compilation with dynamic linking I mean.

Openssl is typically one you want to be kept up to date with OS updates.

Like libc, it can be a pain.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: