glibc: Add 2.27

This commit is contained in:
Shea Levy 2018-02-17 23:08:05 -05:00
parent d73aa60a65
commit 5be93a5883
No known key found for this signature in database
GPG key ID: 5C0BD6957D86FE27
5 changed files with 476 additions and 0 deletions

View file

@ -0,0 +1,101 @@
{ stdenv, callPackage
, withLinuxHeaders ? true
, installLocales ? true
, profilingLibraries ? false
, withGd ? false
}:
assert stdenv.cc.isGNU;
callPackage ./common-2.27.nix { inherit stdenv; } {
name = "glibc" + stdenv.lib.optionalString withGd "-gd";
inherit withLinuxHeaders profilingLibraries installLocales withGd;
NIX_NO_SELF_RPATH = true;
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
# Apparently --bindir is not respected.
makeFlagsArray+=("bindir=$bin/bin" "sbindir=$bin/sbin" "rootsbindir=$bin/sbin")
'';
# The stackprotector and fortify hardening flags are autodetected by glibc
# and enabled by default if supported. Setting it for every gcc invocation
# does not work.
hardeningDisable = [ "stackprotector" "fortify" ];
# 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.cc.cc}/lib/libgcc_s.so.1 ]; then
mkdir -p $out/lib
cp ${stdenv.cc.cc}/lib/libgcc_s.so.1 $out/lib/libgcc_s.so.1
# the .so It used to be a symlink, but now it is a script
cp -a ${stdenv.cc.cc}/lib/libgcc_s.so $out/lib/libgcc_s.so
fi
'';
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
if test -n "$linuxHeaders"; then
# Include the Linux kernel headers in Glibc, except the `scsi'
# subdirectory, which Glibc provides itself.
(cd $dev/include && \
ln -sv $(ls -d $linuxHeaders/include/* | grep -v scsi\$) .)
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
# Get rid of more unnecessary stuff.
rm -rf $out/var $bin/bin/sln
# For some reason these aren't stripped otherwise and retain reference
# to bootstrap-tools; on cross-arm this stripping would break objects.
if [ -z "$crossConfig" ]; then
for i in "$out"/lib/*.a; do
[ "$i" = "$out/lib/libm.a" ] || strip -S "$i"
done
fi
# Put libraries for static linking in a separate output. Note
# that libc_nonshared.a and libpthread_nonshared.a are required
# for dynamically-linked applications.
mkdir -p $static/lib
mv $out/lib/*.a $static/lib
mv $static/lib/lib*_nonshared.a $out/lib
# Some of *.a files are linker scripts where moving broke the paths.
sed "/^GROUP/s|$out/lib/lib|$static/lib/lib|g" \
-i "$static"/lib/*.a
# Work around a Nix bug: hard links across outputs cause a build failure.
cp $bin/bin/getconf $bin/bin/getconf_
mv $bin/bin/getconf_ $bin/bin/getconf
'';
separateDebugInfo = true;
meta.description = "The GNU C Library";
}

View file

@ -0,0 +1,208 @@
/* Build configuration used to build glibc, Info files, and locale
information. */
{ stdenv, lib
, buildPlatform, hostPlatform
, buildPackages
, fetchurl
, linuxHeaders ? null
, gd ? null, libpng ? null
, bison
}:
{ name
, withLinuxHeaders ? false
, profilingLibraries ? false
, installLocales ? false
, withGd ? false
, meta
, ...
} @ args:
let
version = "2.27";
patchSuffix = "";
sha256 = "0wpwq7gsm7sd6ysidv0z575ckqdg13cr2njyfgrbgh4f65adwwji";
cross = if buildPlatform != hostPlatform then hostPlatform else null;
in
assert withLinuxHeaders -> linuxHeaders != null;
assert withGd -> gd != null && libpng != null;
stdenv.mkDerivation ({
inherit installLocales;
linuxHeaders = if withLinuxHeaders then linuxHeaders else null;
# The host/target system.
crossConfig = if cross != null then cross.config else null;
inherit (stdenv) is64bit;
enableParallelBuilding = true;
patches =
[
/* Have rpcgen(1) look for cpp(1) in $PATH. */
./rpcgen-path.patch
/* Allow NixOS and Nix to handle the locale-archive. */
./nix-locale-archive-2.27.patch
/* Don't use /etc/ld.so.cache, for non-NixOS systems. */
./dont-use-system-ld-so-cache-2.27.patch
/* Don't use /etc/ld.so.preload, but /etc/ld-nix.so.preload. */
./dont-use-system-ld-so-preload.patch
/* The command "getconf CS_PATH" returns the default search path
"/bin:/usr/bin", which is inappropriate on NixOS machines. This
patch extends the search path by "/run/current-system/sw/bin". */
./fix_path_attribute_in_getconf.patch
/* Allow running with RHEL 6 -like kernels. The patch adds an exception
for glibc to accept 2.6.32 and to tag the ELFs as 2.6.32-compatible
(otherwise the loader would refuse libc).
Note that glibc will fully work only on their heavily patched kernels
and we lose early mismatch detection on 2.6.32.
On major glibc updates we should check that the patched kernel supports
all the required features. ATM it's verified up to glibc-2.26-131.
# HOWTO: check glibc sources for changes in kernel requirements
git log -p glibc-2.25.. sysdeps/unix/sysv/linux/x86_64/kernel-features.h sysdeps/unix/sysv/linux/kernel-features.h
# get kernel sources (update the URL)
mkdir tmp && cd tmp
curl http://vault.centos.org/6.9/os/Source/SPackages/kernel-2.6.32-696.el6.src.rpm | rpm2cpio - | cpio -idmv
tar xf linux-*.bz2
# check syscall presence, for example
less linux-*?/arch/x86/kernel/syscall_table_32.S
*/
./allow-kernel-2.6.32.patch
]
++ lib.optional stdenv.isx86_64 ./fix-x64-abi.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-nsl"
"--enable-obsolete-rpc"
"--sysconfdir=/etc"
"--enable-stackguard-randomization"
(if withLinuxHeaders
then "--with-headers=${linuxHeaders}/include"
else "--without-headers")
(if profilingLibraries
then "--enable-profile"
else "--disable-profile")
] ++ lib.optionals withLinuxHeaders [
"--enable-kernel=3.2.0" # can't get below with glibc >= 2.26
] ++ lib.optionals (cross != null) [
(if cross ? float && cross.float == "soft" then "--without-fp" else "--with-fp")
] ++ lib.optionals (cross != null) [
"--with-__thread"
] ++ lib.optionals (cross == null && stdenv.isArm) [
"--host=arm-linux-gnueabi"
"--build=arm-linux-gnueabi"
# To avoid linking with -lgcc_s (dynamic link)
# so the glibc does not depend on its compiler store path
"libc_cv_as_needed=no"
] ++ lib.optional withGd "--with-gd";
installFlags = [ "sysconfdir=$(out)/etc" ];
outputs = [ "out" "bin" "dev" "static" ];
depsBuildBuild = [ buildPackages.stdenv.cc ];
nativeBuildInputs = [ bison ];
buildInputs = lib.optionals withGd [ gd libpng ];
# 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";
}
// (removeAttrs args [ "withLinuxHeaders" "withGd" ]) //
{
name = name + "-${version}${patchSuffix}";
src = fetchurl {
url = "mirror://gnu/glibc/glibc-${version}.tar.xz";
inherit sha256;
};
# 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
mkdir ../build
cd ../build
configureScript="`pwd`/../$sourceRoot/configure"
${lib.optionalString (stdenv.cc.libc != null)
''makeFlags="$makeFlags BUILD_LDFLAGS=-Wl,-rpath,${stdenv.cc.libc}/lib"''
}
'' + lib.optionalString (cross != null) ''
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
EOF
'';
preBuild = lib.optionalString withGd "unset NIX_DONT_SET_RPATH";
meta = {
homepage = http://www.gnu.org/software/libc/;
description = "The GNU C Library";
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 = lib.licenses.lgpl2Plus;
maintainers = [ lib.maintainers.eelco ];
platforms = lib.platforms.linux;
} // meta;
}
// lib.optionalAttrs (cross != null) {
preInstall = null; # clobber the native hook
dontStrip = true;
separateDebugInfo = false; # this is currently broken for crossDrv
# To avoid a dependency on the build system 'bash'.
preFixup = ''
rm -f $bin/bin/{ldd,tzselect,catchsegv,xtrace}
'';
})

View file

@ -0,0 +1,46 @@
diff -Naur glibc-2.27-orig/elf/ldconfig.c glibc-2.27/elf/ldconfig.c
--- glibc-2.27-orig/elf/ldconfig.c 2018-02-01 11:17:18.000000000 -0500
+++ glibc-2.27/elf/ldconfig.c 2018-02-17 22:43:17.232175182 -0500
@@ -51,7 +51,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 -Naur glibc-2.27-orig/elf/Makefile glibc-2.27/elf/Makefile
--- glibc-2.27-orig/elf/Makefile 2018-02-01 11:17:18.000000000 -0500
+++ glibc-2.27/elf/Makefile 2018-02-17 22:44:50.334006750 -0500
@@ -559,13 +559,13 @@
$(objpfx)ldconfig: $(ldconfig-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)"'
libof-ldconfig = ldconfig
-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)
cpp-srcs-left := $(all-rtld-routines:=.os)
lib := rtld
diff -Naur glibc-2.27-orig/sysdeps/generic/dl-cache.h glibc-2.27/sysdeps/generic/dl-cache.h
--- glibc-2.27-orig/sysdeps/generic/dl-cache.h 2018-02-01 11:17:18.000000000 -0500
+++ glibc-2.27/sysdeps/generic/dl-cache.h 2018-02-17 22:45:20.471598816 -0500
@@ -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

View file

@ -0,0 +1,118 @@
diff -Naur glibc-2.27-orig/locale/loadarchive.c glibc-2.27/locale/loadarchive.c
--- glibc-2.27-orig/locale/loadarchive.c 2018-02-01 11:17:18.000000000 -0500
+++ glibc-2.27/locale/loadarchive.c 2018-02-17 22:32:25.680169462 -0500
@@ -123,6 +123,23 @@
return MAX (namehash_end, MAX (string_end, locrectab_end));
}
+static int
+open_locale_archive (void)
+{
+ int fd = -1;
+ char *versioned_path = getenv ("LOCAL_ARCHIVE_2_27");
+ char *path = getenv ("LOCAL_ARCHIVE");
+ if (versioned_path)
+ fd = __open_nocancel (versioned_path, O_RDONLY|O_LARGEFILE|O_CLOEXEC);
+ if (path && fd < 0)
+ fd = __open_nocancel (path, O_RDONLY|O_LARGEFILE|O_CLOEXEC);
+ if (fd < 0)
+ fd = __open_nocancel (archfname, O_RDONLY|O_LARGEFILE|O_CLOEXEC);
+ if (fd < 0)
+ fd = __open_nocancel ("/usr/lib/locale/locale-archive", 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
@@ -202,7 +219,7 @@
archmapped = &headmap;
/* The archive has never been opened. */
- fd = __open_nocancel (archfname, O_RDONLY|O_LARGEFILE|O_CLOEXEC);
+ fd = open_locale_archive ();
if (fd < 0)
/* Cannot open the archive, for whatever reason. */
return NULL;
@@ -397,8 +414,7 @@
if (fd == -1)
{
struct stat64 st;
- fd = __open_nocancel (archfname,
- O_RDONLY|O_LARGEFILE|O_CLOEXEC);
+ fd = open_locale_archive ();
if (fd == -1)
/* Cannot open the archive, for whatever reason. */
return NULL;
diff -Naur glibc-2.27-orig/locale/programs/locale.c glibc-2.27/locale/programs/locale.c
--- glibc-2.27-orig/locale/programs/locale.c 2018-02-01 11:17:18.000000000 -0500
+++ glibc-2.27/locale/programs/locale.c 2018-02-17 22:36:39.726293213 -0500
@@ -633,6 +633,24 @@
static int
+open_locale_archive (void)
+{
+ int fd = -1;
+ char *versioned_path = getenv ("LOCAL_ARCHIVE_2_27");
+ char *path = getenv ("LOCAL_ARCHIVE");
+ if (versioned_path)
+ fd = open64 (versioned_path, O_RDONLY);
+ if (path && fd < 0)
+ fd = open64 (path, O_RDONLY);
+ if (fd < 0)
+ fd = open64 (ARCHIVE_NAME, O_RDONLY);
+ if (fd < 0)
+ fd = open64 ("/usr/lib/locale/locale-archive", O_RDONLY);
+ return fd;
+}
+
+
+static int
write_archive_locales (void **all_datap, char *linebuf)
{
struct stat64 st;
@@ -644,7 +662,7 @@
int fd, ret = 0;
uint32_t cnt;
- fd = open64 (ARCHIVE_NAME, O_RDONLY);
+ fd = open_locale_archive ();
if (fd < 0)
return 0;
diff -Naur glibc-2.27-orig/locale/programs/locarchive.c glibc-2.27/locale/programs/locarchive.c
--- glibc-2.27-orig/locale/programs/locarchive.c 2018-02-01 11:17:18.000000000 -0500
+++ glibc-2.27/locale/programs/locarchive.c 2018-02-17 22:40:51.245293975 -0500
@@ -117,6 +117,22 @@
}
+static int
+open_locale_archive (const char * archivefname, int flags)
+{
+ int fd = -1;
+ char *versioned_path = getenv ("LOCAL_ARCHIVE_2_27");
+ char *path = getenv ("LOCAL_ARCHIVE");
+ if (versioned_path)
+ fd = open64 (versioned_path, flags);
+ if (path && fd < 0)
+ fd = open64 (path, flags);
+ if (fd < 0)
+ fd = open64 (archivefname, flags);
+ return fd;
+}
+
+
static void
create_archive (const char *archivefname, struct locarhandle *ah)
{
@@ -578,7 +594,7 @@
while (1)
{
/* Open the archive. We must have exclusive write access. */
- fd = open64 (archivefname, readonly ? O_RDONLY : O_RDWR);
+ fd = open_locale_archive (archivefname, readonly ? O_RDONLY : O_RDWR);
if (fd == -1)
{
/* Maybe the file does not yet exist? If we are opening

View file

@ -8748,6 +8748,9 @@ with pkgs;
glibc = callPackage ../development/libraries/glibc {
installLocales = config.glibc.locales or false;
};
glibc_2_27 = callPackage ../development/libraries/glibc/2.27.nix {
installLocales = config.glibc.locales or false;
};
glibc_memusage = callPackage ../development/libraries/glibc {
installLocales = false;