[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’.
- Toward 0.2, Ludovic Courtès, 2013/02/17
- Re: Toward 0.2, Nikita Karetnikov, 2013/02/17
- Re: Toward 0.2, Ludovic Courtès, 2013/02/18
- Re: Toward 0.2, Nikita Karetnikov, 2013/02/19
- Re: Toward 0.2, Ludovic Courtès, 2013/02/20
- Re: Toward 0.2, Nikita Karetnikov, 2013/02/21
- Re: Toward 0.2, Ludovic Courtès, 2013/02/22
- Re: Toward 0.2, Nikita Karetnikov, 2013/02/26
- Re: Toward 0.2, Mark H Weaver, 2013/02/26
- Re: Toward 0.2,
Ludovic Courtès <=
- Re: Toward 0.2, Nikita Karetnikov, 2013/02/28
Re: Toward 0.2, Andreas Enge, 2013/02/20