about summary refs log tree commit diff
path: root/pkgs/development/libraries/glibc
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2012-09-18 12:38:43 -0400
committerEelco Dolstra <eelco.dolstra@logicblox.com>2012-09-18 12:38:43 -0400
commitaa34058205434abff09fba1875a34482866850e8 (patch)
treef0daa085c1d608cfb9e00db08049963bd0dfe135 /pkgs/development/libraries/glibc
parent375341bd73fb01b7451af750c7e0e86e78fc2b08 (diff)
downloadnixlib-aa34058205434abff09fba1875a34482866850e8.tar
nixlib-aa34058205434abff09fba1875a34482866850e8.tar.gz
nixlib-aa34058205434abff09fba1875a34482866850e8.tar.bz2
nixlib-aa34058205434abff09fba1875a34482866850e8.tar.lz
nixlib-aa34058205434abff09fba1875a34482866850e8.tar.xz
nixlib-aa34058205434abff09fba1875a34482866850e8.tar.zst
nixlib-aa34058205434abff09fba1875a34482866850e8.zip
glibc: Update to 2.16
Diffstat (limited to 'pkgs/development/libraries/glibc')
-rw-r--r--pkgs/development/libraries/glibc/2.16/builder.sh54
-rw-r--r--pkgs/development/libraries/glibc/2.16/common.nix209
-rw-r--r--pkgs/development/libraries/glibc/2.16/default.nix99
-rw-r--r--pkgs/development/libraries/glibc/2.16/dont-use-system-ld-so-cache.patch45
-rw-r--r--pkgs/development/libraries/glibc/2.16/glibc-elf-localscope.patch82
-rw-r--r--pkgs/development/libraries/glibc/2.16/info.nix26
-rw-r--r--pkgs/development/libraries/glibc/2.16/locales-builder.sh17
-rw-r--r--pkgs/development/libraries/glibc/2.16/locales.nix47
-rw-r--r--pkgs/development/libraries/glibc/2.16/nix-locale-archive.patch114
-rw-r--r--pkgs/development/libraries/glibc/2.16/nss-skip-unavail.patch21
-rw-r--r--pkgs/development/libraries/glibc/2.16/rpcgen-path.patch72
11 files changed, 786 insertions, 0 deletions
diff --git a/pkgs/development/libraries/glibc/2.16/builder.sh b/pkgs/development/libraries/glibc/2.16/builder.sh
new file mode 100644
index 000000000000..e68e13f9beca
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/builder.sh
@@ -0,0 +1,54 @@
+# Glibc cannot have itself in its RPATH.
+export NIX_NO_SELF_RPATH=1
+
+source $stdenv/setup
+
+postConfigure() {
+    # Hack: get rid of the `-static' flag set by the bootstrap stdenv.
+    # This has to be done *after* `configure' because it builds some
+    # test binaries.
+    export NIX_CFLAGS_LINK=
+    export NIX_LDFLAGS_BEFORE=
+
+    export NIX_DONT_SET_RPATH=1
+    unset CFLAGS
+}
+
+
+postInstall() {
+    if test -n "$installLocales"; then
+        make -j${NIX_BUILD_CORES:-1} -l${NIX_BUILD_CORES:-1} localedata/install-locales
+    fi
+    
+    test -f $out/etc/ld.so.cache && rm $out/etc/ld.so.cache
+
+    # FIXME: Use `test -n $linuxHeaders' when `kernelHeaders' has been
+    # renamed.
+    if test -z "$hurdHeaders"; then
+        # Include the Linux kernel headers in Glibc, except the `scsi'
+        # subdirectory, which Glibc provides itself.
+	(cd $out/include && \
+	 ln -sv $(ls -d $kernelHeaders/include/* | grep -v 'scsi$') .)
+    fi
+
+    if test -f "$out/lib/libhurduser.so"; then
+	# libc.so, libhurduser.so, and libmachuser.so depend on each
+	# other, so add them to libc.so (a RUNPATH on libc.so.0.3
+	# would be ignored by the cross-linker.)
+	echo "adding \`libhurduser.so' and \`libmachuser.so' to the \`libc.so' linker script..."
+	sed -i "$out/lib/libc.so" \
+	    -e"s|\(libc\.so\.[^ ]\+\>\)|\1 $out/lib/libhurduser.so $out/lib/libmachuser.so|g"
+    fi
+	
+    # Fix for NIXOS-54 (ldd not working on x86_64).  Make a symlink
+    # "lib64" to "lib".
+    if test -n "$is64bit"; then
+        ln -s lib $out/lib64
+    fi
+
+    # This file, that should not remain in the glibc derivation,
+    # may have not been created during the preInstall
+    rm -f $out/lib/libgcc_s.so.1
+}
+
+genericBuild
diff --git a/pkgs/development/libraries/glibc/2.16/common.nix b/pkgs/development/libraries/glibc/2.16/common.nix
new file mode 100644
index 000000000000..5624be5b5495
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/common.nix
@@ -0,0 +1,209 @@
+/* Build configuration used to build glibc, Info files, and locale
+   information.  */
+
+cross:
+
+{ name, fetchurl, stdenv, installLocales ? false
+, gccCross ? null, kernelHeaders ? null
+, machHeaders ? null, hurdHeaders ? null, libpthreadHeaders ? null
+, mig ? null
+, profilingLibraries ? false, meta
+, preConfigure ? "", ... }@args:
+
+let
+  version = "2.16.0";
+
+  needsPortsNative = stdenv.isMips || stdenv.isArm;
+  needsPortsCross = cross.arch == "mips" || cross.arch == "arm";
+  needsPorts =
+    if stdenv.cross or null != null && hurdHeaders == null then true
+    else if cross == null then needsPortsNative
+    else needsPortsCross;
+
+  srcPorts = fetchurl {
+    url = "mirror://gnu/glibc/glibc-ports-${version}.tar.bz2";
+    sha256 = "0qw4n71rqykl83ybq0c92w1n8afsx079sw3hn5nyib5nw6iphrfm";
+  };
+
+in
+
+assert cross != null -> gccCross != null;
+
+assert mig != null -> machHeaders != null;
+assert machHeaders != null -> hurdHeaders != null;
+assert hurdHeaders != null -> libpthreadHeaders != null;
+
+stdenv.mkDerivation ({
+  inherit kernelHeaders installLocales;
+
+  # The host/target system.
+  crossConfig = if cross != null then cross.config else null;
+
+  inherit (stdenv) is64bit;
+
+  enableParallelBuilding = true;
+
+  patches =
+    [ /* Fix for NIXPKGS-79: when doing host name lookups, when
+         nsswitch.conf contains a line like
+
+           hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4
+
+         don't return an error when mdns4_minimal can't be found.  This
+         is a bug in Glibc: when a service can't be found, NSS should
+         continue to the next service unless "UNAVAIL=return" is set.
+         ("NOTFOUND=return" refers to the service returning a NOTFOUND
+         error, not the service itself not being found.)  The reason is
+         that the "status" variable (while initialised to UNAVAIL) is
+         outside of the loop that iterates over the services, the
+         "files" service sets status to NOTFOUND.  So when the call to
+         find "mdns4_minimal" fails, "status" will still be NOTFOUND,
+         and it will return instead of continuing to "dns".  Thus, the
+         line
+
+           hosts: mdns4_minimal [NOTFOUND=return] dns mdns4
+
+         does work because "status" will contain UNAVAIL after the
+         failure to find mdns4_minimal. */
+      ./nss-skip-unavail.patch
+
+      /* Have rpcgen(1) look for cpp(1) in $PATH.  */
+      ./rpcgen-path.patch
+
+      /* Allow NixOS and Nix to handle the locale-archive. */
+      ./nix-locale-archive.patch
+
+      /* Don't use /etc/ld.so.cache, for non-NixOS systems.  Currently
+         disabled on GNU/Hurd, which uses a more recent libc snapshot. */
+      ./dont-use-system-ld-so-cache.patch
+
+      /* Without this patch many KDE binaries crash. */
+      ./glibc-elf-localscope.patch
+    ];
+
+  postPatch = ''
+    # Needed for glibc to build with the gnumake 3.82
+    # http://comments.gmane.org/gmane.linux.lfs.support/31227
+    sed -i 's/ot \$/ot:\n\ttouch $@\n$/' manual/Makefile
+
+    # nscd needs libgcc, and we don't want it dynamically linked
+    # because we don't want it to depend on bootstrap-tools libs.
+    echo "LDFLAGS-nscd += -static-libgcc" >> nscd/Makefile
+  '';
+
+  configureFlags =
+    [ "-C"
+      "--enable-add-ons"
+      "--enable-obsolete-rpc"
+      "--sysconfdir=/etc"
+      "--localedir=/var/run/current-system/sw/lib/locale"
+      "libc_cv_ssp=no"
+      (if kernelHeaders != null
+       then "--with-headers=${kernelHeaders}/include"
+       else "--without-headers")
+      (if profilingLibraries
+       then "--enable-profile"
+       else "--disable-profile")
+    ] ++ stdenv.lib.optionals (cross == null && kernelHeaders != null) [
+      "--enable-kernel=${kernelHeaders.versionForGlibc}"
+    ] ++ stdenv.lib.optionals (cross != null) [
+      (if cross.withTLS then "--with-tls" else "--without-tls")
+      (if cross.float == "soft" then "--without-fp" else "--with-fp")
+    ] ++ stdenv.lib.optionals (cross != null
+          && cross.platform ? kernelMajor
+          && cross.platform.kernelMajor == "2.6") [
+      "--enable-kernel=2.6.0"
+      "--with-__thread"
+    ] ++ stdenv.lib.optionals stdenv.isArm [
+      "--host=arm-linux-gnueabi"
+      "--build=arm-linux-gnueabi"
+      "--without-fp"
+      # To avoid linking with -lgcc_s (dynamic link)
+      # so the glibc does not depend on its compiler store path
+      "libc_cv_as_needed=no"
+    ];
+
+  installFlags = [ "sysconfdir=$(out)/etc" ];
+
+  buildInputs = stdenv.lib.optionals (cross != null) [ gccCross ]
+    ++ stdenv.lib.optional (mig != null) mig;
+
+  # Needed to install share/zoneinfo/zone.tab.  Set to impure /bin/sh to
+  # prevent a retained dependency on the bootstrap tools in the stdenv-linux
+  # bootstrap.
+  BASH_SHELL = "/bin/sh";
+
+  # Workaround for this bug:
+  #   http://sourceware.org/bugzilla/show_bug.cgi?id=411
+  # I.e. when gcc is compiled with --with-arch=i686, then the
+  # preprocessor symbol `__i686' will be defined to `1'.  This causes
+  # the symbol __i686.get_pc_thunk.dx to be mangled.
+  NIX_CFLAGS_COMPILE = stdenv.lib.optionalString (stdenv.system == "i686-linux") "-U__i686";
+}
+
+# Remove the `gccCross' attribute so that the *native* glibc store path
+# doesn't depend on whether `gccCross' is null or not.
+// (removeAttrs args [ "gccCross" "fetchurl" ]) //
+
+{
+  name = name + "-${version}" +
+    stdenv.lib.optionalString (cross != null) "-${cross.config}";
+
+  src = fetchurl {
+    url = "mirror://gnu/glibc/glibc-${version}.tar.gz";
+    sha256 = "0vlz4x6cgz7h54qq4528q526qlhnsjzbsvgc4iizn76cb0bfanx7";
+  };
+
+  # Remove absolute paths from `configure' & co.; build out-of-tree.
+  preConfigure = ''
+    export PWD_P=$(type -tP pwd)
+    for i in configure io/ftwtest-sh; do
+        # Can't use substituteInPlace here because replace hasn't been
+        # built yet in the bootstrap.
+        sed -i "$i" -e "s^/bin/pwd^$PWD_P^g"
+    done
+
+    ${if needsPorts then "tar xvf ${srcPorts}" else ""}
+
+    mkdir ../build
+    cd ../build
+
+    configureScript="`pwd`/../$sourceRoot/configure"
+
+    # Needed to build rpcgen.
+    export LD_LIBRARY_PATH=${stdenv.gcc.libc}/lib
+
+    ${preConfigure}
+  '';
+
+  meta = {
+    homepage = http://www.gnu.org/software/libc/;
+    description = "The GNU C Library"
+      + stdenv.lib.optionalString (hurdHeaders != null) ", for GNU/Hurd";
+
+    longDescription =
+      '' Any Unix-like operating system needs a C library: the library which
+         defines the "system calls" and other basic facilities such as
+         open, malloc, printf, exit...
+
+         The GNU C library is used as the C library in the GNU system and
+         most systems with the Linux kernel.
+      '';
+
+    license = "LGPLv2+";
+
+    maintainers = [ stdenv.lib.maintainers.ludo ];
+    #platforms = stdenv.lib.platforms.linux;
+  } // meta;
+}
+
+// stdenv.lib.optionalAttrs (hurdHeaders != null) {
+  # Work around the fact that the configure snippet that looks for
+  # <hurd/version.h> does not honor `--with-headers=$sysheaders' and that
+  # glibc expects Mach, Hurd, and pthread headers to be in the same place.
+  CPATH = "${hurdHeaders}/include:${machHeaders}/include:${libpthreadHeaders}/include";
+
+  # Install NSS stuff in the right place.
+  # XXX: This will be needed for all new glibcs and isn't Hurd-specific.
+  makeFlags = ''vardbdir="$out/var/db"'';
+})
diff --git a/pkgs/development/libraries/glibc/2.16/default.nix b/pkgs/development/libraries/glibc/2.16/default.nix
new file mode 100644
index 000000000000..0a0752570f32
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/default.nix
@@ -0,0 +1,99 @@
+{ stdenv, fetchurl, kernelHeaders
+, machHeaders ? null, hurdHeaders ? null, libpthreadHeaders ? null
+, mig ? null
+, installLocales ? true
+, profilingLibraries ? false
+, gccCross ? null
+, debugSymbols ? false
+}:
+
+assert stdenv.gcc.gcc != null;
+
+let
+  build = import ./common.nix;
+  cross = if gccCross != null then gccCross.target else null;
+in
+  build cross ({
+    name = "glibc"
+      + stdenv.lib.optionalString (hurdHeaders != null) "-hurd"
+      + stdenv.lib.optionalString debugSymbols "-debug";
+
+    inherit fetchurl stdenv kernelHeaders installLocales profilingLibraries
+      gccCross;
+
+    builder = ./builder.sh;
+
+    # When building glibc from bootstrap-tools, we need libgcc_s at RPATH for
+    # any program we run, because the gcc will have been placed at a new
+    # store path than that determined when built (as a source for the
+    # bootstrap-tools tarball)
+    # Building from a proper gcc staying in the path where it was installed,
+    # libgcc_s will not be at {gcc}/lib, and gcc's libgcc will be found without
+    # any special hack.
+    preInstall = ''
+      if [ -f ${stdenv.gcc.gcc}/lib/libgcc_s.so.1 ]; then
+          mkdir -p $out/lib
+          ln -s ${stdenv.gcc.gcc}/lib/libgcc_s.so.1 $out/lib/libgcc_s.so.1
+      fi
+    '';
+
+    meta.description = "The GNU C Library";
+  }
+
+  //
+
+  (if debugSymbols
+   then {
+     # Build with debugging symbols, but leave optimizations on and don't
+     # attempt to keep the build tree.
+     dontStrip = true;
+     dontCrossStrip = true;
+     NIX_STRIP_DEBUG = 0;
+   }
+   else {})
+
+  //
+
+  (if hurdHeaders != null
+   then rec {
+     inherit machHeaders hurdHeaders libpthreadHeaders mig;
+
+     propagatedBuildInputs = [ machHeaders hurdHeaders libpthreadHeaders ];
+
+     passthru = {
+       # When building GCC itself `propagatedBuildInputs' above is not
+       # honored, so we pass it here so that the GCC builder can do the right
+       # thing.
+       inherit propagatedBuildInputs;
+     };
+   }
+   else { })
+
+  //
+
+  (if cross != null
+   then {
+      preConfigure = ''
+        sed -i s/-lgcc_eh//g "../$sourceRoot/Makeconfig"
+
+        cat > config.cache << "EOF"
+        libc_cv_forced_unwind=yes
+        libc_cv_c_cleanup=yes
+        libc_cv_gnu89_inline=yes
+        # Only due to a problem in gcc configure scripts:
+        libc_cv_sparc64_tls=${if cross.withTLS then "yes" else "no"}
+        EOF
+        export BUILD_CC=gcc
+        export CC="$crossConfig-gcc"
+        export AR="$crossConfig-ar"
+        export RANLIB="$crossConfig-ranlib"
+
+        dontStrip=1
+      '';
+
+      # To avoid a dependency on the build system 'bash'.
+      preFixup = ''
+        rm $out/bin/{ldd,tzselect,catchsegv,xtrace}
+      '';
+    }
+   else {}))
diff --git a/pkgs/development/libraries/glibc/2.16/dont-use-system-ld-so-cache.patch b/pkgs/development/libraries/glibc/2.16/dont-use-system-ld-so-cache.patch
new file mode 100644
index 000000000000..95f537733204
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/dont-use-system-ld-so-cache.patch
@@ -0,0 +1,45 @@
+diff -ru glibc-2.16.0-orig/elf/ldconfig.c glibc-2.16.0/elf/ldconfig.c
+--- glibc-2.16.0-orig/elf/ldconfig.c	2012-06-30 15:12:34.000000000 -0400
++++ glibc-2.16.0/elf/ldconfig.c	2012-09-18 11:59:27.463284814 -0400
+@@ -50,7 +50,7 @@
+ #endif
+ 
+ #ifndef LD_SO_CONF
+-# define LD_SO_CONF SYSCONFDIR "/ld.so.conf"
++# define LD_SO_CONF PREFIX "/etc/ld.so.conf"
+ #endif
+ 
+ /* Get libc version number.  */
+diff -ru glibc-2.16.0-orig/elf/Makefile glibc-2.16.0/elf/Makefile
+--- glibc-2.16.0-orig/elf/Makefile	2012-06-30 15:12:34.000000000 -0400
++++ glibc-2.16.0/elf/Makefile	2012-09-18 12:03:30.031955196 -0400
+@@ -415,12 +415,12 @@
+ 
+ $(objpfx)pldd: $(pldd-modules:%=$(objpfx)%.o)
+ 
+-SYSCONF-FLAGS := -D'SYSCONFDIR="$(sysconfdir)"'
+-CFLAGS-ldconfig.c = $(SYSCONF-FLAGS) -D'LIBDIR="$(libdir)"' \
++PREFIX-FLAGS := -D'PREFIX="$(prefix)"'
++CFLAGS-ldconfig.c = $(PREFIX-FLAGS) -D'LIBDIR="$(libdir)"' \
+ 		    -D'SLIBDIR="$(slibdir)"' -DIS_IN_ldconfig=1
+-CFLAGS-dl-cache.c = $(SYSCONF-FLAGS)
+-CFLAGS-cache.c = $(SYSCONF-FLAGS)
+-CFLAGS-rtld.c = $(SYSCONF-FLAGS)
++CFLAGS-dl-cache.c = $(PREFIX-FLAGS)
++CFLAGS-cache.c = $(PREFIX-FLAGS)
++CFLAGS-rtld.c = $(PREFIX-FLAGS)
+ 
+ CPPFLAGS-.os += $(if $(filter $(@F),$(patsubst %,%.os,$(all-rtld-routines))),\
+ 		     -DNOT_IN_libc=1 -DIS_IN_rtld=1 -DIN_LIB=rtld)
+diff -ru glibc-2.16.0-orig/sysdeps/generic/dl-cache.h glibc-2.16.0/sysdeps/generic/dl-cache.h
+--- glibc-2.16.0-orig/sysdeps/generic/dl-cache.h	2012-06-30 15:12:34.000000000 -0400
++++ glibc-2.16.0/sysdeps/generic/dl-cache.h	2012-09-18 11:59:27.465284809 -0400
+@@ -28,7 +28,7 @@
+ #endif
+ 
+ #ifndef LD_SO_CACHE
+-# define LD_SO_CACHE SYSCONFDIR "/ld.so.cache"
++# define LD_SO_CACHE PREFIX "/etc/ld.so.cache"
+ #endif
+ 
+ #ifndef add_system_dir
diff --git a/pkgs/development/libraries/glibc/2.16/glibc-elf-localscope.patch b/pkgs/development/libraries/glibc/2.16/glibc-elf-localscope.patch
new file mode 100644
index 000000000000..98f7f81087bb
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/glibc-elf-localscope.patch
@@ -0,0 +1,82 @@
+diff -ru a/elf/dl-close.c b/elf/dl-close.c
+--- a/elf/dl-close.c	2011-02-04 00:35:03.000000000 +0100
++++ b/elf/dl-close.c	2011-02-22 02:16:12.367883000 +0100
+@@ -180,24 +186,28 @@
+       /* Signal the object is still needed.  */
+       l->l_idx = IDX_STILL_USED;
+ 
++#define mark_used(dmap) \
++  do {								\
++    if ((dmap)->l_idx != IDX_STILL_USED)			\
++      {								\
++	assert ((dmap)->l_idx >= 0 && (dmap)->l_idx < nloaded);	\
++								\
++	if (!used[(dmap)->l_idx])				\
++	  {							\
++	    used[(dmap)->l_idx] = 1;				\
++	    if ((dmap)->l_idx - 1 < done_index)			\
++	      done_index = (dmap)->l_idx - 1;			\
++	  }							\
++      }								\
++  } while (0)
++
+       /* Mark all dependencies as used.  */
+       if (l->l_initfini != NULL)
+ 	{
+ 	  struct link_map **lp = &l->l_initfini[1];
+ 	  while (*lp != NULL)
+ 	    {
+-	      if ((*lp)->l_idx != IDX_STILL_USED)
+-		{
+-		  assert ((*lp)->l_idx >= 0 && (*lp)->l_idx < nloaded);
+-
+-		  if (!used[(*lp)->l_idx])
+-		    {
+-		      used[(*lp)->l_idx] = 1;
+-		      if ((*lp)->l_idx - 1 < done_index)
+-			done_index = (*lp)->l_idx - 1;
+-		    }
+-		}
+-
++	      mark_used(*lp);
+ 	      ++lp;
+ 	    }
+ 	}
+@@ -206,19 +216,25 @@
+ 	for (unsigned int j = 0; j < l->l_reldeps->act; ++j)
+ 	  {
+ 	    struct link_map *jmap = l->l_reldeps->list[j];
+-
+-	    if (jmap->l_idx != IDX_STILL_USED)
+-	      {
+-		assert (jmap->l_idx >= 0 && jmap->l_idx < nloaded);
+-
+-		if (!used[jmap->l_idx])
+-		  {
+-		    used[jmap->l_idx] = 1;
+-		    if (jmap->l_idx - 1 < done_index)
+-		      done_index = jmap->l_idx - 1;
+-		  }
+-	      }
++	    mark_used(jmap);
+ 	  }
++      /* And the same for owners of our scopes; normally, our last
++	 scope provider would render us unused, but this can be
++	 prevented by the NODELETE flag. */
++      if (__builtin_expect(l->l_type == lt_loaded
++	                   && (l->l_flags_1 & DF_1_NODELETE), 0))
++	for (size_t cnt = 0; l->l_scope[cnt] != NULL; ++cnt)
++	  /* This relies on l_scope[] entries being always set either
++	     to its own l_symbolic_searchlist address, or some map's
++	     l_searchlist address.  */
++	  if (l->l_scope[cnt] != &l->l_symbolic_searchlist)
++	    {
++	      struct link_map *ls = (struct link_map *)
++		((char *) l->l_scope[cnt]
++		 - offsetof (struct link_map, l_searchlist));
++	      assert (ls->l_ns == nsid);
++	      mark_used(ls);
++	    }
+     }
+ 
+   /* Sort the entries.  */
diff --git a/pkgs/development/libraries/glibc/2.16/info.nix b/pkgs/development/libraries/glibc/2.16/info.nix
new file mode 100644
index 000000000000..322f07f02363
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/info.nix
@@ -0,0 +1,26 @@
+{ stdenv, fetchurl, texinfo, perl }:
+
+let build = import ./common.nix; in
+
+/* null cross builder */
+build null {
+  name = "glibc-info";
+
+  inherit fetchurl stdenv;
+
+  configureFlags = [ "--enable-add-ons" ];
+
+  buildInputs = [ texinfo perl ];
+
+  buildPhase = "make info";
+
+  # I don't know why the info is not generated in 'build'
+  # Somehow building the info still does not work, because the final
+  # libc.info hasn't a Top node.
+  installPhase = ''
+    mkdir -p "$out/share/info"
+    cp -v "../$sourceRoot/manual/"*.info* "$out/share/info"
+  '';
+
+  meta.description = "GNU Info manual of the GNU C Library";
+}
diff --git a/pkgs/development/libraries/glibc/2.16/locales-builder.sh b/pkgs/development/libraries/glibc/2.16/locales-builder.sh
new file mode 100644
index 000000000000..d732e208fa22
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/locales-builder.sh
@@ -0,0 +1,17 @@
+# Glibc cannot have itself in its RPATH.
+export NIX_NO_SELF_RPATH=1
+
+source $stdenv/setup
+
+postConfigure() {
+    # Hack: get rid of the `-static' flag set by the bootstrap stdenv.
+    # This has to be done *after* `configure' because it builds some
+    # test binaries.
+    export NIX_CFLAGS_LINK=
+    export NIX_LDFLAGS_BEFORE=
+
+    export NIX_DONT_SET_RPATH=1
+    unset CFLAGS
+}
+
+genericBuild
diff --git a/pkgs/development/libraries/glibc/2.16/locales.nix b/pkgs/development/libraries/glibc/2.16/locales.nix
new file mode 100644
index 000000000000..b7eae50ca385
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/locales.nix
@@ -0,0 +1,47 @@
+/* This function builds just the `lib/locale/locale-archive' file from
+   Glibc and nothing else.  If `allLocales' is true, all supported
+   locales are included; otherwise, just the locales listed in
+   `locales'.  See localedata/SUPPORTED in the Glibc source tree for
+   the list of all supported locales:
+   http://sourceware.org/cgi-bin/cvsweb.cgi/libc/localedata/SUPPORTED?cvsroot=glibc
+*/
+
+{ stdenv, fetchurl, allLocales ? true, locales ? ["en_US.UTF-8/UTF-8"] }:
+
+let build = import ./common.nix;
+in
+  build null {
+    name = "glibc-locales";
+
+    inherit fetchurl stdenv;
+    installLocales = true;
+
+    builder = ./locales-builder.sh;
+
+    # Awful hack: `localedef' doesn't allow the path to `locale-archive'
+    # to be overriden, but you *can* specify a prefix, i.e. it will use
+    # <prefix>/<path-to-glibc>/lib/locale/locale-archive.  So we use
+    # $TMPDIR as a prefix, meaning that the locale-archive is placed in
+    # $TMPDIR/nix/store/...-glibc-.../lib/locale/locale-archive.
+    buildPhase =
+      ''
+        mkdir -p $TMPDIR/"$(dirname $(readlink -f $(type -p localedef)))/../lib/locale"
+
+        # Hack to allow building of the locales (needed since glibc-2.12)
+        sed -i -e "s,^LOCALEDEF=.*,LOCALEDEF=localedef --prefix=$TMPDIR," -e \
+            /library-path/d ../glibc-2*/localedata/Makefile
+        ${if allLocales then "" else
+            "echo SUPPORTED-LOCALES=\"${toString locales}\" > ../glibc-2*/localedata/SUPPORTED"}
+
+        make localedata/install-locales \
+            localedir=$out/lib/locale \
+      '';
+
+    installPhase =
+      ''
+        mkdir -p "$out/lib/locale"
+        cp -v "$TMPDIR/nix/store/"*"/lib/locale/locale-archive" "$out/lib/locale"
+      '';
+
+    meta.description = "Locale information for the GNU C Library";
+  }
diff --git a/pkgs/development/libraries/glibc/2.16/nix-locale-archive.patch b/pkgs/development/libraries/glibc/2.16/nix-locale-archive.patch
new file mode 100644
index 000000000000..88c8adef9226
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/nix-locale-archive.patch
@@ -0,0 +1,114 @@
+diff -ru glibc-2.16.0-orig/locale/loadarchive.c glibc-2.16.0/locale/loadarchive.c
+--- glibc-2.16.0-orig/locale/loadarchive.c	2012-06-30 15:12:34.000000000 -0400
++++ glibc-2.16.0/locale/loadarchive.c	2012-09-18 11:57:57.277515212 -0400
+@@ -123,6 +123,25 @@
+ }
+ 
+ 
++static int
++open_locale_archive ()
++{
++  int fd = -1;
++  char *path = getenv ("LOCALE_ARCHIVE_2_11");
++  char *path2 = getenv ("LOCALE_ARCHIVE");
++  const char *usualpath = "/usr/lib/locale/locale-archive";
++  if (path)
++    fd = open_not_cancel_2 (path, O_RDONLY|O_LARGEFILE|O_CLOEXEC);
++  if (path2 && fd < 0)
++    fd = open_not_cancel_2 (path2, O_RDONLY|O_LARGEFILE|O_CLOEXEC);
++  if (fd < 0)
++    fd = open_not_cancel_2 (archfname, O_RDONLY|O_LARGEFILE|O_CLOEXEC);
++  if (fd < 0)
++    fd = open_not_cancel_2 (usualpath, O_RDONLY|O_LARGEFILE|O_CLOEXEC);
++  return fd;
++}
++
++
+ /* Find the locale *NAMEP in the locale archive, and return the
+    internalized data structure for its CATEGORY data.  If this locale has
+    already been loaded from the archive, just returns the existing data
+@@ -202,7 +221,7 @@
+       archmapped = &headmap;
+ 
+       /* The archive has never been opened.  */
+-      fd = open_not_cancel_2 (archfname, O_RDONLY|O_LARGEFILE|O_CLOEXEC);
++      fd = open_locale_archive ();
+       if (fd < 0)
+ 	/* Cannot open the archive, for whatever reason.  */
+ 	return NULL;
+@@ -393,8 +412,7 @@
+ 	  if (fd == -1)
+ 	    {
+ 	      struct stat64 st;
+-	      fd = open_not_cancel_2 (archfname,
+-				      O_RDONLY|O_LARGEFILE|O_CLOEXEC);
++	      fd = open_locale_archive ();
+ 	      if (fd == -1)
+ 		/* Cannot open the archive, for whatever reason.  */
+ 		return NULL;
+diff -ru glibc-2.16.0-orig/locale/programs/locale.c glibc-2.16.0/locale/programs/locale.c
+--- glibc-2.16.0-orig/locale/programs/locale.c	2012-06-30 15:12:34.000000000 -0400
++++ glibc-2.16.0/locale/programs/locale.c	2012-09-18 11:53:03.719920947 -0400
+@@ -628,6 +628,20 @@
+ 		  ((const struct nameent *) b)->name);
+ }
+ 
++static int
++open_nix_locale_archive (const char * fname, int access)
++{
++  int fd = -1;
++  char *path = getenv ("LOCALE_ARCHIVE_2_11");
++  char *path2 = getenv ("LOCALE_ARCHIVE");
++  if (path)
++    fd = open64 (path, access);
++  if (path2 && fd < 0)
++    fd = open64 (path2, access);
++  if (fd < 0)
++    fd = open64 (fname, access);
++  return fd;
++}
+ 
+ static int
+ write_archive_locales (void **all_datap, char *linebuf)
+@@ -641,7 +655,7 @@
+   int fd, ret = 0;
+   uint32_t cnt;
+ 
+-  fd = open64 (ARCHIVE_NAME, O_RDONLY);
++  fd = open_nix_locale_archive (ARCHIVE_NAME, O_RDONLY);
+   if (fd < 0)
+     return 0;
+ 
+diff -ru glibc-2.16.0-orig/locale/programs/locarchive.c glibc-2.16.0/locale/programs/locarchive.c
+--- glibc-2.16.0-orig/locale/programs/locarchive.c	2012-06-30 15:12:34.000000000 -0400
++++ glibc-2.16.0/locale/programs/locarchive.c	2012-09-18 11:53:03.720920942 -0400
+@@ -509,6 +509,20 @@
+   *ah = new_ah;
+ }
+ 
++static int
++open_nix_locale_archive (const char * fname, int access)
++{
++  int fd = -1;
++  char *path = getenv ("LOCALE_ARCHIVE_2_11");
++  char *path2 = getenv ("LOCALE_ARCHIVE");
++  if (path)
++    fd = open64 (path, access);
++  if (path2 && fd < 0)
++    fd = open64 (path2, access);
++  if (fd < 0)
++    fd = open64 (fname, access);
++  return fd;
++}
+ 
+ void
+ open_archive (struct locarhandle *ah, bool readonly)
+@@ -528,7 +542,7 @@
+   while (1)
+     {
+       /* Open the archive.  We must have exclusive write access.  */
+-      fd = open64 (archivefname, readonly ? O_RDONLY : O_RDWR);
++      fd = open_nix_locale_archive (archivefname, readonly ? O_RDONLY : O_RDWR);
+       if (fd == -1)
+ 	{
+ 	  /* Maybe the file does not yet exist.  */
diff --git a/pkgs/development/libraries/glibc/2.16/nss-skip-unavail.patch b/pkgs/development/libraries/glibc/2.16/nss-skip-unavail.patch
new file mode 100644
index 000000000000..e48dc2bc0a6e
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/nss-skip-unavail.patch
@@ -0,0 +1,21 @@
+diff -ru glibc-2.11.2-orig/sysdeps/posix/getaddrinfo.c glibc-2.11.2/sysdeps/posix/getaddrinfo.c
+--- glibc-2.11.2-orig/sysdeps/posix/getaddrinfo.c	2010-05-19 22:38:20.000000000 +0200
++++ glibc-2.11.2/sysdeps/posix/getaddrinfo.c	2010-08-05 18:39:54.259556327 +0200
+@@ -505,8 +505,6 @@
+ 	  int no_data = 0;
+ 	  int no_inet6_data = 0;
+ 	  service_user *nip = NULL;
+-	  enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
+-	  enum nss_status status = NSS_STATUS_UNAVAIL;
+ 	  int no_more;
+ 	  int old_res_options;
+ 
+@@ -702,6 +700,8 @@
+ 
+ 	  while (!no_more)
+ 	    {
++ 	      enum nss_status inet6_status = NSS_STATUS_UNAVAIL;
++ 	      enum nss_status status = NSS_STATUS_UNAVAIL;
+ 	      no_data = 0;
+ 	      nss_gethostbyname4_r fct4
+ 		= __nss_lookup_function (nip, "gethostbyname4_r");
diff --git a/pkgs/development/libraries/glibc/2.16/rpcgen-path.patch b/pkgs/development/libraries/glibc/2.16/rpcgen-path.patch
new file mode 100644
index 000000000000..fbb03dd5fade
--- /dev/null
+++ b/pkgs/development/libraries/glibc/2.16/rpcgen-path.patch
@@ -0,0 +1,72 @@
+By default, rpcgen(1) looks for cpp(1) from a list of fixed absolute paths
+(`/lib/cpp', etc.), which may only be overrided with the `-Y' option.  This
+patch makes it run any `cpp' command found in $PATH.
+
+--- glibc-2.7/sunrpc/rpc_main.c	2006-11-10 21:54:46.000000000 +0100
++++ glibc-2.7/sunrpc/rpc_main.c	2009-04-22 14:32:10.000000000 +0200
+@@ -79,7 +79,7 @@ static const char *cmdname;
+ 
+ static const char *svcclosetime = "120";
+ static int cppDefined;	/* explicit path for C preprocessor */
+-static const char *CPP = SUNOS_CPP;
++static const char *CPP = "cpp";
+ static const char CPPFLAGS[] = "-C";
+ static char *pathbuf;
+ static int cpp_pid;
+@@ -108,7 +108,6 @@ static char *extendfile (const char *fil
+ static void open_output (const char *infile, const char *outfile);
+ static void add_warning (void);
+ static void clear_args (void);
+-static void find_cpp (void);
+ static void open_input (const char *infile, const char *define);
+ static int check_nettype (const char *name, const char *list_to_check[]);
+ static void c_output (const char *infile, const char *define,
+@@ -327,31 +326,6 @@ clear_args (void)
+   argcount = FIXEDARGS;
+ }
+ 
+-/* make sure that a CPP exists */
+-static void
+-find_cpp (void)
+-{
+-  struct stat buf;
+-
+-  if (stat (CPP, &buf) < 0)
+-    {				/* /lib/cpp or explicit cpp does not exist */
+-      if (cppDefined)
+-	{
+-	  fprintf (stderr, _ ("cannot find C preprocessor: %s \n"), CPP);
+-	  crash ();
+-	}
+-      else
+-	{			/* try the other one */
+-	  CPP = SVR4_CPP;
+-	  if (stat (CPP, &buf) < 0)
+-	    {			/* can't find any cpp */
+-	      fputs (_ ("cannot find any C preprocessor (cpp)\n"), stdout);
+-	      crash ();
+-	    }
+-	}
+-    }
+-}
+-
+ /*
+  * Open input file with given define for C-preprocessor
+  */
+@@ -370,7 +344,6 @@ open_input (const char *infile, const ch
+   switch (cpp_pid)
+     {
+     case 0:
+-      find_cpp ();
+       putarg (0, CPP);
+       putarg (1, CPPFLAGS);
+       addarg (define);
+@@ -380,7 +353,7 @@ open_input (const char *infile, const ch
+       close (1);
+       dup2 (pd[1], 1);
+       close (pd[0]);
+-      execv (arglist[0], (char **) arglist);
++      execvp (arglist[0], (char **) arglist);
+       perror ("execv");
+       exit (1);
+     case -1: