From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mp12.migadu.com ([2001:41d0:303:e16b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by ms8.migadu.com with LMTPS id uBJgFukSVmUYwQAAauVa8A:P1 (envelope-from ) for ; Thu, 16 Nov 2023 14:02:33 +0100 Received: from aspmx1.migadu.com ([2001:41d0:303:e16b::]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) by mp12.migadu.com with LMTPS id uBJgFukSVmUYwQAAauVa8A (envelope-from ) for ; Thu, 16 Nov 2023 14:02:33 +0100 Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by aspmx1.migadu.com (Postfix) with ESMTPS id 1757446FDF for ; Thu, 16 Nov 2023 14:02:33 +0100 (CET) Authentication-Results: aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=deeplinks-com.20230601.gappssmtp.com header.s=20230601 header.b=vaFW2ylU; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org"; dmarc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=yhetil.org; s=key1; t=1700139753; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:resent-cc:resent-from:resent-sender: resent-message-id:in-reply-to:in-reply-to:references:references: list-id:list-help:list-unsubscribe:list-subscribe:list-post: dkim-signature; bh=clWaBmZLWcwgjEAQJk4y/0v7JscOtdL0nSn+8vqfbt4=; b=JQiydFbu02/iK9IgCQpNlDivPWc+LuZhmlbelzP3OW+5G0CPpyle51ghbDzL/pwCJvTQBO 4234RMjY6x4Y8cy6ILawQinmOFPMSTW1EBZXM741ifX//1JNWN3bb7b78IDztAszbUJO/r cmehKUW+ZdUGIE8wPDsWTrHgmrIQipU4VxG9thZ/MpQGQ+2lwvNTFBV3+Zg5DdehatQEpo pzkKTyy4CKj1Q8KLQ9uYDCcRcTQgHmyorcKVBQ+075os+i5Sr7MI6sXOrpjpRZv7C0+uIW knCIPYxkb85GqxCWXtqsJCcJ7G3Q4mIEG/Xm9MYTodMkkBrxq3SBE4ePf1eWlQ== ARC-Authentication-Results: i=1; aspmx1.migadu.com; dkim=fail ("headers rsa verify failed") header.d=deeplinks-com.20230601.gappssmtp.com header.s=20230601 header.b=vaFW2ylU; spf=pass (aspmx1.migadu.com: domain of "guix-patches-bounces+larch=yhetil.org@gnu.org" designates 209.51.188.17 as permitted sender) smtp.mailfrom="guix-patches-bounces+larch=yhetil.org@gnu.org"; dmarc=none ARC-Seal: i=1; s=key1; d=yhetil.org; t=1700139753; a=rsa-sha256; cv=none; b=sKu4mWVarQRSIIXjiea8yLVfGy4u/paYBfZO0bfPpZGTX5jbGWgemJCrCtXp2pmYxr3FjJ mOeGgMK7WGegQ858ZEcjQdmA8V6hnci/thgsGP9LrVKKcQc5oKE0DApOydi3af//XI6lvC 8pfkTlpru1Gz6z/6RtLFFvHGXSVmUKtLgPIiWBetLU3WpPORbiwj8QtHZXai0xT0CGbAwh XsV2wekuGiXZNJMFGyopqxZOW7DSPNYppIRmXISz7RncG6QCvobrVgkRJQt1eFxNydnYXb Qf82dWc7MhExwbiuT1QSPBBfBdP9J02H91Ep62T4iy0DIO5UeHMyF96+JxcEDw== Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1r3c0k-00010q-FE; Thu, 16 Nov 2023 08:02:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1r3c0R-0000rE-5y for guix-patches@gnu.org; Thu, 16 Nov 2023 08:02:10 -0500 Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1r3c0Q-000896-MY for guix-patches@gnu.org; Thu, 16 Nov 2023 08:02:02 -0500 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1r3c0Q-0002fF-0q for guix-patches@gnu.org; Thu, 16 Nov 2023 08:02:02 -0500 X-Loop: help-debbugs@gnu.org Subject: [bug#66801] [PATCH v3 01/14] build-system: Add mix-build-system. Resent-From: Pierre-Henry =?UTF-8?Q?Fr=C3=B6hring?= Original-Sender: "Debbugs-submit" Resent-CC: guix-patches@gnu.org Resent-Date: Thu, 16 Nov 2023 13:02:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 66801 X-GNU-PR-Package: guix-patches X-GNU-PR-Keywords: patch To: 66801@debbugs.gnu.org Cc: Liliana Marie Prikler Received: via spool by 66801-submit@debbugs.gnu.org id=B66801.170013971710220 (code B ref 66801); Thu, 16 Nov 2023 13:02:01 +0000 Received: (at 66801) by debbugs.gnu.org; 16 Nov 2023 13:01:57 +0000 Received: from localhost ([127.0.0.1]:54717 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1r3c0K-0002ek-7H for submit@debbugs.gnu.org; Thu, 16 Nov 2023 08:01:57 -0500 Received: from mail-oi1-x22e.google.com ([2607:f8b0:4864:20::22e]:52465) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1r3c0H-0002eS-GS for 66801@debbugs.gnu.org; Thu, 16 Nov 2023 08:01:54 -0500 Received: by mail-oi1-x22e.google.com with SMTP id 5614622812f47-3b566ee5f1dso440308b6e.0 for <66801@debbugs.gnu.org>; Thu, 16 Nov 2023 05:01:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=deeplinks-com.20230601.gappssmtp.com; s=20230601; t=1700139708; x=1700744508; darn=debbugs.gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=clWaBmZLWcwgjEAQJk4y/0v7JscOtdL0nSn+8vqfbt4=; b=vaFW2ylUASvbeEWtBtAfwXRf0clVPQXaT0lhMPrBZcjBXidyRy9lM6+8iB18E/qWdm MGnQOcz3ykfNxxBqlHppSStopzFki8laEwJQY7+uCOSyb6pYR3/BxOAVERqxcUp1m7Lz Vrex2Ivg6XRusj+lyZZxNb5jqmFxQV9wklqwJ3A9FLhm7TRmJkknLCB5keVTau9SttWb 88igWXh3zzztTN6pTodWJtuvhqA9g6PilqgpGRw3jGjwTE230NnF8XgkC2HTn7NhfUCA xD4Iri2neVjCfgh1Fz7MTn+ilCZ9/z1Inbvt5YKh/lqNEAIV9ybGinmxEVSaJ90VRIJH bFfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700139708; x=1700744508; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=clWaBmZLWcwgjEAQJk4y/0v7JscOtdL0nSn+8vqfbt4=; b=RSaCppKVS0nfpL9i00pwmqe+6Kjzz+Khdm5aQ67dNdrclDlbKHcu4Z6P13viiWeeyR zOW1pEG8nZG7uVbd2MPw9T7zfcag1wbg5NaMvOXS0izHmF9ydseIXqmrlVSvydhQmCXv 4k6i4+DKdsdV/3f5hFwMvWX0I2qq2MKQyBed6/jkmjp+B5cgXP66qLrpnUSxsA7uU5d0 vVvMuhDP51X+SWiF+9bPNj/fB7Icfq2NIRTHEJ4GsKCGYW69LicmwK4bpSKJCbRZjLdA 8mX7Mv3chwBK/uD/32/Lw1MaMlrIAr6O4KVPJctgTeLnCAlI7h3QGR9WVFJkXMXwR2Nm TkGQ== X-Gm-Message-State: AOJu0Yxc30QudsrPtNYmgVxBEyk42SpxWM3eQ3gAZqXKNd2Ol6KfQiQX oFl/RAmmjpDvK2CQQL1GNIg32ZnEPaD6YII2/CPCYLtAiGLePl7MRCY= X-Google-Smtp-Source: AGHT+IG+hKG4NwZnE+TBShd2euLNj8u7vGSXMH2zY2RglZj0B72TROiv7ayx2sfBiwKKrOfmOZNE3dH0fK85q320kIg= X-Received: by 2002:a05:6808:208:b0:398:5d57:3d08 with SMTP id l8-20020a056808020800b003985d573d08mr16158865oie.37.1700139707781; Thu, 16 Nov 2023 05:01:47 -0800 (PST) MIME-Version: 1.0 References: <67c324d191a9698aed8d9887260cb0ef2bc031df.1700088189.git.phfrohring@deeplinks.com> In-Reply-To: From: Pierre-Henry =?UTF-8?Q?Fr=C3=B6hring?= Date: Thu, 16 Nov 2023 14:01:36 +0100 Message-ID: Content-Type: multipart/alternative; boundary="00000000000059e84d060a449fdf" X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: guix-patches@gnu.org List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+larch=yhetil.org@gnu.org Sender: guix-patches-bounces+larch=yhetil.org@gnu.org X-Migadu-Flow: FLOW_IN X-Migadu-Country: US X-Migadu-Spam-Score: -2.09 X-Spam-Score: -2.09 X-Migadu-Queue-Id: 1757446FDF X-Migadu-Scanner: mx13.migadu.com X-TUID: 1NrMHwyFnO0U --00000000000059e84d060a449fdf Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Do you mind if I paste the conversation using the following org format? * Comment ** lilyp > +(define (elixir-version elixir) > + "Return an X.Y string where X and Y are respectively the major and > minor version number of ELIXIR. > +Example: /gnu/store/=E2=80=A6-elixir-1.14.0 =E2=86=92 1.14" > + ((compose > + (cut string-join <> ".") > + (cut take <> 2) > + (cut string-split <> #\.) > + last) > + (string-split elixir #\-))) I don't think we need to be overly cute here. The let-binding version from python-build-system is less surprising to the uninitiated reader. See also strip-store-file-name and package-name->name+version. ** phf Maybe: #+begin_src scheme (define (elixir-version elixir) "Return an X.Y string where X and Y are respectively the major and minor version number of ELIXIR. Example: /gnu/store/=E2=80=A6-elixir-1.14.0 =E2=86=92 1.14" (receive (_ version) (package-name->name+version (strip-store-file-name elixir)) (let* ((components (string-split version #\.)) (major+minor (take components 2))) (string-join major+minor ".")))) #+end_src or: #+begin_src scheme (define (elixir-version elixir) "Return an X.Y string where X and Y are respectively the major and minor version number of ELIXIR. Example: /gnu/store/=E2=80=A6-elixir-1.14.0 =E2=86=92 1.14" (let* ((version (last (string-split elixir #\-))) (components (string-split version #\.)) (major+minor (take components 2))) (string-join major+minor "."))) #+end_src or: just inline the code as it is used just once. See [[id:76abe0e4-a0e2-4176-bdc0-9ff241e8ba42][next comment]]. * 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) =E2=80=A6 (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 * Comment ** lilyp > +(define* (configure #:key inputs mix-path mix-exs #:allow-other- > keys) > + "Set environment variables. > +See: > https://hexdocs.pm/mix/1.15.7/Mix.html#module-environment-variables" > + (setenv "LC_ALL" "en_US.UTF-8") > + (setenv "MIX_HOME" (getcwd)) > + (setenv "MIX_ARCHIVES" "archives") > + (setenv "MIX_BUILD_ROOT" "_build") > + (setenv "MIX_DEPS_PATH" "deps") > + (setenv "MIX_PATH" (or mix-path "")) > + (setenv "MIX_REBAR3" (string-append (assoc-ref inputs "rebar3") > "/bin/rebar3")) > + (setenv "MIX_EXS" mix-exs)) This does not appear to be a configure phase in the traditional sense of the wording. Instead, it should be a post 'set-paths' 'set-mix-env' imho. ** phf After ~install-locale~ since ~(setenv "LC_ALL" "en_US.UTF-8")~ is called in this phase. #+begin_src scheme (define %standard-phases (modify-phases gnu:%standard-phases =E2=80=A6 (delete 'configure) (add-after 'install-locale 'set-mix-env set-mix-env) (replace 'unpack unpack) =E2=80=A6)) #+end_src * Comment ** lilyp > +(define* (install-hex #:key name inputs outputs #:allow-other-keys) > + "Install Hex." > + (let ((hex-archive-path (string-append (getenv "MIX_ARCHIVES") > "/hex"))) > + (mkdir-p hex-archive-path) > + (symlink (car (list-directories (elixir-libdir (assoc-ref inputs > "elixir") > + (assoc-ref inputs > "elixir-hex")))) > + (string-append hex-archive-path "/hex")))) Why do we need this? It looks like we'll be pasting the same (native?) input all over the store, which imho would be bad. ** phf Without ~Hex~, you get this error: #+begin_example starting phase `build' Could not find Hex, which is needed to build dependency :ex_doc Shall I install Hex? (if running non-interactively, use "mix local.hex --force") [Yn] #+end_example This message is called from ~handle_rebar_not_found~ in ~lib/mix/lib/mix/tasks/deps.compile.ex~ ; which is called from ~rebar_cmd~ because a ~manager~ (~Hex~) could not be found. Hex must be present =3D> install-he= x must be executed. I thought that this should not be a problem since Hex is needed at build time, and just symlinked. Maybe should it be copied instead? * Comment ** lilyp > + (define (install-input mix-env input) > + (let ((dir (mix-build-dir mix-env))) > + (mkdir-p dir) > + (match input > + ((_ . path) > + ((compose > + (cut for-each (cut install-lib <> dir) <>) > + (cut append-map list-directories <>) > + (cut filter directory-exists? <>)) > + (list (elixir-libdir (assoc-ref inputs "elixir") path) > + (erlang-libdir path))))))) I think you're at the wrong layer of abstraction here. (match input ((_ . prefix) (begin (install-subdirectories (elixir-libdir path)) (install-subdirectories (erlang-libdir path))))) where (install-subdirectories PATH) is basically (when (directory-exists? PATH) (for-each (cute install-lib <> (mix-build-dir mix-env)) (list-directories PATH))) ** phf Does this work? #+begin_src scheme (define (install-lib lib dir) (let ((lib-name (last (string-split lib #\/)))) (symlink lib (string-append dir "/" lib-name)))) (define (install-subdirectories mix-env path) (let ((build-dir (mix-build-dir mix-env))) (mkdir-p build-dir) (when (directory-exists? path) (for-each (cute install-lib <> build-dir) (list-directories path))))) (define (install-input mix-env input) (match input ((_ . path) (begin (install-subdirectories mix-env (elixir-libdir path)) (install-subdirectories mix-env (erlang-libdir path)))))) #+end_src * 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=3D? 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 succee= d 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 * Comment ** lilyp > +(define (library-name pkg-name) > + "Return the library name deduced from PKG-NAME. > +A package should be named: elixir-lib-name-X.Y.Z from which the > library name > +lib_name is deduced." > + ((compose > + (cut string-join <> "_") > + (cut drop-right <> 1) > + (cut string-split <> #\-)) > + (strip-elixir-prefix pkg-name))) Consider defining (package-name-version->elixir-name) analogous to (package-name-version->erlang-name) in rebar-build-system. Also allow overriding it through a build system argument. The thing you currently have will blow up with git-version. ** phf Faily close to the ~rebar-build-system~ version. #+begin_src scheme (define (package-name-version->elixir-name name+ver) "Convert the Guix package NAME-VER to the corresponding Elixir name-version format. Essentially drop the prefix used in Guix and replace dashes by underscores." (let* ((name- (package-name->name+version name+ver))) (string-join (string-split (if (string-prefix? "elixir-" name-) (string-drop name- (string-length "elixir-")) name-) #\-) "_"))) #+end_src --00000000000059e84d060a449fdf Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Do you mind if I paste the conversation using the followin= g org format?

* Comment
** lilyp
> +(define (el= ixir-version elixir)
> + =C2=A0"Return an X.Y string where X and= Y are respectively the major and
> minor version number of ELIXIR.> +Example: /gnu/store/=E2=80=A6-elixir-1.14.0 =E2=86=92 1.14"> + =C2=A0((compose
> + =C2=A0 =C2=A0(cut string-join <> &q= uot;.")
> + =C2=A0 =C2=A0(cut take <> 2)
> + =C2=A0 = =C2=A0(cut string-split <> #\.)
> + =C2=A0 =C2=A0last)
> = + =C2=A0 (string-split elixir #\-)))

I don't think we need to be= overly cute here.=C2=A0 The let-binding version
from python-build-syste= m is less surprising to the uninitiated reader.

See also strip-store= -file-name and package-name->name+version.


** phf
Maybe:#+begin_src scheme
(define (elixir-version elixir)
=C2=A0 "Ret= urn an X.Y string where X and Y are respectively the major and minor versio= n number of ELIXIR.
Example: /gnu/store/=E2=80=A6-elixir-1.14.0 =E2=86= =92 1.14"
=C2=A0 (receive (_ version) (package-name->name+versio= n (strip-store-file-name elixir))
=C2=A0 =C2=A0 (let* ((components =C2= =A0(string-split version #\.))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= (major+minor (take components 2)))
=C2=A0 =C2=A0 =C2=A0 (string-join maj= or+minor "."))))
#+end_src

or:
#+begin_src scheme(define (elixir-version elixir)
=C2=A0 "Return an X.Y string where= X and Y are respectively the major and minor version number of ELIXIR.
= Example: /gnu/store/=E2=80=A6-elixir-1.14.0 =E2=86=92 1.14"
=C2=A0 = (let* ((version =C2=A0 =C2=A0 (last (string-split elixir #\-)))
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(components =C2=A0(string-split version #\.))=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(major+minor (take components 2)))
= =C2=A0 =C2=A0 (string-join major+minor ".")))
#+end_src
or: just inline the code as it is used just once. See [[id:76abe0e4-a0e2-4= 176-bdc0-9ff241e8ba42][next comment]].


* Comment
:PROPERTIES:=
:ID: =C2=A0 =C2=A0 =C2=A0 76abe0e4-a0e2-4176-bdc0-9ff241e8ba42
:END:=

** lilyp
> +(define (elixir-libdir elixir path)
> + =C2= =A0"Return the path where all libraries for a specified ELIXIR
>= version are installed."
> + =C2=A0(string-append path "/li= b/elixir/" (elixir-version elixir)))

You probably want to swap = path and elixir and perhaps also find a way
to implicitly parameterize t= he 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 wher= e 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)))
=C2=A0 "Return the path where all libraries for a specif= ied ELIXIR version are installed."
=C2=A0 (string-append path "= ;/lib/elixir/" version))

(define* (configure #:key inputs mix-p= ath mix-exs #:allow-other-keys)
=C2=A0 =E2=80=A6
=C2=A0 (elixir-versi= on
=C2=A0 =C2=A0(receive (_ version) (package-name->name+version (str= ip-store-file-name (assoc-ref inputs "elixir")))
=C2=A0 =C2=A0= =C2=A0(let* ((components =C2=A0(string-split version #\.))
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (major+minor (take components 2)))
=C2= =A0 =C2=A0 =C2=A0 =C2=A0(string-join major+minor ".")))))
#+en= d_src


* Comment
** lilyp
> +(define* (configure #:key i= nputs mix-path mix-exs #:allow-other-
> keys)
> + =C2=A0"S= et environment variables.
> +See:
> https://hexdocs.pm/mix= /1.15.7/Mix.html#module-environment-variables"
> + =C2=A0(se= tenv "LC_ALL" "en_US.UTF-8")
> + =C2=A0(setenv &q= uot;MIX_HOME" (getcwd))
> + =C2=A0(setenv "MIX_ARCHIVES&quo= t; "archives")
> + =C2=A0(setenv "MIX_BUILD_ROOT"= "_build")
> + =C2=A0(setenv "MIX_DEPS_PATH" &quo= t;deps")
> + =C2=A0(setenv "MIX_PATH" (or mix-path &qu= ot;"))
> + =C2=A0(setenv "MIX_REBAR3" (string-append (= assoc-ref inputs "rebar3")
> "/bin/rebar3"))
&= gt; + =C2=A0(setenv "MIX_EXS" mix-exs))

This does not appe= ar to be a configure phase in the traditional sense
of the wording.=C2= =A0 Instead, it should be a post 'set-paths' 'set-mix-env'<= br>imho.


** phf
After ~install-locale~ since ~(setenv "L= C_ALL" "en_US.UTF-8")~ is called in this
phase.
#+begi= n_src scheme
(define %standard-phases
=C2=A0 (modify-phases gnu:%stan= dard-phases
=C2=A0 =C2=A0 =E2=80=A6
=C2=A0 =C2=A0 (delete 'config= ure)
=C2=A0 =C2=A0 (add-after 'install-locale 'set-mix-env set-m= ix-env)
=C2=A0 =C2=A0 (replace 'unpack unpack)
=C2=A0 =C2=A0 =E2= =80=A6))
#+end_src


* Comment
** lilyp
> +(define* (i= nstall-hex #:key name inputs outputs #:allow-other-keys)
> + =C2=A0&q= uot;Install Hex."
> + =C2=A0(let ((hex-archive-path (string-appe= nd (getenv "MIX_ARCHIVES")
> "/hex")))
> + = =C2=A0 =C2=A0(mkdir-p hex-archive-path)
> + =C2=A0 =C2=A0(symlink (ca= r (list-directories (elixir-libdir (assoc-ref inputs
> "elixir&q= uot;)
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (assoc-ref inputs
> "e= lixir-hex"))))
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (st= ring-append hex-archive-path "/hex"))))

Why do we need thi= s?=C2=A0 It looks like we'll be pasting the same (native?)
input all= over the store, which imho would be bad.


** phf
Without ~Hex= ~, you get this error:
#+begin_example
starting phase `build'
= Could not find Hex, which is needed to build dependency :ex_doc
Shall I = install Hex? (if running non-interactively, use "mix local.hex --force= ") [Yn]
#+end_example
This message is called from ~handle_rebar_= not_found~ in
~lib/mix/lib/mix/tasks/deps.compile.ex~ ; which is called = from ~rebar_cmd~ because
a ~manager~ (~Hex~) could not be found. Hex mus= t be present =3D> install-hex must be
executed.

I thought that= this should not be a problem since Hex is needed at build time,
and jus= t symlinked. Maybe should it be copied instead?


* Comment
** = lilyp
> + =C2=A0(define (install-input mix-env input)
> + =C2= =A0 =C2=A0(let ((dir (mix-build-dir mix-env)))
> + =C2=A0 =C2=A0 =C2= =A0(mkdir-p dir)
> + =C2=A0 =C2=A0 =C2=A0(match input
> + =C2= =A0 =C2=A0 =C2=A0 =C2=A0((_ . path)
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 (= (compose
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (cut for-each (cut in= stall-lib <> dir) <>)
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (cut append-map list-directories <>)
> + =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 (cut filter directory-exists? <>))
> + =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0(list (elixir-libdir (assoc-ref inputs "el= ixir") path)
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(erlang-libdir path)))))))

I think you're at the wrong= layer of abstraction here.

=C2=A0 (match input
=C2=A0 =C2=A0 ((_= . prefix)
=C2=A0 =C2=A0 =C2=A0(begin
=C2=A0 =C2=A0 =C2=A0 (install-s= ubdirectories (elixir-libdir path))
=C2=A0 =C2=A0 =C2=A0 (install-subdir= ectories (erlang-libdir path)))))

where (install-subdirectories PATH= ) is basically
=C2=A0 (when (directory-exists? PATH)
=C2=A0 =C2=A0 (f= or-each (cute install-lib <> (mix-build-dir mix-env))
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list-directories PATH)))

** phf
Does this work?
#+begin_src scheme
(define (install-lib li= b dir)
=C2=A0 =C2=A0 (let ((lib-name (last (string-split lib #\/))))
= =C2=A0 =C2=A0 =C2=A0 (symlink lib (string-append dir "/" lib-name= ))))

=C2=A0 (define (install-subdirectories mix-env path)
=C2=A0 = =C2=A0 (let ((build-dir (mix-build-dir mix-env)))
=C2=A0 =C2=A0 =C2=A0 (= mkdir-p build-dir)
=C2=A0 =C2=A0 =C2=A0 (when (directory-exists? path)=C2=A0 =C2=A0 =C2=A0 =C2=A0 (for-each (cute install-lib <> build-di= r)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (list-= directories path)))))

=C2=A0 (define (install-input mix-env input)=C2=A0 =C2=A0 (match input
=C2=A0 =C2=A0 =C2=A0 ((_ . path)
=C2=A0 = =C2=A0 =C2=A0 =C2=A0(begin
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(install-su= bdirectories mix-env (elixir-libdir path))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0(install-subdirectories mix-env (erlang-libdir path))))))
#+end_sr= c


* Comment
** lilyp
> + =C2=A0(define (install-inputs = mix-env)
> + =C2=A0 =C2=A0(for-each (cut install-input mix-env <&g= t;)
> + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(append input= s native-inputs)))

Installing native inputs: probably a bad idea (in= hibits cross-
compilation).


** phf
A slight variant that d= oes not link things when it should not:
#+begin_src scheme
(define (i= nstall-inputs mix-env)
=C2=A0 =C2=A0 (for-each (cut install-input mix-en= v <>)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (cond
= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 ((string=3D? mix-en= v "prod") inputs)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 ((member mix-env '("shared" "test")) = (append inputs native-inputs))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 (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, Erl= ang applications are largely platform
independent. Once the code is comp= iled to BEAM bytecode, it can run on any
platform that has the Erlang VM= installed. If an Erlang library uses native
extensions, then cross-comp= ilation 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, al= l dependencies
must be installed


* Comment
** lilyp
>= ; +(define (library-name pkg-name)
> + =C2=A0"Return the library= name deduced from PKG-NAME.
> +A package should be named: elixir-lib= -name-X.Y.Z from which the
> library name
> +lib_name is deduce= d."
> + =C2=A0((compose
> + =C2=A0 =C2=A0(cut string-join = <> "_")
> + =C2=A0 =C2=A0(cut drop-right <> 1)<= br>> + =C2=A0 =C2=A0(cut string-split <> #\-))
> + =C2=A0 (s= trip-elixir-prefix pkg-name)))

Consider defining (package-name-versi= on->elixir-name) analogous to
(package-name-version->erlang-name) = in rebar-build-system.=C2=A0 Also allow
overriding it through a build sy= stem argument.=C2=A0 The thing you currently
have will blow up with git-= version.


** phf
Faily close to the ~rebar-build-system~ versi= on.
#+begin_src scheme
(define (package-name-version->elixir-name = name+ver)
=C2=A0 "Convert the Guix package NAME-VER to the correspo= nding Elixir name-version
format.=C2=A0 Essentially drop the prefix used= in Guix and replace dashes by
underscores."
=C2=A0 (let* ((name= - (package-name->name+version name+ver)))
=C2=A0 =C2=A0 (string-join<= br>=C2=A0 =C2=A0 =C2=A0(string-split
=C2=A0 =C2=A0 =C2=A0 (if (string-pr= efix? "elixir-" name-)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (str= ing-drop name- (string-length "elixir-"))
=C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 name-)
=C2=A0 =C2=A0 =C2=A0 #\-)
=C2=A0 =C2=A0 =C2=A0&= quot;_")))
#+end_src
--00000000000059e84d060a449fdf--