summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--emacs/guix-pcomplete.el5
-rw-r--r--gnu-system.am1
-rw-r--r--gnu/build/file-systems.scm9
-rw-r--r--gnu/packages/audio.scm27
-rw-r--r--gnu/packages/bioinformatics.scm59
-rw-r--r--gnu/packages/commencement.scm1
-rw-r--r--gnu/packages/gcc.scm26
-rw-r--r--gnu/packages/gnome.scm10
-rw-r--r--gnu/packages/llvm.scm51
-rw-r--r--gnu/packages/patches/clang-libc-search-path.patch19
-rw-r--r--gnu/packages/patches/guile-linux-syscalls.patch22
-rw-r--r--gnu/packages/ruby.scm33
-rw-r--r--gnu/packages/video.scm4
-rw-r--r--gnu/system/file-systems.scm27
-rw-r--r--guix/gexp.scm8
-rw-r--r--guix/store.scm11
-rw-r--r--tests/gexp.scm23
17 files changed, 297 insertions, 39 deletions
diff --git a/emacs/guix-pcomplete.el b/emacs/guix-pcomplete.el
index fa71dd5e21..dd42556163 100644
--- a/emacs/guix-pcomplete.el
+++ b/emacs/guix-pcomplete.el
@@ -254,7 +254,8 @@ group - the argument.")
   "Complete argument for guix COMMAND."
   (cond
    ((member command
-            '("archive" "build" "environment" "lint" "refresh"))
+            '("archive" "build" "edit" "environment" "lint" "refresh"
+              "size"))
     (while t
       (pcomplete-here (guix-pcomplete-all-packages))))
    (t (pcomplete-here* (pcomplete-entries)))))
@@ -302,7 +303,7 @@ INPUT is the current partially completed string."
        ((option? "-m" "--manifest")
         (complete* (pcomplete-entries)))))
 
-     ((and (command? "archive" "build")
+     ((and (command? "archive" "build" "size")
            (option? "-s" "--system"))
       (complete* guix-pcomplete-systems))
 
diff --git a/gnu-system.am b/gnu-system.am
index 81cfd7bfff..a420d71a2f 100644
--- a/gnu-system.am
+++ b/gnu-system.am
@@ -394,6 +394,7 @@ dist_patch_DATA =						\
   gnu/packages/patches/calibre-no-updates-dialog.patch		\
   gnu/packages/patches/cdparanoia-fpic.patch			\
   gnu/packages/patches/chmlib-inttypes.patch			\
+  gnu/packages/patches/clang-libc-search-path.patch		\
   gnu/packages/patches/clucene-pkgconfig.patch			\
   gnu/packages/patches/cmake-fix-tests.patch			\
   gnu/packages/patches/coreutils-dummy-man.patch		\
diff --git a/gnu/build/file-systems.scm b/gnu/build/file-systems.scm
index dc99d60d3d..72c8bd59f3 100644
--- a/gnu/build/file-systems.scm
+++ b/gnu/build/file-systems.scm
@@ -286,16 +286,13 @@ run a file system check."
        (when check?
          (check-file-system source type))
        (mkdir-p mount-point)
-       (mount source mount-point type flags
-              (if options
-                  (string->pointer options)
-                  %null-pointer))
+       (mount source mount-point type flags options)
 
        ;; For read-only bind mounts, an extra remount is needed, as per
        ;; <http://lwn.net/Articles/281157/>, which still applies to Linux 4.0.
        (when (and (= MS_BIND (logand flags MS_BIND))
                   (= MS_RDONLY (logand flags MS_RDONLY)))
-         (mount source mount-point type (logior MS_BIND MS_REMOUNT MS_RDONLY)
-                %null-pointer))))))
+         (let ((flags (logior MS_BIND MS_REMOUNT MS_RDONLY)))
+           (mount source mount-point type flags #f)))))))
 
 ;;; file-systems.scm ends here
diff --git a/gnu/packages/audio.scm b/gnu/packages/audio.scm
index f6881883bb..6dd4bd7ffe 100644
--- a/gnu/packages/audio.scm
+++ b/gnu/packages/audio.scm
@@ -1034,6 +1034,33 @@ buffers, and audio capture.")
 and ALSA.")
     (license license:gpl3+)))
 
+(define-public raul
+  (package
+    (name "raul")
+    (version "0.8.0")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://download.drobilla.net/raul-"
+                                  version ".tar.bz2"))
+              (sha256
+               (base32
+                "09ms40xc1x6qli6lxkwn5ibqh62nl9w7dq0b6jh1q2zvnrxwsd8b"))))
+    (build-system waf-build-system)
+    (arguments
+     `(#:python ,python-2
+       #:tests? #f)) ; no check target
+    (inputs
+     `(("glib" ,glib)
+       ("boost" ,boost)))
+    (native-inputs
+     `(("pkg-config" ,pkg-config)))
+    (home-page "http://drobilla.net/software/raul/")
+    (synopsis "Real-time audio utility library")
+    (description
+     "Raul (Real-time Audio Utility Library) is a C++ utility library primarily
+aimed at audio/musical applications.")
+    (license license:gpl2+)))
+
 (define-public rubberband
   (package
     (name "rubberband")
diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 12c9175ed3..8dfaff3e00 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -780,6 +780,65 @@ analysis (from RNA-Seq), transcription factor binding quantification in
 ChIP-Seq, and analysis of metagenomic data.")
     (license license:artistic2.0)))
 
+(define-public fasttree
+  (package
+   (name "fasttree")
+   (version "2.1.8")
+   (source (origin
+             (method url-fetch)
+             (uri (string-append
+                   "http://www.microbesonline.org/fasttree/FastTree-"
+                   version ".c"))
+             (sha256
+              (base32
+               "0dzqc9vr9iiiw21y159xfjl2z90vw0y7r4x6456pcaxiy5hd2wmi"))))
+   (build-system gnu-build-system)
+   (arguments
+    `(#:tests? #f ; no "check" target
+      #:phases
+      (modify-phases %standard-phases
+        (delete 'unpack)
+        (delete 'configure)
+        (replace 'build
+                 (lambda* (#:key source #:allow-other-keys)
+                   (and (zero? (system* "gcc"
+                                        "-O3"
+                                        "-finline-functions"
+                                        "-funroll-loops"
+                                        "-Wall"
+                                        "-o"
+                                        "FastTree"
+                                        source
+                                        "-lm"))
+                        (zero? (system* "gcc"
+                                        "-DOPENMP"
+                                        "-fopenmp"
+                                        "-O3"
+                                        "-finline-functions"
+                                        "-funroll-loops"
+                                        "-Wall"
+                                        "-o"
+                                        "FastTreeMP"
+                                        source
+                                        "-lm")))))
+        (replace 'install
+                 (lambda* (#:key outputs #:allow-other-keys)
+                   (let ((bin (string-append (assoc-ref outputs "out")
+                                             "/bin")))
+                     (mkdir-p bin)
+                     (copy-file "FastTree"
+                                (string-append bin "/FastTree"))
+                     (copy-file "FastTreeMP"
+                                (string-append bin "/FastTreeMP"))
+                     #t))))))
+   (home-page "http://www.microbesonline.org/fasttree")
+   (synopsis "Infers approximately-maximum-likelihood phylogenetic trees")
+   (description
+    "FastTree can handle alignments with up to a million of sequences in a
+reasonable amount of time and memory.  For large alignments, FastTree is
+100-1,000 times faster than PhyML 3.0 or RAxML 7.")
+   (license license:gpl2+)))
+
 (define-public fastx-toolkit
   (package
     (name "fastx-toolkit")
diff --git a/gnu/packages/commencement.scm b/gnu/packages/commencement.scm
index db91bec5da..ebf770bfa7 100644
--- a/gnu/packages/commencement.scm
+++ b/gnu/packages/commencement.scm
@@ -518,6 +518,7 @@ exec ~a/bin/~a-~a -B~a/lib -Wl,-dynamic-linker -Wl,~a/~a \"$@\"~%"
 (define libstdc++
   ;; Intermediate libstdc++ that will allow us to build the final GCC
   ;; (remember that GCC-BOOT0 cannot build libstdc++.)
+  ;; TODO: Write in terms of 'make-libstdc++'.
   (package-with-bootstrap-guile
    (package (inherit gcc-4.9)
      (name "libstdc++")
diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm
index beb007e95b..c370fe8212 100644
--- a/gnu/packages/gcc.scm
+++ b/gnu/packages/gcc.scm
@@ -345,6 +345,32 @@ Go.  It also includes runtime support libraries for these languages.")
                             '("gcc-arm-link-spec-fix.patch"
                               "gcc-5.0-libvtv-runpath.patch")))))))
 
+(define-public (make-libstdc++ gcc)
+  "Return a libstdc++ package based on GCC.  The primary use case is when
+using compilers other than GCC."
+  (package
+    (inherit gcc)
+    (name "libstdc++")
+    (arguments
+     `(#:out-of-source? #t
+       #:phases (alist-cons-before
+                 'configure 'chdir
+                 (lambda _
+                   (chdir "libstdc++-v3"))
+                 %standard-phases)
+       #:configure-flags `("--disable-libstdcxx-pch"
+                           ,(string-append "--with-gxx-include-dir="
+                                           (assoc-ref %outputs "out")
+                                           "/include"))))
+    (outputs '("out" "debug"))
+    (inputs '())
+    (native-inputs '())
+    (propagated-inputs '())
+    (synopsis "GNU C++ standard library")))
+
+(define-public libstdc++-4.9
+  (make-libstdc++ gcc-4.9))
+
 (define* (custom-gcc gcc name languages #:key (separate-lib-output? #t))
   "Return a custom version of GCC that supports LANGUAGES."
   (package (inherit gcc)
diff --git a/gnu/packages/gnome.scm b/gnu/packages/gnome.scm
index 30f834a168..f7a6465eb6 100644
--- a/gnu/packages/gnome.scm
+++ b/gnu/packages/gnome.scm
@@ -2402,15 +2402,17 @@ settings, themes, mouse settings, and startup of other daemons.")
    (native-inputs
     `(("intltool" ,intltool)
       ("glib" ,glib "bin")
+      ("gobject-introspection" ,gobject-introspection)
       ("pkg-config" ,pkg-config)))
-   (inputs
+   (propagated-inputs
     `(("glib" ,glib)
       ("gmime" ,gmime)
-      ("libarchive" ,libarchive)
+      ("libxml2" ,libxml2)))
+   (inputs
+    `(("libarchive" ,libarchive)
       ("libgcrypt" ,libgcrypt)
       ("nettle" ,nettle)
-      ("libsoup" ,libsoup)
-      ("libxml2" ,libxml2)))
+      ("libsoup" ,libsoup)))
    (home-page "https://projects.gnome.org/totem")
    (synopsis "Library to parse and save media playlists for GNOME")
    (description "Totem-pl-parser is a GObjects-based library to parse and save
diff --git a/gnu/packages/llvm.scm b/gnu/packages/llvm.scm
index 6cf1fdab0a..47710e69fc 100644
--- a/gnu/packages/llvm.scm
+++ b/gnu/packages/llvm.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2015 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -25,6 +26,8 @@
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system cmake)
   #:use-module (gnu packages)
+  #:use-module (gnu packages gcc)
+  #:use-module (gnu packages bootstrap)           ;glibc-dynamic-linker
   #:use-module (gnu packages perl)
   #:use-module (gnu packages python)
   #:use-module (gnu packages xml))
@@ -84,7 +87,8 @@ tools as well as libraries with equivalent functionality.")
        (method url-fetch)
        (uri (string-append "http://llvm.org/releases/"
                            version "/cfe-" version ".src.tar.xz"))
-       (sha256 (base32 hash))))
+       (sha256 (base32 hash))
+       (patches (list (search-patch "clang-libc-search-path.patch")))))
     ;; Using cmake allows us to treat llvm as an external library.  There
     ;; doesn't seem to be any way to do this with clang's autotools-based
     ;; build system.
@@ -92,10 +96,53 @@ tools as well as libraries with equivalent functionality.")
     (native-inputs (package-native-inputs llvm))
     (inputs
      `(("libxml2" ,libxml2)
+       ("gcc-lib" ,gcc-4.9 "lib")
        ,@(package-inputs llvm)))
     (propagated-inputs
      `(("llvm" ,llvm)))
-    (arguments `(#:configure-flags '("-DCLANG_INCLUDE_TESTS=True")))
+    (arguments
+     `(#:configure-flags
+       (list "-DCLANG_INCLUDE_TESTS=True"
+
+             ;; Find libgcc_s, crtbegin.o, and crtend.o.
+             (string-append "-DGCC_INSTALL_PREFIX="
+                            (assoc-ref %build-inputs "gcc-lib"))
+
+             ;; Use a sane default include directory.
+             (string-append "-DC_INCLUDE_DIRS="
+                            (assoc-ref %build-inputs "libc")
+                            "/include"))
+
+       ;; Don't use '-g' during the build to save space.
+       #:build-type "Release"
+
+       #:phases (modify-phases %standard-phases
+                  (add-after
+                   'unpack 'set-glibc-file-names
+                   (lambda* (#:key inputs #:allow-other-keys)
+                     (let ((libc (assoc-ref inputs "libc")))
+                       ;; Patch the 'getLinuxDynamicLinker' function to that
+                       ;; it uses the right dynamic linker file name.
+                       (substitute* "lib/Driver/Tools.cpp"
+                         (("/lib64/ld-linux-x86-64.so.2")
+                          (string-append libc
+                                         ,(glibc-dynamic-linker))))
+
+                       ;; Same for libc's libdir, to allow crt1.o & co. to be
+                       ;; found.
+                       (substitute* "lib/Driver/ToolChains.cpp"
+                         (("@GLIBC_LIBDIR@")
+                          (string-append libc "/lib")))))))))
+
+    ;; Clang supports the same environment variables as GCC.
+    (native-search-paths
+     (list (search-path-specification
+            (variable "CPATH")
+            (files '("include")))
+           (search-path-specification
+            (variable "LIBRARY_PATH")
+            (files '("lib" "lib64")))))
+
     (home-page "http://clang.llvm.org")
     (synopsis "C language family frontend for LLVM")
     (description
diff --git a/gnu/packages/patches/clang-libc-search-path.patch b/gnu/packages/patches/clang-libc-search-path.patch
new file mode 100644
index 0000000000..327336ac09
--- /dev/null
+++ b/gnu/packages/patches/clang-libc-search-path.patch
@@ -0,0 +1,19 @@
+Clang attempts to guess file names based on the OS and distro (yes!),
+but unfortunately, that doesn't work for us.
+
+This patch makes it easy to insert libc's $libdir so that Clang passes the
+correct absolute file name of crt1.o etc. to 'ld'.
+
+--- cfe-3.6.0.src/lib/Driver/ToolChains.cpp	2015-02-18 22:03:07.000000000 +0100
++++ cfe-3.6.0.src/lib/Driver/ToolChains.cpp	2015-06-19 16:37:20.459701044 +0200
+@@ -3085,6 +3085,10 @@ Linux::Linux(const Driver &D, const llvm
+ 
+   addPathIfExists(SysRoot + "/lib", Paths);
+   addPathIfExists(SysRoot + "/usr/lib", Paths);
++
++  // Add libc's lib/ directory to the search path, so that crt1.o, crti.o,
++  // and friends can be found.
++  addPathIfExists("@GLIBC_LIBDIR@", Paths);
+ }
+ 
+ bool Linux::HasNativeLLVMSupport() const {
diff --git a/gnu/packages/patches/guile-linux-syscalls.patch b/gnu/packages/patches/guile-linux-syscalls.patch
index 25a5e90e35..ac74d021d7 100644
--- a/gnu/packages/patches/guile-linux-syscalls.patch
+++ b/gnu/packages/patches/guile-linux-syscalls.patch
@@ -3,11 +3,9 @@ This patch adds bindings to Linux syscalls for which glibc has symbols.
 Using the FFI would have been nice, but that's not an option when using
 a statically-linked Guile in an initrd that doesn't have libc.so around.
 
-diff --git a/libguile/posix.c b/libguile/posix.c
-index 324f21b..cbee94d 100644
---- a/libguile/posix.c
-+++ b/libguile/posix.c
-@@ -2245,6 +2245,263 @@ scm_init_popen (void)
+--- guile-2.0.11/libguile/posix.c.orig	2014-02-28 15:01:27.000000000 -0500
++++ guile-2.0.11/libguile/posix.c	2015-06-21 14:28:23.624251038 -0400
+@@ -2245,6 +2245,269 @@
  }
  #endif
  
@@ -26,15 +24,18 @@ index 324f21b..cbee94d 100644
 +#define FUNC_NAME s_scm_mount
 +{
 +  int err;
-+  char *c_source, *c_target, *c_type;
++  char *c_source, *c_target, *c_type, *c_data;
 +  unsigned long c_flags;
-+  void *c_data;
 +
 +  c_source = scm_to_locale_string (source);
 +  c_target = scm_to_locale_string (target);
 +  c_type = scm_to_locale_string (type);
 +  c_flags = SCM_UNBNDP (flags) ? 0 : scm_to_ulong (flags);
-+  c_data = SCM_UNBNDP (data) ? NULL : scm_to_pointer (data);
++
++  if (SCM_UNBNDP (data) || scm_is_false (data))
++    c_data = NULL;
++  else
++    c_data = scm_to_locale_string (data);
 +
 +  err = mount (c_source, c_target, c_type, c_flags, c_data);
 +  if (err != 0)
@@ -44,6 +45,9 @@ index 324f21b..cbee94d 100644
 +  free (c_target);
 +  free (c_type);
 +
++  if (c_data != NULL)
++    free (c_data);
++
 +  if (err != 0)
 +    {
 +      errno = err;
@@ -271,5 +275,3 @@ index 324f21b..cbee94d 100644
  void
  scm_init_posix ()
  {
--- 
-2.4.1
diff --git a/gnu/packages/ruby.scm b/gnu/packages/ruby.scm
index ff30c4988a..af87cf551f 100644
--- a/gnu/packages/ruby.scm
+++ b/gnu/packages/ruby.scm
@@ -88,6 +88,39 @@ a focus on simplicity and productivity.")
     (home-page "https://ruby-lang.org")
     (license license:ruby)))
 
+(define-public ruby-2.1
+  (package (inherit ruby)
+    (version "2.1.6")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "http://cache.ruby-lang.org/pub/ruby/"
+                           (version-major+minor version)
+                           "/ruby-" version ".tar.bz2"))
+       (sha256
+        (base32
+         "1sbcmbhadcxk0509svwxbm2vvgmpf3xjxr1397bgp9x46nz36lkv"))))
+    (arguments
+     `(#:test-target "test"
+       #:parallel-tests? #f
+       #:phases
+        (alist-cons-before
+         'configure 'replace-bin-sh
+         (lambda _
+           (substitute* '("Makefile.in"
+                          "ext/pty/pty.c"
+                          "io.c"
+                          "lib/mkmf.rb"
+                          "process.c")
+             (("/bin/sh") (which "sh"))))
+         %standard-phases)))
+    (native-search-paths
+     (list (search-path-specification
+            (variable "GEM_PATH")
+            (files (list (string-append "lib/ruby/gems/"
+                                        (version-major+minor version)
+                                        ".0"))))))))
+
 (define-public ruby-1.8
   (package (inherit ruby)
     (version "1.8.7-p374")
diff --git a/gnu/packages/video.scm b/gnu/packages/video.scm
index b923e47444..c118b2fe50 100644
--- a/gnu/packages/video.scm
+++ b/gnu/packages/video.scm
@@ -296,14 +296,14 @@ standards (MPEG-2, MPEG-4 ASP/H.263, MPEG-4 AVC/H.264, and VC-1/VMW3).")
 (define-public ffmpeg
   (package
     (name "ffmpeg")
-    (version "2.7")
+    (version "2.7.1")
     (source (origin
              (method url-fetch)
              (uri (string-append "http://www.ffmpeg.org/releases/ffmpeg-"
                                  version ".tar.bz2"))
              (sha256
               (base32
-               "0jl43b63b20db3yia5xxp0hh8zwdbirk5k9p1d7416nq1b5ckfx8"))))
+               "087pyx1wxvniq3wgj6z80wrb7ampwwsmwndmr7lymzhm4iyvj1vy"))))
     (build-system gnu-build-system)
     (inputs
      `(("fontconfig" ,fontconfig)
diff --git a/gnu/system/file-systems.scm b/gnu/system/file-systems.scm
index db861baed2..05c77fe3e8 100644
--- a/gnu/system/file-systems.scm
+++ b/gnu/system/file-systems.scm
@@ -39,6 +39,7 @@
             %pseudo-terminal-file-system
             %devtmpfs-file-system
             %immutable-store
+            %control-groups
 
             %base-file-systems
 
@@ -152,13 +153,31 @@ file system."
     (check? #f)
     (flags '(read-only bind-mount))))
 
+(define %control-groups
+  (cons (file-system
+          (device "cgroup")
+          (mount-point "/sys/fs/cgroup")
+          (type "tmpfs")
+          (check? #f))
+        (map (lambda (subsystem)
+               (file-system
+                 (device "cgroup")
+                 (mount-point (string-append "/sys/fs/cgroup/" subsystem))
+                 (type "cgroup")
+                 (check? #f)
+                 (options subsystem)
+                 (create-mount-point? #t)))
+             '("cpuset" "cpu" "cpuacct" "memory" "devices" "freezer"
+               "blkio" "perf_event" "hugetlb"))))
+
 (define %base-file-systems
   ;; List of basic file systems to be mounted.  Note that /proc and /sys are
   ;; currently mounted by the initrd.
-  (list %devtmpfs-file-system
-        %pseudo-terminal-file-system
-        %shared-memory-file-system
-        %immutable-store))
+  (append (list %devtmpfs-file-system
+                %pseudo-terminal-file-system
+                %shared-memory-file-system
+                %immutable-store)
+          %control-groups))
 
 
 
diff --git a/guix/gexp.scm b/guix/gexp.scm
index 10056e5a1f..0b5c43e2b8 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -157,7 +157,7 @@ cross-compiling.)"
   (recursive? local-file-recursive?))             ;Boolean
 
 (define* (local-file file #:optional (name (basename file))
-                     #:key (recursive? #t))
+                     #:key recursive?)
   "Return an object representing local file FILE to add to the store; this
 object can be used in a gexp.  FILE will be added to the store under NAME--by
 default the base name of FILE.
@@ -167,7 +167,11 @@ designates a flat file and RECURSIVE? is true, its contents are added, and its
 permission bits are kept.
 
 This is the declarative counterpart of the 'interned-file' monadic procedure."
-  (%local-file file name recursive?))
+  ;; Canonicalize FILE so that if it's a symlink, it is resolved.  Failing to
+  ;; do that, when RECURSIVE? is #t, we could end up creating a dangling
+  ;; symlink in the store, and when RECURSIVE? is #f 'add-to-store' would just
+  ;; throw an error, both of which are inconvenient.
+  (%local-file (canonicalize-path file) name recursive?))
 
 (define-gexp-compiler (local-file-compiler (file local-file?) system target)
   ;; "Compile" FILE by adding it to the store.
diff --git a/guix/store.scm b/guix/store.scm
index 933708defc..7b13334952 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -610,11 +610,12 @@ path."
                                  store-path)))
     (lambda (server basename recursive? hash-algo file-name)
       "Add the contents of FILE-NAME under BASENAME to the store.  When
-RECURSIVE? is true and FILE-NAME designates a directory, the contents of
-FILE-NAME are added recursively; if FILE-NAME designates a flat file and
-RECURSIVE? is true, its contents are added, and its permission bits are
-kept.  HASH-ALGO must be a string such as \"sha256\"."
-      (let* ((st    (stat file-name #f))
+RECURSIVE? is false, FILE-NAME must designate a regular file--not a directory
+nor a symlink.  When RECURSIVE? is true and FILE-NAME designates a directory,
+the contents of FILE-NAME are added recursively; if FILE-NAME designates a
+flat file and RECURSIVE? is true, its contents are added, and its permission
+bits are kept.  HASH-ALGO must be a string such as \"sha256\"."
+      (let* ((st    (false-if-exception (lstat file-name)))
              (args  `(,st ,basename ,recursive? ,hash-algo))
              (cache (nix-server-add-to-store-cache server)))
         (or (and st (hash-ref cache args))
diff --git a/tests/gexp.scm b/tests/gexp.scm
index 7e14073fd4..32031663f5 100644
--- a/tests/gexp.scm
+++ b/tests/gexp.scm
@@ -101,7 +101,7 @@
   (let* ((file  (search-path %load-path "guix.scm"))
          (local (local-file file))
          (exp   (gexp (display (ungexp local))))
-         (intd  (add-to-store %store (basename file) #t
+         (intd  (add-to-store %store (basename file) #f
                               "sha256" file)))
     (and (gexp? exp)
          (match (gexp-inputs exp)
@@ -109,6 +109,25 @@
             (eq? x local)))
          (equal? `(display ,intd) (gexp->sexp* exp)))))
 
+(test-assert "one local file, symlink"
+  (let ((file (search-path %load-path "guix.scm"))
+        (link (tmpnam)))
+    (dynamic-wind
+      (const #t)
+      (lambda ()
+        (symlink (canonicalize-path file) link)
+        (let* ((local (local-file link "my-file" #:recursive? #f))
+               (exp   (gexp (display (ungexp local))))
+               (intd  (add-to-store %store "my-file" #f
+                                    "sha256" file)))
+          (and (gexp? exp)
+               (match (gexp-inputs exp)
+                 (((x "out"))
+                  (eq? x local)))
+               (equal? `(display ,intd) (gexp->sexp* exp)))))
+      (lambda ()
+        (false-if-exception (delete-file link))))))
+
 (test-assert "one plain file"
   (let* ((file     (plain-file "hi" "Hello, world!"))
          (exp      (gexp (display (ungexp file))))
@@ -360,7 +379,7 @@
 
 (test-assertm "gexp->derivation, local-file"
   (mlet* %store-monad ((file ->  (search-path %load-path "guix.scm"))
-                       (intd     (interned-file file))
+                       (intd     (interned-file file #:recursive? #f))
                        (local -> (local-file file))
                        (exp ->   (gexp (begin
                                          (stat (ungexp local))