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: Timothy Sample
Subject: Re: Help defining a trivial package.
Date: Thu, 29 Aug 2019 11:26:25 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/26.2 (gnu/linux)

Hi Pierre,

"Pierre-Henry F." <address@hidden> writes:

> So, we have, in ~bash~:
>
>   $ lzip --decompress release_3.tar.lz
>   $ tar xf release_3.tar
>   $ cd blog/ # coming from the preceding line.
>   $ tree
>   .
>   ├── bin
>   │   └── program
>   └── src
>       └── hello_world.py
>
>   $ cat src/hello_world.py
>   print("Hello world!")
>
>   $ cat bin/program
>   #! /usr/bin/env bash
>
>   script_path="${BASH_SOURCE[0]}"
>   script_dir="$(dirname $script_path)"
>   python3 "$script_dir/../src/hello_world.py"
>
> That's it.
>
> The idea is to build a Guix package that does exactly that.
> Expected outcome:
>
>   $ guix package -s blog
>   # fetch release_3.tar.lz
>   # uncompress ...
>   # ...
>
>   $ program
>   Hello World!
>
>
> My question: how to build that Guix package?  I try to get something working 
> using
> the docs.  This is how the package looks to far:
>
>   (use-modules
>     (guix packages)
>     (guix download)
>     (guix build-system trivial)
>     (guix licenses)
>     (guix gexp)
>     (gnu packages base)
>     (gnu packages python))
>
>
>   ;; The "derivation" i.e. low level sequence of instructions that the build 
> deamon is
>   ;; supposed to execute on the behalf of the user.
>   (define build-drv
>     (gexp->derivation
>       "the-thing"
>       #~(begin
>           (mkdir #$output)
>           (chdir #$output)
>           (symlink (string-append #$coreutils "/bin/ls")
>             "list-files"))))
>
>
>   (package
>     (name "blog")
>     (version "3")
>     (source
>       (origin
>         (method url-fetch)
>         (uri (string-append "/home/phf/programs/blog/releases/release_" 
> version ".tar.lz"))
>         (sha256
>           (base32
>             "1y819b53ksyas6asldysr0r8p73n5i8ipbpmbgjrfx8qz8cy2zsx"))))
>     (build-system trivial-build-system)
>     (arguments `(#:builder ,build-drv))
>
>     (inputs `(("python" ,python)))
>     (synopsis "Guix 'hello world' to learn about Guix")
>     (description "Guess what GNU Hello prints!")
>     (home-page "http://www.gnu.org/software/hello/";)
>     (license gpl3+))
>
> Assuming everything else is correct, would you please help refine ~build-drv~ 
> until
> it matches the ~bash~ above ?
>
> This is what the execution trace looks like:
>
>   phf@f02c:~/tools/guix/packages$ guix build --keep-failed --verbosity=2 
> --file=./blog.scm
>   substitute: updating substitutes from 'https://ci.guix.gnu.org'... 100.0%
>   building /gnu/store/8b0gyazhgmc9rkrxir7vxpav0x28xk3d-blog-3.drv...
>   ERROR: In procedure primitive-load:
>   In procedure scm_lreadr: 
> /gnu/store/zlbf2x6n4084v0cpw2rh9dydqmi5b2rn-blog-3-guile-builder:1:10: 
> Unknown # object: #\<

This error is because you can’t pass a derivation object as the
“#:builder” argument.  It has to be some quoted Scheme code that can run
in the build environment.

I took a little time and wrote a package definition that matches your
example.  There are some things you could do to change your source code
to make it more in-line with what Guix expects, but I didn’t do that.  I
hope that an example dealing with what you have will be more helpful.

I’ve attached the package definition I came up with (note that I changed
the URL of the tarball).

(use-modules ((gnu packages base) #:select (tar))
             ((gnu packages bash) #:select (bash-minimal))
             ((gnu packages compression) #:select (lzip))
             ((gnu packages python) #:select (python))
             (guix)
             (guix build-system trivial))

(package
  (name "blog")
  (version "3")
  (source
   (origin
     (method url-fetch)
     (uri (string-append "file:///tmp/phf/release_" version ".tar.lz"))
     (sha256
      (base32
       "1y819b53ksyas6asldysr0r8p73n5i8ipbpmbgjrfx8qz8cy2zsx"))))
  (build-system trivial-build-system)
  (arguments
   `(#:modules ((guix build utils))
     #:builder
     (begin
       (use-modules (guix build utils))
       ;; Unpack
       (let ((source (assoc-ref %build-inputs "source"))
             (tar (assoc-ref %build-inputs "tar"))
             (lzip (assoc-ref %build-inputs "lzip")))
         (setenv "PATH" (string-append tar "/bin"
                                       ":" lzip "/bin"))
         (invoke "tar" "--lzip" "-xvf" source))
       ;; Configure
       (let ((bash (assoc-ref %build-inputs "bash"))
             (python (assoc-ref %build-inputs "python")))
         (substitute* "blog/bin/program"
           (("/usr/bin/env bash") (string-append bash "/bin/bash"))
           (("python3") (string-append python "/bin/python3"))))
       ;; Install
       (let ((out (assoc-ref %outputs "out")))
         (chmod "blog/bin/program" #o775)
         (copy-recursively "blog" out)))))
  (inputs
   `(("bash" ,bash-minimal)
     ("python" ,python)))
  (native-inputs
   `(("lzip" ,lzip)
     ("tar" ,tar)))
  (synopsis #f)
  (description #f)
  (home-page #f)
  (license #f))
The builder code imports the “(guix build utils)” module, which has some
really handy shell-like functions like “invoke” for running programs,
“substitute*” which is like “sed -i”, and “copy-recursively”, which is
like “cp -r”.

The “Unpack” section sets up the “PATH” variable for Tar, and then
invokes “tar” to unpack the tarball.

The “Configure” section replaces the references to Bash and Python with
their absolute paths in the Guix store.

The “Install” section makes the “program” file executable then copies
the code into the Guix-provided output directory.

I hope that makes sense and good luck!


-- Tim

reply via email to

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