bug-guix
[Top][All Lists]
Advanced

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

Re: Toward 0.2


From: Ludovic Courtès
Subject: Re: Toward 0.2
Date: Tue, 26 Feb 2013 20:14:52 +0100
User-agent: Gnus/5.130005 (Ma Gnus v0.5) Emacs/24.2 (gnu/linux)

Nikita Karetnikov <address@hidden> skribis:

> ice-9/boot-9.scm:106:20: In procedure #<procedure 913a8c0 at 
> ice-9/boot-9.scm:97:6 (thrown-k . args)>:
> ice-9/boot-9.scm:106:20: In procedure module-lookup: Unbound variable: memoize

As Mark noted, that’s because of a circular dependency.

> (define-module (wrap-program)
>   #:use-module (guix packages)
>   #:use-module (guix store)
>   #:use-module (srfi srfi-26)
>   #:export (store-location
>             wrap-program))
>
> (define (store-location package output rest)
>   "Return a PACKAGE-related location."
>   (string-append (package-output (open-connection) package output)
>                  rest))

There’s a problem here: this is “host” code, whereas we want code to run
in the builder–i.e., a procedure in (guix build utils).

Remember that (guix build ...) modules must not use Guix modules other
than (guix build ...).  This is a convention to distinguish between code
for the “builder stratum”, and code for the “host stratum”.

> (define (wrap-program program prefix? variable var-dir)
>   "Copy PROGRAM to .PROGRAM-real and make PROGRAM a wrapper."

So here PROGRAM would be a file name (not necessarily absolute).

>   (let* ((bin-location (store-location program "out"
>                                        (string-append "/bin"))) ; not safe
>          (program-name (package-name program))
>          (old (string-append bin-location "/" program-name))
>          (new (string-append bin-location "/." program-name "-real"))
>          (tmp (string-append bin-location "/." program-name "-tmp")))

You just need to keep ‘old’ and ‘new’ (the installation of the wrapper
doesn’t need to be atomic.)

>     (define (change-variable)
>       ;; Prepend VAR-DIR to VARIABLE or return VAR-DIR.
>       (if prefix?
>           (string-append var-dir ":$" variable)
>           var-dir))

This should add a colon before $VARIABLE if and only if VARIABLE is
non-empty, like this:

  export VARIABLE=xxx:${VARIABLE:+:}$VARIABLE

>     (copy-file old new)

Just ‘rename-file’.

>     (call-with-output-file
>         tmp
>       (cut format <> "#!/bin/sh~%export ~a=\"~a\"~%exec ./~a 
> \"address@hidden"~%"
>            variable (change-variable) (basename new)))

Use (which "bash") instead of /bin/sh.  Avoid ‘cut’ because it’s not
helpful here.

Also it’s better to use the absolute file name for ‘exec’, so just
replace (basename new) by (canonicalize-path new).

>     (chmod tmp #o755)

OK.

However, this only allows for prefix, and of one variable only.  I was
instead suggesting this API:

    (define* (wrap-program file #:rest variables)
       ...)

  Where each rest argument has a form like this:

    ("PATH" ":" prefix ("/nix/.../foo/bin" "/nix/.../bar/bin"))

  Instead of ‘prefix’, users could ask for ‘prefix’ (prepend to the search
  path) or ‘=’ (set the search path to exactly that value.)

Examples:

  (wrap-program "wget" '(("PATH" ":" prefix ("/nix/.../gawk/bin"))))
  =>
  #!/.../sh
  export PATH=/nix/.../gawk/bin:${PATH:+:}$PATH
  exec /.../bin/.wget-real


  (wrap-program "wget" '(("PATH" ":" = ("/nix/.../gawk/bin"))
                         ("CERT_PATH" ":" suffix '("/nix/.../share/certs"))))
  =>
  #!/.../sh
  export PATH=/nix/.../gawk/bin
  export CERT_PATH=$CERT_PATH${CERT_PATH:+:}:/nix/.../share/certs
  exec /.../bin/.wget-real

Perhaps the separator string could be optional.

WDYT?

Let me know if this is unclear.

Thanks,
Ludo’.



reply via email to

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