From 5be93a588335082d0610c739067035dfc1ddd260 Mon Sep 17 00:00:00 2001 From: Shea Levy Date: Sat, 17 Feb 2018 23:08:05 -0500 Subject: glibc: Add 2.27 --- pkgs/development/libraries/glibc/2.27.nix | 101 ++++++++++ pkgs/development/libraries/glibc/common-2.27.nix | 208 +++++++++++++++++++++ .../glibc/dont-use-system-ld-so-cache-2.27.patch | 46 +++++ .../libraries/glibc/nix-locale-archive-2.27.patch | 118 ++++++++++++ 4 files changed, 473 insertions(+) create mode 100644 pkgs/development/libraries/glibc/2.27.nix create mode 100644 pkgs/development/libraries/glibc/common-2.27.nix create mode 100644 pkgs/development/libraries/glibc/dont-use-system-ld-so-cache-2.27.patch create mode 100644 pkgs/development/libraries/glibc/nix-locale-archive-2.27.patch (limited to 'pkgs/development/libraries/glibc') diff --git a/pkgs/development/libraries/glibc/2.27.nix b/pkgs/development/libraries/glibc/2.27.nix new file mode 100644 index 00000000000..bb057ae899e --- /dev/null +++ b/pkgs/development/libraries/glibc/2.27.nix @@ -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"; + } diff --git a/pkgs/development/libraries/glibc/common-2.27.nix b/pkgs/development/libraries/glibc/common-2.27.nix new file mode 100644 index 00000000000..d493feb35fa --- /dev/null +++ b/pkgs/development/libraries/glibc/common-2.27.nix @@ -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} + ''; +}) diff --git a/pkgs/development/libraries/glibc/dont-use-system-ld-so-cache-2.27.patch b/pkgs/development/libraries/glibc/dont-use-system-ld-so-cache-2.27.patch new file mode 100644 index 00000000000..f84b1049adf --- /dev/null +++ b/pkgs/development/libraries/glibc/dont-use-system-ld-so-cache-2.27.patch @@ -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 diff --git a/pkgs/development/libraries/glibc/nix-locale-archive-2.27.patch b/pkgs/development/libraries/glibc/nix-locale-archive-2.27.patch new file mode 100644 index 00000000000..1b3590db4fd --- /dev/null +++ b/pkgs/development/libraries/glibc/nix-locale-archive-2.27.patch @@ -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 -- cgit 1.4.1