guix-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: WIP: zig-build-system


From: Ekaitz Zarraga
Subject: Re: WIP: zig-build-system
Date: Tue, 20 Dec 2022 10:16:34 +0000

Hi Efraim and everyone,

> cross-compilation can come later. It's not uncommon when writing new
> build systems.

Great!

> > - The `zig` command uses a compiler to find the libc it needs to use
> > we should be able to remove the `gcc-toolchain` from the
> > dependencies if we just add the libc to the build system properly
> > (this point is mixed with the point above)
>
>
> Are you sure about removing gcc-toolchain? I don't have a problem with
> it if it is possible, especially since zig does provide a 'zig cc'
> command. We'd still likely need to use something like the
> make-gcc-toolchain to properly use ld-wrapper, unless we somehow
> wouldn't need that either.

I managed to remove it from the package descriptions because, as you said, it
comes with the gnu-build-system that I used as a base, but we still need to
(setenv "CC" "gcc") and I don't really like it because I think this will cause
problems in other usecases... Like cross-compilation.

I have to ask the Zig people (hello? Anyone?) about how important having a GCC
around is, maybe we can substitute that GCC call with something else that we
add to the build system. Simply finding the correct libc should be something we
can do.

I've found here and there that the Zig compiler supports a `--libc` argument
which receives a text file as an input, and they probably build that input from
the GCC command. I'm pretty sure that we can build that from our
zig-build-system directly, using scheme code. That way we could tweak it in the
future with no reliance on GCC, which is way more flexible.
Also, I don't like relying in GCC's output a lot because it's a supercomplex
package and it's hard to maintain/understand. If we can stay away from it,
better for everyone.

> Isn't gcc-toolchain part of %standard-packages in a build-system? Did I
> miss it not being there or does it also need to be added here for the
> reason you listed below?

True. Removed from the package as the build-system includes it.

> by default glibc is named 'libc' in the build system, and when
> cross-compiling 'libc' is generally the correct libc that you'd be
> looking for. Also I'd be curious about reusing the libc vendored in zig
> itself or if that's not actually possible/only for embedded uses.
>
> Also if you just need libc you could import glibc-final for the
> non-cross-build as a standard native-input (input?) and then you'd have
> it available.

I'm not sure if I understood this (which probably means I didn't). Can you give
me an example about how to use the `libc` in the build system?
I'm not used to the gexps yet and I don't find the best way to do this :S

The libc that comes with Zig we can use, but in that case we have to check the
system and all that so maybe it's better to leave it for the cross-compilation
step. Also, I'm not sure if it will affect reproducibility somehow?

> > + (add-before 'build 'set-env
> > + (lambda _
> > + (setenv "CC" "gcc"))))))
>
>
> If you really don't need gcc by default you could consider something
> like what we have in the cargo-build-system:
>
> (when (assoc-ref inputs "openssl")
> (setenv "OPENSSL_DIR" (assoc-ref inputs "openssl")))
>
> could be:
>
> (cond
> ((assoc-ref inputs "gcc") (setenv "CC" "gcc"))
> ((assoc-ref inputs "clang") (setenv "CC" "llvm"))
> (_ (setenv "CC" "zig cc")))

That's an accurate suggestion, but we need to solve first if we need to
actually use the external compiler or not. I need a Zig mentor for this :D

> > +(define (default-zig)
> > + "Return the default zig package."
> > + ;; Lazily resolve the binding to avoid a circular dependency.
> > + (let ((zig (resolve-interface '(gnu packages zig))))
> > + (module-ref zig 'zig)))
> > +
> > +(define %zig-build-system-modules
> > + ;; Build-side modules imported by default.
> > + `((guix build zig-build-system)
> > + (guix build syscalls)
> > + ,@%gnu-build-system-modules))
> > +
> > +(define* (zig-build name inputs
> > + #:key
> > + source
> > + (tests? #t)
> > + (test-target #f)
> > + (zig-build-flags ''())
>
>
> Is it possible to pass flags during the test phase also? If it is then
> having a zig-test-flags keyword would also be good.

I think it is! Good catch.

> I would also suggest a 'zig' flag, to allow choosing a different zig
> binary to be used for a build.

Done.

> I would define a global-cache-dir and use ZIG_GLOBAL_CACHE_DIR to refer
> to it and not pass it around to all the phases.

I don't know if I understood what you mean, check the new patch set please and
confirm.

> > + "-p" "" ;; Don't add /usr
>
> If '-p' is the short form of '--prefix' or something then use the long
> form.

Done

> cmake-build-system has an option to determine Release or Debug (or to
> leave it as RelWithDebInfo) named 'build-type'. I think that should be
> added here.

I did something similar, check please if you like it.

> I assume this is to prevent overwriting the actual binary with the tests
> enabled binary? I would consider unsetting it at the end of the phase.
> Or storing its previous value and setting it back to that, we have seen
> packages which use DESTDIR and I wouldn't want any surprises.

Good, applied.

> > + (apply invoke
> > + `("zig" "build" "test"
> > + "--global-cache-dir" "zig-cache"))))
>
> What's the difference between 'zig test build.zig' and 'zig build test'?

I'll give you a really naïve answer: in my computer the second works and the
first doesn't.

> Beware of copy-pasting :). You don't use inputs, don't need let* vs let,
> and could probably directly (copy-recursively #$output out). Or rely on
> 'make install'. 'make install' was available for ncdu2, not sure about
> other zig projects.

Make install won't be available generally, but yeah, I got you.
Should this install phase be something like:
`(map (lambda (out) (copy-recursively (car out) (cdr out))) outputs)`

Maybe this allows an easier way to generate outputs? Or should we just rely on
the packages themselves to define a better install phase than this?
I mean, if we have just this phase, any package that needs to install docs,
just adding a `doc` output and leaving its contents in a `/doc` folder should
work... IDK

Attachment: 0001-WIP-Add-a-zig-build-system.patch
Description: Text Data

Attachment: 0002-Add-a-sample-package-for-testing-the-zig-build-syste.patch
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]