Subject: Re: [PATCH v3 01/14] build-system: Add mix-build-system.

From: Liliana Marie Prikler <[email-masked]>
Date: Thu, 16 Nov 2023 20:34:40 +0100

Am Donnerstag, dem 16.11.2023 um 19:12 +0100 schrieb Pierre-Henry
Fröhring:
> I should really configure mu4e or something like that.
> I'm curious to know if you have a pointer to an efficient setup for
> working through emails like this.
> Below the last three comments:
> 
> * WAITING Comment
> :PROPERTIES:
> :ID:       76abe0e4-a0e2-4176-bdc0-9ff241e8ba42
> :END:
> 
> ** lilyp
> > +(define (elixir-libdir elixir path)
> > +  "Return the path where all libraries for a specified ELIXIR
> > version are installed."
> > +  (string-append path "/lib/elixir/" (elixir-version elixir)))
> 
> You probably want to swap path and elixir and perhaps also find a way
> to implicitly parameterize the latter so as to make it optional.
> 
> 
> ** phf
> Is this what you mean?
> #+begin_src scheme
> ;; The Elixir version is constant as soon as it is computable from
> the current
> ;; execution. It is a X.Y string where X and Y are respectively the
> major and
> ;; minor version number of the Elixir used in the build.
> (define elixir-version (make-parameter "X.Y"))
> 
> (define* (elixir-libdir path #:optional (version (elixir-version)))
>   "Return the path where all libraries for a specified ELIXIR version
> are installed."
>   (string-append path "/lib/elixir/" version))
> 
> (define* (configure #:key inputs mix-path mix-exs #:allow-other-keys)
>   …
>   (elixir-version
>    (receive (_ version) (package-name->name+version (strip-store-
> file-name (assoc-ref inputs "elixir")))
>      (let* ((components  (string-split version #\.))
>             (major+minor (take components 2)))
>        (string-join major+minor ".")))))
> #+end_src
> 
> 
> ** lilyp
> I'd use %elixir-version.
> 
> 
> ** phf
> Parameters do not get reset when a function goes out of scope:
> #+begin_src scheme
> (define x (make-parameter 1))
> (define (set-x-to-2) (x 2))
> (format #t "~a~%" (x))
> (set-x-to-2)
> (format #t "~a~%" (x))
> #+end_src
> 
> #+begin_example
> 1
> 2
> #+end_example
> 
> The documentation seems to indicate that it's an appropriate
> replacement for a global variable.
It also uses the special parameterize thing to scope values.  That
being said, if parameters work for you, then parameters are fine.

> 
> * WAITING Comment** lilyp
> Is hex not an (implicit) native-input in your build system?  Anything
> that keeps it from functioning is a packaging bug imho.
> 
> 
> ** phf
> If ~mix~ finds ~Hex~ under ~$MIX_ARCHIVES/hex/hex~, then ~mix
> compile~ does not emit the message above. I'm not sure how could this
> be changed. I've tried to set ~MIX_PATH~ to ~/gnu/store/…-elixir-hex-
> 2.0.5/lib/elixir/1.14~ without
> success. So, this is the reason why ~install-hex~ phase installs Hex
> like it does.
Look into mix and how it invokes hex.  There's hardcoding potential,
I'm sure of it.

> * WAITING Comment
> ** lilyp
> > +  (define (install-inputs mix-env)
> > +    (for-each (cut install-input mix-env <>)
> > +              (append inputs native-inputs)))
> 
> Installing native inputs: probably a bad idea (inhibits cross-
> compilation).
> 
> 
> ** phf
> A slight variant that does not link things when it should not:
> #+begin_src scheme
> (define (install-inputs mix-env)
>     (for-each (cut install-input mix-env <>)
>               (cond
>                 ((string=? mix-env "prod") inputs)
>                 ((member mix-env '("shared" "test")) (append inputs
> native-inputs))
>                 (else (error (format #f "Unexpected Mix env: ~a~%"
> mix-env))))))
> #+end_src
> 
> I did not consider cross-compilation yet. The following might be
> wrong be here we go. I far as I understand, Erlang applications are
> largely platform independent. Once the code is compiled to BEAM
> bytecode, it can run on any platform that has the Erlang VM
> installed. If an Erlang library uses native extensions, then cross-
> compilation might be required. For a build to succeed
> in a given environment (one of "prod", "test", "shared"), the BEAM
> files of all dependencies should be present on the build machine. So,
> all dependencies must be installed
> 
> 
> ** lilyp
> Not an expert on elixir, but that sounds borked.
> 
> 
> ** phf
> Yes. Did not have time to look into it as of now.
> 
> 
> ** lilyp
> You might get around this with propagated-inputs maybe?  That being
> said, native-inputs shouldn't blow up a build if missing.
> 
> 
> ** phf
> If ~native-inputs~ are missing, it's fine. But wait, maybe there is a
> misunderstanding here. Please, check the reasoning: in a cross-
> compilation context, we have two machines A and B, and:
> - native-inputs: dependencies that must be built on A for A ;
> - inputs: dependencies that must be built on A for B ;
> - propagated-inputs: like inputs but installed in the profile.
> 
> 
> If installing Elixir (like Python) gathers all libraries in the
> profile with a variable like ~GUIX_ERL_LIBS~, then, it would be
> enough to list dependencies (in packages) in ~propagated-inputs~
> instead of ~inputs~ and make them available to Elixir through
> ~ERL_LIBS~ (like ~GUIX_PYTHONPATH~ and ~PYTHONPATH~).
> As a consequence, the ~install-dependencies~ phase would be reduced
> to ~ERL_LIBS=$GUIX_ERL_LIBS~.
> 
> Is this an answer to: "You might get around this with propagated-
> inputs maybe?"
If environment variables work, that is clearly to be preferred over any
other magic we've considered so far.  My hunch is that rebar-build-
system was written this way because environment variables didn't work,
however.  Same with Rust and Node, which are kinda yucky in this
regard.

Other than that, yes, (ab)using propagated-inputs like that is the way
to go when there's no smarter alternative available.

Cheers