summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2013-07-09 22:17:18 +0200
committerLudovic Courtès <ludo@gnu.org>2013-07-09 22:17:18 +0200
commitc769406010156190c76c435c90d5f08ae56c2ca4 (patch)
tree1088a364c987cc6e7dc0bea4918cb498b34649b5
parentee48b283fadca825ca08500eeb3870fd4141221e (diff)
parent91ef73d4642658829facee25ffdc91a48d6ccf73 (diff)
downloadguix-c769406010156190c76c435c90d5f08ae56c2ca4.tar.gz
Merge branch 'core-updates'
-rw-r--r--.gitignore2
-rw-r--r--HACKING101
-rw-r--r--Makefile.am27
-rw-r--r--build-aux/hydra/gnu-system.scm15
-rw-r--r--doc/guix.texi336
-rw-r--r--doc/images/bootstrap-graph.dot83
-rw-r--r--gnu-system.am1
-rw-r--r--gnu/packages/acl.scm11
-rw-r--r--gnu/packages/attr.scm18
-rw-r--r--gnu/packages/base.scm20
-rw-r--r--gnu/packages/bash.scm9
-rw-r--r--gnu/packages/bdw-gc.scm24
-rw-r--r--gnu/packages/bootstrap.scm5
-rw-r--r--gnu/packages/compression.scm4
-rw-r--r--gnu/packages/cross-base.scm38
-rw-r--r--gnu/packages/gawk.scm24
-rw-r--r--gnu/packages/gcc.scm259
-rw-r--r--gnu/packages/gettext.scm53
-rw-r--r--gnu/packages/guile.scm17
-rw-r--r--gnu/packages/ld-wrapper.scm29
-rw-r--r--gnu/packages/libffi.scm16
-rw-r--r--gnu/packages/libsigsegv.scm4
-rw-r--r--gnu/packages/linux.scm10
-rw-r--r--gnu/packages/make-bootstrap.scm214
-rw-r--r--gnu/packages/multiprecision.scm7
-rw-r--r--gnu/packages/ncurses.scm2
-rw-r--r--gnu/packages/patches/gettext-gets-undeclared.patch77
-rw-r--r--gnu/packages/readline.scm4
-rw-r--r--guix/build-system/gnu.scm102
-rw-r--r--guix/build-system/trivial.scm3
-rw-r--r--guix/build/gnu-build-system.scm118
-rw-r--r--guix/build/gnu-cross-build.scm138
-rw-r--r--guix/build/utils.scm16
33 files changed, 1021 insertions, 766 deletions
diff --git a/.gitignore b/.gitignore
index 9ccddce8c2..f97a3b5f3d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,3 +74,5 @@ stamp-h[0-9]
 /doc/guix.vr
 /doc/guix.vrs
 /nix/scripts/substitute-binary
+/doc/images/bootstrap-graph.png
+/doc/images/bootstrap-graph.eps
diff --git a/HACKING b/HACKING
index dd59a68b11..9d8960c1ab 100644
--- a/HACKING
+++ b/HACKING
@@ -40,16 +40,6 @@ addition to that, you must not miss [[http://www.emacswiki.org/emacs/ParEdit][Pa
 directly operate on the syntax tree, such as raising an s-expression or
 wrapping it, swallowing or rejecting the following s-expression, etc.
 
-* Packaging Guidelines
-
-The GNU distribution is about respecting the freedom of users.  Consequently,
-it contains only free software as defined at
-http://www.gnu.org/philosophy/free-sw.html .
-
-In addition, we follow the [[http://www.gnu.org/distros/free-system-distribution-guidelines.html][free software distribution guidelines]].  Among other
-things, this means that the distribution tries hard not to steer users towards
-obtaining information about non-free software.
-
 * Adding new packages
 
 Package recipes in Guix look like this:
@@ -127,94 +117,3 @@ after two weeks, and if you’re confident, it’s OK to commit.
 
 That last part is subject to being adjusted, allowing individuals to commit
 directly on non-controversial changes on parts they’re familiar with.
-
-* Porting the Guix distro on a new platform
-
-** Introduction
-
-Unlike Make or similar build tools, Guix requires absolutely /all/ the
-dependencies of a build process to be specified.
-
-For a user-land software distribution, that means that the process that
-builds GCC (then used to build all other programs) must itself be
-specified; and the process to build the C library to build that GCC; and
-the process to build the GCC to build that library; and...  See the
-problem?  Chicken-and-egg.
-
-To break that cycle, the distro starts from a set of pre-built
-binaries–usually referred to as “bootstrap binaries.”  These include
-statically-linked versions of Guile, GCC, Coreutils, Grep, sed,
-etc., and the GNU C Library.
-
-This section describes how to build those bootstrap binaries when
-porting to a new platform.
-
-** When the platform is supported by Nixpkgs
-
-In that case, the easiest thing is to bootstrap the distro using
-binaries from Nixpkgs.
-
-To do that, you need to comment out the definitions of
-‘%bootstrap-guile’ and ‘%bootstrap-inputs’ in gnu/packages/bootstrap.scm
-to force the use of Nixpkgs derivations.  For instance, when porting to
-‘i686-linux’, you should redefine these variables along these lines:
-
-#+BEGIN_SRC scheme
-  (define %bootstrap-guile
-    (nixpkgs-derivation "guile" "i686-linux"))
-  
-  (define %bootstrap-inputs
-    (compile-time-value
-     `(("libc" ,(nixpkgs-derivation "glibc" "i686-linux"))
-       ,@(map (lambda (name)
-                (list name (nixpkgs-derivation name "i686-linux")))
-              '("gnutar" "gzip" "bzip2" "xz" "patch"
-                "coreutils" "gnused" "gnugrep" "bash"
-                "gawk"                                ; used by `config.status'
-                "gcc" "binutils")))))
-#+END_SRC
-
-That should allow the distro to be bootstrapped.
-
-Then, the tarballs containing the initial binaries of Guile, Coreutils,
-GCC, libc, etc. need to be built.  To that end, run the following
-commands:
-
-#+BEGIN_SRC sh
-  ./pre-inst-env guix build -K                                    \
-      -e '(@ (gnu packages make-bootstrap) %bootstrap-tarballs)'  \
-      --system=i686-linux
-
-#+END_SRC
-
-These should build tarballs containing statically-linked tools usable on
-that system.
-
-In the source tree, you need to install binaries for ‘mkdir’, ‘bash’,
-‘tar’, and ‘xz’ under ‘gnu/packages/bootstrap/i686-linux’.  These
-binaries can be extracted from the static-binaries tarball built above.
-
-A rule for ‘gnu/packages/bootstrap/i686-linux/guile-2.0.7.tar.xz’
-needs to be added in ‘Makefile.am’, with the appropriate hexadecimal
-vrepresentation of its SHA256 hash.
-
-You may then revert your changes to ‘bootstrap.scm’.  For the variables
-‘%bootstrap-coreutils&co’, ‘%bootstrap-binutils’, ‘%bootstrap-glibc’,
-and ‘%bootstrap-gcc’, the expected SHA256 of the corresponding tarballs
-for ‘i686-linux’ (built above) must be added.
-
-This should be enough to bootstrap the distro without resorting to
-Nixpkgs.
-
-** When the platform is *not* supported by Nixpkgs
-
-In that case, the bootstrap binaries should be built using whatever
-tools are available on the target platform.  That is, the tarballs and
-binaries show above must first be built manually, using the available
-tools.
-
-They should have the same properties as those built by the Guix recipes
-shown above.  For example, all the binaries (except for glibc) must be
-statically-linked; the bootstrap Guile must be relocatable (see patch in
-the Guix distro); the static-binaries tarball must contain the same
-programs (Coreutils, Grep, sed, Awk, etc.); and so on.
diff --git a/Makefile.am b/Makefile.am
index 9d872313e7..189b637be3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -60,7 +60,6 @@ MODULES =					\
   guix/build/download.scm			\
   guix/build/cmake-build-system.scm		\
   guix/build/gnu-build-system.scm		\
-  guix/build/gnu-cross-build.scm		\
   guix/build/perl-build-system.scm		\
   guix/build/python-build-system.scm		\
   guix/build/utils.scm				\
@@ -172,7 +171,31 @@ $(guix_install_go_files): install-nobase_dist_guilemoduleDATA
 SUBDIRS = po
 
 info_TEXINFOS = doc/guix.texi
-EXTRA_DIST += doc/fdl-1.3.texi
+EXTRA_DIST +=					\
+  doc/fdl-1.3.texi				\
+  doc/images/bootstrap-graph.dot		\
+  doc/images/bootstrap-graph.eps
+
+infoimagedir = $(infodir)/images
+dist_infoimage_DATA = doc/images/bootstrap-graph.png
+
+# Try hard to obtain an image size and aspect that's reasonable for inclusion
+# in an Info or PDF document.
+DOT_OPTIONS =						\
+  -Tpng -Gratio=.9 -Gnodesep=.005 -Granksep=.00005	\
+  -Nfontsize=9 -Nheight=.1 -Nwidth=.1
+
+.dot.png:
+	dot -Tpng $(DOT_OPTIONS) < "$<" > "$@.tmp"
+	mv "$@.tmp" "$@"
+
+.dot.eps:
+	dot -Teps $(DOT_OPTIONS) < "$<" > "$@.tmp"
+	mv "$@.tmp" "$@"
+
+doc/guix.pdf: doc/images/bootstrap-graph.png
+doc/guix.info: doc/images/bootstrap-graph.png
+doc/guix.ps: doc/images/bootstrap-graph.eps
 
 if BUILD_DAEMON
 
diff --git a/build-aux/hydra/gnu-system.scm b/build-aux/hydra/gnu-system.scm
index f03c201223..de3cd1154b 100644
--- a/build-aux/hydra/gnu-system.scm
+++ b/build-aux/hydra/gnu-system.scm
@@ -79,15 +79,16 @@ SYSTEM."
 (define %packages-to-cross-build
   (list gmp mpfr mpc coreutils findutils diffutils patch sed grep
         gawk gettext hello guile-2.0
-        ;; %bootstrap-binaries-tarball
-        ;; %binutils-bootstrap-tarball
-        ;; %glibc-bootstrap-tarball
-        ;; %gcc-bootstrap-tarball
-        ;; %guile-bootstrap-tarball
-        ))
+        %bootstrap-binaries-tarball
+        %binutils-bootstrap-tarball
+        %glibc-bootstrap-tarball
+        %gcc-bootstrap-tarball
+        %guile-bootstrap-tarball
+        %bootstrap-tarballs))
 
 (define %cross-targets
-  '("mips64el-linux-gnu"))
+  '("mips64el-linux-gnu"
+    "mips64el-linux-gnuabi64"))
 
 (define (hydra-jobs store arguments)
   "Return Hydra jobs."
diff --git a/doc/guix.texi b/doc/guix.texi
index 23e8351c02..0eac8ea277 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -399,6 +399,7 @@ management tools it provides.
 @menu
 * Features::                    How Guix will make your life brighter.
 * Invoking guix package::       Package installation, removal, etc.
+* Packages with Multiple Outputs:: Single source package, multiple outputs.
 * Invoking guix gc::            Running the garbage collector.
 * Invoking guix pull::          Fetching the latest Guix and distribution.
 @end menu
@@ -507,7 +508,8 @@ Install @var{package}.
 such as @code{guile-1.8.8}.  If no version number is specified, the
 newest available version will be selected.  In addition, @var{package}
 may contain a colon, followed by the name of one of the outputs of the
-package, as in @code{gcc:doc} or @code{binutils-2.22:lib}.
+package, as in @code{gcc:doc} or @code{binutils-2.22:lib}
+(@pxref{Packages with Multiple Outputs}).
 
 @cindex propagated inputs
 Sometimes packages have @dfn{propagated inputs}: these are dependencies
@@ -658,12 +660,60 @@ List packages currently available in the software distribution
 installed packages whose name matches @var{regexp}.
 
 For each package, print the following items separated by tabs: its name,
-its version string, the parts of the package (@code{out} for the main
-files, @code{lib} for libraries and possibly headers, etc.), and the
-source location of its definition.
+its version string, the parts of the package (@pxref{Packages with
+Multiple Outputs}), and the source location of its definition.
 
 @end table
 
+@node Packages with Multiple Outputs
+@section Packages with Multiple Outputs
+
+@cindex multiple-output packages
+@cindex package outputs
+
+Often, packages defined in Guix have a single @dfn{output}---i.e., the
+source package leads exactly one directory in the store.  When running
+@command{guix package -i glibc}, one installs the default output of the
+GNU libc package; the default output is called @code{out}, but its name
+can be omitted as shown in this command.  In this particular case, the
+default output of @code{glibc} contains all the C header files, shared
+libraries, static libraries, Info documentation, and other supporting
+files.
+
+Sometimes it is more appropriate to separate the various types of files
+produced from a single source package into separate outputs.  For
+instance, the GLib C library (used by GTK+ and related packages)
+installs more than 20 MiB of reference documentation as HTML pages.
+To save space for users who do not need it, the documentation goes to a
+separate output, called @code{doc}.  To install the main GLib output,
+which contains everything but the documentation, one would run:
+
+@example
+guix package -i glib
+@end example
+
+The command to install its documentation is:
+
+@example
+guix package -i glib:doc
+@end example
+
+Some packages install programs with different ``dependency footprints''.
+For instance, the WordNet package install both command-line tools and
+graphical user interfaces (GUIs).  The former depend solely on the C
+library, whereas the latter depend on Tcl/Tk and the underlying X
+libraries.  In this case, we leave the command-line tools in the default
+output, whereas the GUIs are in a separate output.  This allows users
+who do not need the GUIs to save space.
+
+There are several such multiple-output packages in the GNU distribution.
+Other conventional output names include @code{lib} for libraries and
+possibly header files, @code{bin} for stand-alone programs, and
+@code{debug} for debugging information (@pxref{Installing Debugging
+Files}).  The outputs of a packages are listed in the third column of
+the output of @command{guix package --list-available} (@pxref{Invoking
+guix package}).
+
 
 @node Invoking guix gc
 @section Invoking @command{guix gc}
@@ -1426,28 +1476,278 @@ guix package}):
 guix package --list-available
 @end example
 
-The package definitions of the distribution may are provided by Guile
-modules in the @code{(gnu packages ...)} name space---for instance, the
-@code{(gnu packages emacs)} module exports a variable named
-@code{emacs}, which is bound to a @code{<package>} object
-(@pxref{Defining Packages}).  The @code{(gnu packages)} module provides
-facilities for searching for packages.
+Our goal is to build a practical 100% free software distribution of
+Linux-based and other variants of GNU, with a focus on the promotion and
+tight integration of GNU components, and an emphasis on programs and
+tools that help users exert that freedom.
+
+@menu
+* Packaging Guidelines::        What goes into the distribution.
+* Installing Debugging Files::  Feeding the debugger.
+* Package Modules::             Packages from the programmer's viewpoint.
+* Bootstrapping::               GNU/Linux built from scratch.
+* Porting::                     Targeting another platform or kernel.
+@end menu
+
+Building this distribution is a cooperative effort, and you are invited
+to join!  @ref{Contributing}, for information about how you can help.
+
+@node Packaging Guidelines
+@section Packaging Guidelines
+
+@c Adapted from http://www.gnu.org/philosophy/philosophy.html.
+
+The GNU operating system has been developed so that users can have
+freedom in their computing.  GNU is @dfn{free software}, meaning that
+users have the @url{http://www.gnu.org/philosophy/free-sw.html,four
+essential freedoms}: to run the program, to study and change the program
+in source code form, to redistribute exact copies, and to distribute
+modified versions.  Packages found in the GNU distribution provide only
+software that conveys these four freedoms.
+
+In addition, the GNU distribution follow the
+@url{http://www.gnu.org/distros/free-system-distribution-guidelines.html,free
+software distribution guidelines}.  Among other things, these guidelines
+reject non-free firmware, recommendations of non-free software, and
+discuss ways to deal with trademarks and patents.
+
+
+@node Installing Debugging Files
+@section Installing Debugging Files
+
+Program binaries, as produced by the GCC compilers for instance, are
+typically written in the ELF format, with a section containing
+@dfn{debugging information}.  Debugging information is what allows the
+debugger, GDB, to map binary code to source code; it is required to
+debug a compiled program in good conditions.
+
+The problem with debugging information is that is takes up a fair amount
+of disk space.  For example, debugging information for the GNU C Library
+weighs in at more than 60 MiB.  Thus, as a user, keeping all the
+debugging info of all the installed programs is usually not an option.
+Yet, space savings should not come at the cost of an impediment to
+debugging---especially in the GNU system, which should make it easier
+for users to exert their computing freedom (@pxref{GNU Distribution}).
+
+Thankfully, the GNU Binary Utilities (Binutils) and GDB provide a
+mechanism that allows users to get the best of both worlds: debugging
+information can be stripped from the binaries and stored in separate
+files.  GDB is then able to load debugging information from those files,
+when they are available (@pxref{Separate Debug Files,,, gdb, Debugging
+with GDB}).
+
+The GNU distribution takes advantage of this by storing debugging
+information in the @code{lib/debug} sub-directory of a separate package
+output unimaginatively called @code{debug} (@pxref{Packages with
+Multiple Outputs}).  Users can choose to install the @code{debug} output
+of a package when they need it.  For instance, the following command
+installs the debugging information for the GNU C Library and for GNU
+Guile:
+
+@example
+guix package -i glibc:debug -i guile:debug
+@end example
+
+GDB must then be told to look for debug files in the user's profile, by
+setting the @code{debug-file-directory} variable (consider setting it
+from the @file{~/.gdbinit} file, @pxref{Startup,,, gdb, Debugging with
+GDB}):
+
+@example
+(gdb) set debug-file-directory ~/.guix-profile/lib/debug
+@end example
+
+From there on, GDB will pick up debugging information from the
+@code{.debug} files under @file{~/.guix-profile/lib/debug}.
+
+@c XXX: keep me up-to-date
+The @code{debug} output mechanism in Guix is implemented by the
+@code{gnu-build-system} (@pxref{Defining Packages}).  Currently, it is
+opt-in---debugging information is available only for those packages
+whose definition explicitly declares a @code{debug} output.  This may be
+changed to opt-out in the future, if our build farm servers can handle
+the load.  To check whether a package has a @code{debug} output, use
+@command{guix package --list-available} (@pxref{Invoking guix package}).
+
+
+@node Package Modules
+@section Package Modules
+
+From a programming viewpoint, the package definitions of the
+distribution are provided by Guile modules in the @code{(gnu packages
+...)} name space---for instance, the @code{(gnu packages emacs)} module
+exports a variable named @code{emacs}, which is bound to a
+@code{<package>} object (@pxref{Defining Packages}).  The @code{(gnu
+packages)} module provides facilities for searching for packages.
 
 The distribution is fully @dfn{bootstrapped} and @dfn{self-contained}:
 each package is built based solely on other packages in the
 distribution.  The root of this dependency graph is a small set of
 @dfn{bootstrap binaries}, provided by the @code{(gnu packages
-bootstrap)} module.  These are statically-linked binaries of the core
-tools without which building anything at all would be impossible.
+bootstrap)} module.  More on this in the next section.
+
+
+@node Bootstrapping
+@section Bootstrapping
+
+@c Adapted from the ELS 2013 paper.
+
+@cindex bootstrapping
+
+Bootstrapping in our context refers to how the distribution gets built
+``from nothing''.  Remember that the build environment of a derivation
+contains nothing but its declared inputs (@pxref{Introduction}).  So
+there's an obvious chicken-and-egg problem: how does the first package
+get built?  How does the first compiler get compiled?  Note that this is
+a question of interest only to the curious hacker, not to the regular
+user, so you can shamelessly skip this section if you consider yourself
+a ``regular user''.
+
+@cindex bootstrap binaries
+The GNU system is primarily made of C code, with libc at its core.  The
+GNU build system itself assumes the availability of a Bourne shell and
+command-line tools provided by GNU Coreutils, Awk, Findutils, `sed', and
+`grep'.  Furthermore, build programs---programs that run
+@code{./configure}, @code{make}, etc.---are written in Guile Scheme
+(@pxref{Derivations}).  Consequently, to be able to build anything at
+all, from scratch, Guix relies on pre-built binaries of Guile, GCC,
+Binutils, libc, and the other packages mentioned above---the
+@dfn{bootstrap binaries}.
+
+These bootstrap binaries are ``taken for granted'', though we can also
+re-create them if needed (more on that later.)
+
+@unnumberedsubsec Preparing to Use the Bootstrap Binaries
+
+@c As of Emacs 24.3, Info-mode displays the image, but since it's a
+@c large image, it's hard to scroll.  Oh well.
+@image{images/bootstrap-graph,,,Dependency graph of the early bootstrap derivations}
+
+The figure above shows the very beginning of the dependency graph of the
+distribution, corresponding to the package definitions of the @code{(gnu
+packages bootstrap)} module.  At this level of detail, things are
+slightly complex.  First, Guile itself consists of an ELF executable,
+along with many source and compiled Scheme files that are dynamically
+loaded when it runs.  This gets stored in the @file{guile-2.0.7.tar.xz}
+tarball shown in this graph.  This tarball is part of Guix's ``source''
+distribution, and gets inserted into the store with @code{add-to-store}
+(@pxref{The Store}).
 
+But how do we write a derivation that unpacks this tarball and adds it
+to the store?  To solve this problem, the @code{guile-bootstrap-2.0.drv}
+derivation---the first one that gets built---uses @code{bash} as its
+builder, which runs @code{build-bootstrap-guile.sh}, which in turn calls
+@code{tar} to unpack the tarball.  Thus, @file{bash}, @file{tar},
+@file{xz}, and @file{mkdir} are statically-linked binaries, also part of
+the Guix source distribution, whose sole purpose is to allow the Guile
+tarball to be unpacked.
+
+Once @code{guile-bootstrap-2.0.drv} is built, we have a functioning
+Guile that can be used to run subsequent build programs.  Its first task
+is to download tarballs containing the other pre-built binaries---this
+is what the @code{.tar.xz.drv} derivations do.  Guix modules such as
+@code{ftp-client.scm} are used for this purpose.  The
+@code{module-import.drv} derivations import those modules in a directory
+in the store, using the original layout.  The
+@code{module-import-compiled.drv} derivations compile those modules, and
+write them in an output directory with the right layout.  This
+corresponds to the @code{#:modules} argument of
+@code{build-expression->derivation} (@pxref{Derivations}).
+
+Finally, the various tarballs are unpacked by the
+derivations @code{gcc-bootstrap-0.drv}, @code{glibc-bootstrap-0.drv},
+etc., at which point we have a working C tool chain.
+
+
+@unnumberedsubsec Building the Build Tools
+
+@c TODO: Add a package-level dependency graph generated from (gnu
+@c packages base).
+
+Bootstrapping is complete when we have a full tool chain that does not
+depend on the pre-built bootstrap tools discussed above.  This
+no-dependency requirement is verified by checking whether the files of
+the final tool chain contain references to the @file{/nix/store}
+directories of the bootstrap inputs.  The process that leads to this
+``final'' tool chain is described by the package definitions found in
+the @code{(gnu packages base)} module.
+
+@c See <http://lists.gnu.org/archive/html/gnu-system-discuss/2012-10/msg00000.html>.
+The first tool that gets built with the bootstrap binaries is
+GNU Make, which is a prerequisite for all the following packages.
+From there Findutils and Diffutils get built.
+
+Then come the first-stage Binutils and GCC, built as pseudo cross
+tools---i.e., with @code{--target} equal to @code{--host}.  They are
+used to build libc.  Thanks to this cross-build trick, this libc is
+guaranteed not to hold any reference to the initial tool chain.
+
+From there the final Binutils and GCC are built.  GCC uses @code{ld}
+from the final Binutils, and links programs against the just-built libc.
+This tool chain is used to build the other packages used by Guix and by
+the GNU Build System: Guile, Bash, Coreutils, etc.
+
+And voilà!  At this point we have the complete set of build tools that
+the GNU Build System expects.  These are in the @code{%final-inputs}
+variables of the @code{(gnu packages base)} module, and are implicitly
+used by any package that uses @code{gnu-build-system} (@pxref{Defining
+Packages}).
+
+
+@unnumberedsubsec Building the Bootstrap Binaries
+
+Because the final tool chain does not depend on the bootstrap binaries,
+those rarely need to be updated.  Nevertheless, it is useful to have an
+automated way to produce them, should an update occur, and this is what
+the @code{(gnu packages make-bootstrap)} module provides.
+
+The following command builds the tarballs containing the bootstrap
+binaries (Guile, Binutils, GCC, libc, and a tarball containing a mixture
+of Coreutils and other basic command-line tools):
 
-Our goal is to build a practical 100% free software distribution of
-Linux-based and other variants of GNU, with a focus on the promotion and
-tight integration of GNU components, and an emphasis on programs and
-tools that help users exert that freedom.
+@example
+guix build bootstrap-tarballs
+@end example
+
+The generated tarballs are those that should be referred to in the
+@code{(gnu packages bootstrap)} module mentioned at the beginning of
+this section.
+
+Still here?  Then perhaps by now you've started to wonder: when do we
+reach a fixed point?  That is an interesting question!  The answer is
+unknown, but if you would like to investigate further (and have
+significant computational and storage resources to do so), then let us
+know.
+
+@node Porting
+@section Porting to a New Platform
+
+As discussed above, the GNU distribution is self-contained, and
+self-containment is achieved by relying on pre-built ``bootstrap
+binaries'' (@pxref{Bootstrapping}).  These binaries are specific to an
+operating system kernel, CPU architecture, and application binary
+interface (ABI).  Thus, to port the distribution to a platform that is
+not yet supported, one must build those bootstrap binaries, and update
+the @code{(gnu packages bootstrap)} module to use them on that platform.
+
+Fortunately, Guix can @emph{cross compile} those bootstrap binaries.
+When everything goes well, and assuming the GNU tool chain supports the
+target platform, this can be as simple as running a command like this
+one:
+
+@example
+guix build --target=armv5tel-linux-gnueabi bootstrap-tarballs
+@end example
+
+In practice, there may be some complications.  First, it may be that the
+extended GNU triplet that specifies an ABI (like the @code{eabi} suffix
+above) is not recognized by all the GNU tools.  Typically, glibc
+recognizes some of these, whereas GCC uses an extra @code{--with-abi}
+configure flag (see @code{gcc.scm} for examples of how to handle this.)
+Second, some of the required packages could fail to build for that
+platform.  Lastly, the generated binaries could be broken for some
+reason.
 
-Building this distribution is a cooperative effort, and you are invited
-to join!  @ref{Contributing}, for information about how you can help.
 
 @c *********************************************************************
 @node Contributing
diff --git a/doc/images/bootstrap-graph.dot b/doc/images/bootstrap-graph.dot
new file mode 100644
index 0000000000..06d7f29c7a
--- /dev/null
+++ b/doc/images/bootstrap-graph.dot
@@ -0,0 +1,83 @@
+# Obtained by running "nix-store --graph" on the first GCC derivation.
+
+digraph G {
+"/nix/store/x60397za40lx0n88f51a2csfdq5xvb19-gcc-bootstrap-0.drv" [label = "gcc-bootstrap-0.drv", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/3iawic1z95112yfz5y9xdp66qbxxr8l1-tar" -> "/nix/store/x60397za40lx0n88f51a2csfdq5xvb19-gcc-bootstrap-0.drv" [color = "black"];
+"/nix/store/4sv9xhcjap6byca130fzpzzjalb7iixv-glibc-bootstrap-0.drv" -> "/nix/store/x60397za40lx0n88f51a2csfdq5xvb19-gcc-bootstrap-0.drv" [color = "red"];
+"/nix/store/8cc81w6m04csm52y247xj3gydrbz2niv-xz" -> "/nix/store/x60397za40lx0n88f51a2csfdq5xvb19-gcc-bootstrap-0.drv" [color = "green"];
+"/nix/store/96yx6013dhggr3mpg5ayxv8dm9mv2ghv-module-import.drv" -> "/nix/store/x60397za40lx0n88f51a2csfdq5xvb19-gcc-bootstrap-0.drv" [color = "blue"];
+"/nix/store/fl9cwcczfdv73vq5sr0c4rd5hqzrgvac-gcc-4.7.2.tar.xz.drv" -> "/nix/store/x60397za40lx0n88f51a2csfdq5xvb19-gcc-bootstrap-0.drv" [color = "magenta"];
+"/nix/store/jaaqdl979wjirnbxz1jqsipg22nva5n4-bash" -> "/nix/store/x60397za40lx0n88f51a2csfdq5xvb19-gcc-bootstrap-0.drv" [color = "burlywood"];
+"/nix/store/r3dsy5j2c16sv26raala6kahff7w18hb-gcc-bootstrap-0-guile-builder" -> "/nix/store/x60397za40lx0n88f51a2csfdq5xvb19-gcc-bootstrap-0.drv" [color = "black"];
+"/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" -> "/nix/store/x60397za40lx0n88f51a2csfdq5xvb19-gcc-bootstrap-0.drv" [color = "red"];
+"/nix/store/y4n7rzysx6qz3p0n91dw9qz5w93l6iqv-module-import-compiled.drv" -> "/nix/store/x60397za40lx0n88f51a2csfdq5xvb19-gcc-bootstrap-0.drv" [color = "green"];
+"/nix/store/3iawic1z95112yfz5y9xdp66qbxxr8l1-tar" [label = "tar", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/4sv9xhcjap6byca130fzpzzjalb7iixv-glibc-bootstrap-0.drv" [label = "glibc-bootstrap-0.drv", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/3iawic1z95112yfz5y9xdp66qbxxr8l1-tar" -> "/nix/store/4sv9xhcjap6byca130fzpzzjalb7iixv-glibc-bootstrap-0.drv" [color = "blue"];
+"/nix/store/8cc81w6m04csm52y247xj3gydrbz2niv-xz" -> "/nix/store/4sv9xhcjap6byca130fzpzzjalb7iixv-glibc-bootstrap-0.drv" [color = "magenta"];
+"/nix/store/8iivk9hpnps21yrbq3zzsxgzv9ixbhgh-glibc-bootstrap-0-guile-builder" -> "/nix/store/4sv9xhcjap6byca130fzpzzjalb7iixv-glibc-bootstrap-0.drv" [color = "burlywood"];
+"/nix/store/96yx6013dhggr3mpg5ayxv8dm9mv2ghv-module-import.drv" -> "/nix/store/4sv9xhcjap6byca130fzpzzjalb7iixv-glibc-bootstrap-0.drv" [color = "black"];
+"/nix/store/wdwrkg02gn28bkpbxgdb2nv558v8s3ji-glibc-2.17.tar.xz.drv" -> "/nix/store/4sv9xhcjap6byca130fzpzzjalb7iixv-glibc-bootstrap-0.drv" [color = "red"];
+"/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" -> "/nix/store/4sv9xhcjap6byca130fzpzzjalb7iixv-glibc-bootstrap-0.drv" [color = "green"];
+"/nix/store/y4n7rzysx6qz3p0n91dw9qz5w93l6iqv-module-import-compiled.drv" -> "/nix/store/4sv9xhcjap6byca130fzpzzjalb7iixv-glibc-bootstrap-0.drv" [color = "blue"];
+"/nix/store/8cc81w6m04csm52y247xj3gydrbz2niv-xz" [label = "xz", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/8iivk9hpnps21yrbq3zzsxgzv9ixbhgh-glibc-bootstrap-0-guile-builder" [label = "glibc-bootstrap-0-guile-builder", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/3iawic1z95112yfz5y9xdp66qbxxr8l1-tar" -> "/nix/store/8iivk9hpnps21yrbq3zzsxgzv9ixbhgh-glibc-bootstrap-0-guile-builder" [color = "magenta"];
+"/nix/store/8cc81w6m04csm52y247xj3gydrbz2niv-xz" -> "/nix/store/8iivk9hpnps21yrbq3zzsxgzv9ixbhgh-glibc-bootstrap-0-guile-builder" [color = "burlywood"];
+"/nix/store/96yx6013dhggr3mpg5ayxv8dm9mv2ghv-module-import.drv" [label = "module-import.drv", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/9zrdfvnrpljryr82an2n1mj6bh2przhn-module-import-guile-builder" -> "/nix/store/96yx6013dhggr3mpg5ayxv8dm9mv2ghv-module-import.drv" [color = "black"];
+"/nix/store/mj7amprgvl2rgash1nr0v64apik8vc7f-utils.scm" -> "/nix/store/96yx6013dhggr3mpg5ayxv8dm9mv2ghv-module-import.drv" [color = "red"];
+"/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" -> "/nix/store/96yx6013dhggr3mpg5ayxv8dm9mv2ghv-module-import.drv" [color = "green"];
+"/nix/store/9zrdfvnrpljryr82an2n1mj6bh2przhn-module-import-guile-builder" [label = "module-import-guile-builder", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/mj7amprgvl2rgash1nr0v64apik8vc7f-utils.scm" -> "/nix/store/9zrdfvnrpljryr82an2n1mj6bh2przhn-module-import-guile-builder" [color = "blue"];
+"/nix/store/fl9cwcczfdv73vq5sr0c4rd5hqzrgvac-gcc-4.7.2.tar.xz.drv" [label = "gcc-4.7.2.tar.xz.drv", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/6kslnirvm26fij7wpjqbw617ri4gf5x5-gcc-4.7.2.tar.xz-guile-builder" -> "/nix/store/fl9cwcczfdv73vq5sr0c4rd5hqzrgvac-gcc-4.7.2.tar.xz.drv" [color = "magenta"];
+"/nix/store/kvk5wp8c9rzvvrmq5fv5r58l78q8i6ch-module-import.drv" -> "/nix/store/fl9cwcczfdv73vq5sr0c4rd5hqzrgvac-gcc-4.7.2.tar.xz.drv" [color = "burlywood"];
+"/nix/store/pzv319p3q7raiad7nq7fcdw9rafzp14k-module-import-compiled.drv" -> "/nix/store/fl9cwcczfdv73vq5sr0c4rd5hqzrgvac-gcc-4.7.2.tar.xz.drv" [color = "black"];
+"/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" -> "/nix/store/fl9cwcczfdv73vq5sr0c4rd5hqzrgvac-gcc-4.7.2.tar.xz.drv" [color = "red"];
+"/nix/store/6kslnirvm26fij7wpjqbw617ri4gf5x5-gcc-4.7.2.tar.xz-guile-builder" [label = "gcc-4.7.2.tar.xz-guile-builder", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/jaaqdl979wjirnbxz1jqsipg22nva5n4-bash" [label = "bash", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/kvk5wp8c9rzvvrmq5fv5r58l78q8i6ch-module-import.drv" [label = "module-import.drv", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/abagrdbdndkd0y2dwk0nw1gw0g0rhl2z-ftp-client.scm" -> "/nix/store/kvk5wp8c9rzvvrmq5fv5r58l78q8i6ch-module-import.drv" [color = "green"];
+"/nix/store/dwd2iwd1ban8a8rmx568dpgrbkkidfhw-download.scm" -> "/nix/store/kvk5wp8c9rzvvrmq5fv5r58l78q8i6ch-module-import.drv" [color = "blue"];
+"/nix/store/mj7amprgvl2rgash1nr0v64apik8vc7f-utils.scm" -> "/nix/store/kvk5wp8c9rzvvrmq5fv5r58l78q8i6ch-module-import.drv" [color = "magenta"];
+"/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" -> "/nix/store/kvk5wp8c9rzvvrmq5fv5r58l78q8i6ch-module-import.drv" [color = "burlywood"];
+"/nix/store/yfixjx2gpvsi5dhkpdx5gj6gx0xdk1c8-module-import-guile-builder" -> "/nix/store/kvk5wp8c9rzvvrmq5fv5r58l78q8i6ch-module-import.drv" [color = "black"];
+"/nix/store/abagrdbdndkd0y2dwk0nw1gw0g0rhl2z-ftp-client.scm" [label = "ftp-client.scm", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/dwd2iwd1ban8a8rmx568dpgrbkkidfhw-download.scm" [label = "download.scm", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/mj7amprgvl2rgash1nr0v64apik8vc7f-utils.scm" [label = "utils.scm", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/pzv319p3q7raiad7nq7fcdw9rafzp14k-module-import-compiled.drv" [label = "module-import-compiled.drv", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/98gzqlgpm4gxrpl5bzykpqbwrx8ckx8l-module-import-compiled-guile-builder" -> "/nix/store/pzv319p3q7raiad7nq7fcdw9rafzp14k-module-import-compiled.drv" [color = "red"];
+"/nix/store/kvk5wp8c9rzvvrmq5fv5r58l78q8i6ch-module-import.drv" -> "/nix/store/pzv319p3q7raiad7nq7fcdw9rafzp14k-module-import-compiled.drv" [color = "green"];
+"/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" -> "/nix/store/pzv319p3q7raiad7nq7fcdw9rafzp14k-module-import-compiled.drv" [color = "blue"];
+"/nix/store/98gzqlgpm4gxrpl5bzykpqbwrx8ckx8l-module-import-compiled-guile-builder" [label = "module-import-compiled-guile-builder", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/r3dsy5j2c16sv26raala6kahff7w18hb-gcc-bootstrap-0-guile-builder" [label = "gcc-bootstrap-0-guile-builder", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/3iawic1z95112yfz5y9xdp66qbxxr8l1-tar" -> "/nix/store/r3dsy5j2c16sv26raala6kahff7w18hb-gcc-bootstrap-0-guile-builder" [color = "magenta"];
+"/nix/store/8cc81w6m04csm52y247xj3gydrbz2niv-xz" -> "/nix/store/r3dsy5j2c16sv26raala6kahff7w18hb-gcc-bootstrap-0-guile-builder" [color = "burlywood"];
+"/nix/store/jaaqdl979wjirnbxz1jqsipg22nva5n4-bash" -> "/nix/store/r3dsy5j2c16sv26raala6kahff7w18hb-gcc-bootstrap-0-guile-builder" [color = "black"];
+"/nix/store/wdwrkg02gn28bkpbxgdb2nv558v8s3ji-glibc-2.17.tar.xz.drv" [label = "glibc-2.17.tar.xz.drv", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/kvk5wp8c9rzvvrmq5fv5r58l78q8i6ch-module-import.drv" -> "/nix/store/wdwrkg02gn28bkpbxgdb2nv558v8s3ji-glibc-2.17.tar.xz.drv" [color = "red"];
+"/nix/store/pzv319p3q7raiad7nq7fcdw9rafzp14k-module-import-compiled.drv" -> "/nix/store/wdwrkg02gn28bkpbxgdb2nv558v8s3ji-glibc-2.17.tar.xz.drv" [color = "green"];
+"/nix/store/q7as3jddipj4g6si8lawrdbkjg0zcjvg-glibc-2.17.tar.xz-guile-builder" -> "/nix/store/wdwrkg02gn28bkpbxgdb2nv558v8s3ji-glibc-2.17.tar.xz.drv" [color = "blue"];
+"/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" -> "/nix/store/wdwrkg02gn28bkpbxgdb2nv558v8s3ji-glibc-2.17.tar.xz.drv" [color = "magenta"];
+"/nix/store/q7as3jddipj4g6si8lawrdbkjg0zcjvg-glibc-2.17.tar.xz-guile-builder" [label = "glibc-2.17.tar.xz-guile-builder", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" [label = "guile-bootstrap-2.0.drv", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/bplka3yqdg8prqq3zdxza6wxlkjdhr2g-build-bootstrap-guile.sh" -> "/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" [color = "burlywood"];
+"/nix/store/jaaqdl979wjirnbxz1jqsipg22nva5n4-bash" -> "/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" [color = "black"];
+"/nix/store/bplka3yqdg8prqq3zdxza6wxlkjdhr2g-build-bootstrap-guile.sh" [label = "build-bootstrap-guile.sh", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/3iawic1z95112yfz5y9xdp66qbxxr8l1-tar" -> "/nix/store/bplka3yqdg8prqq3zdxza6wxlkjdhr2g-build-bootstrap-guile.sh" [color = "red"];
+"/nix/store/4xv2y0m6zr2lgi8x8pcb3zxjqxsz69kj-mkdir" -> "/nix/store/bplka3yqdg8prqq3zdxza6wxlkjdhr2g-build-bootstrap-guile.sh" [color = "green"];
+"/nix/store/8cc81w6m04csm52y247xj3gydrbz2niv-xz" -> "/nix/store/bplka3yqdg8prqq3zdxza6wxlkjdhr2g-build-bootstrap-guile.sh" [color = "blue"];
+"/nix/store/c450lqvaaz3ngx9pfiiiw55rqq6ssfda-guile-2.0.7.tar.xz" -> "/nix/store/bplka3yqdg8prqq3zdxza6wxlkjdhr2g-build-bootstrap-guile.sh" [color = "magenta"];
+"/nix/store/4xv2y0m6zr2lgi8x8pcb3zxjqxsz69kj-mkdir" [label = "mkdir", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/c450lqvaaz3ngx9pfiiiw55rqq6ssfda-guile-2.0.7.tar.xz" [label = "guile-2.0.7.tar.xz", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/y4n7rzysx6qz3p0n91dw9qz5w93l6iqv-module-import-compiled.drv" [label = "module-import-compiled.drv", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/8jiqjlb6zxjys16ca7s6jvxcc620c71k-module-import-compiled-guile-builder" -> "/nix/store/y4n7rzysx6qz3p0n91dw9qz5w93l6iqv-module-import-compiled.drv" [color = "burlywood"];
+"/nix/store/96yx6013dhggr3mpg5ayxv8dm9mv2ghv-module-import.drv" -> "/nix/store/y4n7rzysx6qz3p0n91dw9qz5w93l6iqv-module-import-compiled.drv" [color = "black"];
+"/nix/store/x9x1a86flhx15cams7235rfy5gc5cww1-guile-bootstrap-2.0.drv" -> "/nix/store/y4n7rzysx6qz3p0n91dw9qz5w93l6iqv-module-import-compiled.drv" [color = "red"];
+"/nix/store/8jiqjlb6zxjys16ca7s6jvxcc620c71k-module-import-compiled-guile-builder" [label = "module-import-compiled-guile-builder", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/yfixjx2gpvsi5dhkpdx5gj6gx0xdk1c8-module-import-guile-builder" [label = "module-import-guile-builder", fontname = Helvetica, shape = box, style = filled, fillcolor = "#ffffff"];
+"/nix/store/abagrdbdndkd0y2dwk0nw1gw0g0rhl2z-ftp-client.scm" -> "/nix/store/yfixjx2gpvsi5dhkpdx5gj6gx0xdk1c8-module-import-guile-builder" [color = "green"];
+"/nix/store/dwd2iwd1ban8a8rmx568dpgrbkkidfhw-download.scm" -> "/nix/store/yfixjx2gpvsi5dhkpdx5gj6gx0xdk1c8-module-import-guile-builder" [color = "blue"];
+"/nix/store/mj7amprgvl2rgash1nr0v64apik8vc7f-utils.scm" -> "/nix/store/yfixjx2gpvsi5dhkpdx5gj6gx0xdk1c8-module-import-guile-builder" [color = "magenta"];
+}
diff --git a/gnu-system.am b/gnu-system.am
index 37072957ce..41871ed021 100644
--- a/gnu-system.am
+++ b/gnu-system.am
@@ -184,7 +184,6 @@ dist_patch_DATA =						\
   gnu/packages/patches/flex-bison-tests.patch			\
   gnu/packages/patches/gawk-shell.patch				\
   gnu/packages/patches/gcc-cross-environment-variables.patch	\
-  gnu/packages/patches/gettext-gets-undeclared.patch		\
   gnu/packages/patches/glib-tests-desktop.patch			\
   gnu/packages/patches/glib-tests-homedir.patch			\
   gnu/packages/patches/glib-tests-prlimit.patch			\
diff --git a/gnu/packages/acl.scm b/gnu/packages/acl.scm
index 54c9116baf..dde9ac4f34 100644
--- a/gnu/packages/acl.scm
+++ b/gnu/packages/acl.scm
@@ -46,7 +46,7 @@
         (lambda _
           (patch-makefile-SHELL "include/buildmacros"))
         ,(if (%current-target-system)
-             '%standard-cross-phases
+             '%standard-phases
              '(alist-replace 'check
                              (lambda _
                                (system* "make" "tests" "-C" "test")
@@ -60,14 +60,9 @@
               ;; Perl is needed to run tests; remove it from cross builds.
               ,@(if (%current-target-system)
                     '()
-                    `(("gettext" ,guix:gettext)
-                      ("perl" ,perl)))))
+                    `(("perl" ,perl)))))
     (native-inputs
-     ;; FIXME: Upon next core-updates, make gettext a native input
-     ;; unconditionally.
-     (if (%current-target-system)
-         `(("gettext" ,guix:gettext))
-         '()))
+     `(("gettext" ,guix:gettext)))
 
     (home-page
      "http://savannah.nongnu.org/projects/acl")
diff --git a/gnu/packages/attr.scm b/gnu/packages/attr.scm
index 3fb15d235f..3108a9072a 100644
--- a/gnu/packages/attr.scm
+++ b/gnu/packages/attr.scm
@@ -55,7 +55,7 @@
 
          ;; When building natively, adjust the test cases.
          ,(if (%current-target-system)
-              '%standard-cross-phases
+              '%standard-phases
               '(alist-replace 'check
                               (lambda _
                                 ;; Use the right shell.
@@ -69,17 +69,13 @@
                                 ;; dependent on the underlying file system.
                                 #t)
                               %standard-phases))))))
-    (inputs `(;; Perl is needed to run tests; remove it from cross builds.
-              ,@(if (%current-target-system)
-                    '()
-                    `(("perl" ,perl)
-                      ("gettext" ,guix:gettext)))))
-    (native-inputs
-     ;; FIXME: Upon next core-updates, make gettext a native input
-     ;; unconditionally.
+    (inputs
+     ;; Perl is needed to run tests; remove it from cross builds.
      (if (%current-target-system)
-         `(("gettext" ,guix:gettext))
-         '()))
+         '()
+         `(("perl" ,perl))))
+    (native-inputs
+     `(("gettext" ,guix:gettext)))
 
     (home-page "http://savannah.nongnu.org/projects/attr/")
     (synopsis "Library and tools for manipulating extended attributes")
diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm
index 85380549ff..9e453522ec 100644
--- a/gnu/packages/base.scm
+++ b/gnu/packages/base.scm
@@ -279,6 +279,7 @@ The tools supplied with this package are:
              ,@(if (%current-target-system)
                    '()
                    `(("perl" ,perl)))))
+   (outputs '("out" "debug"))
    (arguments
     `(#:parallel-build? #f            ; help2man may be called too early
       #:phases (alist-cons-before
@@ -293,9 +294,7 @@ The tools supplied with this package are:
                     (substitute* (find-files "tests" "\\.sh$")
                       (("#!/bin/sh")
                        (format #f "#!~a/bin/bash" bash)))))
-                ,(if (%current-target-system)
-                     '%standard-cross-phases
-                     '%standard-phases))))
+                %standard-phases)))
    (synopsis "Core GNU utilities (file, text, shell)")
    (description
     "The GNU Core Utilities are the basic file, shell and text manipulation
@@ -318,6 +317,7 @@ are expected to exist on every operating system.")
    (build-system gnu-build-system)
    (native-inputs
     `(("patch/impure-dirs" ,(search-patch "make-impure-dirs.patch"))))
+   (outputs '("out" "debug"))
    (arguments
     '(#:patches (list (assoc-ref %build-inputs "patch/impure-dirs"))
       #:phases (alist-cons-before
@@ -405,7 +405,7 @@ BFD (Binary File Descriptor) library, `gprof', `nm', `strip', etc.")
    ;; reference to them anyway, so there's no space savings here.
    ;; TODO: Eventually we may want to add a $LOCALE_ARCHIVE search path like
    ;; Nixpkgs does.
-   (outputs '("out" "locales"))
+   (outputs '("out" "locales" "debug"))
 
    (arguments
     `(#:out-of-source? #t
@@ -511,7 +511,7 @@ with the Linux kernel.")
 (define-public tzdata
   (package
     (name "tzdata")
-    (version "2013c")
+    (version "2013d")
     (source (origin
              (method url-fetch)
              (uri (string-append
@@ -519,7 +519,7 @@ with the Linux kernel.")
                    version ".tar.gz"))
              (sha256
               (base32
-               "11swq6fg20m2dh520qcr8vb23gqhzbvqhizx8wifnmci4gmsg5z5"))))
+               "08jzd8y2xkgd89wqrv3835pqr48yjabaczxr2rmg42zaykr11an0"))))
     (build-system gnu-build-system)
     (arguments
      '(#:tests? #f
@@ -566,7 +566,7 @@ with the Linux kernel.")
                                 version ".tar.gz"))
                           (sha256
                            (base32
-                            "1w6nkdwhi6k9llshp4baac1yj43jqf3apdf6n66i0wvjj8qyjvp4"))))))
+                            "13xd30ngwhqmj7w216ghd5knvg047hzpc0xca5l297g5cwb62hza"))))))
     (home-page "http://www.iana.org/time-zones")
     (synopsis "Database of current and historical time zones")
     (description "The Time Zone Database (often called tz or zoneinfo)
@@ -756,7 +756,11 @@ identifier SYSTEM."
                ;; Call it differently so that the builder can check whether
                ;; the "libc" input is #f.
                ("libc-native" ,@(assoc-ref %boot0-inputs "libc"))
-               ,@(alist-delete "libc" %boot0-inputs))))))
+               ,@(alist-delete "libc" %boot0-inputs)))
+
+     ;; No need for Texinfo at this stage.
+     (native-inputs (alist-delete "texinfo"
+                                  (package-native-inputs gcc-4.7))))))
 
 (define linux-libre-headers-boot0
   (package-with-bootstrap-guile
diff --git a/gnu/packages/bash.scm b/gnu/packages/bash.scm
index bf51403f1a..aa3f397a52 100644
--- a/gnu/packages/bash.scm
+++ b/gnu/packages/bash.scm
@@ -82,9 +82,7 @@
 
         #:phases (alist-cons-after 'install 'post-install
                                    ,post-install-phase
-                                   ,(if (%current-target-system)
-                                        '%standard-cross-phases
-                                        '%standard-phases))))
+                                   %standard-phases)))
      (synopsis "The GNU Bourne-Again SHell")
      (description
       "Bash is the shell, or command language interpreter, that will appear in
@@ -106,10 +104,7 @@ modification.")
      (let ((args `(#:modules ((guix build gnu-build-system)
                               (guix build utils)
                               (srfi srfi-1)
-                              (srfi srfi-26)
-                              ,@(if (%current-target-system)
-                                    '((guix build gnu-cross-build))
-                                    '()))
+                              (srfi srfi-26))
                    ,@(package-arguments bash))))
        (substitute-keyword-arguments args
          ((#:configure-flags flags)
diff --git a/gnu/packages/bdw-gc.scm b/gnu/packages/bdw-gc.scm
index e119fc0bb9..7cce9671d1 100644
--- a/gnu/packages/bdw-gc.scm
+++ b/gnu/packages/bdw-gc.scm
@@ -25,7 +25,7 @@
 (define-public libgc
   (package
    (name "libgc")
-   (version "7.2alpha6")
+   (version "7.2d")
    (source (origin
             (method url-fetch)
             (uri (string-append
@@ -33,9 +33,13 @@
                   version ".tar.gz"))
             (sha256
              (base32
-              "05jwadjbrv8pr7z9cb4miskicxqpxm0pca4h2rg5cgbpajr2bx7b"))))
+              "0phwa5driahnpn79zqff14w9yc8sn3599cxz91m78hqdcpl0mznr"))))
    (build-system gnu-build-system)
-   ;; TODO: Build with -DUSE_LIBC_PRIVATES (see make-bootstrap.scm).
+   (arguments
+    ;; Make it so that we don't rely on /proc.  This is especially useful in
+    ;; an initrd run before /proc is mounted.
+    '(#:configure-flags '("CPPFLAGS=-DUSE_LIBC_PRIVATES")))
+   (outputs '("out" "debug"))
    (synopsis "The Boehm-Demers-Weiser conservative garbage collector
 for C and C++")
    (description
@@ -58,17 +62,3 @@ C or C++ programs, though that is not its primary goal.")
    ;; permissive X11-style license:
    ;; http://www.hpl.hp.com/personal/Hans_Boehm/gc/license.txt
    (license x11)))
-
-(define-public libgc-7.2
-  ;; This is the latest final release of the 7.2 series.
-  ;; TODO: Use it as the default when doing a core-updates.
-  (package (inherit libgc)
-    (version "7.2d")
-    (source (origin
-             (method url-fetch)
-             (uri (string-append
-                   "http://www.hpl.hp.com/personal/Hans_Boehm/gc/gc_source/gc-"
-                   version ".tar.gz"))
-             (sha256
-              (base32
-               "0phwa5driahnpn79zqff14w9yc8sn3599cxz91m78hqdcpl0mznr"))))))
diff --git a/gnu/packages/bootstrap.scm b/gnu/packages/bootstrap.scm
index eaad45a741..86723a9591 100644
--- a/gnu/packages/bootstrap.scm
+++ b/gnu/packages/bootstrap.scm
@@ -131,7 +131,10 @@ check whether everything is alright."
       (propagated-inputs (map rewritten-input
                               (package-propagated-inputs p)))))))
 
-(define* (glibc-dynamic-linker #:optional (system (%current-system)))
+(define* (glibc-dynamic-linker
+          #:optional (system (or (and=> (%current-target-system)
+                                        gnu-triplet->nix-system)
+                                 (%current-system))))
   "Return the name of Glibc's dynamic linker for SYSTEM."
   (cond ((string=? system "x86_64-linux") "/lib/ld-linux-x86-64.so.2")
         ((string=? system "i686-linux") "/lib/ld-linux.so.2")
diff --git a/gnu/packages/compression.scm b/gnu/packages/compression.scm
index b39119f611..8196d695b3 100644
--- a/gnu/packages/compression.scm
+++ b/gnu/packages/compression.scm
@@ -66,14 +66,14 @@ in compression.")
 (define-public gzip
   (package
    (name "gzip")
-   (version "1.5")
+   (version "1.6")
    (source (origin
             (method url-fetch)
             (uri (string-append "mirror://gnu/gzip/gzip-"
                                 version ".tar.gz"))
             (sha256
              (base32
-              "18rm80kar7n016g8bsyy1a3zk50i2826xdgs874yh64rzj7nxmdm"))))
+              "0zlgdm4v3dndrbiz7b67mbbj25dpwqbmbzjiycssvrfrcfvq7swp"))))
    (build-system gnu-build-system)
    (synopsis "General file (de)compression (using lzw)")
    (arguments
diff --git a/gnu/packages/cross-base.scm b/gnu/packages/cross-base.scm
index 5c46d00b20..28224a1c40 100644
--- a/gnu/packages/cross-base.scm
+++ b/gnu/packages/cross-base.scm
@@ -56,8 +56,13 @@
                         ;; library.  This works because as a side effect
                         ;; `genscripts.sh' sets `USE_LIBPATH=yes', which tells
                         ;; elf32.em to use DT_RUNPATH in its search list.
-                        `(cons "--with-sysroot=/no-such-path"
-                               ,flags)))))))
+                        ;; See <http://sourceware.org/ml/binutils/2013-05/msg00312.html>.
+                        ;;
+                        ;; In theory choosing / as the sysroot could lead ld
+                        ;; to pick up native libs instead of target ones.  In
+                        ;; practice the RUNPATH of target libs only refers to
+                        ;; target libs, not native libs, so this is safe.
+                        `(cons "--with-sysroot=/" ,flags)))))))
     (cross binutils target)))
 
 (define* (cross-gcc target
@@ -65,12 +70,6 @@
   "Return a cross-compiler for TARGET, where TARGET is a GNU triplet.  Use
 XBINUTILS as the associated cross-Binutils.  If LIBC is false, then build a
 GCC that does not target a libc; otherwise, target that libc."
-  (define args
-    ;; Get the arguments as if we were building for TARGET.  In particular, we
-    ;; want `glibc-dynamic-linker' to return the right thing.
-    (parameterize ((%current-system (gnu-triplet->nix-system target)))
-      (package-arguments gcc-4.7)))
-
   (package (inherit gcc-4.7)
     (name (string-append "gcc-cross-"
                          (if libc "" "sans-libc-")
@@ -84,9 +83,10 @@ GCC that does not target a libc; otherwise, target that libc."
                   (srfi srfi-26))
        #:patches (list (assoc-ref %build-inputs "patch/cross-env-vars"))
 
-       ,@(substitute-keyword-arguments args
+       ,@(substitute-keyword-arguments (package-arguments gcc-4.7)
            ((#:configure-flags flags)
             `(append (list ,(string-append "--target=" target)
+                           ,@(gcc-configure-flags-for-triplet target)
                            ,@(if libc
                                  '()
                                  `( ;; Disable features not needed at this stage.
@@ -175,7 +175,8 @@ GCC that does not target a libc; otherwise, target that libc."
             ;; <http://lists.fedoraproject.org/pipermail/arm/2010-August/000663.html>
             ;; for instance.
             #f))))
-    (inputs
+
+    (native-inputs
      `(("patch/cross-env-vars"
         ,(search-patch "gcc-cross-environment-variables.patch"))
 
@@ -193,6 +194,8 @@ GCC that does not target a libc; otherwise, target that libc."
                  ,@inputs)
                inputs))))
 
+    (inputs '())
+
     ;; Only search target inputs, not host inputs.
     (search-paths
      (list (search-path-specification
@@ -225,9 +228,9 @@ XBINUTILS and the cross tool chain."
               (and (zero? (system* "make" "defconfig"))
                    (zero? (system* "make" "mrproper" "headers_check"))))
             ,phases))))
-      (inputs `(("cross-gcc" ,xgcc)
-                ("cross-binutils" ,xbinutils)
-                ,@(package-inputs linux-libre-headers)))))
+      (native-inputs `(("cross-gcc" ,xgcc)
+                       ("cross-binutils" ,xbinutils)
+                       ,@(package-native-inputs linux-libre-headers)))))
 
   (package (inherit glibc)
     (name (string-append "glibc-cross-" target))
@@ -247,10 +250,11 @@ XBINUTILS and the cross tool chain."
                       (string-append linux "/include"))
               #t))
           ,phases))))
+
     (propagated-inputs `(("cross-linux-headers" ,xlinux-headers)))
-    (inputs `(("cross-gcc" ,xgcc)
-              ("cross-binutils" ,xbinutils)
-              ,@(package-inputs glibc)))))
+    (native-inputs `(("cross-gcc" ,xgcc)
+                     ("cross-binutils" ,xbinutils)
+                     ,@(package-native-inputs glibc)))))
 
 
 ;;;
@@ -258,7 +262,7 @@ XBINUTILS and the cross tool chain."
 ;;;
 
 (define-public xgcc-mips64el
-  (let ((triplet "mips64el-linux-gnu"))
+  (let ((triplet "mips64el-linux-gnuabi64"))      ; N64 ABI
     (cross-gcc triplet
                (cross-binutils triplet)
                (cross-libc triplet))))
diff --git a/gnu/packages/gawk.scm b/gnu/packages/gawk.scm
index 444fa5e556..aff856d9f3 100644
--- a/gnu/packages/gawk.scm
+++ b/gnu/packages/gawk.scm
@@ -27,35 +27,37 @@
 (define-public gawk
   (package
    (name "gawk")
-   (version "4.0.2")
+   (version "4.1.0")
    (source (origin
             (method url-fetch)
             (uri (string-append "mirror://gnu/gawk/gawk-" version
                                 ".tar.xz"))
             (sha256
-             (base32 "04vd0axif762mf781pj3days6ilv2333b9zi9c50y5mma66g5q91"))))
+             (base32 "0hin2hswbbd6kd6i4zzvgciwpl5fba8d2s524z8y5qagyz3x010q"))))
    (build-system gnu-build-system)
    (arguments
     `(#:parallel-tests? #f                ; test suite fails in parallel
 
-      ;; Work around test failure on Cygwin.
-      #:tests? ,(not (string=? (%current-system) "i686-cygwin"))
-
       #:phases (alist-cons-before
                 'configure 'set-shell-file-name
                 (lambda* (#:key inputs #:allow-other-keys)
                   ;; Refer to the right shell.
-                  ;; FIXME: Remove `else' arm upon core-updates.
                   (let ((bash (assoc-ref inputs "bash")))
                     (substitute* "io.c"
                       (("/bin/sh")
-                       (string-append bash "/bin/bash")))))
-                ,(if (%current-target-system)
-                     '%standard-cross-phases
-                     '%standard-phases))))
+                       (string-append bash "/bin/bash")))
+
+                    ;; When cross-compiling, remove dependencies on the
+                    ;; `check-for-shared-lib-support' target, which tries to
+                    ;; run the cross-built `gawk'.
+                    ,@(if (%current-target-system)
+                          '((substitute* "extension/Makefile.in"
+                              (("^.*: check-for-shared-lib-support" match)
+                               (string-append "### " match))))
+                          '())))
+                %standard-phases)))
    (inputs `(("libsigsegv" ,libsigsegv)
 
-             ;; TODO: On next core-updates, make Bash input unconditional.
              ,@(if (%current-target-system)
                    `(("bash" ,bash))
                    '())))
diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm
index b754b4b7fb..571526ebdf 100644
--- a/gnu/packages/gcc.scm
+++ b/gnu/packages/gcc.scm
@@ -23,138 +23,185 @@
   #:use-module (gnu packages bootstrap)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages multiprecision)
+  #:use-module (gnu packages texinfo)
   #:use-module (guix packages)
   #:use-module (guix download)
-  #:use-module (guix build-system gnu))
+  #:use-module (guix build-system gnu)
+  #:use-module (ice-9 regex))
 
 (define %gcc-infrastructure
   ;; Base URL for GCC's infrastructure.
   "ftp://gcc.gnu.org/pub/gcc/infrastructure/")
 
+(define-public (gcc-configure-flags-for-triplet target)
+  "Return a list of additional GCC `configure' flags for TARGET, a GNU triplet.
+
+The purpose of this procedure is to translate extended GNU triplets---e.g.,
+where the OS part is overloaded to denote a specific ABI---into GCC
+`configure' options.  We take extended GNU triplets that glibc recognizes."
+  (cond ((string-match "^mips64el.*gnuabin?64$" target)
+         ;; Triplets recognized by glibc as denoting the N64 ABI; see
+         ;; ports/sysdeps/mips/preconfigure.
+         '("--with-abi=64"))
+        (else
+         ;; TODO: Add `armel.*gnueabi', `hf', etc.
+         '())))
+
 (define-public gcc-4.7
-  (let ((stripped? #t))                         ; TODO: make this a parameter
+  (let* ((stripped? #t)                           ; TODO: make this a parameter
+         (maybe-target-tools
+          (lambda ()
+            ;; Return the `_FOR_TARGET' variables that are needed when
+            ;; cross-compiling GCC.
+            (let ((target (%current-target-system)))
+              (if target
+                  (map (lambda (var tool)
+                         (string-append (string-append var "_FOR_TARGET")
+                                        "=" target "-" tool))
+                       '("CC"  "CXX" "LD" "AR" "NM" "RANLIB" "STRIP")
+                       '("gcc" "g++" "ld" "ar" "nm" "ranlib" "strip"))
+                  '()))))
+         (configure-flags
+          (lambda ()
+            ;; This is terrible.  Since we have two levels of quasiquotation,
+            ;; we have to do this convoluted thing just so we can insert the
+            ;; contents of (maybe-target-tools).
+            (list 'quasiquote
+                  (append
+                   '("--enable-plugin"
+                     "--enable-languages=c,c++"
+                     "--disable-multilib"
+
+                     "--with-local-prefix=/no-gcc-local-prefix"
+
+                     ,(let ((libc (assoc-ref %build-inputs "libc")))
+                        (if libc
+                            (string-append "--with-native-system-header-dir=" libc
+                                           "/include")
+                            "--without-headers")))
+
+                   ;; When cross-compiling GCC, pass the right options for the
+                   ;; target triplet.
+                   (or (and=> (%current-target-system)
+                              gcc-configure-flags-for-triplet)
+                       '())
+
+                   (maybe-target-tools))))))
     (package
-     (name "gcc")
-     (version "4.7.3")
-     (source (origin
-              (method url-fetch)
-              (uri (string-append "mirror://gnu/gcc/gcc-"
-                                  version "/gcc-" version ".tar.bz2"))
-              (sha256
-               (base32
-                "1hx9h64ivarlzi4hxvq42as5m9vlr5cyzaaq4gzj4i619zmkfz1g"))))
-     (build-system gnu-build-system)
-    (inputs `(("gmp" ,gmp)
-              ("mpfr" ,mpfr)
-              ("mpc" ,mpc)
-              ("isl" ,isl)
-              ("cloog" ,cloog)
-              ("libelf" ,libelf)
-              ("zlib" ,zlib)))
-     (arguments
-      `(#:out-of-source? #t
-        #:strip-binaries? ,stripped?
-        #:configure-flags
-        `("--enable-plugin"
-          "--enable-languages=c,c++"
-          "--disable-multilib"
+      (name "gcc")
+      (version "4.7.3")
+      (source (origin
+               (method url-fetch)
+               (uri (string-append "mirror://gnu/gcc/gcc-"
+                                   version "/gcc-" version ".tar.bz2"))
+               (sha256
+                (base32
+                 "1hx9h64ivarlzi4hxvq42as5m9vlr5cyzaaq4gzj4i619zmkfz1g"))))
+      (build-system gnu-build-system)
+      (inputs `(("gmp" ,gmp)
+                ("mpfr" ,mpfr)
+                ("mpc" ,mpc)
+                ("isl" ,isl)
+                ("cloog" ,cloog)
+                ("libelf" ,libelf)
+                ("zlib" ,zlib)))
 
-          "--with-local-prefix=/no-gcc-local-prefix"
+      ;; GCC is one of the few packages that doesn't ship .info files.
+      (native-inputs `(("texinfo" ,texinfo)))
 
-          ,(let ((libc (assoc-ref %build-inputs "libc")))
-             (if libc
-                 (string-append "--with-native-system-header-dir=" libc
-                                "/include")
-                 "--without-headers")))
-        #:make-flags
-        (let ((libc (assoc-ref %build-inputs "libc")))
-          `(,@(if libc
-                  (list (string-append "LDFLAGS_FOR_TARGET="
-                                       "-B" libc "/lib "
-                                       "-Wl,-dynamic-linker "
-                                       "-Wl," libc
-                                       ,(glibc-dynamic-linker)))
-                  '())
-            ,(string-append "BOOT_CFLAGS=-O2 "
-                            ,(if stripped? "-g0" "-g"))))
+      (arguments
+       `(#:out-of-source? #t
+         #:strip-binaries? ,stripped?
+         #:configure-flags ,(configure-flags)
+         #:make-flags
+         (let ((libc (assoc-ref %build-inputs "libc")))
+           `(,@(if libc
+                   (list (string-append "LDFLAGS_FOR_TARGET="
+                                        "-B" libc "/lib "
+                                        "-Wl,-dynamic-linker "
+                                        "-Wl," libc
+                                        ,(glibc-dynamic-linker)))
+                   '())
+             ,(string-append "BOOT_CFLAGS=-O2 "
+                             ,(if stripped? "-g0" "-g"))))
 
-        #:tests? #f
-        #:phases
-        (alist-cons-before
-         'configure 'pre-configure
-         (lambda* (#:key inputs outputs #:allow-other-keys)
-           (let ((out  (assoc-ref outputs "out"))
-                 (libc (assoc-ref inputs "libc")))
-             (when libc
-               ;; The following is not performed for `--without-headers'
-               ;; cross-compiler builds.
+         #:tests? #f
+         #:phases
+         (alist-cons-before
+          'configure 'pre-configure
+          (lambda* (#:key inputs outputs #:allow-other-keys)
+            (let ((out  (assoc-ref outputs "out"))
+                  (libc (assoc-ref inputs "libc")))
+              (when libc
+                ;; The following is not performed for `--without-headers'
+                ;; cross-compiler builds.
 
-               ;; Fix the dynamic linker's file name.
-               (substitute* (find-files "gcc/config"
-                                        "^linux(64|-elf)?\\.h$")
-                 (("#define GLIBC_DYNAMIC_LINKER([^ ]*).*$" _ suffix)
-                  (format #f "#define GLIBC_DYNAMIC_LINKER~a \"~a\"~%"
-                          suffix
-                          (string-append libc ,(glibc-dynamic-linker)))))
+                ;; Fix the dynamic linker's file name.
+                (substitute* (find-files "gcc/config"
+                                         "^linux(64|-elf)?\\.h$")
+                  (("#define GLIBC_DYNAMIC_LINKER([^ ]*).*$" _ suffix)
+                   (format #f "#define GLIBC_DYNAMIC_LINKER~a \"~a\"~%"
+                           suffix
+                           (string-append libc ,(glibc-dynamic-linker)))))
 
-               ;; Tell where to find libstdc++, libc, and `?crt*.o', except
-               ;; `crt{begin,end}.o', which come with GCC.
-               (substitute* (find-files "gcc/config"
-                                        "^(gnu-user(64)?|linux-elf)\\.h$")
-                 (("#define LIB_SPEC (.*)$" _ suffix)
-                  ;; Note that with this "lib" spec, we may still add a
-                  ;; RUNPATH to GCC even when `libgcc_s' is not NEEDED.
-                  ;; There's not much that can be done to avoid it, though.
-                  (format #f "#define LIB_SPEC \"-L~a/lib %{!static:-rpath=~a/lib \
+                ;; Tell where to find libstdc++, libc, and `?crt*.o', except
+                ;; `crt{begin,end}.o', which come with GCC.
+                (substitute* (find-files "gcc/config"
+                                         "^(gnu-user(64)?|linux-elf)\\.h$")
+                  (("#define LIB_SPEC (.*)$" _ suffix)
+                   ;; Note that with this "lib" spec, we may still add a
+                   ;; RUNPATH to GCC even when `libgcc_s' is not NEEDED.
+                   ;; There's not much that can be done to avoid it, though.
+                   (format #f "#define LIB_SPEC \"-L~a/lib %{!static:-rpath=~a/lib \
 %{!static-libgcc:-rpath=~a/lib64 -rpath=~a/lib}} \" ~a"
-                          libc libc out out suffix))
-                 (("#define STARTFILE_SPEC.*$" line)
-                  (format #f "#define STANDARD_STARTFILE_PREFIX_1 \"~a/lib\"
+                           libc libc out out suffix))
+                  (("#define STARTFILE_SPEC.*$" line)
+                   (format #f "#define STANDARD_STARTFILE_PREFIX_1 \"~a/lib\"
 #define STANDARD_STARTFILE_PREFIX_2 \"\"
 ~a~%"
-                          libc line))))
+                           libc line))))
 
-             ;; Don't retain a dependency on the build-time sed.
-             (substitute* "fixincludes/fixincl.x"
-               (("static char const sed_cmd_z\\[\\] =.*;")
-                "static char const sed_cmd_z[] = \"sed\";"))))
+              ;; Don't retain a dependency on the build-time sed.
+              (substitute* "fixincludes/fixincl.x"
+                (("static char const sed_cmd_z\\[\\] =.*;")
+                 "static char const sed_cmd_z[] = \"sed\";"))))
 
-         (alist-cons-after
-          'configure 'post-configure
-          (lambda _
-            ;; Don't store configure flags, to avoid retaining references to
-            ;; build-time dependencies---e.g., `--with-ppl=/nix/store/xxx'.
-            (substitute* "Makefile"
-              (("^TOPLEVEL_CONFIGURE_ARGUMENTS=(.*)$" _ rest)
-               "TOPLEVEL_CONFIGURE_ARGUMENTS=\n")))
-          (alist-replace 'install
-                         (lambda* (#:key outputs #:allow-other-keys)
-                           (zero?
-                            (system* "make"
-                                     ,(if stripped?
-                                          "install-strip"
-                                          "install"))))
-                         %standard-phases)))))
+          (alist-cons-after
+           'configure 'post-configure
+           (lambda _
+             ;; Don't store configure flags, to avoid retaining references to
+             ;; build-time dependencies---e.g., `--with-ppl=/nix/store/xxx'.
+             (substitute* "Makefile"
+               (("^TOPLEVEL_CONFIGURE_ARGUMENTS=(.*)$" _ rest)
+                "TOPLEVEL_CONFIGURE_ARGUMENTS=\n")))
+           (alist-replace 'install
+                          (lambda* (#:key outputs #:allow-other-keys)
+                            (zero?
+                             (system* "make"
+                                      ,(if stripped?
+                                           "install-strip"
+                                           "install"))))
+                          %standard-phases)))))
 
-     (native-search-paths
-      (list (search-path-specification
-             (variable "CPATH")
-             (directories '("include")))
-            (search-path-specification
-             (variable "LIBRARY_PATH")
-             (directories '("lib" "lib64")))))
+      (native-search-paths
+       (list (search-path-specification
+              (variable "CPATH")
+              (directories '("include")))
+             (search-path-specification
+              (variable "LIBRARY_PATH")
+              (directories '("lib" "lib64")))))
 
-     (properties `((gcc-libc . ,(assoc-ref inputs "libc"))))
-     (synopsis "GNU Compiler Collection")
-     (description
-      "The GNU Compiler Collection includes compiler front ends for C, C++,
+      (properties `((gcc-libc . ,(assoc-ref inputs "libc"))))
+      (synopsis "GNU Compiler Collection")
+      (description
+       "The GNU Compiler Collection includes compiler front ends for C, C++,
 Objective-C, Fortran, OpenMP for C/C++/Fortran, Java, and Ada, as well as
 libraries for these languages (libstdc++, libgcj, libgomp,...).
 
 GCC development is a part of the GNU Project, aiming to improve the compiler
 used in the GNU system including the GNU/Linux variant.")
-     (license gpl3+)
-     (home-page "http://gcc.gnu.org/"))))
+      (license gpl3+)
+      (home-page "http://gcc.gnu.org/"))))
 
 (define-public gcc-4.8
   (package (inherit gcc-4.7)
diff --git a/gnu/packages/gettext.scm b/gnu/packages/gettext.scm
index e22b1ba6ff..399d96784c 100644
--- a/gnu/packages/gettext.scm
+++ b/gnu/packages/gettext.scm
@@ -26,39 +26,30 @@
 (define-public gettext
   (package
     (name "gettext")
-    (version "0.18.1.1")
-    (source
-     (origin
-      (method url-fetch)
-      (uri (string-append "mirror://gnu/gettext/gettext-"
-                          version ".tar.gz"))
-      (sha256
-       (base32
-        "1sa3ch12qxa4h3ya6hkz119yclcccmincl9j20dhrdx5mykp3b4k"))))
+    (version "0.18.3")
+    (source (origin
+             (method url-fetch)
+             (uri (string-append "mirror://gnu/gettext/gettext-"
+                                 version ".tar.gz"))
+             (sha256
+              (base32
+               "0j7rp56c61j4k1bz1xdc041hzv7186yyzhbp95fmc0zq7l2c3wrn"))))
     (build-system gnu-build-system)
     (arguments
-     `(#:patches (list (assoc-ref %build-inputs "patch/gets"))
-       #:phases ,(if (%current-target-system)
-                     '%standard-cross-phases
-                     '(alist-cons-before
-                       'check 'patch-tests
-                       (lambda* (#:key inputs #:allow-other-keys)
-                         ;; TODO: Use (which "sh").
-                         (let ((bash (assoc-ref inputs "bash")))
-                           (substitute* (find-files "gettext-tools/tests"
-                                                    "^msgexec-[0-9]")
-                             (("#![[:blank:]]/bin/sh")
-                              (format #f "#!~a/bin/sh" bash)))
-                           (substitute* (find-files "gettext-tools/gnulib-tests"
-                                                    "posix_spawn")
-                             (("/bin/sh")
-                              (format #f "~a/bin/bash" bash)))))
-                       %standard-phases))))
-    (inputs
-     `(("patch/gets"
-        ,(search-patch "gettext-gets-undeclared.patch"))))
-    (home-page
-     "http://www.gnu.org/software/gettext/")
+     `(#:phases (alist-cons-before
+                 'check 'patch-tests
+                 (lambda* (#:key inputs #:allow-other-keys)
+                   (let ((bash (which "sh")))
+                     (substitute* (find-files "gettext-tools/tests"
+                                              "^msgexec-[0-9]")
+                       (("#![[:blank:]]/bin/sh")
+                        (format #f "#!~a" bash)))
+                     (substitute* (find-files "gettext-tools/gnulib-tests"
+                                              "posix_spawn")
+                       (("/bin/sh")
+                        bash))))
+                 %standard-phases)))
+    (home-page "http://www.gnu.org/software/gettext/")
     (synopsis "Tools and documentation for translation")
     (description
      "Usually, programs are written and documented in English, and use
diff --git a/gnu/packages/guile.scm b/gnu/packages/guile.scm
index b53f3eb770..772776349e 100644
--- a/gnu/packages/guile.scm
+++ b/gnu/packages/guile.scm
@@ -138,29 +138,18 @@ extensible.  It supports many SRFIs.")
 
    (self-native-input? #t)
 
+   (outputs '("out" "debug"))
+
    (arguments
     `(#:phases (alist-cons-before
                 'configure 'pre-configure
                 (lambda* (#:key inputs #:allow-other-keys)
-                  ;; By default we end up with GUILE_LOAD_PATH="" and
-                  ;; GUILE_LOAD_COMPILED_PATH="".  But that is equivalent to
-                  ;; ".", and breaks the build system when cross-compiling.
-                  ;; Thus, make sure they are unset.
-                  ;; TODO: Eventually fix `set-path-environment-variable'
-                  ;; for that case.
-                  ,@(if (%current-target-system)
-                        '((unsetenv "GUILE_LOAD_PATH")
-                          (unsetenv "GUILE_LOAD_COMPILED_PATH"))
-                        '())
-
                   ;; Tell (ice-9 popen) the file name of Bash.
                   (let ((bash (assoc-ref inputs "bash")))
                     (substitute* "module/ice-9/popen.scm"
                       (("/bin/sh")
                        (string-append bash "/bin/bash")))))
-                ,(if (%current-target-system)
-                     '%standard-cross-phases
-                     '%standard-phases))
+                %standard-phases)
 
       ,@(if (%current-target-system)
             '(#:configure-flags '("CC_FOR_BUILD=gcc"))
diff --git a/gnu/packages/ld-wrapper.scm b/gnu/packages/ld-wrapper.scm
index fd5a4cbd0c..41ff3df986 100644
--- a/gnu/packages/ld-wrapper.scm
+++ b/gnu/packages/ld-wrapper.scm
@@ -11,7 +11,7 @@ main="(@ (gnu build-support ld-wrapper) ld-wrapper)"
 exec @GUILE@ -c "(load-compiled \"$0.go\") (apply $main (cdr (command-line)))" "$@"
 !#
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -82,13 +82,26 @@ exec @GUILE@ -c "(load-compiled \"$0.go\") (apply $main (cdr (command-line)))" "
   (getenv "GUIX_LD_WRAPPER_DEBUG"))
 
 (define (pure-file-name? file)
-  ;; Return #t when FILE is the name of a file either within the store or
-  ;; within the build directory.
-  (or (not (string-prefix? "/" file))
-      (string-prefix? %store-directory file)
-      (string-prefix? %temporary-directory file)
-      (and %build-directory
-           (string-prefix? %build-directory file))))
+  ;; Return #t when FILE is the name of a file either within the store
+  ;; (possibly via a symlink) or within the build directory.
+  (define %max-symlink-depth 50)
+
+  (let loop ((file  file)
+             (depth 0))
+    (or (not (string-prefix? "/" file))
+        (string-prefix? %store-directory file)
+        (string-prefix? %temporary-directory file)
+        (if %build-directory
+            (string-prefix? %build-directory file)
+
+            ;; When used from a user environment, FILE may refer to
+            ;; ~/.guix-profile/lib/libfoo.so, which is itself a symlink to the
+            ;; store.  Check whether this is the case.
+            (let ((s (false-if-exception (lstat file))))
+              (and s
+                   (eq? 'symlink (stat:type s))
+                   (< depth %max-symlink-depth)
+                   (loop (readlink file) (+ 1 depth))))))))
 
 (define (switch-arguments switch args)
   ;; Return the arguments passed for the occurrences of SWITCH--e.g.,
diff --git a/gnu/packages/libffi.scm b/gnu/packages/libffi.scm
index f7d4a8c908..e4a2761273 100644
--- a/gnu/packages/libffi.scm
+++ b/gnu/packages/libffi.scm
@@ -29,7 +29,7 @@
             (define out (assoc-ref outputs "out"))
             (mkdir (string-append out "/include"))
             (with-directory-excursion
-                (string-append out "/lib/libffi-3.0.9/include")
+                (string-append out "/lib/libffi-3.0.13/include")
               (for-each (lambda (h)
                           (format #t "moving `~a' to includedir~%" h)
                           (rename-file h (string-append out "/include/" h)))
@@ -38,7 +38,7 @@
                                    (not (member x '("." ".."))))))))))
    (package
     (name "libffi")
-    (version "3.0.9")
+    (version "3.0.13")
     (source (origin
              (method url-fetch)
              (uri
@@ -46,18 +46,14 @@
                              name "-" version ".tar.gz"))
              (sha256
               (base32
-               "0ln4jbpb6clcsdpb9niqk0frgx4k0xki96wiv067ig0q4cajb7aq"))))
+               "077ibkf84bvcd6rw1m6jb107br63i2pp301rkmsbgg6300adxp8x"))))
     (build-system gnu-build-system)
     (arguments `(#:modules ((guix build utils) (guix build gnu-build-system)
-                            (ice-9 ftw) (srfi srfi-26)
-                            ,@(if (%current-target-system)
-                                  '((guix build gnu-cross-build))
-                                  '()))
+                            (ice-9 ftw) (srfi srfi-26))
                  #:phases (alist-cons-after 'install 'post-install
                                             ,post-install-phase
-                                            ,(if (%current-target-system)
-                                                 '%standard-cross-phases
-                                                 '%standard-phases))))
+                                            %standard-phases)))
+    (outputs '("out" "debug"))
     (synopsis "Foreign function call interface library")
     (description
      "The libffi library provides a portable, high level programming interface
diff --git a/gnu/packages/libsigsegv.scm b/gnu/packages/libsigsegv.scm
index 4689b3d8b5..62fb40737a 100644
--- a/gnu/packages/libsigsegv.scm
+++ b/gnu/packages/libsigsegv.scm
@@ -49,9 +49,7 @@
                     (lambda _
                       (substitute* "src/fault-linux-mips-old.h"
                         (("#include <asm/sigcontext\\.h>") "")))
-                    ,(if (%current-target-system)
-                         '%standard-cross-phases
-                         '%standard-phases)))
+                    %standard-phases))
         '()))
    (description
 "GNU libsigsegv is a library for handling page faults in user mode. A page
diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm
index 0bc9fbcb5e..dde53e9f5d 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -80,18 +80,12 @@
     (arguments
      `(#:modules ((guix build gnu-build-system)
                   (guix build utils)
-                  (srfi srfi-1)
-                  ,@(if (%current-target-system)
-                        '((guix build gnu-cross-build))
-                        '()))
+                  (srfi srfi-1))
        #:phases (alist-replace
                  'build ,(build-phase (%current-system))
                  (alist-replace
                   'install ,install-phase
-                  (alist-delete 'configure
-                                ,(if (%current-target-system)
-                                     '%standard-cross-phases
-                                     '%standard-phases))))
+                  (alist-delete 'configure %standard-phases)))
        #:tests? #f))
     (synopsis "GNU Linux-Libre kernel headers")
     (description "Headers of the Linux-Libre kernel.")
diff --git a/gnu/packages/make-bootstrap.scm b/gnu/packages/make-bootstrap.scm
index 9b16f37031..97362baff2 100644
--- a/gnu/packages/make-bootstrap.scm
+++ b/gnu/packages/make-bootstrap.scm
@@ -24,6 +24,7 @@
   #:use-module (guix build-system gnu)
   #:use-module ((gnu packages) #:select (search-patch))
   #:use-module (gnu packages base)
+  #:use-module (gnu packages cross-base)
   #:use-module (gnu packages bash)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages gawk)
@@ -49,20 +50,20 @@
 ;;;
 ;;; Code:
 
-(define* (glibc-for-bootstrap #:optional (base glibc-final))
+(define* (glibc-for-bootstrap #:optional (base glibc))
   "Return a libc deriving from BASE whose `system' and `popen' functions looks
 for `sh' in $PATH, and without nscd, and with static NSS modules."
   (package (inherit base)
     (arguments
      (substitute-keyword-arguments (package-arguments base)
        ((#:patches patches)
-	`(cons (assoc-ref %build-inputs "patch/system") ,patches))
+        `(cons (assoc-ref %build-inputs "patch/system") ,patches))
        ((#:configure-flags flags)
-	;; Arrange so that getaddrinfo & co. do not contact the nscd,
-	;; and can use statically-linked NSS modules.
-	`(cons* "--disable-nscd" "--disable-build-nscd"
-		"--enable-static-nss"
-		,flags))))
+        ;; Arrange so that getaddrinfo & co. do not contact the nscd,
+        ;; and can use statically-linked NSS modules.
+        `(cons* "--disable-nscd" "--disable-build-nscd"
+                "--enable-static-nss"
+                ,flags))))
     (inputs
      `(("patch/system" ,(search-patch "glibc-bootstrap-system.patch"))
        ,@(package-inputs base)))))
@@ -71,17 +72,39 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
   "Return a variant of P that uses the libc as defined by
 `glibc-for-bootstrap'."
 
-  (define inputs
-    `(("libc", (glibc-for-bootstrap))
-      ("gcc" ,(package-with-explicit-inputs
-               gcc-4.7
-	       `(("libc",(glibc-for-bootstrap))
-		 ,@(alist-delete "libc" %final-inputs))
-	       (current-source-location)))
-      ,@(fold alist-delete %final-inputs '("libc" "gcc"))))
+  (define (cross-bootstrap-libc)
+    (let ((target (%current-target-system)))
+      (glibc-for-bootstrap
+       ;; `cross-libc' already returns a cross libc, so clear
+       ;; %CURRENT-TARGET-SYSTEM.
+       (parameterize ((%current-target-system #f))
+         (cross-libc target)))))
+
+  ;; Standard inputs with the above libc and corresponding GCC.
+
+  (define (inputs)
+    (if (%current-target-system)                ; is this package cross built?
+        `(("cross-libc" ,(cross-bootstrap-libc)))
+        '()))
+
+  (define (native-inputs)
+    (if (%current-target-system)
+        (let ((target (%current-target-system)))
+          `(("cross-gcc"      ,(cross-gcc target
+                                          (cross-binutils target)
+                                          (cross-bootstrap-libc)))
+            ("cross-binutils" ,(cross-binutils target))
+            ,@%final-inputs))
+        `(("libc" ,(glibc-for-bootstrap))
+          ("gcc" ,(package (inherit gcc-4.7)
+                    (inputs
+                     `(("libc",(glibc-for-bootstrap))
+                       ,@(package-inputs gcc-4.7)))))
+          ,@(fold alist-delete %final-inputs '("libc" "gcc")))))
 
   (package-with-explicit-inputs p inputs
-				(current-source-location)))
+                                (current-source-location)
+                                #:native-inputs native-inputs))
 
 (define %bash-static
   (static-package bash-light))
@@ -140,9 +163,12 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
                             (substitute* "configure"
                               (("-export-dynamic") "")))
                           ,phases)))))
-                (inputs `(("patch/sh" ,(search-patch "gawk-shell.patch"))))))
-	(finalize (compose static-package
-			   package-with-relocatable-glibc)))
+                (inputs `(("patch/sh" ,(search-patch "gawk-shell.patch"))
+                          ,@(if (%current-target-system)
+                                `(("bash" ,%bash-static))
+                                '())))))
+        (finalize (compose static-package
+                           package-with-relocatable-glibc)))
     `(,@(map (match-lambda
               ((name package)
                (list name (finalize package))))
@@ -155,12 +181,7 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
                ("sed" ,sed)
                ("grep" ,grep)
                ("gawk" ,gawk)))
-      ("bash" ,%bash-static)
-      ;; ("ld-wrapper" ,ld-wrapper)
-      ;; ("binutils" ,binutils-final)
-      ;; ("gcc" ,gcc-final)
-      ;; ("libc" ,glibc-final)
-      )))
+      ("bash" ,%bash-static))))
 
 (define %static-binaries
   (package
@@ -239,7 +260,11 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
   (package (inherit binutils)
     (name "binutils-static")
     (arguments
-     `(#:configure-flags '("--disable-gold" "--with-lib-path=/no-ld-lib-path")
+     `(#:configure-flags (cons "--disable-gold"
+                               ,(match (memq #:configure-flags
+                                             (package-arguments binutils))
+                                  ((#:configure-flags flags _ ...)
+                                   flags)))
        #:strip-flags '("--strip-all")
        #:phases (alist-cons-before
                  'configure 'all-static
@@ -330,7 +355,12 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
              (copy-recursively (string-append linux "/include/asm-generic")
                                (string-append incdir "/asm-generic"))
              #t))))
-      (inputs `(("libc" ,glibc)
+      (inputs `(("libc" ,(let ((target (%current-target-system)))
+                           (if target
+                               (glibc-for-bootstrap
+                                (parameterize ((%current-target-system #f))
+                                  (cross-libc target)))
+                               glibc)))
                 ("linux-headers" ,linux-libre-headers)))
 
       ;; Only one output.
@@ -339,7 +369,7 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
 (define %gcc-static
   ;; A statically-linked GCC, with stripped-down functionality.
   (package-with-relocatable-glibc
-   (package (inherit gcc-final)
+   (package (inherit gcc-4.7)
      (name "gcc-static")
      (arguments
       `(#:modules ((guix build utils)
@@ -347,7 +377,7 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
                    (srfi srfi-1)
                    (srfi srfi-26)
                    (ice-9 regex))
-        ,@(substitute-keyword-arguments (package-arguments gcc-final)
+        ,@(substitute-keyword-arguments (package-arguments gcc-4.7)
             ((#:guile _) #f)
             ((#:implicit-inputs? _) #t)
             ((#:configure-flags flags)
@@ -363,12 +393,14 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
                       (remove (cut string-match "--(.*plugin|enable-languages)" <>)
                               ,flags)))
             ((#:make-flags flags)
-             `(cons "BOOT_LDFLAGS=-static" ,flags)))))
+             (if (%current-target-system)
+                 `(cons "LDFLAGS=-static" ,flags)
+                 `(cons "BOOT_LDFLAGS=-static" ,flags))))))
      (inputs `(("gmp-source" ,(package-source gmp))
-	       ("mpfr-source" ,(package-source mpfr))
-	       ("mpc-source" ,(package-source mpc))
-	       ("binutils" ,binutils-final)
-	       ,@(package-inputs gcc-4.7))))))
+               ("mpfr-source" ,(package-source mpfr))
+               ("mpc-source" ,(package-source mpc))
+               ("binutils" ,binutils)
+               ,@(package-inputs gcc-4.7))))))
 
 (define %gcc-stripped
   ;; The subset of GCC files needed for bootstrap.
@@ -410,58 +442,55 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
   ;; A statically-linked Guile that is relocatable--i.e., it can search
   ;; .scm and .go files relative to its installation directory, rather
   ;; than in hard-coded configure-time paths.
-  (let* ((libgc (package (inherit libgc)
-		  (arguments
-		   ;; Make it so that we don't rely on /proc.  This is
-		   ;; especially useful in an initrd run before /proc is
-		   ;; mounted.
-		   '(#:configure-flags '("CPPFLAGS=-DUSE_LIBC_PRIVATES")))))
-	 (guile (package (inherit guile-2.0)
-		  (name (string-append (package-name guile-2.0) "-static"))
-		  (inputs
-		   `(("patch/relocatable"
-		      ,(search-patch "guile-relocatable.patch"))
-		     ("patch/utf8"
-		      ,(search-patch "guile-default-utf8.patch"))
-		     ("patch/syscalls"
-		      ,(search-patch "guile-linux-syscalls.patch"))
-		     ,@(package-inputs guile-2.0)))
-		  (propagated-inputs
-		   `(("bdw-gc" ,libgc)
-		     ,@(alist-delete "bdw-gc"
-				     (package-propagated-inputs guile-2.0))))
-		  (arguments
-		   `(;; When `configure' checks for ltdl availability, it
-		     ;; doesn't try to link using libtool, and thus fails
-		     ;; because of a missing -ldl.  Work around that.
-		     #:configure-flags '("LDFLAGS=-ldl")
-
-		     #:phases (alist-cons-before
-			       'configure 'static-guile
-			       (lambda _
-				 (substitute* "libguile/Makefile.in"
-				   ;; Create a statically-linked `guile'
-				   ;; executable.
-				   (("^guile_LDFLAGS =")
-				    "guile_LDFLAGS = -all-static")
-
-				   ;; Add `-ldl' *after* libguile-2.0.la.
-				   (("^guile_LDADD =(.*)$" _ ldadd)
-				    (string-append "guile_LDADD = "
-						   (string-trim-right ldadd)
-						   " -ldl\n"))))
-			       %standard-phases)
-
-		     ;; Allow Guile to be relocated, as is needed during
-		     ;; bootstrap.
-		     #:patches
-		     (list (assoc-ref %build-inputs "patch/relocatable")
-			   (assoc-ref %build-inputs "patch/utf8")
-			   (assoc-ref %build-inputs "patch/syscalls"))
-
-		     ;; There are uses of `dynamic-link' in
-		     ;; {foreign,coverage}.test that don't fly here.
-		     #:tests? #f)))))
+  (let* ((guile (package (inherit guile-2.0)
+                  (name (string-append (package-name guile-2.0) "-static"))
+                  (inputs
+                   `(("patch/relocatable"
+                      ,(search-patch "guile-relocatable.patch"))
+                     ("patch/utf8"
+                      ,(search-patch "guile-default-utf8.patch"))
+                     ("patch/syscalls"
+                      ,(search-patch "guile-linux-syscalls.patch"))
+                     ,@(package-inputs guile-2.0)))
+                  (propagated-inputs
+                   `(("bdw-gc" ,libgc)
+                     ,@(alist-delete "bdw-gc"
+                                     (package-propagated-inputs guile-2.0))))
+                  (arguments
+                   `(;; When `configure' checks for ltdl availability, it
+                     ;; doesn't try to link using libtool, and thus fails
+                     ;; because of a missing -ldl.  Work around that.
+                     #:configure-flags '("LDFLAGS=-ldl"
+                                         ,@(if (%current-target-system)
+                                               '("CC_FOR_BUILD=gcc")
+                                               '()))
+
+                     #:phases (alist-cons-before
+                               'configure 'static-guile
+                               (lambda _
+                                 (substitute* "libguile/Makefile.in"
+                                   ;; Create a statically-linked `guile'
+                                   ;; executable.
+                                   (("^guile_LDFLAGS =")
+                                    "guile_LDFLAGS = -all-static")
+
+                                   ;; Add `-ldl' *after* libguile-2.0.la.
+                                   (("^guile_LDADD =(.*)$" _ ldadd)
+                                    (string-append "guile_LDADD = "
+                                                   (string-trim-right ldadd)
+                                                   " -ldl\n"))))
+                               %standard-phases)
+
+                     ;; Allow Guile to be relocated, as is needed during
+                     ;; bootstrap.
+                     #:patches
+                     (list (assoc-ref %build-inputs "patch/relocatable")
+                           (assoc-ref %build-inputs "patch/utf8")
+                           (assoc-ref %build-inputs "patch/syscalls"))
+
+                     ;; There are uses of `dynamic-link' in
+                     ;; {foreign,coverage}.test that don't fly here.
+                     #:tests? #f)))))
     (package-with-relocatable-glibc (static-package guile))))
 
 (define %guile-static-stripped
@@ -490,7 +519,8 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
                       (string-append out "/bin/guile"))
            (remove-store-references (string-append out "/bin/guile"))
            #t))))
-    (inputs `(("guile" ,%guile-static)))))
+    (inputs `(("guile" ,%guile-static)))
+    (outputs '("out"))))
 
 (define (tarball-package pkg)
   "Return a package containing a tarball of PKG."
@@ -498,9 +528,9 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
     (location (source-properties->location (current-source-location)))
     (name (string-append (package-name pkg) "-tarball"))
     (build-system trivial-build-system)
-    (inputs `(("tar" ,tar)
-              ("xz" ,xz)
-              ("input" ,pkg)))
+    (native-inputs `(("tar" ,tar)
+                     ("xz" ,xz)))
+    (inputs `(("input" ,pkg)))
     (arguments
      (let ((name    (package-name pkg))
            (version (package-version pkg)))
@@ -518,7 +548,9 @@ for `sh' in $PATH, and without nscd, and with static NSS modules."
                (zero? (system* "tar" "cJvf"
                                (string-append out "/"
                                               ,name "-" ,version
-                                              "-" ,(%current-system)
+                                              "-"
+                                              ,(or (%current-target-system)
+                                                   (%current-system))
                                               ".tar.xz")
                                "."))))))))))
 
diff --git a/gnu/packages/multiprecision.scm b/gnu/packages/multiprecision.scm
index 19c32352b3..16383d1ec1 100644
--- a/gnu/packages/multiprecision.scm
+++ b/gnu/packages/multiprecision.scm
@@ -27,7 +27,7 @@
 (define-public gmp
   (package
    (name "gmp")
-   (version "5.1.1")
+   (version "5.1.2")
    (source (origin
             (method url-fetch)
             (uri
@@ -35,9 +35,10 @@
                             version ".tar.xz"))
             (sha256
              (base32
-              "1hili06lcf0clg5qfvz7knm6pmj6ab54yhsvskp1mdny5xw4vmjb"))))
+              "1hnbxz7a6jrli8ph27i8zb6k2f456zn6l5xi78yhskzbxjk47nf7"))))
    (build-system gnu-build-system)
    (native-inputs `(("m4" ,m4)))
+   (outputs '("out" "debug"))
    (arguments `(#:configure-flags
                 '(;; Build a "fat binary", with routines for several
                   ;; sub-architectures.
@@ -78,6 +79,7 @@ faster algorithms.")
             (sha256 (base32
                      "0fs501qi8l523gs3cpy4jjcnvwxggyfbklcys80wq236xx3hz79r"))))
    (build-system gnu-build-system)
+   (outputs '("out" "debug"))
    (propagated-inputs `(("gmp" ,gmp)))            ; <mpfr.h> refers to <gmp.h>
    (synopsis "C library for arbitrary precision floating-point arithmetic")
    (description
@@ -103,6 +105,7 @@ double-precision floating-point arithmetic (53-bit mantissa).")
             (sha256 (base32
                      "1zq0fidp1jii2j5k5n9hmx55a6wwid33gjzhimvxq9d5zrf82npd"))))
    (build-system gnu-build-system)
+   (outputs '("out" "debug"))
    (propagated-inputs `(("gmp" ,gmp)              ; <mpc.h> refers to both
                         ("mpfr" ,mpfr)))
    (synopsis "C library for arbitrary precision complex arithmetic")
diff --git a/gnu/packages/ncurses.scm b/gnu/packages/ncurses.scm
index c1badae8a3..e5a9bce0f1 100644
--- a/gnu/packages/ncurses.scm
+++ b/gnu/packages/ncurses.scm
@@ -116,7 +116,7 @@
                          ,cross-pre-install-phase
                          (alist-cons-after
                           'install 'post-install ,post-install-phase
-                          %standard-cross-phases)))
+                          %standard-phases)))
 
                       `(alist-cons-after          ; native build
                         'install 'post-install ,post-install-phase
diff --git a/gnu/packages/patches/gettext-gets-undeclared.patch b/gnu/packages/patches/gettext-gets-undeclared.patch
deleted file mode 100644
index 072a8d94ab..0000000000
--- a/gnu/packages/patches/gettext-gets-undeclared.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-This patch is needed to allow builds with newer versions of
-the GNU libc (2.16+).
-
-The upstream fix was:
-
-  commit 66712c23388e93e5c518ebc8515140fa0c807348
-  Author: Eric Blake <eblake@redhat.com>
-  Date:   Thu Mar 29 13:30:41 2012 -0600
-
-      stdio: don't assume gets any more
-
-      Gnulib intentionally does not have a gets module, and now that C11
-      and glibc have dropped it, we should be more proactive about warning
-      any user on a platform that still has a declaration of this dangerous
-      interface.
-
-      * m4/stdio_h.m4 (gl_STDIO_H, gl_STDIO_H_DEFAULTS): Drop gets
-      support.
-      * modules/stdio (Makefile.am): Likewise.
-      * lib/stdio-read.c (gets): Likewise.
-      * tests/test-stdio-c++.cc: Likewise.
-      * m4/warn-on-use.m4 (gl_WARN_ON_USE_PREPARE): Fix comment.
-      * lib/stdio.in.h (gets): Make warning occur in more places.
-      * doc/posix-functions/gets.texi (gets): Update documentation.
-      Reported by Christer Solskogen.
-
-      Signed-off-by: Eric Blake <eblake@redhat.com>
-
-This patch just gets rid of the offending part.
-
---- gettext-0.18.1.1/gettext-tools/libgettextpo/stdio.in.h-orig	2012-11-24 01:13:14.000000000 +0400
-+++ gettext-0.18.1.1/gettext-tools/libgettextpo/stdio.in.h		2012-11-24 01:13:46.000000000 +0400
-@@ -137,12 +137,6 @@
-                  "use gnulib module fflush for portable POSIX compliance");
- #endif
- 
--/* It is very rare that the developer ever has full control of stdin,
--   so any use of gets warrants an unconditional warning.  Assume it is
--   always declared, since it is required by C89.  */
--#undef gets
--_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
--
- #if @GNULIB_FOPEN@
- # if @REPLACE_FOPEN@
- #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-
---- gettext-0.18.1.1/gettext-runtime/gnulib-lib/stdio.in.h-orig	2012-11-24 00:26:49.000000000 +0400
-+++ gettext-0.18.1.1/gettext-runtime/gnulib-lib/stdio.in.h		2012-11-24 00:45:54.000000000 +0400
-@@ -137,12 +137,6 @@
-                  "use gnulib module fflush for portable POSIX compliance");
- #endif
- 
--/* It is very rare that the developer ever has full control of stdin,
--   so any use of gets warrants an unconditional warning.  Assume it is
--   always declared, since it is required by C89.  */
--#undef gets
--_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
--
- #if @GNULIB_FOPEN@
- # if @REPLACE_FOPEN@
- #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
-
---- gettext-0.18.1.1/gettext-tools/gnulib-lib/stdio.in.h-orig	2012-11-24 01:00:26.000000000 +0400
-+++ gettext-0.18.1.1/gettext-tools/gnulib-lib/stdio.in.h		2012-11-24 01:00:53.000000000 +0400
-@@ -137,12 +137,6 @@
-                  "use gnulib module fflush for portable POSIX compliance");
- #endif
- 
--/* It is very rare that the developer ever has full control of stdin,
--   so any use of gets warrants an unconditional warning.  Assume it is
--   always declared, since it is required by C89.  */
--#undef gets
--_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
--
- #if @GNULIB_FOPEN@
- # if @REPLACE_FOPEN@
- #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
diff --git a/gnu/packages/readline.scm b/gnu/packages/readline.scm
index 1fb4376971..8857666fcc 100644
--- a/gnu/packages/readline.scm
+++ b/gnu/packages/readline.scm
@@ -61,9 +61,7 @@
                    #:phases (alist-cons-after
                              'install 'post-install
                              ,post-install-phase
-                             ,(if (%current-target-system)
-                                  '%standard-cross-phases
-                                  '%standard-phases))))
+                             %standard-phases)))
       (synopsis "Edit command lines while typing, with history support")
       (description
        "The GNU Readline library provides a set of functions for use by
diff --git a/guix/build-system/gnu.scm b/guix/build-system/gnu.scm
index 35590aa3da..c12a871fd8 100644
--- a/guix/build-system/gnu.scm
+++ b/guix/build-system/gnu.scm
@@ -41,42 +41,64 @@
 ;;
 ;; Code:
 
-(define* (package-with-explicit-inputs p boot-inputs
+(define* (package-with-explicit-inputs p inputs
                                        #:optional
                                        (loc (current-source-location))
-                                       #:key guile)
-  "Rewrite P, which is assumed to use GNU-BUILD-SYSTEM, to take
-BOOT-INPUTS as explicit inputs instead of the implicit default, and
-return it.  Use GUILE to run the builder, or the distro's final Guile
-when GUILE is #f."
-  (define rewritten-input
-    (match-lambda
-     ((name (? package? p) sub-drv ...)
-      (cons* name
-             (package-with-explicit-inputs p boot-inputs #:guile guile)
-             sub-drv))
-     (x x)))
-
-  (define boot-input-names
-    (map car boot-inputs))
+                                       #:key (native-inputs '())
+                                       guile)
+  "Rewrite P, which is assumed to use GNU-BUILD-SYSTEM, to take INPUTS and
+NATIVE-INPUTS as explicit inputs instead of the implicit default, and return
+it.  INPUTS and NATIVE-INPUTS can be either input lists or thunks; in the
+latter case, they will be called in a context where the `%current-system' and
+`%current-target-system' are suitably parametrized.  Use GUILE to run the
+builder, or the distro's final Guile when GUILE is #f."
+  (define inputs* inputs)
+  (define native-inputs* native-inputs)
+
+  (define (call inputs)
+    (if (procedure? inputs)
+        (inputs)
+        inputs))
+
+  (define (duplicate-filter inputs)
+    (let ((names (match (call inputs)
+                   (((name _ ...) ...)
+                    name))))
+      (lambda (inputs)
+        (fold alist-delete inputs names))))
 
-  (define (filtered-inputs inputs)
-    (fold alist-delete inputs boot-input-names))
+  (let loop ((p p))
+    (define rewritten-input
+      (memoize
+       (match-lambda
+        ((name (? package? p) sub-drv ...)
+         ;; XXX: Check whether P's build system knows #:implicit-inputs, for
+         ;; things like `cross-pkg-config'.
+         (if (eq? (package-build-system p) gnu-build-system)
+             (cons* name (loop p) sub-drv)
+             (cons* name p sub-drv)))
+        (x x))))
 
-  (package (inherit p)
-    (location (if (pair? loc) (source-properties->location loc) loc))
-    (arguments
-     (let ((args (package-arguments p)))
-       `(#:guile ,guile
-         #:implicit-inputs? #f ,@args)))
-    (native-inputs (map rewritten-input
-                        (filtered-inputs (package-native-inputs p))))
-    (propagated-inputs (map rewritten-input
-                            (filtered-inputs
-                             (package-propagated-inputs p))))
-    (inputs `(,@boot-inputs
-              ,@(map rewritten-input
-                     (filtered-inputs (package-inputs p)))))))
+    (package (inherit p)
+      (location (if (pair? loc) (source-properties->location loc) loc))
+      (arguments
+       (let ((args (package-arguments p)))
+         `(#:guile ,guile
+           #:implicit-inputs? #f
+           ,@args)))
+      (native-inputs
+       (let ((filtered (duplicate-filter native-inputs*)))
+        `(,@(call native-inputs*)
+          ,@(map rewritten-input
+                 (filtered (package-native-inputs p))))))
+      (propagated-inputs
+       (map rewritten-input
+            (package-propagated-inputs p)))
+      (inputs
+       (let ((filtered (duplicate-filter inputs*)))
+         `(,@(call inputs*)
+           ,@(map rewritten-input
+                  (filtered (package-inputs p)))))))))
 
 (define (package-with-extra-configure-variable p variable value)
   "Return a version of P with VARIABLE=VALUE specified as an extra `configure'
@@ -277,7 +299,9 @@ which could lead to gratuitous input divergence."
                                   ,@(if implicit-inputs?
                                         implicit-inputs
                                         '()))
-                                #:outputs outputs
+                                #:outputs (if strip-binaries?
+                                              outputs
+                                              (delete "debug" outputs))
                                 #:modules imported-modules
                                 #:guile-for-build guile-for-build))
 
@@ -332,7 +356,7 @@ inputs."
                           (make-flags ''())
                           (patches ''()) (patch-flags ''("--batch" "-p1"))
                           (out-of-source? #f)
-                          (tests? #t)
+                          (tests? #f)             ; nothing can be done
                           (test-target "check")
                           (parallel-build? #t) (parallel-tests? #t)
                           (patch-shebangs? #t)
@@ -340,14 +364,12 @@ inputs."
                           (strip-flags ''("--strip-debug"))
                           (strip-directories ''("lib" "lib64" "libexec"
                                                 "bin" "sbin"))
-                          (phases '%standard-cross-phases)
+                          (phases '%standard-phases)
                           (system (%current-system))
-                          (implicit-inputs? #t)    ; useful when bootstrapping
+                          (implicit-inputs? #t)
                           (imported-modules '((guix build gnu-build-system)
-                                              (guix build gnu-cross-build)
                                               (guix build utils)))
                           (modules '((guix build gnu-build-system)
-                                     (guix build gnu-cross-build)
                                      (guix build utils))))
   "Cross-build NAME for TARGET, where TARGET is a GNU triplet.  INPUTS are
 cross-built inputs, and NATIVE-INPUTS are inputs that run on the build
@@ -450,7 +472,9 @@ platform."
                                   ,@(if implicit-inputs?
                                         implicit-host-inputs
                                         '()))
-                                #:outputs outputs
+                                #:outputs (if strip-binaries?
+                                              outputs
+                                              (delete "debug" outputs))
                                 #:modules imported-modules
                                 #:guile-for-build guile-for-build))
 
diff --git a/guix/build-system/trivial.scm b/guix/build-system/trivial.scm
index 85a3c697e3..3c5031c4bd 100644
--- a/guix/build-system/trivial.scm
+++ b/guix/build-system/trivial.scm
@@ -53,8 +53,7 @@ ignored."
                               outputs guile system builder (modules '())
                               search-paths native-search-paths)
   "Like `trivial-build', but in a cross-compilation context."
-  (build-expression->derivation store name system
-                                `(let ((%target ,target)) ,builder)
+  (build-expression->derivation store name system builder
                                 (append native-inputs inputs)
                                 #:outputs outputs
                                 #:modules modules
diff --git a/guix/build/gnu-build-system.scm b/guix/build/gnu-build-system.scm
index 47820aa02e..ebcb185e13 100644
--- a/guix/build/gnu-build-system.scm
+++ b/guix/build/gnu-build-system.scm
@@ -48,15 +48,28 @@
                     #f
                     dir))
 
-(define* (set-paths #:key inputs (search-paths '())
+(define* (set-paths #:key target inputs native-inputs
+                    (search-paths '()) (native-search-paths '())
                     #:allow-other-keys)
   (define input-directories
     (match inputs
       (((_ . dir) ...)
        dir)))
 
+  (define native-input-directories
+    (match native-inputs
+      (((_ . dir) ...)
+       dir)
+      (#f                                         ; not cross compiling
+       '())))
+
+  ;; When cross building, $PATH must refer only to native (host) inputs since
+  ;; target inputs are not executable.
   (set-path-environment-variable "PATH" '("bin" "sbin")
-                                 input-directories)
+                                 (append native-input-directories
+                                         (if target
+                                             '()
+                                             input-directories)))
 
   (for-each (match-lambda
              ((env-var (directories ...) separator)
@@ -65,8 +78,16 @@
                                              #:separator separator)))
             search-paths)
 
-  ;; Dump the environment variables as a shell script, for handy debugging.
-  (system "export > environment-variables"))
+  (when native-search-paths
+    ;; Search paths for native inputs, when cross building.
+    (for-each (match-lambda
+               ((env-var (directories ...) separator)
+                (set-path-environment-variable env-var directories
+                                               native-input-directories
+                                               #:separator separator)))
+              native-search-paths))
+
+  #t)
 
 (define* (unpack #:key source #:allow-other-keys)
   (and (zero? (system* "tar" "xvf" source))
@@ -102,7 +123,8 @@ makefiles."
                          (append patch-flags (list "--input" p)))))
          patches))
 
-(define* (configure #:key inputs outputs (configure-flags '()) out-of-source?
+(define* (configure #:key target native-inputs inputs outputs
+                    (configure-flags '()) out-of-source?
                     #:allow-other-keys)
   (define (package-name)
     (let* ((out  (assoc-ref outputs "out"))
@@ -119,7 +141,7 @@ makefiles."
          (libdir     (assoc-ref outputs "lib"))
          (includedir (assoc-ref outputs "include"))
          (docdir     (assoc-ref outputs "doc"))
-         (bash       (or (and=> (assoc-ref inputs "bash")
+         (bash       (or (and=> (assoc-ref (or native-inputs inputs) "bash")
                                 (cut string-append <> "/bin/bash"))
                          "/bin/sh"))
          (flags      `(,(string-append "CONFIG_SHELL=" bash)
@@ -148,6 +170,9 @@ makefiles."
                              (list (string-append "--docdir=" docdir
                                                   "/doc/" (package-name)))
                              '())
+                       ,@(if target               ; cross building
+                             (list (string-append "--host=" target))
+                             '())
                        ,@configure-flags))
          (abs-srcdir (getcwd))
          (srcdir     (if out-of-source?
@@ -189,8 +214,8 @@ makefiles."
                         '())
                   ,@make-flags))))
 
-(define* (check #:key (make-flags '()) (tests? #t) (test-target "check")
-                (parallel-tests? #t)
+(define* (check #:key target (make-flags '()) (tests? (not target))
+                (test-target "check") (parallel-tests? #t)
                 #:allow-other-keys)
   (if tests?
       (zero? (apply system* "make" test-target
@@ -230,18 +255,70 @@ makefiles."
                 bindirs)))
   #t)
 
-(define* (strip #:key outputs (strip-binaries? #t)
+(define* (strip #:key target outputs (strip-binaries? #t)
+                (strip-command (if target
+                                   (string-append target "-strip")
+                                   "strip"))
+                (objcopy-command (if target
+                                     (string-append target "-objcopy")
+                                     "objcopy"))
                 (strip-flags '("--strip-debug"))
                 (strip-directories '("lib" "lib64" "libexec"
                                      "bin" "sbin"))
                 #:allow-other-keys)
+  (define debug-output
+    ;; If an output is called "debug", then that's where debugging information
+    ;; will be stored instead of being discarded.
+    (assoc-ref outputs "debug"))
+
+  (define debug-file-extension
+    ;; File name extension for debugging information.
+    ".debug")
+
+  (define (debug-file file)
+    ;; Return the name of the debug file for FILE, an absolute file name.
+    ;; Once installed in the user's profile, it is in $PROFILE/lib/debug/FILE,
+    ;; which is where GDB looks for it (info "(gdb) Separate Debug Files").
+    (string-append debug-output "/lib/debug/"
+                   file debug-file-extension))
+
+  (define (make-debug-file file)
+    ;; Create a file in DEBUG-OUTPUT containing the debugging info of FILE.
+    (let ((debug (debug-file file)))
+      (mkdir-p (dirname debug))
+      (copy-file file debug)
+      (and (zero? (system* strip-command "--only-keep-debug" debug))
+           (begin
+             (chmod debug #o400)
+             #t))))
+
+  (define (add-debug-link file)
+    ;; Add a debug link in FILE (info "(binutils) strip").
+
+    ;; `objcopy --add-gnu-debuglink' wants to have the target of the debug
+    ;; link around so it can compute a CRC of that file (see the
+    ;; `bfd_fill_in_gnu_debuglink_section' function.)  No reference to
+    ;; DEBUG-OUTPUT is kept because bfd keeps only the basename of the debug
+    ;; file.
+    (zero? (system* objcopy-command
+                    (string-append "--add-gnu-debuglink="
+                                   (debug-file file))
+                    file)))
+
   (define (strip-dir dir)
-    (format #t "stripping binaries in ~s with flags ~s~%"
-            dir strip-flags)
+    (format #t "stripping binaries in ~s with ~s and flags ~s~%"
+            dir strip-command strip-flags)
+    (when debug-output
+      (format #t "debugging output written to ~s using ~s~%"
+              debug-output objcopy-command))
     (file-system-fold (const #t)
                       (lambda (path stat result)  ; leaf
-                        (zero? (apply system* "strip"
-                                      (append strip-flags (list path)))))
+                        (and (or (not debug-output)
+                                 (make-debug-file path))
+                             (zero? (apply system* strip-command
+                                           (append strip-flags (list path))))
+                             (or (not debug-output)
+                                 (add-debug-link path))))
                       (const #t)                  ; down
                       (const #t)                  ; up
                       (const #t)                  ; skip
@@ -287,10 +364,13 @@ in order.  Return #t if all the PHASES succeeded, #f otherwise."
   (every (match-lambda
           ((name . proc)
            (let ((start (gettimeofday)))
-            (format #t "starting phase `~a'~%" name)
-            (let ((result (apply proc args))
-                  (end    (gettimeofday)))
-              (format #t "phase `~a' ~:[failed~;succeeded~] after ~a seconds~%"
-                      name result (- (car end) (car start)))
-              result))))
+             (format #t "starting phase `~a'~%" name)
+             (let ((result (apply proc args))
+                   (end    (gettimeofday)))
+               (format #t "phase `~a' ~:[failed~;succeeded~] after ~a seconds~%"
+                       name result (- (car end) (car start)))
+
+               ;; Dump the environment variables as a shell script, for handy debugging.
+               (system "export > $NIX_BUILD_TOP/environment-variables")
+               result))))
          phases))
diff --git a/guix/build/gnu-cross-build.scm b/guix/build/gnu-cross-build.scm
deleted file mode 100644
index dab60684ac..0000000000
--- a/guix/build/gnu-cross-build.scm
+++ /dev/null
@@ -1,138 +0,0 @@
-;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013 Ludovic Courtès <ludo@gnu.org>
-;;;
-;;; This file is part of GNU Guix.
-;;;
-;;; GNU Guix is free software; you can redistribute it and/or modify it
-;;; under the terms of the GNU General Public License as published by
-;;; the Free Software Foundation; either version 3 of the License, or (at
-;;; your option) any later version.
-;;;
-;;; GNU Guix is distributed in the hope that it will be useful, but
-;;; WITHOUT ANY WARRANTY; without even the implied warranty of
-;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-;;; GNU General Public License for more details.
-;;;
-;;; You should have received a copy of the GNU General Public License
-;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
-
-(define-module (guix build gnu-cross-build)
-  #:use-module (guix build utils)
-  #:use-module ((guix build gnu-build-system)
-                #:renamer (symbol-prefix-proc 'build:))
-  #:use-module (ice-9 ftw)
-  #:use-module (ice-9 match)
-  #:use-module (srfi srfi-1)
-  #:export (%standard-cross-phases
-            gnu-cross-build))
-
-;;; Commentary:
-;;;
-;;; Extension of `gnu-build-system.scm' to support cross-compilation.
-;;;
-;;; Code:
-
-(define* (set-paths #:key inputs native-inputs
-                    (search-paths '()) (native-search-paths '())
-                    #:allow-other-keys)
-  (define input-directories
-    (match inputs
-      (((_ . dir) ...)
-       dir)))
-
-  (define native-input-directories
-    (match native-inputs
-      (((_ . dir) ...)
-       dir)))
-
-  ;; $PATH must refer only to native (host) inputs since target inputs are not
-  ;; executable.
-  (set-path-environment-variable "PATH" '("bin" "sbin")
-                                 native-input-directories)
-
-  ;; Search paths for target inputs.
-  (for-each (match-lambda
-             ((env-var (directories ...) separator)
-              (set-path-environment-variable env-var directories
-                                             input-directories
-                                             #:separator separator)))
-            search-paths)
-
-  ;; Search paths for native inputs.
-  (for-each (match-lambda
-             ((env-var (directories ...) separator)
-              (set-path-environment-variable env-var directories
-                                             native-input-directories
-                                             #:separator separator)))
-            native-search-paths)
-
-  ;; Dump the environment variables as a shell script, for handy debugging.
-  (system "export > environment-variables"))
-
-(define* (configure #:key
-                    inputs outputs (configure-flags '()) out-of-source?
-                    target native-inputs
-                    #:allow-other-keys)
-  (format #t "configuring for cross-compilation to `~a'~%" target)
-  (apply (assoc-ref build:%standard-phases 'configure)
-         #:configure-flags (cons (string-append "--host=" target)
-                                 configure-flags)
-
-         ;; XXX: The underlying `configure' phase looks for Bash among
-         ;; #:inputs, so fool it this way.
-         #:inputs native-inputs
-
-         #:outputs outputs
-         #:out-of-source? out-of-source?
-         '()))
-
-(define* (strip #:key target outputs (strip-binaries? #t)
-                (strip-flags '("--strip-debug"))
-                (strip-directories '("lib" "lib64" "libexec"
-                                     "bin" "sbin"))
-                #:allow-other-keys)
-  ;; TODO: The only difference with `strip' in gnu-build-system.scm is the
-  ;; name of the strip command; factorize it.
-
-  (define (strip-dir dir)
-    (format #t "stripping binaries in ~s with flags ~s~%"
-            dir strip-flags)
-    (file-system-fold (const #t)
-                      (lambda (path stat result)  ; leaf
-                        (zero? (apply system*
-                                      (string-append target "-strip")
-                                      (append strip-flags (list path)))))
-                      (const #t)                  ; down
-                      (const #t)                  ; up
-                      (const #t)                  ; skip
-                      (lambda (path stat errno result)
-                        (format (current-error-port)
-                                "strip: failed to access `~a': ~a~%"
-                                path (strerror errno))
-                        #f)
-                      #t
-                      dir))
-
-  (or (not strip-binaries?)
-      (every strip-dir
-             (append-map (match-lambda
-                          ((_ . dir)
-                           (filter-map (lambda (d)
-                                         (let ((sub (string-append dir "/" d)))
-                                           (and (directory-exists? sub) sub)))
-                                       strip-directories)))
-                         outputs))))
-
-(define %standard-cross-phases
-  ;; The standard phases when cross-building.
-  (let ((replacements `((set-paths ,set-paths)
-                        (configure ,configure)
-                        (strip ,strip))))
-    (fold (lambda (replacement phases)
-            (match replacement
-              ((name proc)
-               (alist-replace name proc phases))))
-          (alist-delete 'check build:%standard-phases)
-          replacements)))
-
-;;; gnu-cross-build.scm ends here
diff --git a/guix/build/utils.scm b/guix/build/utils.scm
index a4a82a5f8c..06e88b1ff8 100644
--- a/guix/build/utils.scm
+++ b/guix/build/utils.scm
@@ -27,6 +27,8 @@
   #:use-module (ice-9 rdelim)
   #:use-module (rnrs bytevectors)
   #:use-module (rnrs io ports)
+  #:re-export (alist-cons
+               alist-delete)
   #:export (directory-exists?
             executable-file?
             call-with-ascii-input-file
@@ -248,9 +250,17 @@ SEPARATOR-separated path accordingly.  Example:
 "
   (let* ((path  (search-path-as-list sub-directories input-dirs))
          (value (list->search-path-as-string path separator)))
-   (setenv env-var value)
-   (format #t "environment variable `~a' set to `~a'~%"
-           env-var value)))
+    (if (string-null? value)
+        (begin
+          ;; Never set ENV-VAR to an empty string because often, the empty
+          ;; string is equivalent to ".".  This is the case for
+          ;; GUILE_LOAD_PATH in Guile 2.0, for instance.
+          (unsetenv env-var)
+          (format #t "environment variable `~a' unset~%" env-var))
+        (begin
+          (setenv env-var value)
+          (format #t "environment variable `~a' set to `~a'~%"
+                  env-var value)))))
 
 (define (which program)
   "Return the complete file name for PROGRAM as found in $PATH, or #f if