From 4ed64c534a3084bdb50346fcb13f38bda465f701 Mon Sep 17 00:00:00 2001 From: Danny Milosavljevic Date: Fri, 3 Mar 2017 20:50:47 +0100 Subject: build/cargo-build-system: Make cargo-build-system install working packages. * guix/build/cargo-build-system.scm (configure): Remove proprietary dependencies. Add rust dependencies and configure Cargo to find them. (build): Also build libraries, not just applications. (file-sha256): New variable. (generate-checksums): New variable. Export it. (touch): New variable. (install): Generate checksums so Cargo accepts the package. --- guix/build/cargo-build-system.scm | 116 +++++++++++++++++++++++++++++++------- 1 file changed, 95 insertions(+), 21 deletions(-) (limited to 'guix/build') diff --git a/guix/build/cargo-build-system.scm b/guix/build/cargo-build-system.scm index 7d656a8d58..f11d858749 100644 --- a/guix/build/cargo-build-system.scm +++ b/guix/build/cargo-build-system.scm @@ -19,13 +19,16 @@ (define-module (guix build cargo-build-system) #:use-module ((guix build gnu-build-system) #:prefix gnu:) #:use-module (guix build utils) + #:use-module (ice-9 popen) + #:use-module (ice-9 rdelim) #:use-module (ice-9 ftw) #:use-module (ice-9 format) #:use-module (ice-9 match) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) #:export (%standard-phases - cargo-build)) + cargo-build + generate-checksums)) ;; Commentary: ;; @@ -45,27 +48,57 @@ (define* (configure #:key inputs #:allow-other-keys) "Replace Cargo.toml [dependencies] section with guix inputs." ;; Make sure Cargo.toml is writeable when the crate uses git-fetch. (chmod "Cargo.toml" #o644) - (let ((port (open-file "Cargo.toml" "a" #:encoding "utf-8"))) - (format port "~%[replace]~%") - (for-each - (match-lambda - ((name . path) - (let ((crate (package-name->crate-name name))) - (when (and crate path) - (match (string-split (basename path) #\-) - ((_ ... version) - (format port "\"~a:~a\" = { path = \"~a/share/rust-source\" }~%" - crate version path))))))) - inputs) - (close-port port)) + (chmod "." #o755) + (if (not (file-exists? "vendor")) + (if (not (file-exists? "Cargo.lock")) + (begin + (substitute* "Cargo.toml" + ((".*32-sys.*") " +") + ((".*winapi.*") " +") + ((".*core-foundation.*") " +")) + ;; Prepare one new directory with all the required dependencies. + ;; It's necessary to do this (instead of just using /gnu/store as the + ;; directory) because we want to hide the libraries in subdirectories + ;; share/rust-source/... instead of polluting the user's profile root. + (mkdir "vendor") + (for-each + (match-lambda + ((name . path) + (let ((crate (package-name->crate-name name))) + (when (and crate path) + (match (string-split (basename path) #\-) + ((_ ... version) + (symlink (string-append path "/share/rust-source") + (string-append "vendor/" (basename path))))))))) + inputs) + ;; Configure cargo to actually use this new directory. + (mkdir-p ".cargo") + (let ((port (open-file ".cargo/config" "w" #:encoding "utf-8"))) + (display " +[source.crates-io] +registry = 'https://github.com/rust-lang/crates.io-index' +replace-with = 'vendored-sources' + +[source.vendored-sources] +directory = '" port) + (display (getcwd) port) + (display "/vendor" port) + (display "' +" port) + (close-port port))))) + (setenv "CC" (string-append (assoc-ref inputs "gcc") "/bin/gcc")) + + ;(setenv "CARGO_HOME" "/gnu/store") + ; (setenv "CMAKE_C_COMPILER" cc) #t) -(define* (build #:key (cargo-build-flags '("--release" "--frozen")) +(define* (build #:key (cargo-build-flags '("--release")) #:allow-other-keys) "Build a given Cargo package." - (if (file-exists? "Cargo.lock") - (zero? (apply system* `("cargo" "build" ,@cargo-build-flags))) - #t)) + (zero? (apply system* `("cargo" "build" ,@cargo-build-flags)))) (define* (check #:key tests? #:allow-other-keys) "Run tests for a given Cargo package." @@ -73,6 +106,44 @@ (define* (check #:key tests? #:allow-other-keys) (zero? (system* "cargo" "test")) #t)) +(define (file-sha256 file-name) + "Calculate the hexdigest of the sha256 checksum of FILE-NAME and return it." + (let ((port (open-pipe* OPEN_READ + "sha256sum" + "--" + file-name))) + (let ((result (read-delimited " " port))) + (close-pipe port) + result))) + +;; Example dir-name: "/gnu/store/hwlr49riz3la33m6in2n898ly045ylld-rust-rand-0.3.15". +(define (generate-checksums dir-name src-name) + "Given DIR-NAME, checksum all the files in it one by one and put the + result into the file \".cargo-checksum.json\" in the same directory. + Also includes the checksum of an extra file SRC-NAME as if it was + part of the directory DIR-NAME with name \"package\"." + (let* ((file-names (find-files dir-name ".")) + (dir-prefix-name (string-append dir-name "/")) + (dir-prefix-name-len (string-length dir-prefix-name)) + (checksums-file-name (string-append dir-name "/.cargo-checksum.json"))) + (call-with-output-file checksums-file-name + (lambda (port) + (display "{\"files\":{" port) + (let ((sep "")) + (for-each (lambda (file-name) + (let ((file-relative-name (string-drop file-name dir-prefix-name-len))) + (display sep port) + (set! sep ",") + (write file-relative-name port) + (display ":" port) + (write (file-sha256 file-name) port))) file-names)) + (display "},\"package\":" port) + (write (file-sha256 src-name) port) + (display "}" port))))) + +(define (touch file-name) + (call-with-output-file file-name (const #t))) + (define* (install #:key inputs outputs #:allow-other-keys) "Install a given Cargo package." (let* ((out (assoc-ref outputs "out")) @@ -86,16 +157,19 @@ (define* (install #:key inputs outputs #:allow-other-keys) ;; distributing crates as source and replacing ;; references in Cargo.toml with store paths. (copy-recursively "src" (string-append rsrc "/src")) + (touch (string-append rsrc "/.cargo-ok")) + (generate-checksums rsrc src) (install-file "Cargo.toml" rsrc) ;; When the package includes executables we install ;; it using cargo install. This fails when the crate ;; doesn't contain an executable. (if (file-exists? "Cargo.lock") - (system* "cargo" "install" "--root" out) - (mkdir out)))) + (zero? (system* "cargo" "install" "--root" out)) + (begin + (mkdir out) + #t)))) (define %standard-phases - ;; 'configure' phase is not needed. (modify-phases gnu:%standard-phases (replace 'configure configure) (replace 'build build) -- cgit v1.2.3 From 36626c556ed75219bce196ac93d148f6b9af984c Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 17 Mar 2017 23:07:01 +0100 Subject: build: Require Guile >= 2.0.9. * configure.ac: Bump requirement to 2.0.9. * doc/guix.texi (Requirements): Adjust accordingly. * README (Requirements): Likewise. * build-aux/download.scm: Remove workaround for . * guix/build/download.scm: Likewise. (http-fetch)[post-2.0.7?]: Remove. Remove conditional code for not POST-2.0.7?. * guix/http-client.scm: Remove workaround for . (http-fetch)[post-2.0.7?]: Remove. Remove conditional code for not POST-2.0.7?. * guix/serialization.scm (read-latin1-string): Remove mention of 2.0.9. * tests/nar.scm: Use (ice-9 control). (let/ec): Remove. --- README | 2 +- build-aux/download.scm | 5 ----- configure.ac | 2 +- doc/guix.texi | 2 +- guix/build/download.scm | 29 +++-------------------------- guix/http-client.scm | 15 +++------------ guix/serialization.scm | 3 +-- tests/nar.scm | 12 +----------- 8 files changed, 11 insertions(+), 59 deletions(-) (limited to 'guix/build') diff --git a/README b/README index 5829320dc7..4921f255da 100644 --- a/README +++ b/README @@ -20,7 +20,7 @@ Guix is based on the [[http://nixos.org/nix/][Nix]] package manager. GNU Guix currently depends on the following packages: - - [[http://gnu.org/software/guile/][GNU Guile 2.0.x]], version 2.0.7 or later + - [[http://gnu.org/software/guile/][GNU Guile 2.2.x or 2.0.x]], version 2.0.9 or later - [[http://gnupg.org/][GNU libgcrypt]] - [[http://www.gnu.org/software/make/][GNU Make]] - optionally [[http://savannah.nongnu.org/projects/guile-json/][Guile-JSON]], for the 'guix import pypi' command diff --git a/build-aux/download.scm b/build-aux/download.scm index 8f41f33b14..18b820a153 100644 --- a/build-aux/download.scm +++ b/build-aux/download.scm @@ -36,11 +36,6 @@ (define %url-base ;;"http://www.fdn.fr/~lcourtes/software/guix/packages" ) -;; XXX: Work around , present in Guile -;; up to 2.0.7. -(module-define! (resolve-module '(web client)) - 'shutdown (const #f)) - (define (file-name->uri file) "Return the URI for FILE." (match (string-tokenize file (char-set-complement (char-set #\/))) diff --git a/configure.ac b/configure.ac index 3bf2bf1610..76f52e0ec3 100644 --- a/configure.ac +++ b/configure.ac @@ -82,7 +82,7 @@ if test "x$GUILD" = "x"; then fi if test "x$GUILE_EFFECTIVE_VERSION" = "x2.0"; then - PKG_CHECK_MODULES([GUILE], [guile-2.0 >= 2.0.7]) + PKG_CHECK_MODULES([GUILE], [guile-2.0 >= 2.0.9]) fi dnl Installation directory for .scm and .go files. diff --git a/doc/guix.texi b/doc/guix.texi index 0a09bba06f..944e1fad1b 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -552,7 +552,7 @@ in the Guix source tree for additional details. GNU Guix depends on the following packages: @itemize -@item @url{http://gnu.org/software/guile/, GNU Guile}, version 2.0.7 or +@item @url{http://gnu.org/software/guile/, GNU Guile}, version 2.0.9 or later, including 2.2.x; @item @url{http://gnupg.org/, GNU libgcrypt}; @item diff --git a/guix/build/download.scm b/guix/build/download.scm index e7a7afecd1..d956a9f33e 100644 --- a/guix/build/download.scm +++ b/guix/build/download.scm @@ -512,12 +512,6 @@ (define (close-connection port) 'set-port-encoding! (lambda (p e) #f)) -;; XXX: Work around , present in Guile -;; up to 2.0.7. -(module-define! (resolve-module '(web client)) - 'shutdown (const #f)) - - ;; XXX: Work around , fixed in Guile commit ;; 16050431f29d56f80c4a8253506fc851b8441840. Guile's date validation ;; procedure rejects dates in which the hour is not padded with a zero but @@ -682,12 +676,6 @@ (define* (http-fetch uri file #:key timeout (verify-certificate? #t)) FILE on success. When VERIFY-CERTIFICATE? is true, verify HTTPS certificates; otherwise simply ignore them." - (define post-2.0.7? - (or (> (string->number (major-version)) 2) - (> (string->number (minor-version)) 0) - (> (string->number (micro-version)) 7) - (string>? (version) "2.0.7"))) - (define headers `(;; Some web sites, such as http://dist.schmorp.de, would block you if ;; there's no 'User-Agent' header, presumably on the assumption that @@ -712,20 +700,9 @@ (define headers #:verify-certificate? verify-certificate?)) ((resp bv-or-port) - ;; XXX: `http-get*' was introduced in 2.0.7, and replaced by - ;; #:streaming? in 2.0.8. We know we're using it within the - ;; chroot, but `guix-download' might be using a different - ;; version. So keep this compatibility hack for now. - (if post-2.0.7? - (http-get uri #:port connection #:decode-body? #f - #:streaming? #t - #:headers headers) - (if (module-defined? (resolve-interface '(web client)) - 'http-get*) - (http-get* uri #:port connection #:decode-body? #f - #:headers headers) - (http-get uri #:port connection #:decode-body? #f - #:extra-headers headers)))) + (http-get uri #:port connection #:decode-body? #f + #:streaming? #t + #:headers headers)) ((code) (response-code resp)) ((size) diff --git a/guix/http-client.scm b/guix/http-client.scm index 78d39a0208..855ae95a43 100644 --- a/guix/http-client.scm +++ b/guix/http-client.scm @@ -217,10 +217,6 @@ (define (read-header-line port) (when (module-variable %web-http 'read-line*) (module-set! %web-http 'read-line* read-header-line)))) -;; XXX: Work around , present in Guile -;; up to 2.0.7. -(module-define! (resolve-module '(web client)) - 'shutdown (const #f)) (define* (http-fetch uri #:key port (text? #f) (buffered? #t) keep-alive? (verify-certificate? #t) @@ -252,14 +248,9 @@ (define* (http-fetch uri #:key port (text? #f) (buffered? #t) (unless (or buffered? (not (file-port? port))) (setvbuf port _IONBF)) (let*-values (((resp data) - ;; Try hard to use the API du jour to get an input port. - (if (guile-version>? "2.0.7") - (http-get uri #:streaming? #t #:port port - #:keep-alive? #t - #:headers headers) ; 2.0.9+ - (http-get* uri #:decode-body? text? ; 2.0.7 - #:keep-alive? #t - #:port port #:headers headers))) + (http-get uri #:streaming? #t #:port port + #:keep-alive? #t + #:headers headers)) ((code) (response-code resp))) (case code diff --git a/guix/serialization.scm b/guix/serialization.scm index 4cab5910f7..4a8cd2086e 100644 --- a/guix/serialization.scm +++ b/guix/serialization.scm @@ -130,8 +130,7 @@ (define (read-latin1-string p) ;; . See for ;; a discussion. (let ((bv (read-byte-string p))) - ;; XXX: Rewrite using (ice-9 iconv) when the minimum requirement is - ;; upgraded to Guile >= 2.0.9. + ;; XXX: Rewrite using (ice-9 iconv). (list->string (map integer->char (bytevector->u8-list bv))))) (define (read-maybe-utf8-string p) diff --git a/tests/nar.scm b/tests/nar.scm index 28ead8b783..61646db964 100644 --- a/tests/nar.scm +++ b/tests/nar.scm @@ -35,6 +35,7 @@ (define-module (test-nar) #:use-module (srfi srfi-64) #:use-module (ice-9 ftw) #:use-module (ice-9 regex) + #:use-module ((ice-9 control) #:select (let/ec)) #:use-module (ice-9 match)) ;; Test the (guix nar) module. @@ -148,17 +149,6 @@ (define %test-dir (string-append (dirname (search-path %load-path "pre-inst-env")) "/test-nar-" (number->string (getpid)))) -(define-syntax-rule (let/ec k exp...) - ;; This one appeared in Guile 2.0.9, so provide a copy here. - (let ((tag (make-prompt-tag))) - (call-with-prompt tag - (lambda () - (let ((k (lambda args - (apply abort-to-prompt tag args)))) - exp...)) - (lambda (_ . args) - (apply values args))))) - (test-begin "nar") -- cgit v1.2.3 From 4fd06a4dd1d4a894b96e586cef594270f8bbb88f Mon Sep 17 00:00:00 2001 From: Ludovic Courtès Date: Fri, 17 Mar 2017 23:41:37 +0100 Subject: http-client: Avoid name clash with 'open-connection-for-uri' in 2.2.0. * guix/build/download.scm (open-connection-for-uri): Add note about same-named binding in Guile 2.2.0. * guix/http-client.scm: Use 'guix:open-connection-for-uri' for the procedure coming from (guix build download). * guix/scripts/lint.scm: Likewise. * guix/scripts/substitute.scm: Likewise. --- guix/build/download.scm | 3 +++ guix/http-client.scm | 10 ++++++---- guix/scripts/lint.scm | 6 ++++-- guix/scripts/substitute.scm | 23 +++++++++++++---------- 4 files changed, 26 insertions(+), 16 deletions(-) (limited to 'guix/build') diff --git a/guix/build/download.scm b/guix/build/download.scm index d956a9f33e..36c815c167 100644 --- a/guix/build/download.scm +++ b/guix/build/download.scm @@ -464,6 +464,9 @@ (define* (open-connection-for-uri uri "Like 'open-socket-for-uri', but also handle HTTPS connections. The resulting port must be closed with 'close-connection'. When VERIFY-CERTIFICATE? is true, verify HTTPS server certificates." + ;; Note: Guile 2.2.0's (web client) has a same-named export that's actually + ;; undefined. See Guile commit 011669af3b428e5626f7bbf66b11d57d9768c047. + (define https? (eq? 'https (uri-scheme uri))) diff --git a/guix/http-client.scm b/guix/http-client.scm index 855ae95a43..6874c51db6 100644 --- a/guix/http-client.scm +++ b/guix/http-client.scm @@ -38,7 +38,9 @@ (define-module (guix http-client) #:select (mkdir-p dump-port)) #:use-module ((guix build download) #:select (open-socket-for-uri - open-connection-for-uri resolve-uri-reference)) + (open-connection-for-uri + . guix:open-connection-for-uri) + resolve-uri-reference)) #:re-export (open-socket-for-uri) #:export (&http-get-error http-get-error? @@ -234,9 +236,9 @@ (define* (http-fetch uri #:key port (text? #f) (buffered? #t) (let loop ((uri (if (string? uri) (string->uri uri) uri))) - (let ((port (or port (open-connection-for-uri uri - #:verify-certificate? - verify-certificate?))) + (let ((port (or port (guix:open-connection-for-uri uri + #:verify-certificate? + verify-certificate?))) (headers (match (uri-userinfo uri) ((? string? str) (cons (cons 'Authorization diff --git a/guix/scripts/lint.scm b/guix/scripts/lint.scm index 776e7332c5..66c82f0409 100644 --- a/guix/scripts/lint.scm +++ b/guix/scripts/lint.scm @@ -44,7 +44,8 @@ (define-module (guix scripts lint) #:use-module (web uri) #:use-module ((guix build download) #:select (maybe-expand-mirrors - open-connection-for-uri + (open-connection-for-uri + . guix:open-connection-for-uri) close-connection)) #:use-module (web request) #:use-module (web response) @@ -377,7 +378,8 @@ (define headers ((or 'http 'https) (catch #t (lambda () - (let ((port (open-connection-for-uri uri #:timeout timeout)) + (let ((port (guix:open-connection-for-uri + uri #:timeout timeout)) (request (build-request uri #:headers headers))) (define response (dynamic-wind diff --git a/guix/scripts/substitute.scm b/guix/scripts/substitute.scm index 524b019a31..faeb019120 100755 --- a/guix/scripts/substitute.scm +++ b/guix/scripts/substitute.scm @@ -1,5 +1,5 @@ ;;; GNU Guix --- Functional package management for GNU -;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès +;;; Copyright © 2013, 2014, 2015, 2016, 2017 Ludovic Courtès ;;; Copyright © 2014 Nikita Karetnikov ;;; ;;; This file is part of GNU Guix. @@ -34,7 +34,8 @@ (define-module (guix scripts substitute) #:use-module ((guix build download) #:select (current-terminal-columns progress-proc uri-abbreviation nar-uri-abbreviation - open-connection-for-uri + (open-connection-for-uri + . guix:open-connection-for-uri) close-connection store-path-abbreviation byte-count->string)) #:use-module (ice-9 rdelim) @@ -210,8 +211,8 @@ (define* (fetch uri #:key (buffered? #t) (timeout? #t)) (close-connection port)))) (begin (when (or (not port) (port-closed? port)) - (set! port (open-connection-for-uri uri - #:verify-certificate? #f)) + (set! port (guix:open-connection-for-uri + uri #:verify-certificate? #f)) (unless (or buffered? (not (file-port? port))) (setvbuf port _IONBF))) (http-fetch uri #:text? #f #:port port @@ -247,9 +248,10 @@ (define (read-cache-info port) read-cache-info) #f)) ((http https) - (let ((port (open-connection-for-uri uri - #:verify-certificate? #f - #:timeout %fetch-timeout))) + (let ((port (guix:open-connection-for-uri + uri + #:verify-certificate? #f + #:timeout %fetch-timeout))) (guard (c ((http-get-error? c) (warning (_ "while fetching '~a': ~a (~s)~%") (uri->string (http-get-error-uri c)) @@ -533,9 +535,10 @@ (define* (http-multiple-get base-uri proc seed requests (result seed)) ;; (format (current-error-port) "connecting (~a requests left)..." ;; (length requests)) - (let ((p (or port (open-connection-for-uri base-uri - #:verify-certificate? - verify-certificate?)))) + (let ((p (or port (guix:open-connection-for-uri + base-uri + #:verify-certificate? + verify-certificate?)))) ;; For HTTPS, P is not a file port and does not support 'setvbuf'. (when (file-port? p) (setvbuf p _IOFBF (expt 2 16))) -- cgit v1.2.3