diff --git a/.gitignore b/.gitignore index 7bf77adf406..3d2a1c30bca 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ perl/Makefile.config /autom4te.cache /precompiled-headers.h.gch /config.* +/config/ /configure /stamp-h1 /svn-revision diff --git a/config/install-sh b/config/install-sh deleted file mode 100755 index 377bb8687ff..00000000000 --- a/config/install-sh +++ /dev/null @@ -1,527 +0,0 @@ -#!/bin/sh -# install - install a program, script, or datafile - -scriptversion=2011-11-20.07; # UTC - -# This originates from X11R5 (mit/util/scripts/install.sh), which was -# later released in X11R6 (xc/config/util/install.sh) with the -# following copyright and license. -# -# Copyright (C) 1994 X Consortium -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to -# deal in the Software without restriction, including without limitation the -# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -# sell copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- -# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -# Except as contained in this notice, the name of the X Consortium shall not -# be used in advertising or otherwise to promote the sale, use or other deal- -# ings in this Software without prior written authorization from the X Consor- -# tium. -# -# -# FSF changes to this file are in the public domain. -# -# Calling this script install-sh is preferred over install.sh, to prevent -# 'make' implicit rules from creating a file called install from it -# when there is no Makefile. -# -# This script is compatible with the BSD install script, but was written -# from scratch. - -nl=' -' -IFS=" "" $nl" - -# set DOITPROG to echo to test this script - -# Don't use :- since 4.3BSD and earlier shells don't like it. -doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi - -# Put in absolute file names if you don't have them in your path; -# or use environment vars. - -chgrpprog=${CHGRPPROG-chgrp} -chmodprog=${CHMODPROG-chmod} -chownprog=${CHOWNPROG-chown} -cmpprog=${CMPPROG-cmp} -cpprog=${CPPROG-cp} -mkdirprog=${MKDIRPROG-mkdir} -mvprog=${MVPROG-mv} -rmprog=${RMPROG-rm} -stripprog=${STRIPPROG-strip} - -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - -posix_mkdir= - -# Desired mode of installed file. -mode=0755 - -chgrpcmd= -chmodcmd=$chmodprog -chowncmd= -mvcmd=$mvprog -rmcmd="$rmprog -f" -stripcmd= - -src= -dst= -dir_arg= -dst_arg= - -copy_on_change=false -no_target_directory= - -usage="\ -Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE - or: $0 [OPTION]... SRCFILES... DIRECTORY - or: $0 [OPTION]... -t DIRECTORY SRCFILES... - or: $0 [OPTION]... -d DIRECTORIES... - -In the 1st form, copy SRCFILE to DSTFILE. -In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. -In the 4th, create DIRECTORIES. - -Options: - --help display this help and exit. - --version display version info and exit. - - -c (ignored) - -C install only if different (preserve the last data modification time) - -d create directories instead of installing files. - -g GROUP $chgrpprog installed files to GROUP. - -m MODE $chmodprog installed files to MODE. - -o USER $chownprog installed files to USER. - -s $stripprog installed files. - -t DIRECTORY install into DIRECTORY. - -T report an error if DSTFILE is a directory. - -Environment variables override the default commands: - CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG - RMPROG STRIPPROG -" - -while test $# -ne 0; do - case $1 in - -c) ;; - - -C) copy_on_change=true;; - - -d) dir_arg=true;; - - -g) chgrpcmd="$chgrpprog $2" - shift;; - - --help) echo "$usage"; exit $?;; - - -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; - - -o) chowncmd="$chownprog $2" - shift;; - - -s) stripcmd=$stripprog;; - - -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; - - -T) no_target_directory=true;; - - --version) echo "$0 $scriptversion"; exit $?;; - - --) shift - break;; - - -*) echo "$0: invalid option: $1" >&2 - exit 1;; - - *) break;; - esac - shift -done - -if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then - # When -d is used, all remaining arguments are directories to create. - # When -t is used, the destination is already specified. - # Otherwise, the last argument is the destination. Remove it from $@. - for arg - do - if test -n "$dst_arg"; then - # $@ is not empty: it contains at least $arg. - set fnord "$@" "$dst_arg" - shift # fnord - fi - shift # arg - dst_arg=$arg - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - done -fi - -if test $# -eq 0; then - if test -z "$dir_arg"; then - echo "$0: no input file specified." >&2 - exit 1 - fi - # It's OK to call 'install-sh -d' without argument. - # This can happen when creating conditional directories. - exit 0 -fi - -if test -z "$dir_arg"; then - do_exit='(exit $ret); exit $ret' - trap "ret=129; $do_exit" 1 - trap "ret=130; $do_exit" 2 - trap "ret=141; $do_exit" 13 - trap "ret=143; $do_exit" 15 - - # Set umask so as not to create temps with too-generous modes. - # However, 'strip' requires both read and write access to temps. - case $mode in - # Optimize common cases. - *644) cp_umask=133;; - *755) cp_umask=22;; - - *[0-7]) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw='% 200' - fi - cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; - *) - if test -z "$stripcmd"; then - u_plus_rw= - else - u_plus_rw=,u+rw - fi - cp_umask=$mode$u_plus_rw;; - esac -fi - -for src -do - # Protect names problematic for 'test' and other utilities. - case $src in - -* | [=\(\)!]) src=./$src;; - esac - - if test -n "$dir_arg"; then - dst=$src - dstdir=$dst - test -d "$dstdir" - dstdir_status=$? - else - - # Waiting for this to be detected by the "$cpprog $src $dsttmp" command - # might cause directories to be created, which would be especially bad - # if $src (and thus $dsttmp) contains '*'. - if test ! -f "$src" && test ! -d "$src"; then - echo "$0: $src does not exist." >&2 - exit 1 - fi - - if test -z "$dst_arg"; then - echo "$0: no destination specified." >&2 - exit 1 - fi - dst=$dst_arg - - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. - if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 - fi - dstdir=$dst - dst=$dstdir/`basename "$src"` - dstdir_status=0 - else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - - test -d "$dstdir" - dstdir_status=$? - fi - fi - - obsolete_mkdir_used=false - - if test $dstdir_status != 0; then - case $posix_mkdir in - '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; - esac - - if - $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" - ) - then : - else - - # The umask is ridiculous, or mkdir does not conform to POSIX, - # or it failed possibly due to a race condition. Create the - # directory the slow way, step by step, checking for races as we go. - - case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; - esac - - eval "$initialize_posix_glob" - - oIFS=$IFS - IFS=/ - $posix_glob set -f - set fnord $dstdir - shift - $posix_glob set +f - IFS=$oIFS - - prefixes= - - for d - do - test X"$d" = X && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ - done - - if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true - fi - fi - fi - - if test -n "$dir_arg"; then - { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && - { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || - test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 - else - - # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ - - # Trap to clean up those temp files at exit. - trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 - - # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && - - # and set any options; do chmod last to preserve setuid bits. - # - # If any of these fail, we abort the whole thing. If we want to - # ignore errors from any of these, just make sure not to ignore - # errors from the above "$doit $cpprog $src $dsttmp" command. - # - { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && - { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && - { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && - { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && - - # If -C, don't bother to copy if it wouldn't change the file. - if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && - set X $old && old=:$2:$4:$5:$6 && - set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - - test "$old" = "$new" && - $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 - then - rm -f "$dsttmp" - else - # Rename the file to the real destination. - $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || - - # The rename failed, perhaps because mv can't rename something else - # to itself, or perhaps because mv is so ancient that it does not - # support -f. - { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" - } - fi || exit 1 - - trap '' 0 - fi -done - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/dep-patches/boehmgc-coroutine-sp-fallback.diff b/dep-patches/boehmgc-coroutine-sp-fallback.diff deleted file mode 100644 index 2afbe96712b..00000000000 --- a/dep-patches/boehmgc-coroutine-sp-fallback.diff +++ /dev/null @@ -1,99 +0,0 @@ -diff --git a/darwin_stop_world.c b/darwin_stop_world.c -index 0468aaec..b348d869 100644 ---- a/darwin_stop_world.c -+++ b/darwin_stop_world.c -@@ -356,6 +356,7 @@ GC_INNER void GC_push_all_stacks(void) - int nthreads = 0; - word total_size = 0; - mach_msg_type_number_t listcount = (mach_msg_type_number_t)THREAD_TABLE_SZ; -+ size_t stack_limit; - if (!EXPECT(GC_thr_initialized, TRUE)) - GC_thr_init(); - -@@ -411,6 +412,19 @@ GC_INNER void GC_push_all_stacks(void) - GC_push_all_stack_sections(lo, hi, p->traced_stack_sect); - } - if (altstack_lo) { -+ // When a thread goes into a coroutine, we lose its original sp until -+ // control flow returns to the thread. -+ // While in the coroutine, the sp points outside the thread stack, -+ // so we can detect this and push the entire thread stack instead, -+ // as an approximation. -+ // We assume that the coroutine has similarly added its entire stack. -+ // This could be made accurate by cooperating with the application -+ // via new functions and/or callbacks. -+ stack_limit = pthread_get_stacksize_np(p->id); -+ if (altstack_lo >= altstack_hi || altstack_lo < altstack_hi - stack_limit) { // sp outside stack -+ altstack_lo = altstack_hi - stack_limit; -+ } -+ - total_size += altstack_hi - altstack_lo; - GC_push_all_stack(altstack_lo, altstack_hi); - } -diff --git a/include/gc.h b/include/gc.h -index edab6c22..f2c61282 100644 ---- a/include/gc.h -+++ b/include/gc.h -@@ -2172,6 +2172,11 @@ GC_API void GC_CALL GC_win32_free_heap(void); - (*GC_amiga_allocwrapper_do)(a,GC_malloc_atomic_ignore_off_page) - #endif /* _AMIGA && !GC_AMIGA_MAKINGLIB */ - -+#if !__APPLE__ -+/* Patch doesn't work on apple */ -+#define NIX_BOEHM_PATCH_VERSION 1 -+#endif -+ - #ifdef __cplusplus - } /* extern "C" */ - #endif -diff --git a/pthread_stop_world.c b/pthread_stop_world.c -index b5d71e62..aed7b0bf 100644 ---- a/pthread_stop_world.c -+++ b/pthread_stop_world.c -@@ -768,6 +768,8 @@ STATIC void GC_restart_handler(int sig) - /* world is stopped. Should not fail if it isn't. */ - GC_INNER void GC_push_all_stacks(void) - { -+ size_t stack_limit; -+ pthread_attr_t pattr; - GC_bool found_me = FALSE; - size_t nthreads = 0; - int i; -@@ -851,6 +853,37 @@ GC_INNER void GC_push_all_stacks(void) - hi = p->altstack + p->altstack_size; - /* FIXME: Need to scan the normal stack too, but how ? */ - /* FIXME: Assume stack grows down */ -+ } else { -+#ifdef HAVE_PTHREAD_ATTR_GET_NP -+ if (!pthread_attr_init(&pattr) -+ || !pthread_attr_get_np(p->id, &pattr)) -+#else /* HAVE_PTHREAD_GETATTR_NP */ -+ if (pthread_getattr_np(p->id, &pattr)) -+#endif -+ { -+ ABORT("GC_push_all_stacks: pthread_getattr_np failed!"); -+ } -+ if (pthread_attr_getstacksize(&pattr, &stack_limit)) { -+ ABORT("GC_push_all_stacks: pthread_attr_getstacksize failed!"); -+ } -+ if (pthread_attr_destroy(&pattr)) { -+ ABORT("GC_push_all_stacks: pthread_attr_destroy failed!"); -+ } -+ // When a thread goes into a coroutine, we lose its original sp until -+ // control flow returns to the thread. -+ // While in the coroutine, the sp points outside the thread stack, -+ // so we can detect this and push the entire thread stack instead, -+ // as an approximation. -+ // We assume that the coroutine has similarly added its entire stack. -+ // This could be made accurate by cooperating with the application -+ // via new functions and/or callbacks. -+ #ifndef STACK_GROWS_UP -+ if (lo >= hi || lo < hi - stack_limit) { // sp outside stack -+ lo = hi - stack_limit; -+ } -+ #else -+ #error "STACK_GROWS_UP not supported in boost_coroutine2 (as of june 2021), so we don't support it in Nix." -+ #endif - } - GC_push_all_stack_sections(lo, hi, traced_stack_sect); - # ifdef STACK_GROWS_UP diff --git a/flake.lock b/flake.lock index bb2e400c0a9..d0ef5f4305a 100644 --- a/flake.lock +++ b/flake.lock @@ -48,6 +48,22 @@ "type": "github" } }, + "nixpkgs-nixos-unstable": { + "locked": { + "lastModified": 1709479366, + "narHash": "sha256-n6F0n8UV6lnTZbYPl1A9q1BS0p4hduAv1mGAP17CVd0=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b8697e57f10292a6165a20f03d2f42920dfaf973", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, "nixpkgs-regression": { "locked": { "lastModified": 1643052045, @@ -69,6 +85,7 @@ "flake-compat": "flake-compat", "libgit2": "libgit2", "nixpkgs": "nixpkgs", + "nixpkgs-nixos-unstable": "nixpkgs-nixos-unstable", "nixpkgs-regression": "nixpkgs-regression" } } diff --git a/flake.nix b/flake.nix index 42aaace6746..7cfb906832c 100644 --- a/flake.nix +++ b/flake.nix @@ -4,16 +4,34 @@ # TODO switch to nixos-23.11-small # https://nixpk.gs/pr-tracker.html?pr=291954 inputs.nixpkgs.url = "github:NixOS/nixpkgs/release-23.11"; - inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2"; inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; }; inputs.libgit2 = { url = "github:libgit2/libgit2"; flake = false; }; - outputs = { self, nixpkgs, nixpkgs-regression, libgit2, ... }: + # dev + inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2"; + inputs.nixpkgs-nixos-unstable.url = "github:NixOS/nixpkgs/nixos-unstable"; + + outputs = inputs@{ self, nixpkgs, nixpkgs-regression, libgit2, ... }: let inherit (nixpkgs) lib; inherit (lib) fileset; + nixpkgsChannel = inputs.nixpkgsChannel or "nixos-23.11"; + # If nixpkgsChannel hasn't been set, its the default invocation of the + # flake outputs, and we want to add attributes for the other variants. + shouldAddVariants = ! inputs?nixpkgsChannel; + + self_nixos-unstable = + (import ./flake.nix).outputs + (inputs // { + nixpkgs = inputs.nixpkgs-nixos-unstable; + nixpkgsChannel = "nixos-unstable"; + self = self_nixos-unstable; + }); + + prefixAttrs = prefix: lib.concatMapAttrs (k: v: { "${prefix}${k}" = v; }); + officialRelease = false; version = lib.fileContents ./.version + versionSuffix; @@ -155,8 +173,6 @@ enableLargeConfig = true; }).overrideAttrs(o: { patches = (o.patches or []) ++ [ - ./dep-patches/boehmgc-coroutine-sp-fallback.diff - # https://github.com/ivmai/bdwgc/pull/586 ./dep-patches/boehmgc-traceable_allocator-public.diff ]; @@ -306,10 +322,19 @@ nixpkgsLibTests = forAllSystems (system: - import (nixpkgs + "/lib/tests/release.nix") - { pkgs = nixpkgsFor.${system}.native; - nixVersions = [ self.packages.${system}.nix ]; - } + if nixpkgsChannel == "nixos-23.11" + then + import (nixpkgs + "/lib/tests/release.nix") + { pkgs = nixpkgsFor.${system}.native; + nixVersions = [ self.packages.${system}.nix ]; + } + else + import (nixpkgs + "/lib/tests/test-with-nix.nix") + { + lib = nixpkgsFor.${system}.native.lib; + nix = self.packages.${system}.nix; + pkgs = nixpkgsFor.${system}.native; + } ); }; @@ -336,7 +361,8 @@ binaryTarballs = self.hydraJobs.binaryTarball; inherit nixpkgsFor; }; - + } // lib.optionalAttrs shouldAddVariants { + nixos-unstable = self_nixos-unstable.hydraJobs; }; checks = forAllSystems (system: { @@ -351,7 +377,9 @@ ''; } // (lib.optionalAttrs (builtins.elem system linux64BitSystems)) { dockerImage = self.hydraJobs.dockerImage.${system}; - }); + } // lib.optionalAttrs shouldAddVariants ( + prefixAttrs "nixos-unstable-" self_nixos-unstable.checks.${system} + )); packages = forAllSystems (system: rec { inherit (nixpkgsFor.${system}.native) nix changelog-d-nix; @@ -383,7 +411,11 @@ name = "nix-${stdenvName}"; value = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".nix; }) - stdenvs))); + stdenvs)) + // lib.optionalAttrs shouldAddVariants ( + prefixAttrs "nixos-unstable-" self_nixos-unstable.packages.${system} + ) + ); devShells = let makeShell = pkgs: stdenv: (pkgs.nix.override { inherit stdenv; forDevShell = true; }).overrideAttrs (attrs: { @@ -418,6 +450,9 @@ { default = self.devShells.${system}.native-stdenvPackages; } + // lib.optionalAttrs shouldAddVariants ( + prefixAttrs "nixos-unstable-" self_nixos-unstable.devShells.${system} + ) ); }; } diff --git a/package.nix b/package.nix index a90973b4c82..fa898e906db 100644 --- a/package.nix +++ b/package.nix @@ -349,9 +349,15 @@ in { # Needed for tests if we are not doing a build, but testing existing # built Nix. - preInstallCheck = lib.optionalString (! doBuild) '' - mkdir -p src/nix-channel - ''; + preInstallCheck = + lib.optionalString (! doBuild) '' + mkdir -p src/nix-channel + '' + # See https://github.com/NixOS/nix/issues/2523 + # Occurs often in tests since https://github.com/NixOS/nix/pull/9900 + + lib.optionalString stdenv.hostPlatform.isDarwin '' + export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES + ''; separateDebugInfo = !stdenv.hostPlatform.isStatic; diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 722ff690816..28220b24bd8 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -248,6 +249,50 @@ class BoehmGCStackAllocator : public StackAllocator { static BoehmGCStackAllocator boehmGCStackAllocator; +/** + * When a thread goes into a coroutine, we lose its original sp until + * control flow returns to the thread. + * While in the coroutine, the sp points outside the thread stack, + * so we can detect this and push the entire thread stack instead, + * as an approximation. + * The coroutine's stack is covered by `BoehmGCStackAllocator`. + * This is not an optimal solution, because the garbage is scanned when a + * coroutine is active, for both the coroutine and the original thread stack. + * However, the implementation is quite lean, and usually we don't have active + * coroutines during evaluation, so this is acceptable. + */ +void fixupBoehmStackPointer(void ** sp_ptr, void * pthread_id) { + void *& sp = *sp_ptr; + pthread_attr_t pattr; + size_t osStackSize; + void * osStackLow; + void * osStackBase; + + #ifdef __APPLE__ + osStackSize = pthread_get_stacksize_np((pthread_t)pthread_id); + osStackLow = pthread_get_stackaddr_np((pthread_t)pthread_id); + #else + if (pthread_attr_init(&pattr)) { + throw Error("fixupBoehmStackPointer: pthread_attr_init failed"); + } + if (pthread_getattr_np((pthread_t)pthread_id, &pattr)) { + throw Error("fixupBoehmStackPointer: pthread_getattr_np failed"); + } + if (pthread_attr_getstack(&pattr, &osStackLow, &osStackSize)) { + throw Error("fixupBoehmStackPointer: pthread_attr_getstack failed"); + } + if (pthread_attr_destroy(&pattr)) { + throw Error("fixupBoehmStackPointer: pthread_attr_destroy failed"); + } + #endif + osStackBase = (char *)osStackLow + osStackSize; + // NOTE: We assume the stack grows down, as it does on all architectures we support. + // Architectures that grow the stack up are rare. + if (sp >= osStackBase || sp < osStackLow) { // lo is outside the os stack + sp = osStackBase; + } +} + #endif @@ -303,14 +348,23 @@ void initGC() StackAllocator::defaultAllocator = &boehmGCStackAllocator; + // TODO: Remove __APPLE__ condition. + // Comment suggests an implementation that works on darwin and windows + // https://github.com/ivmai/bdwgc/issues/362#issuecomment-1936672196 + #if GC_VERSION_MAJOR >= 8 && GC_VERSION_MINOR >= 4 && !defined(__APPLE__) + GC_set_sp_corrector(&fixupBoehmStackPointer); + + if (!GC_get_sp_corrector()) { + printTalkative("BoehmGC on this platform does not support sp_corrector; will disable GC inside coroutines"); + /* Used to disable GC when entering coroutines on macOS */ + create_coro_gc_hook = []() -> std::shared_ptr { + return std::make_shared(); + }; + } + #else + #warning "BoehmGC version does not support GC while coroutine exists. GC will be disabled inside coroutines. Consider updating bwd-gc to 8.4 or later." + #endif -#if NIX_BOEHM_PATCH_VERSION != 1 - printTalkative("Unpatched BoehmGC, disabling GC inside coroutines"); - /* Used to disable GC when entering coroutines on macOS */ - create_coro_gc_hook = []() -> std::shared_ptr { - return std::make_shared(); - }; -#endif /* Set the initial heap size to something fairly big (25% of physical RAM, up to a maximum of 384 MiB) so that in most cases diff --git a/src/libexpr/local.mk b/src/libexpr/local.mk index 0c3e36750e8..988bc84c969 100644 --- a/src/libexpr/local.mk +++ b/src/libexpr/local.mk @@ -12,7 +12,9 @@ libexpr_SOURCES := \ $(d)/lexer-tab.cc \ $(d)/parser-tab.cc -libexpr_CXXFLAGS += -I src/libutil -I src/libstore -I src/libfetchers -I src/libmain -I src/libexpr +libexpr_CXXFLAGS += \ + -I src/libutil -I src/libstore -I src/libfetchers -I src/libmain -I src/libexpr \ + -DGC_THREADS libexpr_LIBS = libutil libstore libfetchers diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 78f7f71ed84..78f902b9a8d 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1563,6 +1563,9 @@ static RegisterPrimOp primop_pathExists({ .doc = R"( Return `true` if the path *path* exists at evaluation time, and `false` otherwise. + + If the path refers to a symlink, `pathExists` returns `true` without + checking the target of the symlink. )", .fun = prim_pathExists, }); diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 7bced0aa429..d6cc6174c7f 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -22,6 +22,9 @@ #endif #include +#if HAVE_BOEHMGC +#include +#endif namespace nix { @@ -300,6 +303,17 @@ void printVersion(const std::string & programName) std::cout << "Store directory: " << settings.nixStore << "\n"; std::cout << "State directory: " << settings.nixStateDir << "\n"; std::cout << "Data directory: " << settings.nixDataDir << "\n"; +#if HAVE_BOEHMGC +#define _TO_STRING(x) #x +#define TO_STRING(x) _TO_STRING(x) + std::cout << "Evaluator gc: bdw-gc " + << TO_STRING(GC_VERSION_MAJOR) << "." + << TO_STRING(GC_VERSION_MINOR) << "." + << TO_STRING(GC_VERSION_MICRO) << "\n"; +#undef TO_STRING +#else + std::cout << "Evaluator gc: built without gc support" << "\n"; +#endif } throw Exit(); }