Compare commits

..

1 commit

398 changed files with 8491 additions and 6580 deletions

View file

@ -24,8 +24,3 @@ indent_size = 4
# Match diffs, avoid to trim trailing whitespace
[*.{diff,patch}]
trim_trailing_whitespace = false
[*.md]
indent_style = space
indent_size = 2
max_line_length = 0

129
.gitignore vendored
View file

@ -1,5 +1,128 @@
Makefile.config
perl/Makefile.config
# /
/aclocal.m4
/autom4te.cache
/precompiled-headers.h.gch
/config.*
/configure
/stamp-h1
/svn-revision
/libtool
/config
# /doc/manual/
/doc/manual/*.1
/doc/manual/*.5
/doc/manual/*.8
/doc/manual/generated/*
/doc/manual/nix.json
/doc/manual/conf-file.json
/doc/manual/language.json
/doc/manual/xp-features.json
/doc/manual/src/command-ref/experimental-features-shortlist.md
/doc/manual/src/contributing/experimental-feature-descriptions.md
/doc/manual/src/release-notes/rl-next-generated.md
# /scripts/
/scripts/nix-profile.sh
/scripts/nix-profile-daemon.sh
/scripts/nix-profile.fish
/scripts/nix-profile-daemon.fish
# /src/libexpr/
/src/libexpr/lexer-tab.cc
/src/libexpr/lexer-tab.hh
/src/libexpr/parser-tab.cc
/src/libexpr/parser-tab.hh
/src/libexpr/parser-tab.output
/src/libexpr/nix.tbl
/src/libexpr/tests
/tests/unit/libexpr/libnixexpr-tests
# /src/libstore/
*.gen.*
/src/libstore/tests
/tests/unit/libstore/libnixstore-tests
# /src/libutil/
/src/libutil/tests
/tests/unit/libutil/libnixutil-tests
/src/nix/nix
/src/nix/doc
# /src/nix-env/
/src/nix-env/nix-env
# /src/nix-instantiate/
/src/nix-instantiate/nix-instantiate
# /src/nix-store/
/src/nix-store/nix-store
/src/nix-prefetch-url/nix-prefetch-url
/src/nix-collect-garbage/nix-collect-garbage
# /src/nix-channel/
/src/nix-channel/nix-channel
# /src/nix-build/
/src/nix-build/nix-build
/src/nix-copy-closure/nix-copy-closure
/src/error-demo/error-demo
/src/build-remote/build-remote
# /tests/functional/
/tests/functional/test-tmp
/tests/functional/common/vars-and-functions.sh
/tests/functional/result*
/tests/functional/restricted-innocent
/tests/functional/shell
/tests/functional/shell.drv
/tests/functional/config.nix
/tests/functional/ca/config.nix
/tests/functional/dyn-drv/config.nix
/tests/functional/repl-result-out
/tests/functional/debugger-test-out
/tests/functional/test-libstoreconsumer/test-libstoreconsumer
# /tests/functional/lang/
/tests/functional/lang/*.out
/tests/functional/lang/*.out.xml
/tests/functional/lang/*.err
/tests/functional/lang/*.ast
/perl/lib/Nix/Config.pm
/perl/lib/Nix/Store.cc
/misc/systemd/nix-daemon.service
/misc/systemd/nix-daemon.socket
/misc/systemd/nix-daemon.conf
/misc/upstart/nix-daemon.conf
/src/resolve-system-dependencies/resolve-system-dependencies
outputs/
*.a
*.o
*.o.tmp
*.so
*.dylib
*.dll
*.exe
*.dep
*~
*.pc
*.plist
# GNU Global
GPATH
GRTAGS
@ -9,11 +132,17 @@ GTAGS
# ccls
/.ccls-cache
# auto-generated compilation database
compile_commands.json
nix-rust/target
result
result-*
.vscode/
.direnv/
.envrc.local
# clangd and possibly more
.cache/

71
Makefile Normal file
View file

@ -0,0 +1,71 @@
include mk/build-dir.mk
-include $(buildprefix)Makefile.config
clean-files += $(buildprefix)Makefile.config
ifeq ($(ENABLE_BUILD), yes)
makefiles = \
mk/precompiled-headers.mk \
local.mk \
src/libutil/local.mk \
src/libstore/local.mk \
src/libfetchers/local.mk \
src/libmain/local.mk \
src/libexpr/local.mk \
src/libcmd/local.mk \
src/nix/local.mk \
src/resolve-system-dependencies/local.mk \
scripts/local.mk \
misc/bash/local.mk \
misc/fish/local.mk \
misc/zsh/local.mk \
misc/systemd/local.mk \
misc/launchd/local.mk
endif
ifeq ($(ENABLE_BUILD)_$(ENABLE_TESTS), yes_yes)
UNIT_TEST_ENV = _NIX_TEST_UNIT_DATA=unit-test-data
makefiles += \
tests/unit/libutil/local.mk \
tests/unit/libutil-support/local.mk \
tests/unit/libstore/local.mk
endif
ifeq ($(ENABLE_TESTS), yes)
makefiles += \
tests/unit/libstore-support/local.mk \
tests/unit/libexpr/local.mk \
tests/unit/libexpr-support/local.mk \
tests/functional/local.mk \
tests/functional/ca/local.mk \
tests/functional/dyn-drv/local.mk \
tests/functional/test-libstoreconsumer/local.mk \
tests/functional/repl_characterization/local.mk \
tests/functional/plugins/local.mk
else
makefiles += \
mk/disable-tests.mk
endif
# Some makefiles require access to built programs and must be included late.
makefiles-late =
ifeq ($(ENABLE_BUILD), yes)
makefiles-late += doc/manual/local.mk
makefiles-late += doc/internal-api/local.mk
endif
# Miscellaneous global Flags
OPTIMIZE = 1
ifeq ($(OPTIMIZE), 1)
GLOBAL_CXXFLAGS += -O2 $(CXXLTO)
GLOBAL_LDFLAGS += $(CXXLTO)
else
GLOBAL_CXXFLAGS += -O0 -U_FORTIFY_SOURCE
endif
include mk/lib.mk
GLOBAL_CXXFLAGS += -g -Wall -Wimplicit-fallthrough -include $(buildprefix)config.h -std=c++2a -I src

52
Makefile.config.in Normal file
View file

@ -0,0 +1,52 @@
AR = @AR@
BDW_GC_LIBS = @BDW_GC_LIBS@
BOOST_LDFLAGS = @BOOST_LDFLAGS@
BUILD_SHARED_LIBS = @BUILD_SHARED_LIBS@
CC = @CC@
CFLAGS = @CFLAGS@
CXX = @CXX@
CXXFLAGS = @CXXFLAGS@
CXXLTO = @CXXLTO@
EDITLINE_LIBS = @EDITLINE_LIBS@
ENABLE_S3 = @ENABLE_S3@
GTEST_LIBS = @GTEST_LIBS@
HAVE_LIBCPUID = @HAVE_LIBCPUID@
HAVE_SECCOMP = @HAVE_SECCOMP@
HOST_OS = @host_os@
LDFLAGS = @LDFLAGS@
LIBARCHIVE_LIBS = @LIBARCHIVE_LIBS@
LIBBROTLI_LIBS = @LIBBROTLI_LIBS@
LIBCURL_LIBS = @LIBCURL_LIBS@
LIBSECCOMP_LIBS = @LIBSECCOMP_LIBS@
LOWDOWN_LIBS = @LOWDOWN_LIBS@
NIXDOC_LIBS = -llix_doc
OPENSSL_LIBS = @OPENSSL_LIBS@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
RAPIDCHECK_HEADERS = @RAPIDCHECK_HEADERS@
SHELL = @bash@
SODIUM_LIBS = @SODIUM_LIBS@
SQLITE3_LIBS = @SQLITE3_LIBS@
bash = @bash@
bindir = @bindir@
datadir = @datadir@
datarootdir = @datarootdir@
doc_generate = @doc_generate@
docdir = @docdir@
embedded_sandbox_shell = @embedded_sandbox_shell@
exec_prefix = @exec_prefix@
includedir = @includedir@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
lsof = @lsof@
mandir = @mandir@
pkglibdir = $(libdir)/$(PACKAGE_NAME)
prefix = @prefix@
sandbox_shell = @sandbox_shell@
storedir = @storedir@
sysconfdir = @sysconfdir@
system = @system@
ENABLE_BUILD = @ENABLE_BUILD@
ENABLE_TESTS = @ENABLE_TESTS@
internal_api_docs = @internal_api_docs@

View file

@ -44,41 +44,32 @@ void FixIncludesCallbacks::LexedFileChanged(FileID, LexedFileChangeReason,
}
void FixIncludesCallbacks::InclusionDirective(
SourceLocation, const Token &, StringRef FileName, bool IsAngled,
SourceLocation, const Token &, StringRef, bool,
CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef,
StringRef, const Module *, SrcMgr::CharacteristicKind) {
if (Ignore)
return;
// FIXME: this is kinda evil, but this is a one-time fixup
const std::vector<std::string> SourceDirs = {"src/", "include/lix/"};
const std::string SourceDir = "src/";
const auto Bracketize = [IsAngled](StringRef s) {
return IsAngled ? ("<" + s + ">").str() : ("\"" + s + "\"").str();
};
if (File && File->getNameAsRequested().contains(SourceDir)) {
StringRef Name = File->getNameAsRequested();
auto Idx = Name.find(SourceDir);
assert(Idx != std::string::npos);
StringRef Suffix = Name.drop_front(Idx + SourceDir.length());
for (const auto &SourceDir : SourceDirs) {
const bool IsAlreadyFixed = FileName.starts_with("lix/lib");
if (File && File->getNameAsRequested().contains(SourceDir) &&
!IsAlreadyFixed) {
StringRef Name = File->getNameAsRequested();
auto Idx = Name.find(SourceDir);
assert(Idx != std::string::npos);
std::string Suffix = Name.drop_front(Idx + SourceDir.length()).str();
if (!Suffix.starts_with("lib")) {
llvm::dbgs() << "ignored: " << Suffix << "\n";
return;
}
Suffix = "lix/" + Suffix;
auto Diag = Check.diag(FilenameRange.getBegin(),
"include needs to specify the source subdir");
Diag << FilenameRange
<< FixItHint::CreateReplacement(FilenameRange, Bracketize(Suffix));
if (!Suffix.starts_with("lib")) {
llvm::dbgs() << "ignored: " << Suffix << "\n";
return;
}
auto Diag = Check.diag(FilenameRange.getBegin(),
"include needs to specify the source subdir");
Diag << FilenameRange
<< FixItHint::CreateReplacement(FilenameRange,
("\"" + Suffix + "\"").str());
}
}

View file

@ -1,6 +1,6 @@
# Clang tidy lints for Lix
# Clang tidy lints for Nix
This is a skeleton of a clang-tidy lints library for Lix.
This is a skeleton of a clang-tidy lints library for Nix.
Currently there is one check (which is already obsolete as it has served its
goal and is there as an example), `HasPrefixSuffixCheck`.
@ -10,13 +10,13 @@ goal and is there as an example), `HasPrefixSuffixCheck`.
One file:
```
ninja -C build && clang-tidy --checks='-*,lix-*' --load=build/liblix-clang-tidy.so -p ../compile_commands.json -header-filter '\.\./src/.*\.h' --fix ../src/libcmd/installables.cc
ninja -C build && clang-tidy --checks='-*,nix-*' --load=build/libnix-clang-tidy.so -p ../compile_commands.json --fix ../src/libcmd/installables.cc
```
Several files, in parallel:
```
ninja -C build && run-clang-tidy -checks='-*,lix-*' -load=build/liblix-clang-tidy.so -p .. -header-filter '\.\./src/.*\.h' -fix ../src | tee -a clang-tidy-result
ninja -C build && run-clang-tidy -checks='-*,nix-*' -load=build/libnix-clang-tidy.so -p .. -fix ../src | tee -a clang-tidy-result
```
## Resources

396
configure.ac Normal file
View file

@ -0,0 +1,396 @@
AC_INIT([nix],[m4_esyscmd(bash -c "echo -n $(cat ./.version)$VERSION_SUFFIX")])
AC_CONFIG_MACRO_DIRS([m4])
AC_CONFIG_SRCDIR(README.md)
AC_CONFIG_AUX_DIR(config)
AC_PROG_SED
# Construct a Nix system name (like "i686-linux"):
# https://www.gnu.org/software/autoconf/manual/html_node/Canonicalizing.html#index-AC_005fCANONICAL_005fHOST-1
# The inital value is produced by the `config/config.guess` script:
# upstream: https://git.savannah.gnu.org/cgit/config.git/tree/config.guess
# It has the following form, which is not documented anywhere:
# <cpu>-<vendor>-<os>[<version>][-<abi>]
# If `./configure` is passed any of the `--host`, `--build`, `--target` options, the value comes from `config/config.sub` instead:
# upstream: https://git.savannah.gnu.org/cgit/config.git/tree/config.sub
AC_CANONICAL_HOST
AC_MSG_CHECKING([for the canonical Nix system name])
AC_ARG_WITH(system, AS_HELP_STRING([--with-system=SYSTEM],[Platform identifier (e.g., `i686-linux').]),
[system=$withval],
[case "$host_cpu" in
i*86)
machine_name="i686";;
amd64)
machine_name="x86_64";;
armv6|armv7)
machine_name="${host_cpu}l";;
*)
machine_name="$host_cpu";;
esac
case "$host_os" in
linux-gnu*|linux-musl*)
# For backward compatibility, strip the `-gnu' part.
system="$machine_name-linux";;
*)
# Strip the version number from names such as `gnu0.3',
# `darwin10.2.0', etc.
system="$machine_name-`echo $host_os | "$SED" -e's/@<:@0-9.@:>@*$//g'`";;
esac])
AC_MSG_RESULT($system)
AC_SUBST(system)
AC_DEFINE_UNQUOTED(SYSTEM, ["$system"], [platform identifier ('cpu-os')])
# State should be stored in /nix/var, unless the user overrides it explicitly.
test "$localstatedir" = '${prefix}/var' && localstatedir=/nix/var
# Assign a default value to C{,XX}FLAGS as the default configure script sets them
# to -O2 otherwise, which we don't want to have hardcoded
CFLAGS=${CFLAGS-""}
CXXFLAGS=${CXXFLAGS-""}
AC_PROG_CC
AC_PROG_CXX
AC_PROG_CPP
AC_CHECK_TOOL([AR], [ar])
# Use 64-bit file system calls so that we can support files > 2 GiB.
AC_SYS_LARGEFILE
# Solaris-specific stuff.
AC_STRUCT_DIRENT_D_TYPE
case "$host_os" in
solaris*)
# Solaris requires -lsocket -lnsl for network functions
LDFLAGS="-lsocket -lnsl $LDFLAGS"
;;
esac
ENSURE_NO_GCC_BUG_80431
# Check for pubsetbuf.
AC_MSG_CHECKING([for pubsetbuf])
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <iostream>
using namespace std;
static char buf[1024];]],
[[cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));]])],
[AC_MSG_RESULT(yes) AC_DEFINE(HAVE_PUBSETBUF, 1, [Whether pubsetbuf is available.])],
AC_MSG_RESULT(no))
AC_LANG_POP(C++)
AC_CHECK_FUNCS([statvfs pipe2])
# Check for lutimes, optionally used for changing the mtime of
# symlinks.
AC_CHECK_FUNCS([lutimes])
# Check whether the store optimiser can optimise symlinks.
AC_MSG_CHECKING([whether it is possible to create a link to a symlink])
ln -s bla tmp_link
if ln tmp_link tmp_link2 2> /dev/null; then
AC_MSG_RESULT(yes)
AC_DEFINE(CAN_LINK_SYMLINK, 1, [Whether link() works on symlinks.])
else
AC_MSG_RESULT(no)
fi
rm -f tmp_link tmp_link2
# Check for <locale>.
AC_LANG_PUSH(C++)
AC_CHECK_HEADERS([locale])
AC_LANG_POP(C++)
AC_DEFUN([NEED_PROG],
[
AC_PATH_PROG($1, $2)
if test -z "$$1"; then
AC_MSG_ERROR([$2 is required])
fi
])
NEED_PROG(bash, bash)
AC_PATH_PROG(flex, flex, false)
AC_PATH_PROG(bison, bison, false)
AC_PATH_PROG(dot, dot)
AC_PATH_PROG(lsof, lsof, lsof)
NEED_PROG(jq, jq)
AC_SUBST(coreutils, [$(dirname $(type -p cat))])
AC_ARG_WITH(store-dir, AS_HELP_STRING([--with-store-dir=PATH],[path of the Nix store (defaults to /nix/store)]),
storedir=$withval, storedir='/nix/store')
AC_SUBST(storedir)
# Look for boost, a required dependency.
# Note that AX_BOOST_BASE only exports *CPP* BOOST_CPPFLAGS, no CXX flags,
# and CPPFLAGS are not passed to the C++ compiler automatically.
# Thus we append the returned CPPFLAGS to the CXXFLAGS here.
AX_BOOST_BASE([1.66], [CXXFLAGS="$BOOST_CPPFLAGS $CXXFLAGS"], [AC_MSG_ERROR([Nix requires boost.])])
# For unknown reasons, setting this directly in the ACTION-IF-FOUND above
# ends up with LDFLAGS being empty, so we set it afterwards.
LDFLAGS="$BOOST_LDFLAGS $LDFLAGS"
# On some platforms, new-style atomics need a helper library
AC_MSG_CHECKING(whether -latomic is needed)
AC_LINK_IFELSE([AC_LANG_SOURCE([[
#include <stdint.h>
uint64_t v;
int main() {
return (int)__atomic_load_n(&v, __ATOMIC_ACQUIRE);
}]])], GCC_ATOMIC_BUILTINS_NEED_LIBATOMIC=no, GCC_ATOMIC_BUILTINS_NEED_LIBATOMIC=yes)
AC_MSG_RESULT($GCC_ATOMIC_BUILTINS_NEED_LIBATOMIC)
if test "x$GCC_ATOMIC_BUILTINS_NEED_LIBATOMIC" = xyes; then
LDFLAGS="-latomic $LDFLAGS"
fi
# Running the functional tests without building Nix is useful for testing
# different pre-built versions of Nix against each other.
AC_ARG_ENABLE(build, AS_HELP_STRING([--disable-build],[Do not build nix]),
ENABLE_BUILD=$enableval, ENABLE_BUILD=yes)
AC_SUBST(ENABLE_BUILD)
# Building without tests is useful for bootstrapping with a smaller footprint
# or running the tests in a separate derivation. Otherwise, we do compile and
# run them.
AC_ARG_ENABLE(tests, AS_HELP_STRING([--disable-tests],[Do not build the tests]),
ENABLE_TESTS=$enableval, ENABLE_TESTS=yes)
AC_SUBST(ENABLE_TESTS)
# Building without API docs is the default as Nix' C++ interfaces are internal and unstable.
AC_ARG_ENABLE(internal_api_docs, AS_HELP_STRING([--enable-internal-api-docs],[Build API docs for Nix's internal unstable C++ interfaces]),
internal_api_docs=$enableval, internal_api_docs=no)
AC_SUBST(internal_api_docs)
# LTO is currently broken with clang for unknown reasons; ld segfaults in the llvm plugin
AC_ARG_ENABLE(lto, AS_HELP_STRING([--enable-lto],[Enable LTO (only supported with GCC) [default=no]]),
lto=$enableval, lto=no)
if test "$lto" = yes; then
if $CXX --version | grep -q GCC; then
AC_SUBST(CXXLTO, [-flto=jobserver])
else
echo "error: LTO is only supported with GCC at the moment" >&2
exit 1
fi
else
AC_SUBST(CXXLTO, [""])
fi
PKG_PROG_PKG_CONFIG
AC_ARG_ENABLE(shared, AS_HELP_STRING([--enable-shared],[Build shared libraries for Nix [default=yes]]),
shared=$enableval, shared=yes)
if test "$shared" = yes; then
AC_SUBST(BUILD_SHARED_LIBS, 1, [Whether to build shared libraries.])
else
AC_SUBST(BUILD_SHARED_LIBS, 0, [Whether to build shared libraries.])
PKG_CONFIG="$PKG_CONFIG --static"
fi
# Look for OpenSSL, a required dependency. FIXME: this is only (maybe)
# used by S3BinaryCacheStore.
PKG_CHECK_MODULES([OPENSSL], [libcrypto >= 1.1.1], [CXXFLAGS="$OPENSSL_CFLAGS $CXXFLAGS"])
# Look for libarchive.
PKG_CHECK_MODULES([LIBARCHIVE], [libarchive >= 3.1.2], [CXXFLAGS="$LIBARCHIVE_CFLAGS $CXXFLAGS"])
# Workaround until https://github.com/libarchive/libarchive/issues/1446 is fixed
if test "$shared" != yes; then
LIBARCHIVE_LIBS+=' -lz'
fi
# Look for SQLite, a required dependency.
PKG_CHECK_MODULES([SQLITE3], [sqlite3 >= 3.6.19], [CXXFLAGS="$SQLITE3_CFLAGS $CXXFLAGS"])
# Look for libcurl, a required dependency.
PKG_CHECK_MODULES([LIBCURL], [libcurl], [CXXFLAGS="$LIBCURL_CFLAGS $CXXFLAGS"])
# Look for editline, a required dependency.
# The the libeditline.pc file was added only in libeditline >= 1.15.2,
# see https://github.com/troglobit/editline/commit/0a8f2ef4203c3a4a4726b9dd1336869cd0da8607,
# but e.g. Ubuntu 16.04 has an older version, so we fall back to searching for
# editline.h when the pkg-config approach fails.
PKG_CHECK_MODULES([EDITLINE], [libeditline], [CXXFLAGS="$EDITLINE_CFLAGS $CXXFLAGS"], [
AC_CHECK_HEADERS([editline.h], [true],
[AC_MSG_ERROR([Nix requires libeditline; it was found neither via pkg-config nor its normal header.])])
AC_SEARCH_LIBS([readline read_history], [editline], [],
[AC_MSG_ERROR([Nix requires libeditline; it was not found via pkg-config, but via its header, but required functions do not work. Maybe it is too old? >= 1.14 is required.])])
])
# Look for libsodium.
PKG_CHECK_MODULES([SODIUM], [libsodium], [CXXFLAGS="$SODIUM_CFLAGS $CXXFLAGS"])
# Look for libbrotli{enc,dec}.
PKG_CHECK_MODULES([LIBBROTLI], [libbrotlienc libbrotlidec], [CXXFLAGS="$LIBBROTLI_CFLAGS $CXXFLAGS"])
# Look for libcpuid.
have_libcpuid=
if test "$machine_name" = "x86_64"; then
AC_ARG_ENABLE([cpuid],
AS_HELP_STRING([--disable-cpuid], [Do not determine microarchitecture levels with libcpuid (relevant to x86_64 only)]))
if test "x$enable_cpuid" != "xno"; then
PKG_CHECK_MODULES([LIBCPUID], [libcpuid],
[CXXFLAGS="$LIBCPUID_CFLAGS $CXXFLAGS"
have_libcpuid=1
AC_DEFINE([HAVE_LIBCPUID], [1], [Use libcpuid])]
)
fi
fi
AC_SUBST(HAVE_LIBCPUID, [$have_libcpuid])
# Look for libseccomp, required for Linux sandboxing.
case "$host_os" in
linux*)
AC_ARG_ENABLE([seccomp-sandboxing],
AS_HELP_STRING([--disable-seccomp-sandboxing],[Don't build support for seccomp sandboxing (only recommended if your arch doesn't support libseccomp yet!)
]))
if test "x$enable_seccomp_sandboxing" != "xno"; then
PKG_CHECK_MODULES([LIBSECCOMP], [libseccomp],
[CXXFLAGS="$LIBSECCOMP_CFLAGS $CXXFLAGS"])
have_seccomp=1
AC_DEFINE([HAVE_SECCOMP], [1], [Whether seccomp is available and should be used for sandboxing.])
else
have_seccomp=
fi
;;
*)
have_seccomp=
;;
esac
AC_SUBST(HAVE_SECCOMP, [$have_seccomp])
# Look for aws-cpp-sdk-s3.
AC_LANG_PUSH(C++)
AC_CHECK_HEADERS([aws/s3/S3Client.h],
[AC_DEFINE([ENABLE_S3], [1], [Whether to enable S3 support via aws-sdk-cpp.]) enable_s3=1],
[AC_DEFINE([ENABLE_S3], [0], [Whether to enable S3 support via aws-sdk-cpp.]) enable_s3=])
AC_SUBST(ENABLE_S3, [$enable_s3])
AC_LANG_POP(C++)
if test -n "$enable_s3"; then
declare -a aws_version_tokens=($(printf '#include <aws/core/VersionConfig.h>\nAWS_SDK_VERSION_STRING' | $CPP $CPPFLAGS - | grep -v '^#.*' | sed 's/"//g' | tr '.' ' '))
AC_DEFINE_UNQUOTED([AWS_VERSION_MAJOR], ${aws_version_tokens@<:@0@:>@}, [Major version of aws-sdk-cpp.])
AC_DEFINE_UNQUOTED([AWS_VERSION_MINOR], ${aws_version_tokens@<:@1@:>@}, [Minor version of aws-sdk-cpp.])
AC_DEFINE_UNQUOTED([AWS_VERSION_PATCH], ${aws_version_tokens@<:@2@:>@}, [Patch version of aws-sdk-cpp.])
fi
# Whether to use the Boehm garbage collector.
AC_ARG_ENABLE(gc, AS_HELP_STRING([--enable-gc],[enable garbage collection in the Nix expression evaluator (requires Boehm GC) [default=yes]]),
gc=$enableval, gc=yes)
if test "$gc" = yes; then
PKG_CHECK_MODULES([BDW_GC], [bdw-gc])
CXXFLAGS="$BDW_GC_CFLAGS $CXXFLAGS"
AC_DEFINE(HAVE_BOEHMGC, 1, [Whether to use the Boehm garbage collector.])
fi
if test "$ENABLE_TESTS" = yes; then
# Look for gtest.
PKG_CHECK_MODULES([GTEST], [gtest_main gmock_main])
# Look for rapidcheck.
AC_ARG_VAR([RAPIDCHECK_HEADERS], [include path of gtest headers shipped by RAPIDCHECK])
# No pkg-config yet, https://github.com/emil-e/rapidcheck/issues/302
AC_LANG_PUSH(C++)
AC_SUBST(RAPIDCHECK_HEADERS)
[CXXFLAGS="-I $RAPIDCHECK_HEADERS $CXXFLAGS"]
[LIBS="-lrapidcheck -lgtest $LIBS"]
AC_CHECK_HEADERS([rapidcheck/gtest.h], [], [], [#include <gtest/gtest.h>])
dnl AC_CHECK_LIB doesn't work for C++ libs with mangled symbols
AC_LINK_IFELSE([
AC_LANG_PROGRAM([[
#include <gtest/gtest.h>
#include <rapidcheck/gtest.h>
]], [[
return RUN_ALL_TESTS();
]])
],
[],
[AC_MSG_ERROR([librapidcheck is not found.])])
AC_LANG_POP(C++)
fi
# Look for nlohmann/json.
PKG_CHECK_MODULES([NLOHMANN_JSON], [nlohmann_json >= 3.9])
# documentation generation switch
AC_ARG_ENABLE(doc-gen, AS_HELP_STRING([--disable-doc-gen],[disable documentation generation]),
doc_generate=$enableval, doc_generate=yes)
AC_SUBST(doc_generate)
# Look for lowdown library.
PKG_CHECK_MODULES([LOWDOWN], [lowdown >= 0.9.0], [CXXFLAGS="$LOWDOWN_CFLAGS $CXXFLAGS"])
# Look for toml11, a required dependency.
AC_ARG_VAR([TOML11_HEADERS], [include path of toml11 headers])
AC_LANG_PUSH(C++)
[CXXFLAGS="-I $TOML11_HEADERS $CXXFLAGS"]
AC_CHECK_HEADER([toml.hpp], [], [AC_MSG_ERROR([toml11 is not found.])])
AC_LANG_POP(C++)
# Setuid installations.
AC_CHECK_FUNCS([setresuid setreuid lchown])
# Nice to have, but not essential.
AC_CHECK_FUNCS([strsignal posix_fallocate sysconf])
AC_ARG_WITH(sandbox-shell, AS_HELP_STRING([--with-sandbox-shell=PATH],[path of a statically-linked shell to use as /bin/sh in sandboxes]),
sandbox_shell=$withval)
AC_SUBST(sandbox_shell)
if test ${cross_compiling:-no} = no && ! test -z ${sandbox_shell+x}; then
AC_MSG_CHECKING([whether sandbox-shell has the standalone feature])
# busybox shell sometimes allows executing other busybox applets,
# even if they are not in the path, breaking our sandbox
if PATH= $sandbox_shell -c "busybox" 2>&1 | grep -qv "not found"; then
AC_MSG_RESULT(enabled)
AC_MSG_ERROR([Please disable busybox FEATURE_SH_STANDALONE])
else
AC_MSG_RESULT(disabled)
fi
fi
AC_ARG_ENABLE(embedded-sandbox-shell, AS_HELP_STRING([--enable-embedded-sandbox-shell],[include the sandbox shell in the Nix binary [default=no]]),
embedded_sandbox_shell=$enableval, embedded_sandbox_shell=no)
AC_SUBST(embedded_sandbox_shell)
if test "$embedded_sandbox_shell" = yes; then
AC_DEFINE(HAVE_EMBEDDED_SANDBOX_SHELL, 1, [Include the sandbox shell in the Nix binary.])
fi
# Expand all variables in config.status.
test "$prefix" = NONE && prefix=$ac_default_prefix
test "$exec_prefix" = NONE && exec_prefix='${prefix}'
for name in $ac_subst_vars; do
declare $name="$(eval echo "${!name}")"
declare $name="$(eval echo "${!name}")"
declare $name="$(eval echo "${!name}")"
done
rm -f Makefile.config
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_FILES([])
AC_OUTPUT

19
doc/internal-api/local.mk Normal file
View file

@ -0,0 +1,19 @@
.PHONY: internal-api-html
ifeq ($(internal_api_docs), yes)
$(docdir)/internal-api/html/index.html $(docdir)/internal-api/latex: $(d)/doxygen.cfg
mkdir -p $(docdir)/internal-api
{ cat $< ; echo "OUTPUT_DIRECTORY=$(docdir)/internal-api" ; } | doxygen -
# Generate the HTML API docs for Nix's unstable internal interfaces.
internal-api-html: $(docdir)/internal-api/html/index.html
else
# Make a nicer error message
internal-api-html:
@echo "Internal API docs are disabled. Configure with '--enable-internal-api-docs', or avoid calling 'make internal-api-html'."
@exit 1
endif

View file

@ -28,7 +28,6 @@ internal_api_docs = custom_target(
output : 'html',
install : true,
install_dir : datadir / 'doc/nix/internal-api',
build_always_stale : true,
)
alias_target('internal-api-html', internal_api_docs)

View file

@ -11,10 +11,6 @@ additional-js = ["redirects.js"]
# to just submit a Gerrit CL by the web for trivial stuff.
edit-url-template = "https://github.com/lix-project/lix/tree/main/doc/manual/{path}"
git-repository-url = "https://git.lix.systems/lix-project/lix"
# Folding by default would prevent things like "Ctrl+F for nix-env" from working
# trivially, but the user should be able to fold if they want to.
fold.enable = true
fold.level = 30
# Handles replacing @docroot@ with a path to ./src relative to that markdown file,
# {{#include handlebars}}, and the @generated@ syntax used within these. it mostly

View file

@ -1,115 +0,0 @@
# This file is a mapping of metadata for change authors, sort of like
# maintainer-list.nix in nixpkgs.
#
# It's used for crediting people accurately in release notes. The release notes
# script will link to forgejo, then to GitHub if forgejo is not present.
9999years:
display_name: wiggles
forgejo: rbt
github: 9999years
Artturin:
github: Artturin
DavHau:
github: DavHau
Kha:
github: Kha
Lunaphied:
forgejo: Lunaphied
github: Lunaphied
Qyriad:
forgejo: Qyriad
github: Qyriad
SharzyL:
github: SharzyL
alois31:
forgejo: alois31
github: alois31
artemist:
display_name: Artemis Tosini
forgejo: artemist
cole-h:
display_name: Cole Helbling
github: cole-h
edolstra:
display_name: Eelco Dolstra
github: edolstra
ericson:
display_name: John Ericson
github: ericson2314
horrors:
display_name: eldritch horrors
forgejo: pennae
github: pennae
iFreilicht:
github: iFreilicht
jade:
forgejo: jade
github: lf-
lovesegfault:
github: lovesegfault
ma27:
forgejo: ma27
github: ma27
matthewbauer:
github: matthewbauer
midnightveil:
display_name: julia
forgejo: midnightveil
github: midnightveil
ncfavier:
github: ncfavier
puck:
display_name: puck
forgejo: puck
github: puckipedia
r-vdp:
github: r-vdp
raito:
display_name: Raito Bezarius
forgejo: raito
github: RaitoBezarius
roberth:
display_name: Robert Hensing
github: roberth
thufschmitt:
display_name: Théophane Hufschmitt
github: thufschmitt
tomberek:
display_name: Tom Bereknyei
github: tomberek
valentin:
display_name: Valentin Gagarin
github: fricklerhandwerk
winter:
forgejo: winter
github: winterqt
yshui:
github: yshui

178
doc/manual/local.mk Normal file
View file

@ -0,0 +1,178 @@
ifeq ($(doc_generate),yes)
# The version of Nix used to generate the doc. Can also be
# `$(nix_INSTALL_PATH)` or just `nix` (to grap ambient from the `PATH`),
# if one prefers.
doc_nix = $(nix_PATH)
MANUAL_SRCS := \
$(call rwildcard, $(d)/src, *.md) \
$(call rwildcard, $(d)/src, */*.md)
man-pages := $(foreach n, \
nix-env.1 nix-store.1 \
nix-build.1 nix-shell.1 nix-instantiate.1 \
nix-collect-garbage.1 \
nix-prefetch-url.1 nix-channel.1 \
nix-hash.1 nix-copy-closure.1 \
nix.conf.5 nix-daemon.8 \
nix-profiles.5 \
, doc/manual/generated/in/$(n))
# man pages for subcommands
# convert from `$(d)/src/command-ref/nix-{1}/{2}.md` to `$(d)/nix-{1}-{2}.1`
# FIXME: unify with how nix3-cli man pages are generated
man-pages += $(foreach subcommand, \
$(filter-out %opt-common.md %env-common.md, $(wildcard $(d)/src/command-ref/nix-*/*.md)), \
doc/manual/generated/in/$(subst /,-,$(subst $(d)/src/command-ref/,,$(subst .md,.1,$(subcommand)))))
clean-files += $(d)/*.1 $(d)/*.5 $(d)/*.8
# Provide a dummy environment for nix, so that it will not access files outside the macOS sandbox.
# Set cores to 0 because otherwise nix config show resolves the cores based on the current machine
dummy-env = env -i \
HOME=/dummy \
NIX_CONF_DIR=/dummy \
NIX_SSL_CERT_FILE=/dummy/no-ca-bundle.crt \
NIX_STATE_DIR=/dummy \
NIX_CONFIG='cores = 0'
nix-eval = $(dummy-env) $(doc_nix) eval --experimental-features nix-command -I nix/corepkgs=corepkgs --store dummy:// --impure --raw
doc/manual/generated/in/nix-env-%.1: doc/manual/generated/out
$(trace-gen) doc/manual/render-manpage.sh \
--out-no-smarty "$(subst nix-env-,nix-env --,$$(basename "$@" .1))" 1 \
doc/manual/generated/out/markdown/command-ref/nix-env/$*.md \
$@
doc/manual/generated/in/nix-store-%.1: doc/manual/generated/out
$(trace-gen) doc/manual/render-manpage.sh \
--out-no-smarty "$(subst nix-store-,nix-store --,$$(basename "$@" .1))" 1 \
doc/manual/generated/out/markdown/command-ref/nix-store/$*.md \
$@
doc/manual/generated/in/%.1: doc/manual/generated/out
$(trace-gen) doc/manual/render-manpage.sh "$$(basename $@ .1)" 1 \
doc/manual/generated/out/markdown/command-ref/$*.md \
$@
doc/manual/generated/in/%.8: doc/manual/generated/out
$(trace-gen) doc/manual/render-manpage.sh "$$(basename $@ .8)" 8 \
doc/manual/generated/out/markdown/command-ref/$*.md \
$@
doc/manual/generated/in/nix.conf.5: doc/manual/generated/out
$(trace-gen) doc/manual/render-manpage.sh "$$(basename $@ .5)" 5 \
doc/manual/generated/out/markdown/command-ref/conf-file.md \
$@
doc/manual/generated/in/nix-profiles.5: doc/manual/generated/out
$(trace-gen) doc/manual/render-manpage.sh "$$(basename $@ .5)" 5 \
doc/manual/generated/out/markdown/command-ref/files/profiles.md \
$@
doc/manual/generated/in/command-ref/new-cli: doc/manual/generated/in/nix.json $(d)/utils.nix $(d)/generate-manpage.nix $(doc_nix)
@mkdir -p doc/manual/generated/in/command-ref
@rm -rf $@ $@.tmp
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-manpage.nix true (builtins.readFile $<)'
@mv $@.tmp $@
doc/manual/generated/in/command-ref/conf-file.md: doc/manual/generated/in/conf-file.json $(d)/utils.nix doc/manual/generated/in/command-ref/experimental-features-shortlist.md $(doc_nix)
@mkdir -p doc/manual/generated/in/command-ref
$(trace-gen) $(nix-eval) --expr '(import doc/manual/utils.nix).showSettings { inlineHTML = true; } (builtins.fromJSON (builtins.readFile $<))' >> $@
doc/manual/generated/in/nix.json: $(doc_nix)
@mkdir -p doc/manual/generated/in
$(trace-gen) $(dummy-env) $(doc_nix) __dump-cli > $@.tmp
@mv $@.tmp $@
doc/manual/generated/in/conf-file.json: $(doc_nix)
@mkdir -p doc/manual/generated/in
$(trace-gen) $(dummy-env) $(doc_nix) config show --json --experimental-features nix-command > $@.tmp
@mv $@.tmp $@
doc/manual/generated/in/contributing/experimental-feature-descriptions.md: doc/manual/generated/in/xp-features.json $(d)/utils.nix $(d)/generate-xp-features.nix $(doc_nix)
@mkdir -p doc/manual/generated/in/contributing
@rm -rf $@ $@.tmp
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-xp-features.nix (builtins.fromJSON (builtins.readFile $<))'
@mv $@.tmp $@
doc/manual/generated/in/command-ref/experimental-features-shortlist.md: doc/manual/generated/in/xp-features.json $(d)/utils.nix $(d)/generate-xp-features-shortlist.nix $(doc_nix)
@mkdir -p doc/manual/generated/in/command-ref
@rm -rf $@ $@.tmp
$(trace-gen) $(nix-eval) --write-to $@.tmp --expr 'import doc/manual/generate-xp-features-shortlist.nix (builtins.fromJSON (builtins.readFile $<))'
@mv $@.tmp $@
doc/manual/generated/in/xp-features.json: $(doc_nix)
$(trace-gen) $(dummy-env) NIX_PATH=nix/corepkgs=corepkgs $(doc_nix) __dump-xp-features > $@.tmp
@mv $@.tmp $@
doc/manual/generated/in/language/builtins.md: doc/manual/generated/in/language.json $(d)/generate-builtins.nix $(doc_nix)
@mkdir -p doc/manual/generated/in/language
$(trace-gen) $(nix-eval) --expr 'import doc/manual/generate-builtins.nix (builtins.fromJSON (builtins.readFile $<)).builtins' >> $@
doc/manual/generated/in/language/builtin-constants.md: doc/manual/generated/in/language.json $(d)/generate-builtin-constants.nix $(doc_nix)
@mkdir -p doc/manual/generated/in/language
$(trace-gen) $(nix-eval) --expr 'import doc/manual/generate-builtin-constants.nix (builtins.fromJSON (builtins.readFile $<)).constants' >> $@
doc/manual/generated/in/language.json: $(doc_nix)
@mkdir -p doc/manual/generated/in
$(trace-gen) $(dummy-env) NIX_PATH=nix/corepkgs=corepkgs $(doc_nix) __dump-language > $@.tmp
@mv $@.tmp $@
# Generate "Upcoming release" notes (or clear it and remove from menu)
doc/manual/generated/in/release-notes/rl-next-generated.md: $(d)/rl-next $(d)/rl-next/*
@mkdir -p doc/manual/generated/in/release-notes
@if type -p build-release-notes > /dev/null; then \
echo " GEN " $@; \
build-release-notes doc/manual/rl-next > $@; \
else \
echo " NULL " $@; \
true > $@; \
fi
# Generate the HTML manual.
.PHONY: manual-html
manual-html: $(docdir)/manual/index.html
install: $(docdir)/manual/index.html
# Generate 'nix' manpages.
install: $(mandir)/man1/nix3-manpages
man: doc/manual/generated/man1/nix3-manpages
all: doc/manual/generated/man1/nix3-manpages
# FIXME: unify with how the other man pages are generated.
# this one works differently and does not use any of the amenities provided by `/mk/lib.mk`.
$(mandir)/man1/nix3-manpages: doc/manual/generated/man1/nix3-manpages
@mkdir -p $(DESTDIR)$$(dirname $@)
$(trace-install) install -m 0644 $$(dirname $<)/* $(DESTDIR)$$(dirname $@)
doc/manual/generated/man1/nix3-manpages: doc/manual/generated/out
@mkdir -p $(DESTDIR)$$(dirname $@)
$(trace-gen) for i in doc/manual/generated/out/markdown/command-ref/new-cli/*.md; do \
name=$$(basename $$i .md); \
tmpFile=$$(mktemp); \
if [[ $$name = SUMMARY ]]; then continue; fi; \
printf "Title: %s\n\n" "$$name" > $$tmpFile; \
cat $$i >> $$tmpFile; \
lowdown -sT man --nroff-nolinks -M section=1 $$tmpFile -o $(DESTDIR)$$(dirname $@)/$$name.1; \
rm $$tmpFile; \
done
@touch $@
doc/manual/generated/out: $(MANUAL_SRCS) $(d)/book.toml $(d)/anchors.jq $(d)/custom.css $(d)/src/SUMMARY.md doc/manual/generated/in/command-ref/new-cli doc/manual/generated/in/command-ref/experimental-features-shortlist.md doc/manual/generated/in/contributing/experimental-feature-descriptions.md doc/manual/generated/in/command-ref/conf-file.md doc/manual/generated/in/language/builtins.md doc/manual/generated/in/language/builtin-constants.md doc/manual/generated/in/release-notes/rl-next-generated.md $(d)/substitute.py
@rm -rf $@
$(trace-gen) \
MDBOOK_SUBSTITUTE_SEARCH=doc/manual/generated/in \
RUST_LOG=warn \
mdbook build doc/manual -d generated/out 2>&1 \
| { grep -Fv "because fragment resolution isn't implemented" || :; }
@find $@ -iname meson.build -delete
$(docdir)/manual/index.html: doc/manual/generated/out
@mkdir -p $(DESTDIR)$(docdir)
@rm -rf $(DESTDIR)$(docdir)/manual
@cp -r $</html $(DESTDIR)$(docdir)/manual
endif

View file

@ -1,8 +0,0 @@
[lix-docs]
type = s3
provider = Other
env_auth = true
endpoint = https://s3.lix.systems
location_constraint = garage
region = garage
acl = private

View file

@ -24,6 +24,7 @@ const redirects = {
"chap-writing-nix-expressions": "language/index.html",
"part-command-ref": "command-ref/command-ref.html",
"conf-allow-import-from-derivation": "command-ref/conf-file.html#conf-allow-import-from-derivation",
"conf-allow-new-privileges": "command-ref/conf-file.html#conf-allow-new-privileges",
"conf-allowed-uris": "command-ref/conf-file.html#conf-allowed-uris",
"conf-allowed-users": "command-ref/conf-file.html#conf-allowed-users",
"conf-auto-optimise-store": "command-ref/conf-file.html#conf-auto-optimise-store",

View file

@ -1,14 +0,0 @@
---
synopsis: "Add a builtin `addDrvOutputDependencies`"
prs: 9216
issues: 7910
credits: [ericson, horrors]
category: Features
---
This builtin allows taking a `drvPath`-like string and turning it into a string
with context such that, when it lands in a derivation, it will create
dependencies on *all the outputs* in its closure (!). Although `drvPath` does this
today, this builtin starts forming a path to migrate to making `drvPath` have a
more normal and less surprising string context behaviour (see linked issue and
PR for more details).

View file

@ -1,13 +0,0 @@
---
synopsis: "Add an option `always-allow-substitutes` to ignore `allowSubstitutes` in derivations"
prs: 8047
credits: [lovesegfault, horrors]
category: Improvements
---
You can set this setting to force a system to always allow substituting even
trivial derivations like `pkgs.writeText`. This is useful for
[`nix-fast-build --skip-cached`][skip-cached] and similar to be able to also
ignore trivial derivations.
[skip-cached]: https://github.com/Mic92/nix-fast-build?tab=readme-ov-file#avoiding-redundant-package-downloads

View file

@ -2,8 +2,6 @@
synopsis: Concise error printing in `nix repl`
prs: 9928
cls: 811
category: Improvements
credits: 9999years
---
Previously, if an element of a list or attribute set threw an error while

View file

@ -1,9 +0,0 @@
---
synopsis: Show all FOD errors with `nix build --keep-going`
credits: [ma27]
category: Improvements
cls: [1108]
---
`nix build --keep-going` now behaves consistently with `nix-build --keep-going`. This means
that if e.g. multiple FODs fail to build, all hash mismatches are displayed.

View file

@ -1,21 +0,0 @@
---
synopsis: "Fix CVE-2024-27297 (GHSA-2ffj-w4mj-pg37)"
cls: 266
credits: [puck, jade, thufschmitt, tomberek, valentin]
category: Fixes
---
Since Lix fixed-output derivations run in the host network namespace (which we
wish to change in the future, see
[lix#285](https://git.lix.systems/lix-project/lix/issues/285)), they may open
abstract-namespace Unix sockets to each other and to programs on the host. Lix
contained a now-fixed time-of-check/time-of-use vulnerability where one
derivation could send writable handles to files in their final location in the
store to another over an abstract-namespace Unix socket, exit, then the other
derivation could wait for Lix to hash the paths and overwrite them.
The impact of this vulnerability is that two malicious fixed-output derivations
could create a poisoned path for the sources to Bash or similarly important
software containing a backdoor, leading to local privilege execution.
CppNix advisory: https://github.com/NixOS/nix/security/advisories/GHSA-2ffj-w4mj-pg37

View file

@ -2,8 +2,6 @@
synopsis: "`--debugger` can now access bindings from `let` expressions"
prs: 9918
issues: 8827
category: Fixes
credits: 9999years
---
Breakpoints and errors in the bindings of a `let` expression can now access

View file

@ -1,8 +1,6 @@
---
synopsis: Enter the `--debugger` when `builtins.trace` is called if `debugger-on-trace` is set
prs: 9914
category: Features
credits: 9999years
---
If the `debugger-on-trace` option is set and `--debugger` is given,

View file

@ -1,16 +0,0 @@
---
synopsis: "Deprecate the online flake registries and vendor the default registry"
cls: 1127
credits: midnightveil
issues: [fj#183, fj#110, fj#116, 8953, 9087]
category: Breaking Changes
---
The online flake registry [https://channels.nixos.org/flake-registry.json](https://channels.nixos.org/flake-registry.json) is not pinned in any way,
and the targets of the indirections can both update or change entirely at any
point. Furthermore, it is refetched on every use of a flake reference, even if
there is a local flake reference, and even if you are offline (which breaks).
For now, we deprecate the (any) online flake registry, and vendor a copy of the
current online flake registry. This makes it work offline, and ensures that
it won't change in the future.

View file

@ -1,8 +1,6 @@
---
synopsis: Stop vendoring toml11
cls: 675
category: Packaging
credits: winter
---
We don't apply any patches to it, and vendoring it locks users into

View file

@ -1,8 +1,6 @@
---
synopsis: Fix handling of truncated `.drv` files.
prs: 9673
category: Fixes
credits: horrors
---
Previously a `.drv` that was truncated in the middle of a string would case nix to enter an infinite loop, eventually exhausting all memory and crashing.

View file

@ -1,8 +1,6 @@
---
synopsis: Duplicate attribute reports are more accurate
cls: 557
credits: horrors
category: Improvements
---
Duplicate attribute errors are now more accurate, showing the path at which an error was detected rather than the full, possibly longer, path that caused the error.

View file

@ -1,8 +1,6 @@
---
synopsis: Disallow empty search regex in `nix search`
prs: 9481
credits: [iFreilicht, horrors]
category: Miscellany
---
[`nix search`](@docroot@/command-ref/new-cli/nix3-search.md) now requires a search regex to be passed. To show all packages, use `^`.

View file

@ -1,13 +0,0 @@
---
synopsis: "Add an option `enable-core-dumps` that enables core dumps from builds"
cls: 1088
credits: midnightveil
category: Features
---
In the past, Lix disabled core dumps by setting the soft `RLIMIT_CORE` to 0
unconditionally. Although this rlimit could be altered from the builder since
it is just the soft limit, this was kind of annoying to do. By passing
`--option enable-core-dumps true` to an offending build, one can now cause the
core dumps to be handled by the system in the normal way (winding up in
`coredumpctl`, say, on Linux).

View file

@ -2,8 +2,6 @@
synopsis: The `--debugger` will start more reliably in `let` expressions and function calls
prs: 9917
issues: 6649
credits: [9999years, horrors]
category: Fixes
---
Previously, if you attempted to evaluate this file with the debugger:

View file

@ -1,9 +1,6 @@
---
synopsis: Reduce eval memory usage and wall time
prs: 9658
cls: 207
credits: horrors
category: Improvements
---
Reduce the size of the `Env` struct used in the evaluator by a pointer, or 8 bytes on most modern machines.

View file

@ -1,8 +1,6 @@
---
synopsis: Add new `eval-system` setting
prs: 4093
credits: [matthewbauer, horrors]
category: Features
---
Add a new `eval-system` option.

View file

@ -1,8 +1,6 @@
---
synopsis: Creating setuid/setgid binaries with fchmodat2 is now prohibited by the build sandbox
prs: 10501
credits: ma27
category: Fixes
---
The build sandbox blocks any attempt to create setuid/setgid binaries, but didn't check

View file

@ -2,9 +2,6 @@
synopsis: Fix nested flake input `follows`
prs: 6621
cls: 994
credits: [Kha, ma27]
category: Fixes
significance: significant
---
Previously nested-input overrides were ignored; that is, the following did not

View file

@ -1,30 +0,0 @@
---
synopsis: Warn on unknown settings anywhere in the command line
prs: 10701
credits: [cole-h]
category: Improvements
---
All `nix` commands will now properly warn when an unknown option is specified anywhere in the command line.
Before:
```console
$ nix-instantiate --option foobar baz --expr '{}'
warning: unknown setting 'foobar'
$ nix-instantiate '{}' --option foobar baz --expr
$ nix eval --expr '{}' --option foobar baz
{ }
```
After:
```console
$ nix-instantiate --option foobar baz --expr '{}'
warning: unknown setting 'foobar'
$ nix-instantiate '{}' --option foobar baz --expr
warning: unknown setting 'foobar'
$ nix eval --expr '{}' --option foobar baz
warning: unknown setting 'foobar'
{ }
```

View file

@ -1,8 +1,6 @@
---
synopsis: Nested debuggers are no longer supported
prs: 9920
credits: 9999years
category: Improvements
---
Previously, evaluating an expression that throws an error in the debugger would

View file

@ -1,8 +1,6 @@
---
synopsis: consistent order of lambda formals in printed expressions
prs: 9874
credits: horrors
category: Fixes
---
Always print lambda formals in lexicographic order rather than the internal, creation-time based symbol order.

View file

@ -1,8 +0,0 @@
---
synopsis: Find GC roots using libproc on Darwin
cls: 723
credits: artemist
category: Improvements
---
Previously, the garbage collector found runtime roots on Darwin by shelling out to `lsof -n -w -F n` then parsing the result. The version of `lsof` packaged in Nixpkgs is very slow on Darwin, so Lix now uses `libproc` directly to speed up GC root discovery, in some tests taking 250ms now instead of 40s.

View file

@ -1,8 +1,6 @@
---
synopsis: fix duplicate attribute error positions for `inherit`
prs: 9874
credits: horrors
category: Fixes
---
When an inherit caused a duplicate attribute error, the position of the error was not reported correctly, placing the error with the inherit itself or at the start of the bindings block instead of the offending attribute name.
When an inherit caused a duplicate attribute error the position of the error was not reported correctly, placing the error with the inherit itself or at the start of the bindings block instead of the offending attribute name.

View file

@ -1,8 +1,6 @@
---
synopsis: "`inherit (x) ...` evaluates `x` only once"
prs: 9847
category: Fixes
credits: horrors
---
`inherit (x) a b ...` now evaluates the expression `x` only once for all inherited attributes rather than once for each inherited attribute.

View file

@ -2,8 +2,6 @@
synopsis: Store paths are allowed to start with `.`
issues: 912
prs: [9867, 9091, 9095, 9120, 9121, 9122, 9130, 9219, 9224]
credits: [roberth, horrors]
category: Fixes
---
Leading periods were allowed by accident in Nix 2.4. The Nix team has considered this to be a bug, but this behavior has since been relied on by users, leading to unnecessary difficulties.

View file

@ -1,12 +0,0 @@
---
synopsis: Enforce syscall filtering and no-new-privileges on Linux
cls: 1063
category: Breaking Changes
credits: alois31
---
In order to improve consistency of the build environment, system call filtering and no-new-privileges are now unconditionally enabled on Linux.
The `filter-syscalls` and `allow-new-privileges` options which could be used to disable these features under some circumstances have been removed.
In order to support building on architectures without libseccomp support, the option to disable syscall filtering at build time remains.
However, other uses of this option are heavily discouraged, since it would reduce the security of the sandbox substantially.

View file

@ -1,9 +0,0 @@
---
synopsis: Increase default stack size on macOS
prs: 9860
credits: 9999years
category: Improvements
---
Increase the default stack size on macOS to the same value as on Linux, subject to system restrictions to maximum stack size.
This should reduce the number of stack overflow crashes on macOS when evaluating Nix code with deep call stacks.

View file

@ -1,9 +0,0 @@
---
synopsis: Show more log context for failed builds
prs: 9670
credits: DavHau
category: Improvements
---
Show 25 lines of log tail instead of 10 for failed builds.
This increases the chances of having useful information in the shown logs.

View file

@ -1,9 +1,6 @@
---
synopsis: Lix turns more internal bugs into crashes
cls: [797, 626]
credits: jade
category: Packaging
significance: significant
---
Lix now enables build options such as trapping on signed overflow and enabling

View file

@ -2,11 +2,6 @@
synopsis: rename 'nix show-config' to 'nix config show'
issues: 7672
prs: 9477
cls: 993
credits: [thufschmitt, ma27]
category: Improvements
---
`nix show-config` was renamed to `nix config show` to be more consistent with the rest of the command-line interface.
Running `nix show-config` will now print a deprecation warning saying to use `nix config show` instead.

View file

@ -1,8 +1,6 @@
---
synopsis: Fix `nix-env --query --drv-path --json`
prs: 9257
credits: [Artturin, horrors]
category: Fixes
---
Fixed a bug where `nix-env --query` ignored `--drv-path` when `--json` was set.

View file

@ -1,9 +0,0 @@
---
synopsis: Print derivation paths in `nix eval`
cls: 446
credits: 9999years
category: Improvements
---
`nix eval` previously printed derivations as attribute sets, so commands that print derivations (e.g. `nix eval nixpkgs#bash`) would infinitely loop and segfault.
It now prints the `.drv` path the derivation generates instead.

View file

@ -2,10 +2,6 @@
synopsis: "`nix flake check` logs the checks"
issues: 8882
prs: 8893
cls: [259, 260, 261, 262]
credits: [9999years, raito, horrors]
category: Improvements
significance: significant
---
`nix flake check` now logs the checks it runs and the derivations it evaluates:

View file

@ -1,8 +1,6 @@
---
synopsis: "Overhaul `nix flake update` and `nix flake lock` UX"
synopsis: "`Overhaul `nix flake update` and `nix flake lock` UX"
prs: 8817
credits: [iFreilicht, Lunaphied, thufschmitt]
category: Breaking Changes
---
The interface for creating and updating lock files has been overhauled:

View file

@ -2,8 +2,6 @@
synopsis: "`nix profile` now allows referring to elements by human-readable name, and no longer accepts indices"
prs: 8678
cls: [978, 980]
category: Breaking Changes
credits: [iFreilicht, Qyriad, edolstra]
---
[`nix profile`](@docroot@/command-ref/new-cli/nix3-profile.md) now uses names to refer to installed packages when running [`list`](@docroot@/command-ref/new-cli/nix3-profile-list.md), [`remove`](@docroot@/command-ref/new-cli/nix3-profile-remove.md) or [`upgrade`](@docroot@/command-ref/new-cli/nix3-profile-upgrade.md) as opposed to indices. Indices have been removed. Profile element names are generated when a package is installed and remain the same until the package is removed.

View file

@ -1,18 +0,0 @@
---
synopsis: "Add an option `--unpack` to unpack archives in `nix store prefetch-file`"
prs: 9805
cls: 224
credits: [yshui, horrors]
category: Improvements
---
It is now possible to fetch an archive then NAR-hash it (as in, hash it in the
same manner as `builtins.fetchTarball` or fixed-output derivations with
recursive hash type) in one command.
Example:
```
~ » nix store prefetch-file --name source --unpack https://git.lix.systems/lix-project/lix/archive/2.90-beta.1.tar.gz
Downloaded 'https://git.lix.systems/lix-project/lix/archive/2.90-beta.1.tar.gz' to '/nix/store/yvfqnq52ryjc3janw02ziv7kr6gd0cs1-source' (hash 'sha256-REWlo2RYHfJkxnmZTEJu3Cd/2VM+wjjpPy7Xi4BdDTQ=').
```

View file

@ -1,17 +1,11 @@
---
synopsis: "`builtins.nixVersion` and `builtins.langVersion` return fixed values"
cls: [558, 1144]
credits: jade
category: Breaking Changes
synopsis: "`builtins.nixVersion` now returns a fixed value \"2.18.3-lix\""
cls: 558
---
`builtins.nixVersion` now returns a fixed value `"2.18.3-lix"`.
`builtins.langVersion` returns a fixed value `6`, matching CppNix 2.18.
This prevents feature detection assuming that features that exist in Nix
post-Lix-branch-off might exist, even though the Lix version is greater than
the Nix version.
`builtins.nixVersion` now returns a fixed value `"2.18.3-lix"`. This prevents
feature detection assuming that features that exist in Nix post-Lix-branch-off
might exist, even though the Lix version is greater than the Nix version.
In the future, check for builtins for feature detection. If a feature cannot be
detected by *those* means, please file a Lix bug.

View file

@ -1,8 +1,6 @@
---
synopsis: re-evaluate cached evaluation errors
cls: 771
credits: Qyriad
category: Fixes
---
"cached failure of [expr]" errors have been removed: expressions already in the

View file

@ -1,55 +0,0 @@
---
synopsis: "REPL printing improvements"
prs: [9931, 10208]
cls: [375, 492]
credits: [9999years, horrors]
category: Improvements
---
The REPL printer has been improved to do the following:
- If a string is passed to `:print`, it is printed literally to the screen
- Structures will be printed as multiple lines when necessary
Before:
```
nix-repl> { attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
{ attrs = { ... }; list = [ ... ]; list' = [ ... ]; }
nix-repl> :p { attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
{ attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
nix-repl> :p "meow"
"meow"
```
After:
```
nix-repl> { attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
{
attrs = { ... };
list = [ ... ];
list' = [ ... ];
}
nix-repl> :p { attrs = { a = { b = { c = { }; }; }; }; list = [ 1 ]; list' = [ 1 2 3 ]; }
{
attrs = {
a = {
b = {
c = { };
};
};
};
list = [ 1 ];
list' = [
1
2
3
];
}
nix-repl> :p "meow"
meow
```

View file

@ -2,8 +2,6 @@
synopsis: Coercion errors include the failing value
issues: 561
prs: 9754
credits: [9999years, horrors]
category: Improvements
---
The `error: cannot coerce a <TYPE> to a string` message now includes the value

View file

@ -1,20 +0,0 @@
---
synopsis: New-cli flake commands that expect derivations now print the failing value and its type
credits: Qyriad
category: Improvements
cls: 1177
---
In errors like `flake output attribute 'legacyPackages.x86_64-linux.lib' is not a derivation or path`, the message now includes the failing value and type.
Before:
```
error: flake output attribute 'nixosConfigurations.yuki.config' is not a derivation or path
````
After:
```
error: expected flake output attribute 'nixosConfigurations.yuki.config' to be a derivation or path but found a set: { appstream = «thunk»; assertions = «thunk»; boot = { bcache = «thunk»; binfmt = «thunk»; binfmtMiscRegistrations = «thunk»; blacklistedKernelModules = «thunk»; bootMount = «thunk»; bootspec = «thunk»; cleanTmpDir = «thunk»; consoleLogLevel = «thunk»; «43 attributes elided» }; «48 attributes elided» }
```

View file

@ -2,8 +2,6 @@
synopsis: Type errors include the failing value
issues: 561
prs: 9753
credits: [9999years, horrors]
category: Improvements
---
In errors like `value is an integer while a list was expected`, the message now

View file

@ -1,8 +1,6 @@
---
synopsis: "Visual clutter in `--debugger` is reduced"
prs: 9919
category: Improvements
credits: [9999years, horrors]
---
Before:

View file

@ -1,31 +0,0 @@
---
synopsis: Rename all the libraries nixexpr, nixstore, etc to lixexpr, lixstore, etc
credits: jade
category: Breaking Changes
---
The Lix C++ API libraries have had the following changes:
- Includes moved from `include/nix/` to `include/lix/`
- `pkg-config` files renamed from `nix-expr` to `lix-expr` and so on.
- Libraries renamed from `libnixexpr.so` to `liblixexpr.so` and so on.
There are other changes between Nix 2.18 and Lix, since these APIs are not
stable. However, this change in particular is a deliberate compatibility break
to force downstreams linking to Lix to specifically handle Lix and avoid Lix
accidentally getting ensnared in compatibility code for newer CppNix.
Migration path:
- expr.hh -> lix/libexpr/expr.hh
- nix/config.h -> lix/config.h
To apply this migration automatically, remove all `<nix/>` from includes, so `#include <nix/expr.hh>` -> `#include <expr.hh>`.
Then, the correct paths will be resolved from the tangled mess, and the clang-tidy automated fix will work.
Then run the following for out of tree projects (header filter is set to only fix instances in headers in `../src` relative to the compiler's working directory, as would be the case in nix-eval-jobs or other things built with meson, e.g.):
```console
lix_root=$HOME/lix
(cd $lix_root/clang-tidy && nix develop -c 'meson setup build && ninja -C build')
run-clang-tidy -checks='-*,lix-fixincludes' -load=$lix_root/clang-tidy/build/liblix-clang-tidy.so -p build/ -header-filter '\.\./src/.*\.h' -fix src
```

View file

@ -1,9 +1,6 @@
---
synopsis: Experimental REPL support for documentation comments using `:doc`
cls: 564
category: Features
credits: [Lunaphied, jade]
significance: significant
---
Using `:doc` in the REPL now supports showing documentation comments when defined on a function.

View file

@ -1,9 +0,0 @@
---
synopsis: "`nix repl` history is saved more reliably"
cls: 1164
credits: puck
---
`nix repl` now saves its history file after each line, rather than at the end
of the session; ensuring that it will remember what you typed even after it
crashes.

View file

@ -1,10 +0,0 @@
---
synopsis: Interrupting builds in the REPL works more than once
cls: 1097
category: Fixes
credits: alois31
---
Builds in the REPL can be interrupted by pressing Ctrl+C.
Previously, this only worked once per REPL session; further attempts would be ignored.
This issue is now fixed, so that builds can be canceled consistently.

View file

@ -2,9 +2,6 @@
synopsis: Add `repl-overlays` option
prs: 10203
cls: 504
credits: 9999years
significance: significant
category: Features
---
A `repl-overlays` option has been added, which specifies files that can overlay

View file

@ -1,7 +0,0 @@
---
synopsis: "REPL now supports CTRL+Z to suspend"
credits: [Qyriad]
category: Improvements
---
Editline is now built with SIGTSTP support, so now typing CTRL+Z in the REPL will suspend the REPL and allow it to be resumed later or backgrounded.

View file

@ -1,13 +0,0 @@
---
synopsis: Allow single quotes in nix-shell shebangs
prs: 8470
credits: [ncfavier, horrors]
category: Improvements
---
Example:
```bash
#! /usr/bin/env nix-shell
#! nix-shell -i bash --packages 'terraform.withPlugins (plugins: [ plugins.openstack ])'
```

View file

@ -1,11 +1,9 @@
---
synopsis: reintroduce shortened `-E` form for `--expr` to new CLI
cls: 605
credits: Lunaphied
category: Improvements
---
In the old CLI, it was possible to supply a shorter `-E` flag instead of fully
In the past, it was possible to supply a shorter `-E` flag instead of fully
specifying `--expr` every time you wished to provide an expression that would
be evaluated to produce the given command's input. This was retained for the
`--file` flag when the new CLI utilities were written with `-f`, but `-E` was

View file

@ -1,8 +1,6 @@
---
synopsis: "In the debugger, `while evaluating the attribute` errors now include position information"
prs: 9915
credits: 9999years
category: Fixes
---
Before:

View file

@ -2,8 +2,6 @@
synopsis: Source locations are printed more consistently in errors
issues: 561
prs: 9555
credits: [9999years, horrors]
category: Improvements
---
Source location information is now included in error messages more

View file

@ -1,8 +0,0 @@
---
synopsis: Include phase reporting in log file for ssh-ng builds
prs: 9280
credits: r-vdp
category: Fixes
---
Store phase information of remote builds run via `ssh-ng` remotes in the local log file, matching logging behavior of local builds.

View file

@ -1,9 +0,0 @@
---
synopsis: Fix `ssh-ng://` remotes not respecting `--substitute-on-destination`
prs: 9600
credits: SharzyL
category: Fixes
---
`nix copy ssh-ng://` now respects `--substitute-on-destination`, as does `nix-copy-closure` and other commands that operate on remote `ssh-ng` stores.
Previously this was always set by `builders-use-substitutes` setting.

View file

@ -2,9 +2,6 @@
synopsis: Some stack overflow segfaults are fixed
issues: 9616
prs: 9617
cls: 205
category: Improvements
credits: [9999years, horrors]
---
The number of nested function calls has been restricted, to detect and report

View file

@ -1,8 +1,6 @@
---
synopsis: add `--store-path` argument to `nix upgrade-nix`, to manually specify the Nix to upgrade to
synopsis: add --store-path argument to `nix upgrade-nix`, to manually specify the Nix to upgrade to
cls: 953
credits: Qyriad
category: Features
---
`nix upgrade-nix` by default downloads a manifest to find the new Nix version to upgrade to, but now you can specify `--store-path` to upgrade Nix to an arbitrary version from the Nix store.

View file

@ -1,8 +1,6 @@
---
synopsis: using `nix profile` on `/nix/var/nix/profiles/default` no longer breaks `nix upgrade-nix`
cls: 952
credits: Qyriad
category: Fixes
---
On non-NixOS, Nix is conventionally installed into a `nix-env` style profile at /nix/var/nix/profiles/default.

View file

@ -1,8 +1,6 @@
---
synopsis: Upstart scripts removed
cls: 574
category: Packaging
credits: jade
---
Upstart scripts have been removed from Lix, since Upstart is obsolete and has

View file

@ -1,9 +0,0 @@
---
synopsis: Warn about ignored client settings
cls: 1026
credits: jade
category: Improvements
---
Emit a warning for every client-provided setting the daemon ignores because the requesting client is not run by a trusted user.
Previously this was only a debug message.

View file

@ -1,9 +1,6 @@
---
synopsis: Better error reporting for `with` expressions
prs: 9658
cls: 207
credits: horrors
category: Improvements
---
`with` expressions using non-attrset values to resolve variables are now reported with proper positions.

View file

@ -14,8 +14,9 @@
# Disambiguation
This man page describes the command `nix-build`, which is distinct from [`nix build`](./new-cli/nix3-build.md).
For documentation on the latter, run `nix build --help` or see `man nix3-build`.
This man page describes the command `nix-build`, which is distinct from `nix
build`. For documentation on the latter, run `nix build --help` or see `man
nix3-build`.
# Description

View file

@ -102,14 +102,14 @@ $ meson compile -C build nixexpr
All targets may be addressed as their output, relative to the build directory, e.g.:
```bash
$ meson compile -C build src/libexpr/liblixexpr.so
$ meson compile -C build src/libexpr/libnixexpr.so
```
But Meson does not consider intermediate files like object files targets.
To build a specific object file, use Ninja directly and specify the output file relative to the build directory:
```bash
$ ninja -C build src/libexpr/liblixexpr.so.p/nixexpr.cc.o
$ ninja -C build src/libexpr/libnixexpr.so.p/nixexpr.cc.o
```
To inspect the canonical source of truth on what the state of the buildsystem configuration is, use:

View file

@ -68,7 +68,10 @@ The most current alternative to this section is to read `package.nix` and see wh
may also work, but ancient versions like the ubiquitous 2.5.4a
won't.
- The `libseccomp` is used to provide syscall filtering on Linux. To get
- The `libseccomp` is used to provide syscall filtering on Linux. This
is an optional dependency and can be disabled passing a
`--disable-seccomp-sandboxing` option to the `configure` script (Not
recommended unless your system doesn't support `libseccomp`). To get
the library, visit <https://github.com/seccomp/libseccomp>.
- On 64-bit x86 machines only, `libcpuid` library

View file

@ -7,14 +7,3 @@ These constants are built into the Nix language evaluator:
{{#include @generated@/language/builtin-constants.md}}
</dl>
## Things which might be mistaken for constants
<dl>
<dt><code>__curPos</code></dt>
<dd>
This is not a constant but a [context-dependent keyword](@docroot@/language/constructs.md#keywords-__curPos)
</dd>
</dl>

View file

@ -380,70 +380,3 @@ let a = 1; in let a = 2; in let a = 3; in let a = 4; in ...
Comments can be single-line, started with a `#` character, or
inline/multi-line, enclosed within `/* ... */`.
## Context-dependent keywords
<dl>
<dt id="keywords-__curPos">
<a href="#keywords-__curPos"><code>__curPos</code></a>
</dt>
<dd>
A quasi-constant which will be replaced with an attribute set describing
the location where `__curPos` was used, with attributes `file`, `line`,
and `column`. For example, `import ./file.nix` will result in
```nix
{
column = 1;
file = "/path/to/some/file.nix";
line = 1;
}
```
assuming `file.nix` contains nothing but `__curPos`.
In context without a source file (such as `nix-repl`), it will always
be replaced with `null`:
```nix-repl
nix-repl> __curPos
null
```
While it may vaguely look like a builtin, this is a very different beast
that is handled directly by the parser. It thus cannot be shadowed,
bound to a different name, and is also not available under
[`builtins`](@docroot@/language/builtin-constants.md#builtins-builtins).
```nix-repl
nix-repl> let __curPos = "no"; in __curPos
null
```
Despite this `__curPos`, much like `or`, may still be used as an identifier,
it is only treated specially when it appears as an unqualified name:
```nix-repl
nix-repl> { __curPos = 1; }.__curPos
1
```
</dd>
<dt id="keywords-or">
<a href="#keywords-or"><code>or</code></a>
</dt>
<dd>
`or` is used in [Attribute selection](@docroot@/language/operators.html#attribute-selection),
where it is a keyword.
However, it is not a keyword in some other contexts, and can be used as
a binding name in attribute sets, let-bindings, non-initial function
application position, and as a label in attribute paths.
Its use as anything other than a keyword is discouraged.
</dd>
</dl>

View file

@ -125,7 +125,7 @@ The builder is executed as follows:
directory (typically, `/nix/store`).
- `NIX_ATTRS_JSON_FILE` & `NIX_ATTRS_SH_FILE` if `__structuredAttrs`
is set to `true` for the derivation. A detailed explanation of this
is set to `true` for the dervation. A detailed explanation of this
behavior can be found in the
[section about structured attrs](./advanced-attributes.md#adv-attr-structuredAttrs).

View file

@ -1,14 +1,12 @@
rl_next_generated = custom_target(
command : [
'bash',
'-euo',
'pipefail',
'-c',
'''
if type -p build-release-notes > /dev/null; then
build-release-notes --change-authors @CURRENT_SOURCE_DIR@/../../change-authors.yml @CURRENT_SOURCE_DIR@/../../rl-next
build-release-notes @CURRENT_SOURCE_DIR@
fi
@0@ @INPUT0@ @CURRENT_SOURCE_DIR@/../../rl-next > @DEPFILE@
@0@ @INPUT0@ @CURRENT_SOURCE_DIR@ > @DEPFILE@
'''.format(
python.full_path(),
),

View file

@ -18,11 +18,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1715123187,
"narHash": "sha256-0czuu757t53lK6uWeo1a5/jJbCd9t4sOtLDFpts60DM=",
"lastModified": 1711481231,
"narHash": "sha256-J/fW3Xhm3WsJPNd8ksZmfMnol5aOG2qEMDPbOnNNdTQ=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "0c592f9a288bdf764b6f24c757277c0e49757a46",
"rev": "9d6ddb13cee3cc1192e4430277708c732685f38a",
"type": "github"
},
"original": {

190
flake.nix
View file

@ -57,7 +57,7 @@
officialRelease = false;
# Set to true to build the release notes for the next release.
buildUnreleasedNotes = true;
buildUnreleasedNotes = false;
version = lib.fileContents ./.version + versionSuffix;
versionSuffix =
@ -83,9 +83,7 @@
crossSystems = [
"armv6l-linux"
"armv7l-linux"
# FIXME: doesn't evaluate, plausibly fixed in >=24.05, so recheck when
# we update to 24.05
# "x86_64-freebsd13"
"x86_64-freebsd13"
"x86_64-netbsd"
];
@ -98,10 +96,6 @@
];
forAllSystems = lib.genAttrs systems;
# Same as forAllSystems, but removes nulls, in case something is broken
# on that system.
forAvailableSystems =
f: lib.filterAttrs (name: value: value != null && value != { }) (forAllSystems f);
forAllCrossSystems = lib.genAttrs crossSystems;
@ -163,6 +157,7 @@
# Forward from the previous stage as we dont want it to pick the lowdown override
nixUnstable = prev.nixUnstable;
build-release-notes = final.buildPackages.callPackage ./maintainers/build-release-notes.nix { };
check-headers = final.buildPackages.callPackage ./maintainers/check-headers.nix { };
clangbuildanalyzer = final.buildPackages.callPackage ./misc/clangbuildanalyzer.nix { };
@ -196,11 +191,10 @@
busybox-sandbox-shell = final.busybox-sandbox-shell or final.default-busybox-sandbox-shell;
};
# Export the patched version of boehmgc that Lix uses into the overlay
# Export the patched version of boehmgc & libseccomp that Lix uses into the overlay
# for consumers of this flake.
boehmgc-nix = final.nix.boehmgc-nix;
# And same thing for our build-release-notes package.
build-release-notes = final.nix.build-release-notes;
libseccomp-nix = final.nix.libseccomp-nix;
};
in
{
@ -222,7 +216,7 @@
pkgs = nixpkgsFor.${system}.native;
in
pkgs.buildPackages.runCommand "test-${name}-release-notes" { } ''
LANG=C.UTF-8 ${lib.getExe pkgs.build-release-notes} --change-authors ${./doc/manual/change-authors.yml} ${dir} >$out
LANG=C.UTF-8 ${lib.getExe pkgs.build-release-notes} ${dir} >$out
'';
in
{
@ -288,21 +282,99 @@
);
};
pre-commit = forAvailableSystems (
pre-commit = forAllSystems (
system:
let
pkgs = nixpkgsFor.${system}.native;
pre-commit-check = import ./misc/pre-commit.nix { inherit self pkgs pre-commit-hooks; };
# dotnet-sdk_6, a nativeBuildInputs of pre-commit, is broken on i686-linux.
available = lib.meta.availableOn { inherit system; } pkgs.dotnet-sdk_6;
# Import pre-commit bypassing the flake because flakes don't let
# you have overlays. Also their implementation forces an
# unnecessary reimport of nixpkgs for our use cases.
tools = import (pre-commit-hooks + "/nix/call-tools.nix") pkgs;
pre-commit-run = pkgs.callPackage (pre-commit-hooks + "/nix/run.nix") {
inherit tools;
isFlakes = true;
# unused!
gitignore-nix-src = builtins.throw "gitignore-nix-src is unused";
};
in
lib.optionalAttrs available pre-commit-check
pre-commit-run {
src = self;
hooks = {
no-commit-to-branch = {
enable = true;
settings.branch = [ "main" ];
};
check-case-conflicts.enable = true;
check-executables-have-shebangs = {
enable = true;
stages = [ "commit" ];
};
check-shebang-scripts-are-executable = {
enable = true;
stages = [ "commit" ];
};
check-symlinks = {
enable = true;
excludes = [ "^tests/functional/lang/symlink-resolution/broken$" ];
};
check-merge-conflicts.enable = true;
end-of-file-fixer = {
enable = true;
excludes = [
"\\.drv$"
"^tests/functional/lang/"
];
};
mixed-line-endings = {
enable = true;
excludes = [ "^tests/functional/lang/" ];
};
release-notes = {
enable = true;
package = pkgs.build-release-notes;
files = "^doc/manual/rl-next(-dev)?";
pass_filenames = false;
entry = ''
${lib.getExe pkgs.build-release-notes} doc/manual/rl-next doc/manual/rl-next-dev
'';
};
check-headers = {
enable = true;
package = pkgs.check-headers;
files = "^src/";
types = [
"c++"
"file"
"header"
];
# generated files; these will never actually be seen by this
# check, and are left here as documentation
excludes = [
"(parser|lexer)-tab\\.hh$"
"\\.gen\\.hh$"
];
entry = lib.getExe pkgs.check-headers;
};
# TODO: Once the test suite is nicer, clean up and start
# enforcing trailing whitespace on tests that don't explicitly
# check for it.
trim-trailing-whitespace = {
enable = true;
stages = [ "commit" ];
excludes = [ "^tests/functional/lang/" ];
};
treefmt = {
enable = true;
settings.formatters = [ pkgs.nixfmt ];
};
};
}
);
};
# NOTE *do not* add fresh derivations to checks, always add them to
# hydraJobs first (so CI will pick them up) and only link them here
checks = forAvailableSystems (
checks = forAllSystems (
system:
{
binaryTarball = self.hydraJobs.binaryTarball.${system};
@ -310,7 +382,6 @@
nixpkgsLibTests = self.hydraJobs.tests.nixpkgsLibTests.${system};
rl-next = self.hydraJobs.rl-next.${system}.user;
rl-next-dev = self.hydraJobs.rl-next.${system}.dev;
# Will be empty attr set on i686-linux, and filtered out by forAvailableSystems.
pre-commit = self.hydraJobs.pre-commit.${system};
}
// (lib.optionalAttrs (builtins.elem system linux64BitSystems)) {
@ -367,14 +438,85 @@
nix = pkgs.callPackage ./package.nix {
inherit stdenv versionSuffix;
busybox-sandbox-shell = pkgs.busybox-sandbox-shell or pkgs.default-busybox-sandbox;
internalApiDocs = true;
forDevShell = true;
};
pre-commit = self.hydraJobs.pre-commit.${pkgs.system} or { };
in
pkgs.callPackage nix.mkDevShell {
pre-commit-checks = pre-commit;
inherit contribNotice;
};
(nix.override {
buildUnreleasedNotes = true;
officialRelease = false;
}).overrideAttrs
(
prev:
{
# Required for clang-tidy checks
buildInputs =
prev.buildInputs
++ [
pkgs.just
pkgs.nixfmt
]
++ lib.optional (pre-commit ? enabledPackages) pre-commit.enabledPackages
++ lib.optionals (stdenv.cc.isClang) [
pkgs.llvmPackages.llvm
pkgs.llvmPackages.clang-unwrapped.dev
];
nativeBuildInputs =
prev.nativeBuildInputs
++ lib.optional (stdenv.cc.isClang && !stdenv.buildPlatform.isDarwin) pkgs.buildPackages.bear
# Required for clang-tidy checks
++ lib.optionals (stdenv.cc.isClang) [
pkgs.buildPackages.cmake
pkgs.buildPackages.ninja
pkgs.buildPackages.llvmPackages.llvm.dev
]
++
lib.optional (stdenv.cc.isClang && stdenv.hostPlatform == stdenv.buildPlatform)
# for some reason that seems accidental and was changed in
# NixOS 24.05-pre, clang-tools is pinned to LLVM 14 when
# default LLVM is newer.
(pkgs.buildPackages.clang-tools.override { inherit (pkgs.buildPackages) llvmPackages; })
++ [
# FIXME(Qyriad): remove once the migration to Meson is complete.
pkgs.buildPackages.meson
pkgs.buildPackages.ninja
pkgs.buildPackages.cmake
pkgs.buildPackages.clangbuildanalyzer
];
src = null;
installFlags = "sysconfdir=$(out)/etc";
strictDeps = false;
shellHook = ''
PATH=$prefix/bin:$PATH
unset PYTHONPATH
export MANPATH=$out/share/man:$MANPATH
# Make bash completion work.
XDG_DATA_DIRS+=:$out/share
${lib.optionalString (pre-commit ? shellHook) pre-commit.shellHook}
# Allow `touch .nocontribmsg` to turn this notice off.
if ! [[ -f .nocontribmsg ]]; then
cat ${contribNotice}
fi
# Install the Gerrit commit-msg hook.
if [[ ! -f .git/hooks/commit-msg ]]; then
mkdir -p .git/hooks
curl -s -Lo .git/hooks/commit-msg https://gerrit.lix.systems/tools/hooks/commit-msg
chmod u+x .git/hooks/commit-msg
fi
'';
}
// lib.optionalAttrs (stdenv.buildPlatform.isLinux && pkgs.glibcLocales != null) {
# Required to make non-NixOS Linux not complain about missing locale files during configure in a dev shell
LOCALE_ARCHIVE = "${lib.getLib pkgs.glibcLocales}/lib/locale/locale-archive";
}
);
in
forAllSystems (
system:

View file

@ -1,27 +1,19 @@
# https://just.systems/man/en/
# List all available targets
list:
just --list
# Clean build artifacts
clean:
rm -rf build
# Prepare meson for building
setup:
meson setup build --prefix="$PWD/outputs/out"
# Build lix
build *OPTIONS:
meson compile -C build {{ OPTIONS }}
alias compile := build
compile:
just build
# Install lix for local development
install *OPTIONS: (build OPTIONS)
meson install -C build
# Run tests
test *OPTIONS:
meson test -C build --print-errorlogs {{ OPTIONS }}
meson test -C build --print-errorlogs --quiet {{ OPTIONS }}

View file

@ -84,13 +84,9 @@ fn indented(s: &str, indent: usize) -> String {
/// Cleans up a single line, erasing prefix single line comments but preserving indentation
fn cleanup_single_line<'a>(s: &'a str) -> &'a str {
let mut cmt_new_start = 0;
let mut iter = s.char_indices().peekable();
while let Some((idx, ch)) = iter.next() {
// peek at the next character, with an explicit '\n' as "next character" at end of line
let (_, next_ch) = iter.peek().unwrap_or(&(0, '\n'));
for (idx, ch) in s.char_indices() {
// if we find a character, save the byte position after it as our new string start
if ch == '#' || (ch == '*' && next_ch.is_whitespace()) {
if ch == '#' || ch == '*' {
cmt_new_start = idx + 1;
break;
}
@ -210,7 +206,7 @@ fn visit_lambda(name: String, lambda: &Lambda) -> SearchResult {
SearchResult {
identifier: name,
doc: comment,
param_block,
param_block
}
}
@ -250,7 +246,7 @@ pub extern "C" fn nd_get_function_docs(
filename: *const c_char,
line: usize,
col: usize,
) -> *const c_char {
) -> *const c_char {
let fname = unsafe { CStr::from_ptr(filename) };
fname
.to_str()
@ -261,9 +257,9 @@ pub extern "C" fn nd_get_function_docs(
eprintln!("panic!! {:#?}", e);
e
})
.ok()
.ok()
})
.flatten()
.flatten()
.and_then(|s| CString::new(s).ok())
.map(|s| s.into_raw() as *const c_char)
.unwrap_or(ptr::null())
@ -323,16 +319,8 @@ mod tests {
let ex1 = " * a";
let ex2 = " # a";
let ex3 = " a";
let ex4 = " *";
assert_eq!(cleanup_single_line(ex1), " a");
assert_eq!(cleanup_single_line(ex2), " a");
assert_eq!(cleanup_single_line(ex3), ex3);
assert_eq!(cleanup_single_line(ex4), "");
}
#[test]
fn test_single_line_retains_bold_headings() {
let ex1 = " **Foo**:";
assert_eq!(cleanup_single_line(ex1), ex1);
}
}

17
local.mk Normal file
View file

@ -0,0 +1,17 @@
# 2024-03-24: jade benchmarked the default sanitize reporting in clang and got
# a regression of about 10% on hackage-packages.nix with clang. So we are trapping instead.
#
# This has an overhead of 0-4% on gcc and unmeasurably little on clang, in
# Nix evaluation benchmarks.
DEFAULT_SANITIZE_FLAGS = -fsanitize=signed-integer-overflow -fsanitize-undefined-trap-on-error
GLOBAL_CXXFLAGS += -Wno-deprecated-declarations -Werror=switch $(DEFAULT_SANITIZE_FLAGS) -D_GLIBCXX_ASSERTIONS=1
GLOBAL_LDFLAGS += $(DEFAULT_SANITIZE_FLAGS)
# Allow switch-enum to be overridden for files that do not support it, usually because of dependency headers.
ERROR_SWITCH_ENUM = -Werror=switch-enum
$(foreach i, config.h $(wildcard src/lib*/*.hh), \
$(eval $(call install-file-in, $(i), $(includedir)/nix, 0644)))
$(GCH): src/libutil/util.hh config.h
GCH_CXXFLAGS = -I src/libutil

951
m4/ax_cxx_compile_stdcxx.m4 Normal file
View file

@ -0,0 +1,951 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the specified
# version of the C++ standard. If necessary, add switches to CXX and
# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
# or '14' (for the C++14 standard).
#
# The second argument, if specified, indicates whether you insist on an
# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
# -std=c++11). If neither is specified, you get whatever works, with
# preference for an extended mode.
#
# The third argument, if specified 'mandatory' or if left unspecified,
# indicates that baseline support for the specified C++ standard is
# required and that the macro should error out if no mode with that
# support is found. If specified 'optional', then configuration proceeds
# regardless, after defining HAVE_CXX${VERSION} if and only if a
# supporting mode is found.
#
# LICENSE
#
# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
# Copyright (c) 2015 Paul Norman <penorman@mac.com>
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 11
dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
dnl (serial version number 13).
AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
[$1], [14], [ax_cxx_compile_alternatives="14 1y"],
[$1], [17], [ax_cxx_compile_alternatives="17 1z"],
[m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$2], [], [],
[$2], [ext], [],
[$2], [noext], [],
[m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
[$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
[$3], [optional], [ax_cxx_compile_cxx$1_required=false],
[m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
AC_LANG_PUSH([C++])dnl
ac_success=no
m4_if([$2], [noext], [], [dnl
if test x$ac_success = xno; then
for alternative in ${ax_cxx_compile_alternatives}; do
switch="-std=gnu++${alternative}"
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
fi
done
fi])
m4_if([$2], [ext], [], [dnl
if test x$ac_success = xno; then
dnl HP's aCC needs +std=c++11 according to:
dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
dnl Cray's crayCC needs "-h std=c++11"
for alternative in ${ax_cxx_compile_alternatives}; do
for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
$cachevar,
[ac_save_CXX="$CXX"
CXX="$CXX $switch"
AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
[eval $cachevar=yes],
[eval $cachevar=no])
CXX="$ac_save_CXX"])
if eval test x\$$cachevar = xyes; then
CXX="$CXX $switch"
if test -n "$CXXCPP" ; then
CXXCPP="$CXXCPP $switch"
fi
ac_success=yes
break
fi
done
if test x$ac_success = xyes; then
break
fi
done
fi])
AC_LANG_POP([C++])
if test x$ax_cxx_compile_cxx$1_required = xtrue; then
if test x$ac_success = xno; then
AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
fi
fi
if test x$ac_success = xno; then
HAVE_CXX$1=0
AC_MSG_NOTICE([No compiler with C++$1 support was found])
else
HAVE_CXX$1=1
AC_DEFINE(HAVE_CXX$1,1,
[define if the compiler supports basic C++$1 syntax])
fi
AC_SUBST(HAVE_CXX$1)
])
dnl Test body for checking C++11 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
)
dnl Test body for checking C++14 support
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
)
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
_AX_CXX_COMPILE_STDCXX_testbody_new_in_11
_AX_CXX_COMPILE_STDCXX_testbody_new_in_14
_AX_CXX_COMPILE_STDCXX_testbody_new_in_17
)
dnl Tests for new features in C++11
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
// If the compiler admits that it is not ready for C++11, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201103L
#error "This is not a C++11 compiler"
#else
namespace cxx11
{
namespace test_static_assert
{
template <typename T>
struct check
{
static_assert(sizeof(int) <= sizeof(T), "not big enough");
};
}
namespace test_final_override
{
struct Base
{
virtual ~Base() {}
virtual void f() {}
};
struct Derived : public Base
{
virtual ~Derived() override {}
virtual void f() override {}
};
}
namespace test_double_right_angle_brackets
{
template < typename T >
struct check {};
typedef check<void> single_type;
typedef check<check<void>> double_type;
typedef check<check<check<void>>> triple_type;
typedef check<check<check<check<void>>>> quadruple_type;
}
namespace test_decltype
{
int
f()
{
int a = 1;
decltype(a) b = 2;
return a + b;
}
}
namespace test_type_deduction
{
template < typename T1, typename T2 >
struct is_same
{
static const bool value = false;
};
template < typename T >
struct is_same<T, T>
{
static const bool value = true;
};
template < typename T1, typename T2 >
auto
add(T1 a1, T2 a2) -> decltype(a1 + a2)
{
return a1 + a2;
}
int
test(const int c, volatile int v)
{
static_assert(is_same<int, decltype(0)>::value == true, "");
static_assert(is_same<int, decltype(c)>::value == false, "");
static_assert(is_same<int, decltype(v)>::value == false, "");
auto ac = c;
auto av = v;
auto sumi = ac + av + 'x';
auto sumf = ac + av + 1.0;
static_assert(is_same<int, decltype(ac)>::value == true, "");
static_assert(is_same<int, decltype(av)>::value == true, "");
static_assert(is_same<int, decltype(sumi)>::value == true, "");
static_assert(is_same<int, decltype(sumf)>::value == false, "");
static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
return (sumf > 0.0) ? sumi : add(c, v);
}
}
namespace test_noexcept
{
int f() { return 0; }
int g() noexcept { return 0; }
static_assert(noexcept(f()) == false, "");
static_assert(noexcept(g()) == true, "");
}
namespace test_constexpr
{
template < typename CharT >
unsigned long constexpr
strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
{
return *s ? strlen_c_r(s + 1, acc + 1) : acc;
}
template < typename CharT >
unsigned long constexpr
strlen_c(const CharT *const s) noexcept
{
return strlen_c_r(s, 0UL);
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("1") == 1UL, "");
static_assert(strlen_c("example") == 7UL, "");
static_assert(strlen_c("another\0example") == 7UL, "");
}
namespace test_rvalue_references
{
template < int N >
struct answer
{
static constexpr int value = N;
};
answer<1> f(int&) { return answer<1>(); }
answer<2> f(const int&) { return answer<2>(); }
answer<3> f(int&&) { return answer<3>(); }
void
test()
{
int i = 0;
const int c = 0;
static_assert(decltype(f(i))::value == 1, "");
static_assert(decltype(f(c))::value == 2, "");
static_assert(decltype(f(0))::value == 3, "");
}
}
namespace test_uniform_initialization
{
struct test
{
static const int zero {};
static const int one {1};
};
static_assert(test::zero == 0, "");
static_assert(test::one == 1, "");
}
namespace test_lambdas
{
void
test1()
{
auto lambda1 = [](){};
auto lambda2 = lambda1;
lambda1();
lambda2();
}
int
test2()
{
auto a = [](int i, int j){ return i + j; }(1, 2);
auto b = []() -> int { return '0'; }();
auto c = [=](){ return a + b; }();
auto d = [&](){ return c; }();
auto e = [a, &b](int x) mutable {
const auto identity = [](int y){ return y; };
for (auto i = 0; i < a; ++i)
a += b--;
return x + identity(a + b);
}(0);
return a + b + c + d + e;
}
int
test3()
{
const auto nullary = [](){ return 0; };
const auto unary = [](int x){ return x; };
using nullary_t = decltype(nullary);
using unary_t = decltype(unary);
const auto higher1st = [](nullary_t f){ return f(); };
const auto higher2nd = [unary](nullary_t f1){
return [unary, f1](unary_t f2){ return f2(unary(f1())); };
};
return higher1st(nullary) + higher2nd(nullary)(unary);
}
}
namespace test_variadic_templates
{
template <int...>
struct sum;
template <int N0, int... N1toN>
struct sum<N0, N1toN...>
{
static constexpr auto value = N0 + sum<N1toN...>::value;
};
template <>
struct sum<>
{
static constexpr auto value = 0;
};
static_assert(sum<>::value == 0, "");
static_assert(sum<1>::value == 1, "");
static_assert(sum<23>::value == 23, "");
static_assert(sum<1, 2>::value == 3, "");
static_assert(sum<5, 5, 11>::value == 21, "");
static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
}
// http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
// Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
// because of this.
namespace test_template_alias_sfinae
{
struct foo {};
template<typename T>
using member = typename T::member_type;
template<typename T>
void func(...) {}
template<typename T>
void func(member<T>*) {}
void test();
void test() { func<foo>(0); }
}
} // namespace cxx11
#endif // __cplusplus >= 201103L
]])
dnl Tests for new features in C++14
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
// If the compiler admits that it is not ready for C++14, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201402L
#error "This is not a C++14 compiler"
#else
namespace cxx14
{
namespace test_polymorphic_lambdas
{
int
test()
{
const auto lambda = [](auto&&... args){
const auto istiny = [](auto x){
return (sizeof(x) == 1UL) ? 1 : 0;
};
const int aretiny[] = { istiny(args)... };
return aretiny[0];
};
return lambda(1, 1L, 1.0f, '1');
}
}
namespace test_binary_literals
{
constexpr auto ivii = 0b0000000000101010;
static_assert(ivii == 42, "wrong value");
}
namespace test_generalized_constexpr
{
template < typename CharT >
constexpr unsigned long
strlen_c(const CharT *const s) noexcept
{
auto length = 0UL;
for (auto p = s; *p; ++p)
++length;
return length;
}
static_assert(strlen_c("") == 0UL, "");
static_assert(strlen_c("x") == 1UL, "");
static_assert(strlen_c("test") == 4UL, "");
static_assert(strlen_c("another\0test") == 7UL, "");
}
namespace test_lambda_init_capture
{
int
test()
{
auto x = 0;
const auto lambda1 = [a = x](int b){ return a + b; };
const auto lambda2 = [a = lambda1(x)](){ return a; };
return lambda2();
}
}
namespace test_digit_separators
{
constexpr auto ten_million = 100'000'000;
static_assert(ten_million == 100000000, "");
}
namespace test_return_type_deduction
{
auto f(int& x) { return x; }
decltype(auto) g(int& x) { return x; }
template < typename T1, typename T2 >
struct is_same
{
static constexpr auto value = false;
};
template < typename T >
struct is_same<T, T>
{
static constexpr auto value = true;
};
int
test()
{
auto x = 0;
static_assert(is_same<int, decltype(f(x))>::value, "");
static_assert(is_same<int&, decltype(g(x))>::value, "");
return x;
}
}
} // namespace cxx14
#endif // __cplusplus >= 201402L
]])
dnl Tests for new features in C++17
m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
// If the compiler admits that it is not ready for C++17, why torture it?
// Hopefully, this will speed up the test.
#ifndef __cplusplus
#error "This is not a C++ compiler"
#elif __cplusplus < 201703L
#error "This is not a C++17 compiler"
#else
#include <initializer_list>
#include <utility>
#include <type_traits>
namespace cxx17
{
namespace test_constexpr_lambdas
{
constexpr int foo = [](){return 42;}();
}
namespace test::nested_namespace::definitions
{
}
namespace test_fold_expression
{
template<typename... Args>
int multiply(Args... args)
{
return (args * ... * 1);
}
template<typename... Args>
bool all(Args... args)
{
return (args && ...);
}
}
namespace test_extended_static_assert
{
static_assert (true);
}
namespace test_auto_brace_init_list
{
auto foo = {5};
auto bar {5};
static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
static_assert(std::is_same<int, decltype(bar)>::value);
}
namespace test_typename_in_template_template_parameter
{
template<template<typename> typename X> struct D;
}
namespace test_fallthrough_nodiscard_maybe_unused_attributes
{
int f1()
{
return 42;
}
[[nodiscard]] int f2()
{
[[maybe_unused]] auto unused = f1();
switch (f1())
{
case 17:
f1();
[[fallthrough]];
case 42:
f1();
}
return f1();
}
}
namespace test_extended_aggregate_initialization
{
struct base1
{
int b1, b2 = 42;
};
struct base2
{
base2() {
b3 = 42;
}
int b3;
};
struct derived : base1, base2
{
int d;
};
derived d1 {{1, 2}, {}, 4}; // full initialization
derived d2 {{}, {}, 4}; // value-initialized bases
}
namespace test_general_range_based_for_loop
{
struct iter
{
int i;
int& operator* ()
{
return i;
}
const int& operator* () const
{
return i;
}
iter& operator++()
{
++i;
return *this;
}
};
struct sentinel
{
int i;
};
bool operator== (const iter& i, const sentinel& s)
{
return i.i == s.i;
}
bool operator!= (const iter& i, const sentinel& s)
{
return !(i == s);
}
struct range
{
iter begin() const
{
return {0};
}
sentinel end() const
{
return {5};
}
};
void f()
{
range r {};
for (auto i : r)
{
[[maybe_unused]] auto v = i;
}
}
}
namespace test_lambda_capture_asterisk_this_by_value
{
struct t
{
int i;
int foo()
{
return [*this]()
{
return i;
}();
}
};
}
namespace test_enum_class_construction
{
enum class byte : unsigned char
{};
byte foo {42};
}
namespace test_constexpr_if
{
template <bool cond>
int f ()
{
if constexpr(cond)
{
return 13;
}
else
{
return 42;
}
}
}
namespace test_selection_statement_with_initializer
{
int f()
{
return 13;
}
int f2()
{
if (auto i = f(); i > 0)
{
return 3;
}
switch (auto i = f(); i + 4)
{
case 17:
return 2;
default:
return 1;
}
}
}
namespace test_template_argument_deduction_for_class_templates
{
template <typename T1, typename T2>
struct pair
{
pair (T1 p1, T2 p2)
: m1 {p1},
m2 {p2}
{}
T1 m1;
T2 m2;
};
void f()
{
[[maybe_unused]] auto p = pair{13, 42u};
}
}
namespace test_non_type_auto_template_parameters
{
template <auto n>
struct B
{};
B<5> b1;
B<'a'> b2;
}
namespace test_structured_bindings
{
int arr[2] = { 1, 2 };
std::pair<int, int> pr = { 1, 2 };
auto f1() -> int(&)[2]
{
return arr;
}
auto f2() -> std::pair<int, int>&
{
return pr;
}
struct S
{
int x1 : 2;
volatile double y1;
};
S f3()
{
return {};
}
auto [ x1, y1 ] = f1();
auto& [ xr1, yr1 ] = f1();
auto [ x2, y2 ] = f2();
auto& [ xr2, yr2 ] = f2();
const auto [ x3, y3 ] = f3();
}
namespace test_exception_spec_type_system
{
struct Good {};
struct Bad {};
void g1() noexcept;
void g2();
template<typename T>
Bad
f(T*, T*);
template<typename T1, typename T2>
Good
f(T1*, T2*);
static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
}
namespace test_inline_variables
{
template<class T> void f(T)
{}
template<class T> inline T g(T)
{
return T{};
}
template<> inline void f<>(int)
{}
template<> int g<>(int)
{
return 5;
}
}
} // namespace cxx17
#endif // __cplusplus < 201703L
]])

View file

@ -0,0 +1,35 @@
# =============================================================================
# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_17.html
# =============================================================================
#
# SYNOPSIS
#
# AX_CXX_COMPILE_STDCXX_17([ext|noext], [mandatory|optional])
#
# DESCRIPTION
#
# Check for baseline language coverage in the compiler for the C++17
# standard; if necessary, add switches to CXX and CXXCPP to enable
# support.
#
# This macro is a convenience alias for calling the AX_CXX_COMPILE_STDCXX
# macro with the version set to C++17. The two optional arguments are
# forwarded literally as the second and third argument respectively.
# Please see the documentation for the AX_CXX_COMPILE_STDCXX macro for
# more information. If you want to use this macro, you also need to
# download the ax_cxx_compile_stdcxx.m4 file.
#
# LICENSE
#
# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
# Copyright (c) 2016 Krzesimir Nowak <qdlacz@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 2
AX_REQUIRE_DEFINED([AX_CXX_COMPILE_STDCXX])
AC_DEFUN([AX_CXX_COMPILE_STDCXX_17], [AX_CXX_COMPILE_STDCXX([17], [$1], [$2])])

64
m4/gcc_bug_80431.m4 Normal file
View file

@ -0,0 +1,64 @@
# Ensure that this bug is not present in the C++ toolchain we are using.
#
# URL for bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80431
#
# The test program is from that issue, with only a slight modification
# to set an exit status instead of printing strings.
AC_DEFUN([ENSURE_NO_GCC_BUG_80431],
[
AC_MSG_CHECKING([that GCC bug 80431 is fixed])
AC_LANG_PUSH(C++)
AC_RUN_IFELSE(
[AC_LANG_PROGRAM(
[[
#include <cstdio>
static bool a = true;
static bool b = true;
struct Options { };
struct Option
{
Option(Options * options)
{
a = false;
}
~Option()
{
b = false;
}
};
struct MyOptions : Options { };
struct MyOptions2 : virtual MyOptions
{
Option foo{this};
};
]],
[[
{
MyOptions2 opts;
}
return (a << 1) | b;
]])],
[status_80431=0],
[status_80431=$?],
[
# Assume we're bug-free when cross-compiling
])
AC_LANG_POP(C++)
AS_CASE([$status_80431],
[0],[
AC_MSG_RESULT(yes)
],
[2],[
AC_MSG_RESULT(no)
AC_MSG_ERROR(Cannot build Nix with C++ compiler with this bug)
],
[
AC_MSG_RESULT(unexpected result $status_80431: not expected failure with bug, ignoring)
])
])

146
maintainers/README.md Normal file
View file

@ -0,0 +1,146 @@
# Nix maintainers team
## Motivation
The team's main responsibility is to set a direction for the development of Nix and ensure that the code is in good shape.
We aim to achieve this by improving the contributor experience and attracting more maintainers that is, by helping other people contributing to Nix and eventually taking responsibility in order to scale the development process to match users' needs.
### Objectives
- It is obvious what is worthwhile to work on.
- It is easy to find the right place in the code to make a change.
- It is clear what is expected of a pull request.
- It is predictable how to get a change merged and released.
### Tasks
- Establish, communicate, and maintain a technical roadmap
- Improve documentation targeted at contributors
- Record architecture and design decisions
- Elaborate contribution guides and abide to them
- Define and assert quality criteria for contributions
- Maintain the issue tracker and triage pull requests
- Help contributors succeed with pull requests that address roadmap milestones
- Manage the release lifecycle
- Regularly publish reports on work done
- Engage with third parties in the interest of the project
- Ensure the required maintainer capacity for all of the above
## Members
- Eelco Dolstra (@edolstra) Team lead
- Théophane Hufschmitt (@thufschmitt)
- Valentin Gagarin (@fricklerhandwerk)
- Thomas Bereknyei (@tomberek)
- Robert Hensing (@roberth)
- John Ericson (@Ericson2314)
## Meeting protocol
The team meets twice a week:
- Discussion meeting: [Fridays 13:00-14:00 CET](https://calendar.google.com/calendar/event?eid=MHNtOGVuNWtrZXNpZHR2bW1sM3QyN2ZjaGNfMjAyMjExMjVUMTIwMDAwWiBiOW81MmZvYnFqYWs4b3E4bGZraGczdDBxZ0Bn)
1. Triage issues and pull requests from the [No Status](#no-status) column (30 min)
2. Discuss issues and pull requests from the [To discuss](#to-discuss) column (30 min)
- Work meeting: [Mondays 13:00-15:00 CET](https://calendar.google.com/calendar/event?eid=NTM1MG1wNGJnOGpmOTZhYms3bTB1bnY5cWxfMjAyMjExMjFUMTIwMDAwWiBiOW81MmZvYnFqYWs4b3E4bGZraGczdDBxZ0Bn)
1. Code review on pull requests from [In review](#in-review).
2. Other chores and tasks.
Meeting notes are collected on a [collaborative scratchpad](https://pad.lassul.us/Cv7FpYx-Ri-4VjUykQOLAw), and published on Discourse under the [Nix category](https://discourse.nixos.org/c/dev/nix/50).
## Project board protocol
The team uses a [GitHub project board](https://github.com/orgs/NixOS/projects/19/views/1) for tracking its work.
Items on the board progress through the following states:
### No Status
During the discussion meeting, the team triages new items.
To be considered, issues and pull requests must have a high-level description to provide the whole team with the necessary context at a glance.
On every meeting, at least one item from each of the following categories is inspected:
1. [critical](https://github.com/NixOS/nix/labels/critical)
2. [security](https://github.com/NixOS/nix/labels/security)
3. [regression](https://github.com/NixOS/nix/labels/regression)
4. [bug](https://github.com/NixOS/nix/issues?q=is%3Aopen+label%3Abug+sort%3Areactions-%2B1-desc)
5. [tests of existing functionality](https://github.com/NixOS/nix/issues?q=is%3Aopen+label%3Atests+-label%3Afeature+sort%3Areactions-%2B1-desc)
- [oldest pull requests](https://github.com/NixOS/nix/pulls?q=is%3Apr+is%3Aopen+sort%3Acreated-asc)
- [most popular pull requests](https://github.com/NixOS/nix/pulls?q=is%3Apr+is%3Aopen+sort%3Areactions-%2B1-desc)
- [oldest issues](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Acreated-asc)
- [most popular issues](https://github.com/NixOS/nix/issues?q=is%3Aissue+is%3Aopen+sort%3Areactions-%2B1-desc)
Team members can also add pull requests or issues they would like the whole team to consider.
To ensure process quality and reliability, all non-trivial pull requests must be triaged before merging.
If there is disagreement on the general idea behind an issue or pull request, it is moved to [To discuss](#to-discuss).
Otherwise, the issue or pull request in questions get the label [`idea approved`](https://github.com/NixOS/nix/labels/idea%20approved).
For issues this means that an implementation is welcome and will be prioritised for review.
For pull requests this means that:
- Unfinished work is encouraged to be continued.
- A reviewer is assigned to take responsibility for getting the pull request merged.
The item is moved to the [Assigned](#assigned) column.
- If needed, the team can decide to do a collarorative review.
Then the item is moved to the [In review](#in-review) column, and review session is scheduled.
What constitutes a trivial pull request is up to maintainers' judgement.
### To discuss
Pull requests and issues that are deemed important and controversial are discussed by the team during discussion meetings.
This may be where the merit of the change itself or the implementation strategy is contested by a team member.
As a general guideline, the order of items is determined as follows:
- Prioritise pull requests over issues
Contributors who took the time to implement concrete change proposals should not wait indefinitely.
- Prioritise fixing bugs and testing over documentation, improvements or new features
The team values stability and accessibility higher than raw functionality.
- Interleave issues and PRs
This way issues without attempts at a solution get a chance to get addressed.
### In review
Pull requests in this column are reviewed together during work meetings.
This is both for spreading implementation knowledge and for establishing common values in code reviews.
When the overall direction is agreed upon, even when further changes are required, the pull request is assigned to one team member.
If significant changes are requested or reviewers cannot come to a conclusion in reasonable time, the pull request is [marked as draft](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/changing-the-stage-of-a-pull-request#converting-a-pull-request-to-a-draft).
### Assigned
One team member is assigned to each of these pull requests.
They will communicate with the authors, and make the final approval once all remaining issues are addressed.
If more substantive issues arise, the assignee can move the pull request back to [To discuss](#to-discuss) or [In review](#in-review) to involve the team again.
### Flowchart
The process is illustrated in the following diagram:
```mermaid
flowchart TD
discuss[To discuss]
review[To review]
New --> |Disagreement on idea| discuss
New & discuss --> |Consensus on idea| review
review --> |Consensus on implementation| Assigned
Assigned --> |Implementation issues arise| review
Assigned --> |Remaining issues fixed| Merged
```

View file

@ -0,0 +1,12 @@
# Backporting
To [automatically backport a pull request](https://github.com/NixOS/nix/blob/master/.github/workflows/backport.yml) to a release branch once it's merged, assign it a label of the form [`backport <branch>`](https://github.com/NixOS/nix/labels?q=backport).
Since [GitHub Actions workflows will not trigger other workflows](https://docs.github.com/en/actions/using-workflows/triggering-a-workflow#triggering-a-workflow-from-a-workflow), checks on the automatic backport need to be triggered by another actor.
This is achieved by closing and reopening the backport pull request.
This specifically affects the [`installer_test`] check.
Note that it only runs after the other tests, so it may take a while to appear.
[`installer_test`]: https://github.com/NixOS/nix/blob/895dfc656a21f6252ddf48df0d1f215effa04ecb/.github/workflows/ci.yml#L70-L91

View file

@ -1,78 +1,25 @@
from collections import defaultdict
import frontmatter
import sys
import pathlib
import textwrap
from typing import Any, Tuple
import dataclasses
import yaml
GH_ROOT = "https://github.com/"
GH_REPO_BASE = "https://github.com/NixOS/nix"
FORGEJO_REPO_BASE = "https://git.lix.systems/lix-project/lix"
FORGEJO_ROOT = "https://git.lix.systems/"
GH_BASE = "https://github.com/NixOS/nix"
FORGEJO_BASE = "https://git.lix.systems/lix-project/lix"
GERRIT_BASE = "https://gerrit.lix.systems/c/lix/+"
KNOWN_KEYS = ('synopsis', 'cls', 'issues', 'prs', 'significance', 'category', 'credits')
SIGNIFICANCECES = {
None: 0,
'significant': 10,
}
# This is just hardcoded for better validation. If you think there should be
# more of them, feel free to add more.
CATEGORIES = [
'Breaking Changes',
'Features',
'Improvements',
'Fixes',
'Packaging',
'Miscellany',
]
@dataclasses.dataclass
class AuthorInfo:
name: str
github: str | None = None
forgejo: str | None = None
display_name: str | None = None
def show_name(self) -> str:
return self.display_name or self.name
def __str__(self) -> str:
if self.forgejo:
return f'[{self.show_name()}]({FORGEJO_ROOT}{self.forgejo})'
elif self.github:
return f'[{self.show_name()}]({GH_ROOT}{self.github})'
else:
return self.show_name()
class AuthorInfoDB:
def __init__(self, author_info: dict[str, dict], throw_on_missing: bool):
self.author_info = {name: AuthorInfo(name=name, **d) for (name, d) in author_info.items()}
self.throw_on_missing = throw_on_missing
def __getitem__(self, name) -> str:
if name in self.author_info:
return str(self.author_info[name])
else:
if self.throw_on_missing:
raise Exception(f'Missing author info for author {name}')
else:
return name
def format_link(ident: str, gh_part: str, fj_part: str) -> str:
# FIXME: deprecate github as default
if ident.isdigit():
num, link, base = int(ident), f"#{ident}", f"{GH_REPO_BASE}/{gh_part}"
num, link, base = int(ident), f"#{ident}", f"{GH_BASE}/{gh_part}"
elif ident.startswith("gh#"):
num, link, base = int(ident[3:]), ident, f"{GH_REPO_BASE}/{gh_part}"
num, link, base = int(ident[3:]), ident, f"{GH_BASE}/{gh_part}"
elif ident.startswith("fj#"):
num, link, base = int(ident[3:]), ident, f"{FORGEJO_REPO_BASE}/{fj_part}"
num, link, base = int(ident[3:]), ident, f"{FORGEJO_BASE}/{fj_part}"
else:
raise Exception("unrecognized reference format", ident)
return f"[{link}]({base}/{num})"
@ -84,20 +31,28 @@ def format_pr(pr: str) -> str:
def format_cl(clid: int) -> str:
return f"[cl/{clid}]({GERRIT_BASE}/{clid})"
def plural_list(strs: list[str]) -> str:
if len(strs) <= 1:
return ''.join(strs)
else:
comma = ',' if len(strs) >= 3 else ''
return '{}{} and {}'.format(', '.join(strs[:-1]), comma, strs[-1])
def run_on_dir(d):
paths = pathlib.Path(d).glob('*.md')
entries = []
for p in paths:
try:
e = frontmatter.load(p)
if 'synopsis' not in e.metadata:
raise Exception('missing synopsis')
unknownKeys = set(e.metadata.keys()) - set(('synopsis', 'cls', 'issues', 'prs', 'significance'))
if unknownKeys:
raise Exception('unknown keys', unknownKeys)
entries.append((p, e))
except Exception as e:
e.add_note(f"in {p}")
raise
def listify(l: list | int) -> list:
if not isinstance(l, list):
return [l]
else:
return l
def listify(l: list | int) -> list:
if not isinstance(l, list):
return [l]
else:
return l
def do_category(author_info: AuthorInfoDB, entries: list[Tuple[pathlib.Path, Any]]):
for p, entry in sorted(entries, key=lambda e: (-SIGNIFICANCECES[e[1].metadata.get('significance')], e[0])):
try:
header = entry.metadata['synopsis']
@ -111,57 +66,11 @@ def do_category(author_info: AuthorInfoDB, entries: list[Tuple[pathlib.Path, Any
print(f"- {header}")
print()
print(textwrap.indent(entry.content, ' '))
if credits := listify(entry.metadata.get('credits', [])):
print()
print(textwrap.indent('Many thanks to {} for this.'.format(plural_list(list(author_info[c] for c in credits))), ' '))
print()
except Exception as e:
e.add_note(f"in {p}")
raise
def run_on_dir(author_info: AuthorInfoDB, d):
d = pathlib.Path(d)
if not d.is_dir():
raise ValueError(f'provided path {d} is not a directory')
paths = pathlib.Path(d).glob('*.md')
entries = defaultdict(list)
for p in paths:
try:
e = frontmatter.load(p)
if 'synopsis' not in e.metadata:
raise Exception('missing synopsis')
unknownKeys = set(e.metadata.keys()) - set(KNOWN_KEYS)
if unknownKeys:
raise Exception('unknown keys', unknownKeys)
category = e.metadata.get('category', 'Miscellany')
if category not in CATEGORIES:
raise Exception('unknown category', category)
entries[category].append((p, e))
except Exception as e:
e.add_note(f"in {p}")
raise
for category in CATEGORIES:
if entries[category]:
print('\n#', category)
do_category(author_info, entries[category])
def main():
import argparse
ap = argparse.ArgumentParser()
ap.add_argument('--change-authors', help='File name of the change authors metadata YAML file', type=argparse.FileType('r'))
ap.add_argument('dirs', help='Directories to run on', nargs='+')
args = ap.parse_args()
author_info = AuthorInfoDB(yaml.safe_load(args.change_authors), throw_on_missing=True) \
if args.change_authors \
else AuthorInfoDB({}, throw_on_missing=False)
for d in args.dirs:
run_on_dir(author_info, d)
if __name__ == '__main__':
main()
for d in sys.argv[1:]:
run_on_dir(d)

View file

@ -152,7 +152,7 @@ section_title="Release $version_full ($DATE)"
# TODO add minor number, and append?
echo "# $section_title"
echo
build-release-notes --change-authors doc/manual/change-authors.yml doc/manual/rl-next
build-release-notes doc/manual/rl-next
) | tee -a $file
log "Wrote $file"

View file

@ -0,0 +1,196 @@
# Nix release process
## Release artifacts
The release process is intended to create the following for each
release:
* A Git tag
* Binary tarballs in https://releases.nixos.org/?prefix=nix/
* Docker images
* Closures in https://cache.nixos.org
* (Optionally) Updated `fallback-paths.nix` in Nixpkgs
* An updated manual on https://nixos.org/manual/nix/stable/
## Creating a new release from the `master` branch
* Make sure that the [Hydra `master` jobset](https://hydra.nixos.org/jobset/nix/master) succeeds.
* In a checkout of the Nix repo, make sure you're on `master` and run
`git pull`.
* Compile the release notes by running
```console
$ git checkout -b release-notes
$ VERSION=X.YY ./maintainers/release-notes
```
where `X.YY` is *without* the patch level, e.g. `2.12` rather than ~~`2.12.0`~~.
A commit is created.
* Proof-read / edit / rearrange the release notes if needed. Breaking changes
and highlights should go to the top.
* Push.
```console
$ git push --set-upstream $REMOTE release-notes
```
* Create a PR for `release-notes`.
* Wait for the PR to be merged.
* Create a branch for the release:
```console
$ git checkout master
$ git pull
$ git checkout -b $VERSION-maintenance
```
* Mark the release as official:
```console
$ sed -e 's/officialRelease = false;/officialRelease = true;/' -i flake.nix
$ sed -e '/rl-next.md/ d' -i doc/manual/src/SUMMARY.md
```
This removes the link to `rl-next.md` from the manual and sets
`officialRelease = true` in `flake.nix`.
* Commit
* Push the release branch:
```console
$ git push --set-upstream origin $VERSION-maintenance
```
* Create a jobset for the release branch on Hydra as follows:
* Go to the jobset of the previous release
(e.g. https://hydra.nixos.org/jobset/nix/maintenance-2.11).
* Select `Actions -> Clone this jobset`.
* Set identifier to `maintenance-$VERSION`.
* Set description to `$VERSION release branch`.
* Set flake URL to `github:NixOS/nix/$VERSION-maintenance`.
* Hit `Create jobset`.
* Wait for the new jobset to evaluate and build. If impatient, go to
the evaluation and select `Actions -> Bump builds to front of
queue`.
* When the jobset evaluation has succeeded building, take note of the
evaluation ID (e.g. `1780832` in
`https://hydra.nixos.org/eval/1780832`).
* Tag the release and upload the release artifacts to
[`releases.nixos.org`](https://releases.nixos.org/) and [Docker Hub](https://hub.docker.com/):
```console
$ IS_LATEST=1 ./maintainers/upload-release.pl <EVAL-ID>
```
Note: `IS_LATEST=1` causes the `latest-release` branch to be
force-updated. This is used by the `nixos.org` website to get the
[latest Nix manual](https://nixos.org/manual/nixpkgs/unstable/).
TODO: This script requires the right AWS credentials. Document.
TODO: This script currently requires a
`/home/eelco/Dev/nix-pristine`.
TODO: trigger nixos.org netlify: https://docs.netlify.com/configure-builds/build-hooks/
* Prepare for the next point release by editing `.version` to
e.g.
```console
$ echo 2.12.1 > .version
$ git commit -a -m 'Bump version'
$ git push
```
Commit and push this to the maintenance branch.
* Bump the version of `master`:
```console
$ git checkout master
$ git pull
$ NEW_VERSION=2.13.0
$ echo $NEW_VERSION > .version
$ git checkout -b bump-$NEW_VERSION
$ git commit -a -m 'Bump version'
$ git push --set-upstream origin bump-$NEW_VERSION
```
Make a pull request and auto-merge it.
* Create a milestone for the next release, move all unresolved issues
from the previous milestone, and close the previous milestone. Set
the date for the next milestone 6 weeks from now.
* Create a backport label.
* Post an [announcement on Discourse](https://discourse.nixos.org/c/announcements/8), including the contents of
`rl-$VERSION.md`.
## Creating a point release
* Checkout.
```console
$ git checkout XX.YY-maintenance
```
* Determine the next patch version.
```console
$ export VERSION=XX.YY.ZZ
```
* Update release notes.
```console
$ ./maintainers/release-notes
```
* Push.
```console
$ git push
```
* Wait for the desired evaluation of the maintenance jobset to finish
building.
* Run
```console
$ IS_LATEST=1 ./maintainers/upload-release.pl <EVAL-ID>
```
Omit `IS_LATEST=1` when creating a point release that is not on the
most recent stable branch. This prevents `nixos.org` to going back
to an older release.
* Bump the version number of the release branch as above (e.g. to
`2.12.2`).
## Recovering from mistakes
`upload-release.pl` should be idempotent. For instance a wrong `IS_LATEST` value can be fixed that way, by running the script on the actual latest release.

256
maintainers/upload-release.pl Executable file
View file

@ -0,0 +1,256 @@
#! /usr/bin/env nix-shell
#! nix-shell -i perl -p perl perlPackages.LWPUserAgent perlPackages.LWPProtocolHttps perlPackages.FileSlurp perlPackages.NetAmazonS3 gnupg1
use strict;
use Data::Dumper;
use File::Basename;
use File::Path;
use File::Slurp;
use File::Copy;
use JSON::PP;
use LWP::UserAgent;
use Net::Amazon::S3;
my $evalId = $ARGV[0] or die "Usage: $0 EVAL-ID\n";
my $releasesBucketName = "nix-releases";
my $channelsBucketName = "nix-channels";
my $TMPDIR = $ENV{'TMPDIR'} // "/tmp";
my $isLatest = ($ENV{'IS_LATEST'} // "") eq "1";
# FIXME: cut&paste from nixos-channel-scripts.
sub fetch {
my ($url, $type) = @_;
my $ua = LWP::UserAgent->new;
$ua->default_header('Accept', $type) if defined $type;
my $response = $ua->get($url);
die "could not download $url: ", $response->status_line, "\n" unless $response->is_success;
return $response->decoded_content;
}
my $evalUrl = "https://hydra.nixos.org/eval/$evalId";
my $evalInfo = decode_json(fetch($evalUrl, 'application/json'));
#print Dumper($evalInfo);
my $flakeUrl = $evalInfo->{flake} or die;
my $flakeInfo = decode_json(`nix flake metadata --json "$flakeUrl"` or die);
my $nixRev = $flakeInfo->{revision} or die;
my $buildInfo = decode_json(fetch("$evalUrl/job/build.x86_64-linux", 'application/json'));
#print Dumper($buildInfo);
my $releaseName = $buildInfo->{nixname};
$releaseName =~ /nix-(.*)$/ or die;
my $version = $1;
print STDERR "Flake URL is $flakeUrl, Nix revision is $nixRev, version is $version\n";
my $releaseDir = "nix/$releaseName";
my $tmpDir = "$TMPDIR/nix-release/$releaseName";
File::Path::make_path($tmpDir);
my $narCache = "$TMPDIR/nar-cache";
File::Path::make_path($narCache);
my $binaryCache = "https://cache.nixos.org/?local-nar-cache=$narCache";
# S3 setup.
my $aws_access_key_id = $ENV{'AWS_ACCESS_KEY_ID'} or die "No AWS_ACCESS_KEY_ID given.";
my $aws_secret_access_key = $ENV{'AWS_SECRET_ACCESS_KEY'} or die "No AWS_SECRET_ACCESS_KEY given.";
my $s3 = Net::Amazon::S3->new(
{ aws_access_key_id => $aws_access_key_id,
aws_secret_access_key => $aws_secret_access_key,
retry => 1,
host => "s3-eu-west-1.amazonaws.com",
});
my $releasesBucket = $s3->bucket($releasesBucketName) or die;
my $s3_us = Net::Amazon::S3->new(
{ aws_access_key_id => $aws_access_key_id,
aws_secret_access_key => $aws_secret_access_key,
retry => 1,
});
my $channelsBucket = $s3_us->bucket($channelsBucketName) or die;
sub getStorePath {
my ($jobName, $output) = @_;
my $buildInfo = decode_json(fetch("$evalUrl/job/$jobName", 'application/json'));
return $buildInfo->{buildoutputs}->{$output or "out"}->{path} or die "cannot get store path for '$jobName'";
}
sub copyManual {
my $manual = getStorePath("build.x86_64-linux", "doc");
print "$manual\n";
my $manualNar = "$tmpDir/$releaseName-manual.nar.xz";
print "$manualNar\n";
unless (-e $manualNar) {
system("NIX_REMOTE=$binaryCache nix store dump-path '$manual' | xz > '$manualNar'.tmp") == 0
or die "unable to fetch $manual\n";
rename("$manualNar.tmp", $manualNar) or die;
}
unless (-e "$tmpDir/manual") {
system("xz -d < '$manualNar' | nix-store --restore $tmpDir/manual.tmp") == 0
or die "unable to unpack $manualNar\n";
rename("$tmpDir/manual.tmp/share/doc/nix/manual", "$tmpDir/manual") or die;
system("rm -rf '$tmpDir/manual.tmp'") == 0 or die;
}
system("aws s3 sync '$tmpDir/manual' s3://$releasesBucketName/$releaseDir/manual") == 0
or die "syncing manual to S3\n";
}
copyManual;
sub downloadFile {
my ($jobName, $productNr, $dstName) = @_;
my $buildInfo = decode_json(fetch("$evalUrl/job/$jobName", 'application/json'));
#print STDERR "$jobName: ", Dumper($buildInfo), "\n";
my $srcFile = $buildInfo->{buildproducts}->{$productNr}->{path} or die "job '$jobName' lacks product $productNr\n";
$dstName //= basename($srcFile);
my $tmpFile = "$tmpDir/$dstName";
if (!-e $tmpFile) {
print STDERR "downloading $srcFile to $tmpFile...\n";
my $fileInfo = decode_json(`NIX_REMOTE=$binaryCache nix store ls --json '$srcFile'`);
$srcFile = $fileInfo->{target} if $fileInfo->{type} eq 'symlink';
#print STDERR $srcFile, " ", Dumper($fileInfo), "\n";
system("NIX_REMOTE=$binaryCache nix store cat '$srcFile' > '$tmpFile'.tmp") == 0
or die "unable to fetch $srcFile\n";
rename("$tmpFile.tmp", $tmpFile) or die;
}
my $sha256_expected = $buildInfo->{buildproducts}->{$productNr}->{sha256hash};
my $sha256_actual = `nix hash file --base16 --type sha256 '$tmpFile'`;
chomp $sha256_actual;
if (defined($sha256_expected) && $sha256_expected ne $sha256_actual) {
print STDERR "file $tmpFile is corrupt, got $sha256_actual, expected $sha256_expected\n";
exit 1;
}
write_file("$tmpFile.sha256", $sha256_actual);
return $sha256_expected;
}
downloadFile("binaryTarball.i686-linux", "1");
downloadFile("binaryTarball.x86_64-linux", "1");
downloadFile("binaryTarball.aarch64-linux", "1");
downloadFile("binaryTarball.x86_64-darwin", "1");
downloadFile("binaryTarball.aarch64-darwin", "1");
downloadFile("binaryTarballCross.x86_64-linux.armv6l-linux", "1");
downloadFile("binaryTarballCross.x86_64-linux.armv7l-linux", "1");
downloadFile("installerScript", "1");
# Upload docker images to dockerhub.
my $dockerManifest = "";
my $dockerManifestLatest = "";
for my $platforms (["x86_64-linux", "amd64"], ["aarch64-linux", "arm64"]) {
my $system = $platforms->[0];
my $dockerPlatform = $platforms->[1];
my $fn = "nix-$version-docker-image-$dockerPlatform.tar.gz";
downloadFile("dockerImage.$system", "1", $fn);
print STDERR "loading docker image for $dockerPlatform...\n";
system("docker load -i $tmpDir/$fn") == 0 or die;
my $tag = "nixos/nix:$version-$dockerPlatform";
my $latestTag = "nixos/nix:latest-$dockerPlatform";
print STDERR "tagging $version docker image for $dockerPlatform...\n";
system("docker tag nix:$version $tag") == 0 or die;
if ($isLatest) {
print STDERR "tagging latest docker image for $dockerPlatform...\n";
system("docker tag nix:$version $latestTag") == 0 or die;
}
print STDERR "pushing $version docker image for $dockerPlatform...\n";
system("docker push -q $tag") == 0 or die;
if ($isLatest) {
print STDERR "pushing latest docker image for $dockerPlatform...\n";
system("docker push -q $latestTag") == 0 or die;
}
$dockerManifest .= " --amend $tag";
$dockerManifestLatest .= " --amend $latestTag"
}
print STDERR "creating multi-platform docker manifest...\n";
system("docker manifest rm nixos/nix:$version");
system("docker manifest create nixos/nix:$version $dockerManifest") == 0 or die;
if ($isLatest) {
print STDERR "creating latest multi-platform docker manifest...\n";
system("docker manifest rm nixos/nix:latest");
system("docker manifest create nixos/nix:latest $dockerManifestLatest") == 0 or die;
}
print STDERR "pushing multi-platform docker manifest...\n";
system("docker manifest push nixos/nix:$version") == 0 or die;
if ($isLatest) {
print STDERR "pushing latest multi-platform docker manifest...\n";
system("docker manifest push nixos/nix:latest") == 0 or die;
}
# Upload nix-fallback-paths.nix.
write_file("$tmpDir/fallback-paths.nix",
"{\n" .
" x86_64-linux = \"" . getStorePath("build.x86_64-linux") . "\";\n" .
" i686-linux = \"" . getStorePath("build.i686-linux") . "\";\n" .
" aarch64-linux = \"" . getStorePath("build.aarch64-linux") . "\";\n" .
" x86_64-darwin = \"" . getStorePath("build.x86_64-darwin") . "\";\n" .
" aarch64-darwin = \"" . getStorePath("build.aarch64-darwin") . "\";\n" .
"}\n");
# Upload release files to S3.
for my $fn (glob "$tmpDir/*") {
my $name = basename($fn);
next if $name eq "manual";
my $dstKey = "$releaseDir/" . $name;
unless (defined $releasesBucket->head_key($dstKey)) {
print STDERR "uploading $fn to s3://$releasesBucketName/$dstKey...\n";
my $configuration = ();
$configuration->{content_type} = "application/octet-stream";
if ($fn =~ /.sha256|install|\.nix$/) {
$configuration->{content_type} = "text/plain";
}
$releasesBucket->add_key_filename($dstKey, $fn, $configuration)
or die $releasesBucket->err . ": " . $releasesBucket->errstr;
}
}
# Update the "latest" symlink.
$channelsBucket->add_key(
"nix-latest/install", "",
{ "x-amz-website-redirect-location" => "https://releases.nixos.org/$releaseDir/install" })
or die $channelsBucket->err . ": " . $channelsBucket->errstr
if $isLatest;
# Tag the release in Git.
chdir("/home/eelco/Dev/nix-pristine") or die;
system("git remote update origin") == 0 or die;
system("git tag --force --sign $version $nixRev -m 'Tagging release $version'") == 0 or die;
system("git push --tags") == 0 or die;
system("git push --force-with-lease origin $nixRev:refs/heads/latest-release") == 0 or die if $isLatest;

View file

@ -1,40 +0,0 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname -- "$0")/.."
# This script uploads the Lix manual to the Lix s3 store.
# It expects credentials to be configured like so:
#
# ~/.aws/credentials:
#
# [default]
# aws_access_key_id = SOMEACCESSKEY
# aws_secret_access_key = SOMESECRETKEY
#
# default can also be replaced by some other string if AWS_PROFILE is set in
# environment.
#
# See: https://rclone.org/s3/#authentication
#
# To obtain such a key, log into the garage host and run:
# (obtain GARAGE_RPC_SECRET into environment perhaps by systemctl cat garage)
# garage key create SOME-KEY-NAME
# garage bucket allow --read --write docs --key SOME-KEY-NAME
if [[ ! -f result-doc/share/doc/nix/manual/index.html ]]; then
echo -e "result-doc does not appear to contain a Lix manual. You can build one with:\n nix build '.#default^*'" >&2
exit 1
fi
# --checksum: https://rclone.org/s3/#avoiding-head-requests-to-read-the-modification-time
# By default rclone uses the modification time to determine if something needs
# syncing. This is actually very bad for our use case, since we have small
# files that have meaningless (Unix epoch) local modification time data. We can
# make it go both 16x faster and more correct by using md5s instead.
rclone \
--config doc/manual/rclone.conf \
-vv \
sync \
--checksum \
result-doc/share/doc/nix/manual/ lix-docs:docs/manual/nightly/

View file

@ -182,9 +182,6 @@ deps += cpuid
# seccomp only makes sense on Linux
seccomp_required = is_linux ? get_option('seccomp-sandboxing') : false
seccomp = dependency('libseccomp', 'seccomp', required : seccomp_required, version : '>=2.5.5')
if is_linux and not seccomp.found()
warning('Sandbox security is reduced because libseccomp has not been found! Please provide libseccomp if it supports your CPU architecture.')
endif
configdata += {
'HAVE_SECCOMP': seccomp.found().to_int(),
}
@ -203,7 +200,7 @@ openssl = dependency('libcrypto', 'openssl', required : true)
deps += openssl
aws_sdk = dependency('aws-cpp-sdk-core', required : false)
aws_sdk_transfer = dependency('aws-cpp-sdk-transfer', required : aws_sdk.found(), fallback : ['aws_sdk', 'aws_cpp_sdk_transfer_dep'])
aws_sdk_transfer = dependency('aws-cpp-sdk-transfer', required : aws_sdk.found())
if aws_sdk.found()
# The AWS pkg-config adds -std=c++11.
# https://github.com/aws/aws-sdk-cpp/issues/2673
@ -230,7 +227,7 @@ if aws_sdk.found()
)
endif
aws_s3 = dependency('aws-cpp-sdk-s3', required : aws_sdk.found(), fallback : ['aws_sdk', 'aws_cpp_sdk_s3_dep'])
aws_s3 = dependency('aws-cpp-sdk-s3', required : false)
if aws_s3.found()
# The AWS pkg-config adds -std=c++11.
# https://github.com/aws/aws-sdk-cpp/issues/2673
@ -398,21 +395,7 @@ config_h = configure_file(
output : 'config.h',
)
install_headers(config_h, subdir : 'lix')
# FIXME: not using the pkg-config module because it creates way too many deps
# while meson migration is in progress, and we want to not include boost here
configure_file(
input : 'src/lix-base.pc.in',
output : 'lix-base.pc',
install_dir : libdir / 'pkgconfig',
configuration : {
'prefix' : prefix,
'libdir' : libdir,
'includedir' : includedir,
'PACKAGE_VERSION' : meson.project_version(),
},
)
install_headers(config_h, subdir : 'nix')
add_project_arguments(
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
@ -422,8 +405,6 @@ add_project_arguments(
'-Wimplicit-fallthrough',
'-Werror=switch',
'-Werror=switch-enum',
'-Wdeprecated-copy',
'-Wignored-qualifiers',
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
# at ~1% overhead in `nix search`.
#

View file

@ -47,4 +47,4 @@ fi
# Intentionally not using -f.
# If these files don't exist then our assumptions have been violated and we should fail.
rm -v "$includedir/lix/libexpr/parser-tab.cc" "$includedir/lix/libexpr/lexer-tab.cc"
rm -v "$includedir/nix/parser-tab.cc" "$includedir/nix/lexer-tab.cc"

1
misc/bash/local.mk Normal file
View file

@ -0,0 +1 @@
$(eval $(call install-file-as, $(d)/completion.sh, $(datarootdir)/bash-completion/completions/nix, 0644))

Some files were not shown because too many files have changed in this diff Show more