help-guix
[Top][All Lists]
Advanced

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

Re: Help defining a trivial package.


From: Pierre-Henry F.
Subject: Re: Help defining a trivial package.
Date: Wed, 04 Sep 2019 11:21:41 +0000

> import os, shutil, stat, subprocess, guix.build.utils
>
> # Unpack
> source = _build_inputs["source"]
> tar = _build_inputs["tar"]
> lzip = _build_inputs["lzip"]
> os.putenv("PATH", ":".join([tar + "/bin", lzip + "/bin"]))
> subprocess.run(["tar", "--lzip", "-xvf", source])
>
> # Configure
> bash = _build_inputs["bash"]
> python = _build_inputs["python"]
> guix.build.utils.substitute("blog/bin/program",
> [["/usr/bin/bash", bash + "/bin/bash"],
> ["python3", python + "/bin/python3"]])
>
> # Install
> out = _outputs["out"]
> os.chmod("blog/bin/program", 0o755)
> shutil.copytree("blog", out)

Excellent!

It's exactly how I understand the thing now (same approach to understanding as 
in
SICP and CTM :-) )

I rebuild the package (Attachment: blog_v2.scm) you gave me and added traces so 
it gives this when
you execute the thing:

    phf@f02c:~/programs/blog/guix$ guix build --keep-failed --verbosity=2 
--file=./blog_v2.scm
    substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%
    building /gnu/store/yhmlzaa07rp324nkc888rbacw7yfarsc-blog-3.drv...
    blog/bin/
    blog/bin/program
    blog/src/
    blog/src/hello_world.py

    Start of build expression execution

    Show inputs
      %build-inputs = (
        (lzip . /gnu/store/2kwysbg8f175gmqmsd5kjggmy6hvxi5k-lzip-1.20)
        (tar . /gnu/store/ipx79bfj2mrc8npj7s3qi3zri11jfhaw-tar-1.30)
        (source . /gnu/store/4xcgzx85274qy4k7yxzadnb7rrq4hfnd-release_3.tar.lz)
        (bash . /gnu/store/y2c5x3xwfbdigdlbxzfbk2g15ayy56cx-bash-minimal-4.4.23)
        (python . /gnu/store/b7fqhszxl02g6pfm3vw6b3cjz472qrly-python-3.7.0))

    Show outputs
      %outputs = ((out . /gnu/store/4s8ij47drq8avldf5fq7inpicrz8dasn-blog-3))

    Unpack source

    Reference interpreters available in the build

    Make executable available to the host system
    `blog/src/hello_world.py' -> 
`/gnu/store/4s8ij47drq8avldf5fq7inpicrz8dasn-blog-3/src/hello_world.py'
    `blog/bin/program' -> 
`/gnu/store/4s8ij47drq8avldf5fq7inpicrz8dasn-blog-3/bin/program'


    End of build expression execution

    successfully built /gnu/store/yhmlzaa07rp324nkc888rbacw7yfarsc-blog-3.drv
    The following graft will be made:
       /gnu/store/w90x2vyymw4ny4n1ii840s1iqw7xjf9h-blog-3.drv
    applying 1 graft for 
/gnu/store/w90x2vyymw4ny4n1ii840s1iqw7xjf9h-blog-3.drv...
    grafting '/gnu/store/4s8ij47drq8avldf5fq7inpicrz8dasn-blog-3' -> 
'/gnu/store/n4q3ppdqvpppfpm5glhq3cbfhybk1hs9-blog-3'...
    successfully built /gnu/store/w90x2vyymw4ny4n1ii840s1iqw7xjf9h-blog-3.drv
    /gnu/store/n4q3ppdqvpppfpm5glhq3cbfhybk1hs9-blog-3

It helped me bind the package spec and the execution.

So, I'm trying to integrate Guix in my workflow and hopefully propagate that to
others.  This is what I'm trying to achieve at minima:

Assume:

    phf@f02c:~/programs/blog$ tree
    .
    ├── bin
    │ ├── make_release
    │ └── program
    ├── guix
    │ ├── blog.scm
    │ └── manifest.scm
    ├── notes
    │ └── guix_refcard.pdf
    ├── notes.org
    ├── releases
    │ ├── release_1.tar.lz
    │ ├── release_2.tar.lz
    │ └── release_3.tar.lz
    └── src
        └── hello_world.py


Development:

    $ guix environment --manifest=./guix/manifest.scm --pure --container
    $ # Develop things. Add dependencies at will in manifest.scm


Build release:

    $ ./deployment/make_release
    Built release: release_4.tar.lz


Deployment:

    $ guix build --keep-failed --verbosity=2 --file=./blog.scm
    …
    /gnu/store/…-blog-4


Test:

    $ /gnu/store/…-blog-4/bin/program
    Hello world!


What would be very helpful:

    - Define blog.scm such that ~$ guix environment blog~ has the same effect as
      ~$ guix environment --manifest=./guix/manifest.scm --pure --container~

    - Define a package ~blog_executable.scm~ derived from ~blog.scm~ such that
      ~$ guix package -i blog_executable~ has the same effect has
      ~$ guix build --file=./blog_v2.scm~, but actually install the thing.

      ~blog_executable.scm~ is essentially ~blog.scm~ but stripped down to the 
bare
      minimum to get the executable working.


If all the above is true then I hope that we (multiple devs) can have the 
guarantee
to have the same dev environment and a simple deployment build that's just the
development environment minus dev dependencies.

With these things in place, a deployment should be deterministic and as simple 
as a:

    $ guix package -i blog_executable


To sum up, here are the questions I try to answer:

    - How to define ~blog.scm~ such that ~$ guix environment blog~ works?
    - How to define ~blog_executable.scm~ such that ~$ guix package -i 
blog_executable~ works?


Thanks!
PHF

PS: Python + quasiquotes => I'm trying to replace Python with Racket whenever I 
can
:-)


‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐
On Tuesday, September 3, 2019 3:58 AM, Timothy Sample <address@hidden> wrote:

> Hello,
>
> "Pierre-Henry F." address@hidden writes:
>
> > Hello Tim !
> > I'm using a couple of hours here an there to try to rebuild the package you 
> > gave me (Thank you for that :-) ).
> > So far, I've built a very stupid but "working" package (see below if you 
> > really want to ;-) ).
>
> Looks good so far!
>
> > Will answer on the mailing list for others to benefit from this exchange.
>
> I’ve added the mailing list back in, then. ;)
>
> > Needless to say, it's not exactly obvious to figure these things out /a 
> > priori/.
>
> For sure. By using the trivial build system, you’re working at a pretty
> low level. It’s especially tough to learn both Guix and Guile at the
> same time. For your reference, here’s a sketch of what the “#:builder”
> code would look like if it were Python:
>
> import os, shutil, stat, subprocess, guix.build.utils
>
> # Unpack
> source = _build_inputs["source"]
> tar = _build_inputs["tar"]
> lzip = _build_inputs["lzip"]
> os.putenv("PATH", ":".join([tar + "/bin", lzip + "/bin"]))
> subprocess.run(["tar", "--lzip", "-xvf", source])
>
> # Configure
> bash = _build_inputs["bash"]
> python = _build_inputs["python"]
> guix.build.utils.substitute("blog/bin/program",
> [["/usr/bin/bash", bash + "/bin/bash"],
> ["python3", python + "/bin/python3"]])
>
> # Install
> out = _outputs["out"]
> os.chmod("blog/bin/program", 0o755)
> shutil.copytree("blog", out)
>
> Here, “_build_inputs” and “_outputs” are set by Guix, and are
> dictionaries. For “_build_inputs”, the keys are the strings you put in
> the “inputs” part of the package, and the values are the paths where the
> packages are installed. So, “_build_inputs["python"]” points to the
> directory in the store where Python is installed. We usually only have
> one output, which is called “out”. This is the path in the store where
> we install the package being built.
>
> The only other thing is that “guix.build.utils.substitute” is basically
> just find-and-replace. It takes the name of a file and a list of
> two-element lists and replaces all the occurrences of the first elements
> in the file with their corresponding second elements.
>
> Obviously the Guile interfaces are a little different, but hopefully
> this Rosetta Stone makes it easier to see what’s going on.
>
> As an aside, ever since I learned that there’s a way to do quasiquotes
> in Python [1], I’ve wondered how strange it would be if Guix were
> written in Python. Pretty strange! :)
>
> [1] https://macropy3.readthedocs.io/en/latest/reference.html#quasiquote
>
> > Anyway, thanks!
>
> You’re welcome!
>
> -- Tim


Attachment: blog_v2.scm
Description: Text Data


reply via email to

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