Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0baf7dc25e | ||
|
|
79ff84e655 | ||
|
|
9b1b4590d0 | ||
|
|
6b5c52b244 | ||
|
|
6609f75a70 | ||
|
|
03aaabce24 | ||
|
|
34d897e0b6 | ||
|
|
03b4a4f7f1 | ||
|
|
10254f7cf7 | ||
|
|
ca4aec6e9a | ||
|
|
d7eade3649 |
@@ -13,5 +13,4 @@
|
||||
(eval . (c-set-offset 'arglist-cont-nonempty '+))
|
||||
(eval . (c-set-offset 'substatement-open 0))
|
||||
(eval . (c-set-offset 'access-label '-))
|
||||
(eval . (c-set-offset 'inlambda 0))
|
||||
)))
|
||||
|
||||
27
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<!--
|
||||
|
||||
# Filing a Nix issue
|
||||
|
||||
*WAIT* Are you sure you're filing your issue in the right repository?
|
||||
|
||||
We appreciate you taking the time to tell us about issues you encounter, but routing the issue to the right place will get you help sooner and save everyone time.
|
||||
|
||||
This is the Nix repository, and issues here should be about Nix the build and package management *_tool_*.
|
||||
|
||||
If you have a problem with a specific package on NixOS or when using Nix, you probably want to file an issue with _nixpkgs_, whose issue tracker is over at https://github.com/NixOS/nixpkgs/issues.
|
||||
|
||||
Examples of _Nix_ issues:
|
||||
|
||||
- Nix segfaults when I run `nix-build -A blahblah`
|
||||
- The Nix language needs a new builtin: `builtins.foobar`
|
||||
- Regression in the behavior of `nix-env` in Nix 2.0
|
||||
|
||||
Examples of _nixpkgs_ issues:
|
||||
|
||||
- glibc is b0rked on aarch64
|
||||
- chromium in NixOS doesn't support U2F but google-chrome does!
|
||||
- The OpenJDK package on macOS is missing a key component
|
||||
|
||||
Chances are if you're a newcomer to the Nix world, you'll probably want the [nixpkgs tracker](https://github.com/NixOS/nixpkgs/issues). It also gets a lot more eyeball traffic so you'll probably get a response a lot more quickly.
|
||||
|
||||
-->
|
||||
32
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -1,32 +0,0 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
If you have a problem with a specific package or NixOS,
|
||||
you probably want to file an issue at https://github.com/NixOS/nixpkgs/issues.
|
||||
|
||||
**Steps To Reproduce**
|
||||
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**`nix-env --version` output**
|
||||
|
||||
**Additional context**
|
||||
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -1,20 +0,0 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: improvement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
14
.github/workflows/test.yml
vendored
@@ -1,14 +0,0 @@
|
||||
name: "Test"
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
jobs:
|
||||
tests:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: cachix/install-nix-action@v8
|
||||
- run: nix-build release.nix --arg nix '{ outPath = ./.; revCount = 123; shortRev = "abcdefgh"; }' --arg systems '[ builtins.currentSystem ]' -A installerScript -A perlBindings
|
||||
16
.gitignore
vendored
@@ -4,10 +4,9 @@ perl/Makefile.config
|
||||
# /
|
||||
/aclocal.m4
|
||||
/autom4te.cache
|
||||
/precompiled-headers.h.gch
|
||||
/precompiled-headers.h.pch
|
||||
/config.*
|
||||
/configure
|
||||
/nix.spec
|
||||
/stamp-h1
|
||||
/svn-revision
|
||||
/libtool
|
||||
@@ -47,10 +46,7 @@ perl/Makefile.config
|
||||
/src/libexpr/nix.tbl
|
||||
|
||||
# /src/libstore/
|
||||
*.gen.*
|
||||
|
||||
# /src/libutil/
|
||||
/src/libutil/tests/libutil-tests
|
||||
/src/libstore/*.gen.hh
|
||||
|
||||
/src/nix/nix
|
||||
|
||||
@@ -78,8 +74,6 @@ perl/Makefile.config
|
||||
|
||||
/src/nix-copy-closure/nix-copy-closure
|
||||
|
||||
/src/error-demo/error-demo
|
||||
|
||||
/src/build-remote/build-remote
|
||||
|
||||
# /tests/
|
||||
@@ -87,10 +81,6 @@ perl/Makefile.config
|
||||
/tests/common.sh
|
||||
/tests/dummy
|
||||
/tests/result*
|
||||
/tests/restricted-innocent
|
||||
/tests/shell
|
||||
/tests/shell.drv
|
||||
/tests/config.nix
|
||||
|
||||
# /tests/lang/
|
||||
/tests/lang/*.out
|
||||
@@ -124,5 +114,3 @@ GPATH
|
||||
GRTAGS
|
||||
GSYMS
|
||||
GTAGS
|
||||
|
||||
nix-rust/target
|
||||
|
||||
2
.travis.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
os: osx
|
||||
script: ./tests/install-darwin.sh
|
||||
10
Makefile
@@ -1,10 +1,7 @@
|
||||
makefiles = \
|
||||
mk/precompiled-headers.mk \
|
||||
local.mk \
|
||||
src/libutil/local.mk \
|
||||
src/libutil/tests/local.mk \
|
||||
src/libstore/local.mk \
|
||||
src/libfetchers/local.mk \
|
||||
src/libmain/local.mk \
|
||||
src/libexpr/local.mk \
|
||||
src/nix/local.mk \
|
||||
@@ -18,16 +15,15 @@ makefiles = \
|
||||
tests/local.mk \
|
||||
tests/plugins/local.mk
|
||||
|
||||
GLOBAL_CXXFLAGS += -g -Wall -include config.h
|
||||
|
||||
-include Makefile.config
|
||||
|
||||
OPTIMIZE = 1
|
||||
|
||||
ifeq ($(OPTIMIZE), 1)
|
||||
GLOBAL_CFLAGS += -O3
|
||||
GLOBAL_CXXFLAGS += -O3
|
||||
else
|
||||
GLOBAL_CXXFLAGS += -O0
|
||||
endif
|
||||
|
||||
include mk/lib.mk
|
||||
|
||||
GLOBAL_CXXFLAGS += -g -Wall -include config.h -std=c++17
|
||||
|
||||
@@ -1,44 +1,38 @@
|
||||
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@
|
||||
EDITLINE_LIBS = @EDITLINE_LIBS@
|
||||
ENABLE_S3 = @ENABLE_S3@
|
||||
GTEST_LIBS = @GTEST_LIBS@
|
||||
HAVE_SECCOMP = @HAVE_SECCOMP@
|
||||
HAVE_SODIUM = @HAVE_SODIUM@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBARCHIVE_LIBS = @LIBARCHIVE_LIBS@
|
||||
LIBBROTLI_LIBS = @LIBBROTLI_LIBS@
|
||||
HAVE_READLINE = @HAVE_READLINE@
|
||||
HAVE_SECCOMP = @HAVE_SECCOMP@
|
||||
LIBCURL_LIBS = @LIBCURL_LIBS@
|
||||
LIBLZMA_LIBS = @LIBLZMA_LIBS@
|
||||
OPENSSL_LIBS = @OPENSSL_LIBS@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
SODIUM_LIBS = @SODIUM_LIBS@
|
||||
LIBLZMA_LIBS = @LIBLZMA_LIBS@
|
||||
SQLITE3_LIBS = @SQLITE3_LIBS@
|
||||
LIBBROTLI_LIBS = @LIBBROTLI_LIBS@
|
||||
EDITLINE_LIBS = @EDITLINE_LIBS@
|
||||
bash = @bash@
|
||||
bindir = @bindir@
|
||||
lsof = @lsof@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
doc_generate = @doc_generate@
|
||||
docdir = @docdir@
|
||||
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@
|
||||
doc_generate = @doc_generate@
|
||||
xmllint = @xmllint@
|
||||
xsltproc = @xsltproc@
|
||||
|
||||
62
README.md
@@ -1,54 +1,22 @@
|
||||
# Nix
|
||||
Nix, the purely functional package manager
|
||||
------------------------------------------
|
||||
|
||||
[](https://opencollective.com/nixos)
|
||||
[](https://github.com/NixOS/nix/actions)
|
||||
Nix is a new take on package management that is fairly unique. Because of its
|
||||
purity aspects, a lot of issues found in traditional package managers don't
|
||||
appear with Nix.
|
||||
|
||||
Nix is a powerful package manager for Linux and other Unix systems that makes package
|
||||
management reliable and reproducible. Please refer to the [Nix manual](https://nixos.org/nix/manual)
|
||||
for more details.
|
||||
To find out more about the tool, usage and installation instructions, please
|
||||
read the manual, which is available on the Nix website at
|
||||
<http://nixos.org/nix/manual>.
|
||||
|
||||
## Installation
|
||||
## Contributing
|
||||
|
||||
On Linux and macOS the easiest way to Install Nix is to run the following shell command
|
||||
(as a user other than root):
|
||||
|
||||
```
|
||||
$ curl -L https://nixos.org/nix/install | sh
|
||||
```
|
||||
|
||||
Information on additional installation methods is available on the [Nix download page](https://nixos.org/download.html).
|
||||
|
||||
## Building And Developing
|
||||
|
||||
### Building Nix
|
||||
|
||||
You can build Nix using one of the targets provided by [release.nix](./release.nix):
|
||||
|
||||
```
|
||||
$ nix-build ./release.nix -A build.aarch64-linux
|
||||
$ nix-build ./release.nix -A build.x86_64-darwin
|
||||
$ nix-build ./release.nix -A build.i686-linux
|
||||
$ nix-build ./release.nix -A build.x86_64-linux
|
||||
```
|
||||
|
||||
### Development Environment
|
||||
|
||||
You can use the provided `shell.nix` to get a working development environment:
|
||||
|
||||
```
|
||||
$ nix-shell
|
||||
$ ./bootstrap.sh
|
||||
$ ./configure
|
||||
$ make
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Nix manual](https://nixos.org/nix/manual)
|
||||
- [Nix jobsets on hydra.nixos.org](https://hydra.nixos.org/project/nix)
|
||||
- [NixOS Discourse](https://discourse.nixos.org/)
|
||||
- [IRC - #nixos on freenode.net](irc://irc.freenode.net/#nixos)
|
||||
Take a look at the [Hacking Section](http://nixos.org/nix/manual/#chap-hacking)
|
||||
of the manual. It helps you to get started with building Nix from source.
|
||||
|
||||
## License
|
||||
|
||||
Nix is released under the [LGPL v2.1](./COPYING).
|
||||
Nix is released under the LGPL v2.1
|
||||
|
||||
This product includes software developed by the OpenSSL Project for
|
||||
use in the [OpenSSL Toolkit](http://www.OpenSSL.org/).
|
||||
|
||||
108
configure.ac
@@ -1,5 +1,4 @@
|
||||
AC_INIT(nix, m4_esyscmd([bash -c "echo -n $(cat ./.version)$VERSION_SUFFIX"]))
|
||||
AC_CONFIG_MACRO_DIRS([m4])
|
||||
AC_INIT(nix, m4_esyscmd([bash -c "echo -n $(cat ./version)$VERSION_SUFFIX"]))
|
||||
AC_CONFIG_SRCDIR(README.md)
|
||||
AC_CONFIG_AUX_DIR(config)
|
||||
|
||||
@@ -43,25 +42,13 @@ esac
|
||||
|
||||
AC_MSG_RESULT($system)
|
||||
AC_SUBST(system)
|
||||
AC_DEFINE_UNQUOTED(SYSTEM, ["$system"], [platform identifier ('cpu-os')])
|
||||
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
|
||||
|
||||
|
||||
CFLAGS=
|
||||
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
|
||||
if test "$sys_name" = sunos; then
|
||||
@@ -70,6 +57,18 @@ if test "$sys_name" = sunos; then
|
||||
fi
|
||||
|
||||
|
||||
CFLAGS=
|
||||
CXXFLAGS=
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CPP
|
||||
AX_CXX_COMPILE_STDCXX_14
|
||||
|
||||
|
||||
# Use 64-bit file system calls so that we can support files > 2 GiB.
|
||||
AC_SYS_LARGEFILE
|
||||
|
||||
|
||||
# Check for pubsetbuf.
|
||||
AC_MSG_CHECKING([for pubsetbuf])
|
||||
AC_LANG_PUSH(C++)
|
||||
@@ -117,15 +116,26 @@ fi
|
||||
])
|
||||
|
||||
NEED_PROG(bash, bash)
|
||||
NEED_PROG(patch, patch)
|
||||
AC_PATH_PROG(xmllint, xmllint, false)
|
||||
AC_PATH_PROG(xsltproc, xsltproc, false)
|
||||
AC_PATH_PROG(flex, flex, false)
|
||||
AC_PATH_PROG(bison, bison, false)
|
||||
NEED_PROG(sed, sed)
|
||||
NEED_PROG(tar, tar)
|
||||
NEED_PROG(bzip2, bzip2)
|
||||
NEED_PROG(gzip, gzip)
|
||||
NEED_PROG(xz, xz)
|
||||
AC_PATH_PROG(dot, dot)
|
||||
AC_PATH_PROG(lsof, lsof, lsof)
|
||||
|
||||
|
||||
AC_SUBST(coreutils, [$(dirname $(type -p cat))])
|
||||
NEED_PROG(cat, cat)
|
||||
NEED_PROG(tr, tr)
|
||||
AC_ARG_WITH(coreutils-bin, AC_HELP_STRING([--with-coreutils-bin=PATH],
|
||||
[path of cat, mkdir, etc.]),
|
||||
coreutils=$withval, coreutils=$(dirname $cat))
|
||||
AC_SUBST(coreutils)
|
||||
|
||||
|
||||
AC_ARG_WITH(store-dir, AC_HELP_STRING([--with-store-dir=PATH],
|
||||
@@ -134,42 +144,7 @@ AC_ARG_WITH(store-dir, AC_HELP_STRING([--with-store-dir=PATH],
|
||||
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
|
||||
LIBS="-latomic $LIBS"
|
||||
fi
|
||||
|
||||
PKG_PROG_PKG_CONFIG
|
||||
|
||||
AC_ARG_ENABLE(shared, AC_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.
|
||||
# Look for OpenSSL, a required dependency.
|
||||
PKG_CHECK_MODULES([OPENSSL], [libcrypto], [CXXFLAGS="$OPENSSL_CFLAGS $CXXFLAGS"])
|
||||
|
||||
|
||||
@@ -178,26 +153,17 @@ AC_CHECK_LIB([bz2], [BZ2_bzWriteOpen], [true],
|
||||
[AC_MSG_ERROR([Nix requires libbz2, which is part of bzip2. See https://web.archive.org/web/20180624184756/http://www.bzip.org/.])])
|
||||
AC_CHECK_HEADERS([bzlib.h], [true],
|
||||
[AC_MSG_ERROR([Nix requires libbz2, which is part of bzip2. See https://web.archive.org/web/20180624184756/http://www.bzip.org/.])])
|
||||
# Checks for libarchive
|
||||
PKG_CHECK_MODULES([LIBARCHIVE], [libarchive >= 3.1.2], [CXXFLAGS="$LIBARCHIVE_CFLAGS $CXXFLAGS"])
|
||||
|
||||
|
||||
# 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.])])
|
||||
])
|
||||
PKG_CHECK_MODULES([EDITLINE], [libeditline], [CXXFLAGS="$EDITLINE_CFLAGS $CXXFLAGS"])
|
||||
|
||||
# Look for libsodium, an optional dependency.
|
||||
PKG_CHECK_MODULES([SODIUM], [libsodium],
|
||||
@@ -206,15 +172,12 @@ PKG_CHECK_MODULES([SODIUM], [libsodium],
|
||||
have_sodium=1], [have_sodium=])
|
||||
AC_SUBST(HAVE_SODIUM, [$have_sodium])
|
||||
|
||||
|
||||
# Look for liblzma, a required dependency.
|
||||
PKG_CHECK_MODULES([LIBLZMA], [liblzma], [CXXFLAGS="$LIBLZMA_CFLAGS $CXXFLAGS"])
|
||||
AC_CHECK_LIB([lzma], [lzma_stream_encoder_mt],
|
||||
[AC_DEFINE([HAVE_LZMA_MT], [1], [xz multithreaded compression support])])
|
||||
|
||||
# Look for zlib, a required dependency.
|
||||
PKG_CHECK_MODULES([ZLIB], [zlib], [CXXFLAGS="$ZLIB_CFLAGS $CXXFLAGS"])
|
||||
AC_CHECK_HEADER([zlib.h],[:],[AC_MSG_ERROR([could not find the zlib.h header])])
|
||||
LDFLAGS="-lz $LDFLAGS"
|
||||
|
||||
# Look for libbrotli{enc,dec}.
|
||||
PKG_CHECK_MODULES([LIBBROTLI], [libbrotlienc libbrotlidec], [CXXFLAGS="$LIBBROTLI_CFLAGS $CXXFLAGS"])
|
||||
@@ -257,8 +220,8 @@ fi
|
||||
|
||||
# Whether to use the Boehm garbage collector.
|
||||
AC_ARG_ENABLE(gc, AC_HELP_STRING([--enable-gc],
|
||||
[enable garbage collection in the Nix expression evaluator (requires Boehm GC) [default=yes]]),
|
||||
gc=$enableval, gc=yes)
|
||||
[enable garbage collection in the Nix expression evaluator (requires Boehm GC) [default=no]]),
|
||||
gc=$enableval, gc=no)
|
||||
if test "$gc" = yes; then
|
||||
PKG_CHECK_MODULES([BDW_GC], [bdw-gc])
|
||||
CXXFLAGS="$BDW_GC_CFLAGS $CXXFLAGS"
|
||||
@@ -266,10 +229,6 @@ if test "$gc" = yes; then
|
||||
fi
|
||||
|
||||
|
||||
# Look for gtest.
|
||||
PKG_CHECK_MODULES([GTEST], [gtest_main])
|
||||
|
||||
|
||||
# documentation generation switch
|
||||
AC_ARG_ENABLE(doc-gen, AC_HELP_STRING([--disable-doc-gen],
|
||||
[disable documentation generation]),
|
||||
@@ -308,6 +267,7 @@ AC_ARG_WITH(sandbox-shell, AC_HELP_STRING([--with-sandbox-shell=PATH],
|
||||
sandbox_shell=$withval)
|
||||
AC_SUBST(sandbox_shell)
|
||||
|
||||
|
||||
# Expand all variables in config.status.
|
||||
test "$prefix" = NONE && prefix=$ac_default_prefix
|
||||
test "$exec_prefix" = NONE && exec_prefix='${prefix}'
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env nix-shell
|
||||
#!nix-shell -i python3 -p python3 --pure
|
||||
|
||||
# To be used with `--trace-function-calls` and `flamegraph.pl`.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# nix-instantiate --trace-function-calls '<nixpkgs>' -A hello 2> nix-function-calls.trace
|
||||
# ./contrib/stack-collapse.py nix-function-calls.trace > nix-function-calls.folded
|
||||
# nix-shell -p flamegraph --run "flamegraph.pl nix-function-calls.folded > nix-function-calls.svg"
|
||||
|
||||
import sys
|
||||
from pprint import pprint
|
||||
import fileinput
|
||||
|
||||
stack = []
|
||||
timestack = []
|
||||
|
||||
for line in fileinput.input():
|
||||
components = line.strip().split(" ", 2)
|
||||
if components[0] != "function-trace":
|
||||
continue
|
||||
|
||||
direction = components[1]
|
||||
components = components[2].rsplit(" ", 2)
|
||||
|
||||
loc = components[0]
|
||||
_at = components[1]
|
||||
time = int(components[2])
|
||||
|
||||
if direction == "entered":
|
||||
stack.append(loc)
|
||||
timestack.append(time)
|
||||
elif direction == "exited":
|
||||
dur = time - timestack.pop()
|
||||
vst = ";".join(stack)
|
||||
print(f"{vst} {dur}")
|
||||
stack.pop()
|
||||
@@ -1,13 +1,29 @@
|
||||
# FIXME: remove this file?
|
||||
let
|
||||
fromEnv = var: def:
|
||||
let val = builtins.getEnv var; in
|
||||
if val != "" then val else def;
|
||||
in rec {
|
||||
shell = "@bash@";
|
||||
coreutils = "@coreutils@";
|
||||
bzip2 = "@bzip2@";
|
||||
gzip = "@gzip@";
|
||||
xz = "@xz@";
|
||||
tar = "@tar@";
|
||||
tarFlags = "@tarFlags@";
|
||||
tr = "@tr@";
|
||||
nixBinDir = fromEnv "NIX_BIN_DIR" "@bindir@";
|
||||
nixPrefix = "@prefix@";
|
||||
nixLibexecDir = fromEnv "NIX_LIBEXEC_DIR" "@libexecdir@";
|
||||
nixLocalstateDir = "@localstatedir@";
|
||||
nixSysconfDir = "@sysconfdir@";
|
||||
nixStoreDir = fromEnv "NIX_STORE_DIR" "@storedir@";
|
||||
|
||||
# If Nix is installed in the Nix store, then automatically add it as
|
||||
# a dependency to the core packages. This ensures that they work
|
||||
# properly in a chroot.
|
||||
chrootDeps =
|
||||
if dirOf nixPrefix == builtins.storeDir then
|
||||
[ (builtins.storePath nixPrefix) ]
|
||||
else
|
||||
[ ];
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
corepkgs_FILES = \
|
||||
unpack-channel.nix \
|
||||
derivation.nix \
|
||||
fetchurl.nix
|
||||
corepkgs_FILES = buildenv.nix unpack-channel.nix derivation.nix fetchurl.nix imported-drv-to-derivation.nix
|
||||
|
||||
$(foreach file,config.nix $(corepkgs_FILES),$(eval $(call install-data-in,$(d)/$(file),$(datadir)/nix/corepkgs)))
|
||||
|
||||
|
||||
@@ -1,12 +1,43 @@
|
||||
{ name, channelName, src }:
|
||||
with import <nix/config.nix>;
|
||||
|
||||
let
|
||||
|
||||
builder = builtins.toFile "unpack-channel.sh"
|
||||
''
|
||||
mkdir $out
|
||||
cd $out
|
||||
xzpat="\.xz\$"
|
||||
gzpat="\.gz\$"
|
||||
if [[ "$src" =~ $xzpat ]]; then
|
||||
${xz} -d < $src | ${tar} xf - ${tarFlags}
|
||||
elif [[ "$src" =~ $gzpat ]]; then
|
||||
${gzip} -d < $src | ${tar} xf - ${tarFlags}
|
||||
else
|
||||
${bzip2} -d < $src | ${tar} xf - ${tarFlags}
|
||||
fi
|
||||
if [ * != $channelName ]; then
|
||||
mv * $out/$channelName
|
||||
fi
|
||||
if [ -n "$binaryCacheURL" ]; then
|
||||
mkdir $out/binary-caches
|
||||
echo -n "$binaryCacheURL" > $out/binary-caches/$channelName
|
||||
fi
|
||||
'';
|
||||
|
||||
in
|
||||
|
||||
{ name, channelName, src, binaryCacheURL ? "" }:
|
||||
|
||||
derivation {
|
||||
builder = "builtin:unpack-channel";
|
||||
system = builtins.currentSystem;
|
||||
builder = shell;
|
||||
args = [ "-e" builder ];
|
||||
inherit name channelName src binaryCacheURL;
|
||||
|
||||
system = "builtin";
|
||||
|
||||
inherit name channelName src;
|
||||
PATH = "${nixBinDir}:${coreutils}";
|
||||
|
||||
# No point in doing this remotely.
|
||||
preferLocalBuild = true;
|
||||
|
||||
inherit chrootDeps;
|
||||
}
|
||||
|
||||
@@ -7,8 +7,5 @@
|
||||
<title>Advanced Topics</title>
|
||||
|
||||
<xi:include href="distributed-builds.xml" />
|
||||
<xi:include href="cores-vs-jobs.xml" />
|
||||
<xi:include href="diff-hook.xml" />
|
||||
<xi:include href="post-build-hook.xml" />
|
||||
|
||||
</part>
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="chap-tuning-cores-and-jobs">
|
||||
|
||||
<title>Tuning Cores and Jobs</title>
|
||||
|
||||
<para>Nix has two relevant settings with regards to how your CPU cores
|
||||
will be utilized: <xref linkend="conf-cores" /> and
|
||||
<xref linkend="conf-max-jobs" />. This chapter will talk about what
|
||||
they are, how they interact, and their configuration trade-offs.</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><xref linkend="conf-max-jobs" /></term>
|
||||
<listitem><para>
|
||||
Dictates how many separate derivations will be built at the same
|
||||
time. If you set this to zero, the local machine will do no
|
||||
builds. Nix will still substitute from binary caches, and build
|
||||
remotely if remote builders are configured.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><xref linkend="conf-cores" /></term>
|
||||
<listitem><para>
|
||||
Suggests how many cores each derivation should use. Similar to
|
||||
<command>make -j</command>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>The <xref linkend="conf-cores" /> setting determines the value of
|
||||
<envar>NIX_BUILD_CORES</envar>. <envar>NIX_BUILD_CORES</envar> is equal
|
||||
to <xref linkend="conf-cores" />, unless <xref linkend="conf-cores" />
|
||||
equals <literal>0</literal>, in which case <envar>NIX_BUILD_CORES</envar>
|
||||
will be the total number of cores in the system.</para>
|
||||
|
||||
<para>The maximum number of consumed cores is a simple multiplication,
|
||||
<xref linkend="conf-max-jobs" /> * <envar>NIX_BUILD_CORES</envar>.</para>
|
||||
|
||||
<para>The balance on how to set these two independent variables depends
|
||||
upon each builder's workload and hardware. Here are a few example
|
||||
scenarios on a machine with 24 cores:</para>
|
||||
|
||||
<table>
|
||||
<caption>Balancing 24 Build Cores</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><xref linkend="conf-max-jobs" /></th>
|
||||
<th><xref linkend="conf-cores" /></th>
|
||||
<th><envar>NIX_BUILD_CORES</envar></th>
|
||||
<th>Maximum Processes</th>
|
||||
<th>Result</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>1</td>
|
||||
<td>24</td>
|
||||
<td>24</td>
|
||||
<td>24</td>
|
||||
<td>
|
||||
One derivation will be built at a time, each one can use 24
|
||||
cores. Undersold if a job can’t use 24 cores.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>4</td>
|
||||
<td>6</td>
|
||||
<td>6</td>
|
||||
<td>24</td>
|
||||
<td>
|
||||
Four derivations will be built at once, each given access to
|
||||
six cores.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>12</td>
|
||||
<td>6</td>
|
||||
<td>6</td>
|
||||
<td>72</td>
|
||||
<td>
|
||||
12 derivations will be built at once, each given access to six
|
||||
cores. This configuration is over-sold. If all 12 derivations
|
||||
being built simultaneously try to use all six cores, the
|
||||
machine's performance will be degraded due to extensive context
|
||||
switching between the 12 builds.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>24</td>
|
||||
<td>1</td>
|
||||
<td>1</td>
|
||||
<td>24</td>
|
||||
<td>
|
||||
24 derivations can build at the same time, each using a single
|
||||
core. Never oversold, but derivations which require many cores
|
||||
will be very slow to compile.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>24</td>
|
||||
<td>0</td>
|
||||
<td>24</td>
|
||||
<td>576</td>
|
||||
<td>
|
||||
24 derivations can build at the same time, each using all the
|
||||
available cores of the machine. Very likely to be oversold,
|
||||
and very likely to suffer context switches.
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<para>It is up to the derivations' build script to respect
|
||||
host's requested cores-per-build by following the value of the
|
||||
<envar>NIX_BUILD_CORES</envar> environment variable.</para>
|
||||
|
||||
</chapter>
|
||||
@@ -1,205 +0,0 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="chap-diff-hook"
|
||||
version="5.0"
|
||||
>
|
||||
|
||||
<title>Verifying Build Reproducibility with <option linkend="conf-diff-hook">diff-hook</option></title>
|
||||
|
||||
<subtitle>Check build reproducibility by running builds multiple times
|
||||
and comparing their results.</subtitle>
|
||||
|
||||
<para>Specify a program with Nix's <xref linkend="conf-diff-hook" /> to
|
||||
compare build results when two builds produce different results. Note:
|
||||
this hook is only executed if the results are not the same, this hook
|
||||
is not used for determining if the results are the same.</para>
|
||||
|
||||
<para>For purposes of demonstration, we'll use the following Nix file,
|
||||
<filename>deterministic.nix</filename> for testing:</para>
|
||||
|
||||
<programlisting>
|
||||
let
|
||||
inherit (import <nixpkgs> {}) runCommand;
|
||||
in {
|
||||
stable = runCommand "stable" {} ''
|
||||
touch $out
|
||||
'';
|
||||
|
||||
unstable = runCommand "unstable" {} ''
|
||||
echo $RANDOM > $out
|
||||
'';
|
||||
}
|
||||
</programlisting>
|
||||
|
||||
<para>Additionally, <filename>nix.conf</filename> contains:
|
||||
|
||||
<programlisting>
|
||||
diff-hook = /etc/nix/my-diff-hook
|
||||
run-diff-hook = true
|
||||
</programlisting>
|
||||
|
||||
where <filename>/etc/nix/my-diff-hook</filename> is an executable
|
||||
file containing:
|
||||
|
||||
<programlisting>
|
||||
#!/bin/sh
|
||||
exec >&2
|
||||
echo "For derivation $3:"
|
||||
/run/current-system/sw/bin/diff -r "$1" "$2"
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<para>The diff hook is executed by the same user and group who ran the
|
||||
build. However, the diff hook does not have write access to the store
|
||||
path just built.</para>
|
||||
|
||||
<section>
|
||||
<title>
|
||||
Spot-Checking Build Determinism
|
||||
</title>
|
||||
|
||||
<para>
|
||||
Verify a path which already exists in the Nix store by passing
|
||||
<option>--check</option> to the build command.
|
||||
</para>
|
||||
|
||||
<para>If the build passes and is deterministic, Nix will exit with a
|
||||
status code of 0:</para>
|
||||
|
||||
<screen>
|
||||
$ nix-build ./deterministic.nix -A stable
|
||||
this derivation will be built:
|
||||
/nix/store/z98fasz2jqy9gs0xbvdj939p27jwda38-stable.drv
|
||||
building '/nix/store/z98fasz2jqy9gs0xbvdj939p27jwda38-stable.drv'...
|
||||
/nix/store/yyxlzw3vqaas7wfp04g0b1xg51f2czgq-stable
|
||||
|
||||
$ nix-build ./deterministic.nix -A stable --check
|
||||
checking outputs of '/nix/store/z98fasz2jqy9gs0xbvdj939p27jwda38-stable.drv'...
|
||||
/nix/store/yyxlzw3vqaas7wfp04g0b1xg51f2czgq-stable
|
||||
</screen>
|
||||
|
||||
<para>If the build is not deterministic, Nix will exit with a status
|
||||
code of 1:</para>
|
||||
|
||||
<screen>
|
||||
$ nix-build ./deterministic.nix -A unstable
|
||||
this derivation will be built:
|
||||
/nix/store/cgl13lbj1w368r5z8gywipl1ifli7dhk-unstable.drv
|
||||
building '/nix/store/cgl13lbj1w368r5z8gywipl1ifli7dhk-unstable.drv'...
|
||||
/nix/store/krpqk0l9ib0ibi1d2w52z293zw455cap-unstable
|
||||
|
||||
$ nix-build ./deterministic.nix -A unstable --check
|
||||
checking outputs of '/nix/store/cgl13lbj1w368r5z8gywipl1ifli7dhk-unstable.drv'...
|
||||
error: derivation '/nix/store/cgl13lbj1w368r5z8gywipl1ifli7dhk-unstable.drv' may not be deterministic: output '/nix/store/krpqk0l9ib0ibi1d2w52z293zw455cap-unstable' differs
|
||||
</screen>
|
||||
|
||||
<para>In the Nix daemon's log, we will now see:
|
||||
<screen>
|
||||
For derivation /nix/store/cgl13lbj1w368r5z8gywipl1ifli7dhk-unstable.drv:
|
||||
1c1
|
||||
< 8108
|
||||
---
|
||||
> 30204
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>Using <option>--check</option> with <option>--keep-failed</option>
|
||||
will cause Nix to keep the second build's output in a special,
|
||||
<literal>.check</literal> path:</para>
|
||||
|
||||
<screen>
|
||||
$ nix-build ./deterministic.nix -A unstable --check --keep-failed
|
||||
checking outputs of '/nix/store/cgl13lbj1w368r5z8gywipl1ifli7dhk-unstable.drv'...
|
||||
note: keeping build directory '/tmp/nix-build-unstable.drv-0'
|
||||
error: derivation '/nix/store/cgl13lbj1w368r5z8gywipl1ifli7dhk-unstable.drv' may not be deterministic: output '/nix/store/krpqk0l9ib0ibi1d2w52z293zw455cap-unstable' differs from '/nix/store/krpqk0l9ib0ibi1d2w52z293zw455cap-unstable.check'
|
||||
</screen>
|
||||
|
||||
<para>In particular, notice the
|
||||
<literal>/nix/store/krpqk0l9ib0ibi1d2w52z293zw455cap-unstable.check</literal>
|
||||
output. Nix has copied the build results to that directory where you
|
||||
can examine it.</para>
|
||||
|
||||
<note xml:id="check-dirs-are-unregistered">
|
||||
<title><literal>.check</literal> paths are not registered store paths</title>
|
||||
|
||||
<para>Check paths are not protected against garbage collection,
|
||||
and this path will be deleted on the next garbage collection.</para>
|
||||
|
||||
<para>The path is guaranteed to be alive for the duration of
|
||||
<xref linkend="conf-diff-hook" />'s execution, but may be deleted
|
||||
any time after.</para>
|
||||
|
||||
<para>If the comparison is performed as part of automated tooling,
|
||||
please use the diff-hook or author your tooling to handle the case
|
||||
where the build was not deterministic and also a check path does
|
||||
not exist.</para>
|
||||
</note>
|
||||
|
||||
<para>
|
||||
<option>--check</option> is only usable if the derivation has
|
||||
been built on the system already. If the derivation has not been
|
||||
built Nix will fail with the error:
|
||||
<screen>
|
||||
error: some outputs of '/nix/store/hzi1h60z2qf0nb85iwnpvrai3j2w7rr6-unstable.drv' are not valid, so checking is not possible
|
||||
</screen>
|
||||
|
||||
Run the build without <option>--check</option>, and then try with
|
||||
<option>--check</option> again.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>
|
||||
Automatic and Optionally Enforced Determinism Verification
|
||||
</title>
|
||||
|
||||
<para>
|
||||
Automatically verify every build at build time by executing the
|
||||
build multiple times.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Setting <xref linkend="conf-repeat" /> and
|
||||
<xref linkend="conf-enforce-determinism" /> in your
|
||||
<filename>nix.conf</filename> permits the automated verification
|
||||
of every build Nix performs.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The following configuration will run each build three times, and
|
||||
will require the build to be deterministic:
|
||||
|
||||
<programlisting>
|
||||
enforce-determinism = true
|
||||
repeat = 2
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Setting <xref linkend="conf-enforce-determinism" /> to false as in
|
||||
the following configuration will run the build multiple times,
|
||||
execute the build hook, but will allow the build to succeed even
|
||||
if it does not build reproducibly:
|
||||
|
||||
<programlisting>
|
||||
enforce-determinism = false
|
||||
repeat = 1
|
||||
</programlisting>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
An example output of this configuration:
|
||||
<screen>
|
||||
$ nix-build ./test.nix -A unstable
|
||||
this derivation will be built:
|
||||
/nix/store/ch6llwpr2h8c3jmnf3f2ghkhx59aa97f-unstable.drv
|
||||
building '/nix/store/ch6llwpr2h8c3jmnf3f2ghkhx59aa97f-unstable.drv' (round 1/2)...
|
||||
building '/nix/store/ch6llwpr2h8c3jmnf3f2ghkhx59aa97f-unstable.drv' (round 2/2)...
|
||||
output '/nix/store/6xg356v9gl03hpbbg8gws77n19qanh02-unstable' of '/nix/store/ch6llwpr2h8c3jmnf3f2ghkhx59aa97f-unstable.drv' differs from '/nix/store/6xg356v9gl03hpbbg8gws77n19qanh02-unstable.check' from previous round
|
||||
/nix/store/6xg356v9gl03hpbbg8gws77n19qanh02-unstable
|
||||
</screen>
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -180,11 +180,4 @@ builders = @/etc/nix/machines
|
||||
causes the list of machines in <filename>/etc/nix/machines</filename>
|
||||
to be included. (This is the default.)</para>
|
||||
|
||||
<para>If you want the builders to use caches, you likely want to set
|
||||
the option <link linkend='conf-builders-use-substitutes'><literal>builders-use-substitutes</literal></link>
|
||||
in your local <filename>nix.conf</filename>.</para>
|
||||
|
||||
<para>To build only on remote builders and disable building on the local machine,
|
||||
you can use the option <option>--max-jobs 0</option>.</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
<chapter xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="chap-post-build-hook"
|
||||
version="5.0"
|
||||
>
|
||||
|
||||
<title>Using the <option linkend="conf-post-build-hook">post-build-hook</option></title>
|
||||
<subtitle>Uploading to an S3-compatible binary cache after each build</subtitle>
|
||||
|
||||
|
||||
<section xml:id="chap-post-build-hook-caveats">
|
||||
<title>Implementation Caveats</title>
|
||||
<para>Here we use the post-build hook to upload to a binary cache.
|
||||
This is a simple and working example, but it is not suitable for all
|
||||
use cases.</para>
|
||||
|
||||
<para>The post build hook program runs after each executed build,
|
||||
and blocks the build loop. The build loop exits if the hook program
|
||||
fails.</para>
|
||||
|
||||
<para>Concretely, this implementation will make Nix slow or unusable
|
||||
when the internet is slow or unreliable.</para>
|
||||
|
||||
<para>A more advanced implementation might pass the store paths to a
|
||||
user-supplied daemon or queue for processing the store paths outside
|
||||
of the build loop.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Prerequisites</title>
|
||||
|
||||
<para>
|
||||
This tutorial assumes you have configured an S3-compatible binary cache
|
||||
according to the instructions at
|
||||
<xref linkend="ssec-s3-substituter-authenticated-writes" />, and
|
||||
that the <literal>root</literal> user's default AWS profile can
|
||||
upload to the bucket.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Set up a Signing Key</title>
|
||||
<para>Use <command>nix-store --generate-binary-cache-key</command> to
|
||||
create our public and private signing keys. We will sign paths
|
||||
with the private key, and distribute the public key for verifying
|
||||
the authenticity of the paths.</para>
|
||||
|
||||
<screen>
|
||||
# nix-store --generate-binary-cache-key example-nix-cache-1 /etc/nix/key.private /etc/nix/key.public
|
||||
# cat /etc/nix/key.public
|
||||
example-nix-cache-1:1/cKDz3QCCOmwcztD2eV6Coggp6rqc9DGjWv7C0G+rM=
|
||||
</screen>
|
||||
|
||||
<para>Then, add the public key and the cache URL to your
|
||||
<filename>nix.conf</filename>'s <xref linkend="conf-trusted-public-keys" />
|
||||
and <xref linkend="conf-substituters" /> like:</para>
|
||||
|
||||
<programlisting>
|
||||
substituters = https://cache.nixos.org/ s3://example-nix-cache
|
||||
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= example-nix-cache-1:1/cKDz3QCCOmwcztD2eV6Coggp6rqc9DGjWv7C0G+rM=
|
||||
</programlisting>
|
||||
|
||||
<para>We will restart the Nix daemon in a later step.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Implementing the build hook</title>
|
||||
<para>Write the following script to
|
||||
<filename>/etc/nix/upload-to-cache.sh</filename>:
|
||||
</para>
|
||||
|
||||
<programlisting>
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
set -f # disable globbing
|
||||
export IFS=' '
|
||||
|
||||
echo "Signing paths" $OUT_PATHS
|
||||
nix sign-paths --key-file /etc/nix/key.private $OUT_PATHS
|
||||
echo "Uploading paths" $OUT_PATHS
|
||||
exec nix copy --to 's3://example-nix-cache' $OUT_PATHS
|
||||
</programlisting>
|
||||
|
||||
<note>
|
||||
<title>Should <literal>$OUT_PATHS</literal> be quoted?</title>
|
||||
<para>
|
||||
The <literal>$OUT_PATHS</literal> variable is a space-separated
|
||||
list of Nix store paths. In this case, we expect and want the
|
||||
shell to perform word splitting to make each output path its
|
||||
own argument to <command>nix sign-paths</command>. Nix guarantees
|
||||
the paths will not contain any spaces, however a store path
|
||||
might contain glob characters. The <command>set -f</command>
|
||||
disables globbing in the shell.
|
||||
</para>
|
||||
</note>
|
||||
<para>
|
||||
Then make sure the hook program is executable by the <literal>root</literal> user:
|
||||
<screen>
|
||||
# chmod +x /etc/nix/upload-to-cache.sh
|
||||
</screen></para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Updating Nix Configuration</title>
|
||||
|
||||
<para>Edit <filename>/etc/nix/nix.conf</filename> to run our hook,
|
||||
by adding the following configuration snippet at the end:</para>
|
||||
|
||||
<programlisting>
|
||||
post-build-hook = /etc/nix/upload-to-cache.sh
|
||||
</programlisting>
|
||||
|
||||
<para>Then, restart the <command>nix-daemon</command>.</para>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<title>Testing</title>
|
||||
|
||||
<para>Build any derivation, for example:</para>
|
||||
|
||||
<screen>
|
||||
$ nix-build -E '(import <nixpkgs> {}).writeText "example" (builtins.toString builtins.currentTime)'
|
||||
this derivation will be built:
|
||||
/nix/store/s4pnfbkalzy5qz57qs6yybna8wylkig6-example.drv
|
||||
building '/nix/store/s4pnfbkalzy5qz57qs6yybna8wylkig6-example.drv'...
|
||||
running post-build-hook '/home/grahamc/projects/github.com/NixOS/nix/post-hook.sh'...
|
||||
post-build-hook: Signing paths /nix/store/ibcyipq5gf91838ldx40mjsp0b8w9n18-example
|
||||
post-build-hook: Uploading paths /nix/store/ibcyipq5gf91838ldx40mjsp0b8w9n18-example
|
||||
/nix/store/ibcyipq5gf91838ldx40mjsp0b8w9n18-example
|
||||
</screen>
|
||||
|
||||
<para>Then delete the path from the store, and try substituting it from the binary cache:</para>
|
||||
<screen>
|
||||
$ rm ./result
|
||||
$ nix-store --delete /nix/store/ibcyipq5gf91838ldx40mjsp0b8w9n18-example
|
||||
</screen>
|
||||
|
||||
<para>Now, copy the path back from the cache:</para>
|
||||
<screen>
|
||||
$ nix-store --realise /nix/store/ibcyipq5gf91838ldx40mjsp0b8w9n18-example
|
||||
copying path '/nix/store/m8bmqwrch6l3h8s0k3d673xpmipcdpsa-example from 's3://example-nix-cache'...
|
||||
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
|
||||
/nix/store/m8bmqwrch6l3h8s0k3d673xpmipcdpsa-example
|
||||
</screen>
|
||||
</section>
|
||||
<section>
|
||||
<title>Conclusion</title>
|
||||
<para>
|
||||
We now have a Nix installation configured to automatically sign and
|
||||
upload every local build to a remote binary cache.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Before deploying this to production, be sure to consider the
|
||||
implementation caveats in <xref linkend="chap-post-build-hook-caveats" />.
|
||||
</para>
|
||||
</section>
|
||||
</chapter>
|
||||
@@ -1,9 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<refentry xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
xml:id="sec-conf-file"
|
||||
version="5">
|
||||
xml:id="sec-conf-file">
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>nix.conf</refentrytitle>
|
||||
@@ -19,30 +17,26 @@
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>By default Nix reads settings from the following places:</para>
|
||||
<para>Nix reads settings from two configuration files:</para>
|
||||
|
||||
<para>The system-wide configuration file
|
||||
<filename><replaceable>sysconfdir</replaceable>/nix/nix.conf</filename>
|
||||
(i.e. <filename>/etc/nix/nix.conf</filename> on most systems), or
|
||||
<filename>$NIX_CONF_DIR/nix.conf</filename> if
|
||||
<envar>NIX_CONF_DIR</envar> is set. Values loaded in this file are not forwarded to the Nix daemon. The
|
||||
client assumes that the daemon has already loaded them.
|
||||
</para>
|
||||
<itemizedlist>
|
||||
|
||||
<para>User-specific configuration files:</para>
|
||||
<listitem>
|
||||
<para>The system-wide configuration file
|
||||
<filename><replaceable>sysconfdir</replaceable>/nix/nix.conf</filename>
|
||||
(i.e. <filename>/etc/nix/nix.conf</filename> on most systems), or
|
||||
<filename>$NIX_CONF_DIR/nix.conf</filename> if
|
||||
<envar>NIX_CONF_DIR</envar> is set.</para>
|
||||
</listitem>
|
||||
|
||||
<para>
|
||||
If <envar>NIX_USER_CONF_FILES</envar> is set, then each path separated by
|
||||
<literal>:</literal> will be loaded in reverse order.
|
||||
</para>
|
||||
<listitem>
|
||||
<para>The user configuration file
|
||||
<filename>$XDG_CONFIG_HOME/nix/nix.conf</filename>, or
|
||||
<filename>~/.config/nix/nix.conf</filename> if
|
||||
<envar>XDG_CONFIG_HOME</envar> is not set.</para>
|
||||
</listitem>
|
||||
|
||||
<para>
|
||||
Otherwise it will look for <filename>nix/nix.conf</filename> files in
|
||||
<envar>XDG_CONFIG_DIRS</envar> and <envar>XDG_CONFIG_HOME</envar>.
|
||||
|
||||
The default location is <filename>$HOME/.config/nix.conf</filename> if
|
||||
those environment variables are unset.
|
||||
</para>
|
||||
</itemizedlist>
|
||||
|
||||
<para>The configuration files consist of
|
||||
<literal><replaceable>name</replaceable> =
|
||||
@@ -242,74 +236,8 @@ false</literal>.</para>
|
||||
linkend='opt-cores'>--cores</option> command line switch and
|
||||
defaults to <literal>1</literal>. The value <literal>0</literal>
|
||||
means that the builder should use all available CPU cores in the
|
||||
system.</para>
|
||||
system.</para></listitem>
|
||||
|
||||
<para>See also <xref linkend="chap-tuning-cores-and-jobs" />.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-diff-hook"><term><literal>diff-hook</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Absolute path to an executable capable of diffing build results.
|
||||
The hook executes if <xref linkend="conf-run-diff-hook" /> is
|
||||
true, and the output of a build is known to not be the same.
|
||||
This program is not executed to determine if two results are the
|
||||
same.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The diff hook is executed by the same user and group who ran the
|
||||
build. However, the diff hook does not have write access to the
|
||||
store path just built.
|
||||
</para>
|
||||
|
||||
<para>The diff hook program receives three parameters:</para>
|
||||
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
A path to the previous build's results
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
A path to the current build's results
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
The path to the build's derivation
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
The path to the build's scratch directory. This directory
|
||||
will exist only if the build was run with
|
||||
<option>--keep-failed</option>.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
|
||||
<para>
|
||||
The stderr and stdout output from the diff hook will not be
|
||||
displayed to the user. Instead, it will print to the nix-daemon's
|
||||
log.
|
||||
</para>
|
||||
|
||||
<para>When using the Nix daemon, <literal>diff-hook</literal> must
|
||||
be set in the <filename>nix.conf</filename> configuration file, and
|
||||
cannot be passed at the command line.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-enforce-determinism">
|
||||
<term><literal>enforce-determinism</literal></term>
|
||||
|
||||
<listitem><para>See <xref linkend="conf-repeat" />.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-extra-sandbox-paths">
|
||||
@@ -386,7 +314,7 @@ false</literal>.</para>
|
||||
|
||||
<programlisting>
|
||||
builtins.fetchurl {
|
||||
url = "https://example.org/foo-1.2.3.tar.xz";
|
||||
url = https://example.org/foo-1.2.3.tar.xz;
|
||||
sha256 = "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae";
|
||||
}
|
||||
</programlisting>
|
||||
@@ -437,7 +365,7 @@ builtins.fetchurl {
|
||||
<varlistentry xml:id="conf-keep-env-derivations"><term><literal>keep-env-derivations</literal></term>
|
||||
|
||||
<listitem><para>If <literal>false</literal> (default), derivations
|
||||
are not stored in Nix user environments. That is, the derivations of
|
||||
are not stored in Nix user environments. That is, the derivation
|
||||
any build-time-only dependencies may be garbage-collected.</para>
|
||||
|
||||
<para>If <literal>true</literal>, when you add a Nix derivation to
|
||||
@@ -487,10 +415,8 @@ builtins.fetchurl {
|
||||
|
||||
<varlistentry xml:id="conf-max-free"><term><literal>max-free</literal></term>
|
||||
|
||||
<listitem><para>When a garbage collection is triggered by the
|
||||
<literal>min-free</literal> option, it stops as soon as
|
||||
<literal>max-free</literal> bytes are available. The default is
|
||||
infinity (i.e. delete all garbage).</para></listitem>
|
||||
<listitem><para>This option defines after how many free bytes to stop collecting
|
||||
garbage once the <literal>min-free</literal> condition gets triggered.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -505,10 +431,7 @@ builtins.fetchurl {
|
||||
regardless). It can be
|
||||
overridden using the <option
|
||||
linkend='opt-max-jobs'>--max-jobs</option> (<option>-j</option>)
|
||||
command line switch.</para>
|
||||
|
||||
<para>See also <xref linkend="chap-tuning-cores-and-jobs" />.</para>
|
||||
</listitem>
|
||||
command line switch.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-max-silent-time"><term><literal>max-silent-time</literal></term>
|
||||
@@ -534,11 +457,9 @@ builtins.fetchurl {
|
||||
<varlistentry xml:id="conf-min-free"><term><literal>min-free</literal></term>
|
||||
|
||||
<listitem>
|
||||
<para>When free disk space in <filename>/nix/store</filename>
|
||||
drops below <literal>min-free</literal> during a build, Nix
|
||||
performs a garbage-collection until <literal>max-free</literal>
|
||||
bytes are available or there is no more garbage. A value of
|
||||
<literal>0</literal> (the default) disables this feature.</para>
|
||||
<para>When the disk reaches <literal>min-free</literal> bytes of free disk space during a build, nix
|
||||
will start to garbage-collection until <literal>max-free</literal> bytes are available on the disk.
|
||||
A value of <literal>0</literal> (the default) means that this feature is disabled.</para>
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
@@ -668,71 +589,15 @@ password <replaceable>my-password</replaceable>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-post-build-hook">
|
||||
<term><literal>post-build-hook</literal></term>
|
||||
<listitem>
|
||||
<para>Optional. The path to a program to execute after each build.</para>
|
||||
|
||||
<para>This option is only settable in the global
|
||||
<filename>nix.conf</filename>, or on the command line by trusted
|
||||
users.</para>
|
||||
|
||||
<para>When using the nix-daemon, the daemon executes the hook as
|
||||
<literal>root</literal>. If the nix-daemon is not involved, the
|
||||
hook runs as the user executing the nix-build.</para>
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>The hook executes after an evaluation-time build.</para></listitem>
|
||||
<listitem><para>The hook does not execute on substituted paths.</para></listitem>
|
||||
<listitem><para>The hook's output always goes to the user's terminal.</para></listitem>
|
||||
<listitem><para>If the hook fails, the build succeeds but no further builds execute.</para></listitem>
|
||||
<listitem><para>The hook executes synchronously, and blocks other builds from progressing while it runs.</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<para>The program executes with no arguments. The program's environment
|
||||
contains the following environment variables:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><envar>DRV_PATH</envar></term>
|
||||
<listitem>
|
||||
<para>The derivation for the built paths.</para>
|
||||
<para>Example:
|
||||
<literal>/nix/store/5nihn1a7pa8b25l9zafqaqibznlvvp3f-bash-4.4-p23.drv</literal>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><envar>OUT_PATHS</envar></term>
|
||||
<listitem>
|
||||
<para>Output paths of the built derivation, separated by a space character.</para>
|
||||
<para>Example:
|
||||
<literal>/nix/store/zf5lbh336mnzf1nlswdn11g4n2m8zh3g-bash-4.4-p23-dev
|
||||
/nix/store/rjxwxwv1fpn9wa2x5ssk5phzwlcv4mna-bash-4.4-p23-doc
|
||||
/nix/store/6bqvbzjkcp9695dq0dpl5y43nvy37pq1-bash-4.4-p23-info
|
||||
/nix/store/r7fng3kk3vlpdlh2idnrbn37vh4imlj2-bash-4.4-p23-man
|
||||
/nix/store/xfghy8ixrhz3kyy6p724iv3cxji088dx-bash-4.4-p23</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
<para>See <xref linkend="chap-post-build-hook" /> for an example
|
||||
implementation.</para>
|
||||
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-repeat"><term><literal>repeat</literal></term>
|
||||
|
||||
<listitem><para>How many times to repeat builds to check whether
|
||||
they are deterministic. The default value is 0. If the value is
|
||||
non-zero, every build is repeated the specified number of
|
||||
times. If the contents of any of the runs differs from the
|
||||
previous ones and <xref linkend="conf-enforce-determinism" /> is
|
||||
true, the build is rejected and the resulting store paths are not
|
||||
registered as “valid” in Nix’s database.</para></listitem>
|
||||
previous ones, the build is rejected and the resulting store paths
|
||||
are not registered as “valid” in Nix’s database.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-require-sigs"><term><literal>require-sigs</literal></term>
|
||||
@@ -763,19 +628,6 @@ password <replaceable>my-password</replaceable>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-run-diff-hook"><term><literal>run-diff-hook</literal></term>
|
||||
<listitem>
|
||||
<para>
|
||||
If true, enable the execution of <xref linkend="conf-diff-hook" />.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
When using the Nix daemon, <literal>run-diff-hook</literal> must
|
||||
be set in the <filename>nix.conf</filename> configuration file,
|
||||
and cannot be passed at the command line.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-sandbox"><term><literal>sandbox</literal></term>
|
||||
|
||||
@@ -805,8 +657,7 @@ password <replaceable>my-password</replaceable>
|
||||
<varname>__noChroot</varname> attribute set to
|
||||
<literal>true</literal> do not run in sandboxes.</para>
|
||||
|
||||
<para>The default is <literal>true</literal> on Linux and
|
||||
<literal>false</literal> on all other platforms.</para>
|
||||
<para>The default is <literal>false</literal>.</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
@@ -877,14 +728,6 @@ password <replaceable>my-password</replaceable>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-stalled-download-timeout"><term><literal>stalled-download-timeout</literal></term>
|
||||
<listitem>
|
||||
<para>The timeout (in seconds) for receiving data from servers
|
||||
during download. Nix cancels idle downloads after this timeout's
|
||||
duration.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-substituters"><term><literal>substituters</literal></term>
|
||||
|
||||
<listitem><para>A list of URLs of substituters, separated by
|
||||
@@ -940,31 +783,6 @@ requiredSystemFeatures = [ "kvm" ];
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-tarball-ttl"><term><literal>tarball-ttl</literal></term>
|
||||
|
||||
<listitem>
|
||||
<para>Default: <literal>3600</literal> seconds.</para>
|
||||
|
||||
<para>The number of seconds a downloaded tarball is considered
|
||||
fresh. If the cached tarball is stale, Nix will check whether
|
||||
it is still up to date using the ETag header. Nix will download
|
||||
a new version if the ETag header is unsupported, or the
|
||||
cached ETag doesn't match.
|
||||
</para>
|
||||
|
||||
<para>Setting the TTL to <literal>0</literal> forces Nix to always
|
||||
check if the tarball is up to date.</para>
|
||||
|
||||
<para>Nix caches tarballs in
|
||||
<filename>$XDG_CACHE_HOME/nix/tarballs</filename>.</para>
|
||||
|
||||
<para>Files fetched via <envar>NIX_PATH</envar>,
|
||||
<function>fetchGit</function>, <function>fetchMercurial</function>,
|
||||
<function>fetchTarball</function>, and <function>fetchurl</function>
|
||||
respect this TTL.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-timeout"><term><literal>timeout</literal></term>
|
||||
|
||||
@@ -985,34 +803,6 @@ requiredSystemFeatures = [ "kvm" ];
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-trace-function-calls"><term><literal>trace-function-calls</literal></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>Default: <literal>false</literal>.</para>
|
||||
|
||||
<para>If set to <literal>true</literal>, the Nix evaluator will
|
||||
trace every function call. Nix will print a log message at the
|
||||
"vomit" level for every function entrance and function exit.</para>
|
||||
|
||||
<informalexample><screen>
|
||||
function-trace entered undefined position at 1565795816999559622
|
||||
function-trace exited undefined position at 1565795816999581277
|
||||
function-trace entered /nix/store/.../example.nix:226:41 at 1565795253249935150
|
||||
function-trace exited /nix/store/.../example.nix:226:41 at 1565795253249941684
|
||||
</screen></informalexample>
|
||||
|
||||
<para>The <literal>undefined position</literal> means the function
|
||||
call is a builtin.</para>
|
||||
|
||||
<para>Use the <literal>contrib/stack-collapse.py</literal> script
|
||||
distributed with the Nix source code to convert the trace logs
|
||||
in to a format suitable for <command>flamegraph.pl</command>.</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="conf-trusted-public-keys"><term><literal>trusted-public-keys</literal></term>
|
||||
|
||||
<listitem><para>A whitespace-separated list of public keys. When
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
<varlistentry><term><envar>IN_NIX_SHELL</envar></term>
|
||||
|
||||
<listitem><para>Indicator that tells if the current environment was set up by
|
||||
<command>nix-shell</command>. Since Nix 2.0 the values are
|
||||
<literal>"pure"</literal> and <literal>"impure"</literal></para></listitem>
|
||||
<command>nix-shell</command>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -33,7 +32,7 @@
|
||||
|
||||
will cause Nix to look for paths relative to
|
||||
<filename>/home/eelco/Dev</filename> and
|
||||
<filename>/etc/nixos</filename>, in this order. It is also
|
||||
<filename>/etc/nixos</filename>, in that order. It is also
|
||||
possible to match paths against a prefix. For example, the value
|
||||
|
||||
<screen>
|
||||
@@ -53,13 +52,13 @@ nixpkgs=/home/eelco/Dev/nixpkgs-branch:/etc/nixos</screen>
|
||||
<envar>NIX_PATH</envar> to
|
||||
|
||||
<screen>
|
||||
nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-15.09.tar.gz</screen>
|
||||
nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-15.09.tar.gz</screen>
|
||||
|
||||
tells Nix to download the latest revision in the Nixpkgs/NixOS
|
||||
15.09 channel.</para>
|
||||
|
||||
<para>A following shorthand can be used to refer to the official channels:
|
||||
|
||||
|
||||
<screen>nixpkgs=channel:nixos-15.09</screen>
|
||||
</para>
|
||||
|
||||
@@ -122,7 +121,7 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
|
||||
<varlistentry><term><envar>NIX_LOG_DIR</envar></term>
|
||||
|
||||
<listitem><para>Overrides the location of the Nix log directory
|
||||
(default <filename><replaceable>prefix</replaceable>/var/log/nix</filename>).</para></listitem>
|
||||
(default <filename><replaceable>prefix</replaceable>/log/nix</filename>).</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -137,19 +136,12 @@ $ mount -o bind /mnt/otherdisk/nix /nix</screen>
|
||||
|
||||
<varlistentry><term><envar>NIX_CONF_DIR</envar></term>
|
||||
|
||||
<listitem><para>Overrides the location of the system Nix configuration
|
||||
<listitem><para>Overrides the location of the Nix configuration
|
||||
directory (default
|
||||
<filename><replaceable>prefix</replaceable>/etc/nix</filename>).</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><envar>NIX_USER_CONF_FILES</envar></term>
|
||||
|
||||
<listitem><para>Overrides the location of the user Nix configuration files
|
||||
to load from (defaults to the XDG spec locations). The variable is treated
|
||||
as a list separated by the <literal>:</literal> token.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><envar>TMPDIR</envar></term>
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
<replaceable>attrPath</replaceable>
|
||||
</arg>
|
||||
<arg><option>--no-out-link</option></arg>
|
||||
<arg><option>--dry-run</option></arg>
|
||||
<arg>
|
||||
<group choice='req'>
|
||||
<arg choice='plain'><option>--out-link</option></arg>
|
||||
@@ -99,10 +98,6 @@ also <xref linkend="sec-common-options" />.</phrase></para>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--dry-run</option></term>
|
||||
<listitem><para>Show what store paths would be built or downloaded.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id='opt-out-link'><term><option>--out-link</option> /
|
||||
<option>-o</option> <replaceable>outlink</replaceable></term>
|
||||
|
||||
|
||||
@@ -31,14 +31,12 @@
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>A Nix channel is a mechanism that allows you to automatically
|
||||
stay up-to-date with a set of pre-built Nix expressions. A Nix
|
||||
channel is just a URL that points to a place containing a set of Nix
|
||||
expressions. <phrase condition="manual">See also <xref
|
||||
linkend="sec-channels" />.</phrase></para>
|
||||
|
||||
<para>To see the list of official NixOS channels, visit <link
|
||||
xlink:href="https://nixos.org/channels" />.</para>
|
||||
<para>A Nix channel is a mechanism that allows you to automatically stay
|
||||
up-to-date with a set of pre-built Nix expressions. A Nix channel is
|
||||
just a URL that points to a place containing both a set of Nix
|
||||
expressions and a pointer to a binary cache. <phrase
|
||||
condition="manual">See also <xref linkend="sec-channels"
|
||||
/>.</phrase></para>
|
||||
|
||||
<para>This command has the following operations:
|
||||
|
||||
@@ -114,13 +112,13 @@ $ nix-env -iA nixpkgs.hello</screen>
|
||||
<para>You can revert channel updates using <option>--rollback</option>:</para>
|
||||
|
||||
<screen>
|
||||
$ nix-instantiate --eval -E '(import <nixpkgs> {}).lib.version'
|
||||
$ nix-instantiate --eval -E '(import <nixpkgs> {}).lib.nixpkgsVersion'
|
||||
"14.04.527.0e935f1"
|
||||
|
||||
$ nix-channel --rollback
|
||||
switching from generation 483 to 482
|
||||
|
||||
$ nix-instantiate --eval -E '(import <nixpkgs> {}).lib.version'
|
||||
$ nix-instantiate --eval -E '(import <nixpkgs> {}).lib.nixpkgsVersion'
|
||||
"14.04.526.dbadfad"
|
||||
</screen>
|
||||
|
||||
@@ -174,6 +172,18 @@ following files:</para>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><filename>binary-cache-url</filename></term>
|
||||
|
||||
<listitem><para>A file containing the URL to a binary cache (such
|
||||
as <uri>https://cache.nixos.org</uri>). Nix will automatically
|
||||
check this cache for pre-built binaries, if the user has
|
||||
sufficient rights to add binary caches. For instance, in a
|
||||
multi-user Nix setup, the binary caches provided by the channels
|
||||
of the root user are used automatically, but caches corresponding
|
||||
to the channels of non-root users are ignored.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</refsection>
|
||||
|
||||
@@ -221,53 +221,31 @@ also <xref linkend="sec-common-options" />.</phrase></para>
|
||||
|
||||
<varlistentry><term><filename>~/.nix-defexpr</filename></term>
|
||||
|
||||
<listitem><para>The source for the default Nix
|
||||
<listitem><para>A directory that contains the default Nix
|
||||
expressions used by the <option>--install</option>,
|
||||
<option>--upgrade</option>, and <option>--query
|
||||
--available</option> operations to obtain derivations. The
|
||||
--available</option> operations to obtain derivations. The
|
||||
<option>--file</option> option may be used to override this
|
||||
default.</para>
|
||||
|
||||
<para>If <filename>~/.nix-defexpr</filename> is a file,
|
||||
it is loaded as a Nix expression. If the expression
|
||||
is a set, it is used as the default Nix expression.
|
||||
If the expression is a function, an empty set is passed
|
||||
as argument and the return value is used as
|
||||
the default Nix expression.</para>
|
||||
|
||||
<para>If <filename>~/.nix-defexpr</filename> is a directory
|
||||
containing a <filename>default.nix</filename> file, that file
|
||||
is loaded as in the above paragraph.</para>
|
||||
|
||||
<para>If <filename>~/.nix-defexpr</filename> is a directory without
|
||||
a <filename>default.nix</filename> file, then its contents
|
||||
(both files and subdirectories) are loaded as Nix expressions.
|
||||
The expressions are combined into a single set, each expression
|
||||
under an attribute with the same name as the original file
|
||||
or subdirectory.
|
||||
</para>
|
||||
|
||||
<para>For example, if <filename>~/.nix-defexpr</filename> contains
|
||||
two files, <filename>foo.nix</filename> and <filename>bar.nix</filename>,
|
||||
<para>The Nix expressions in this directory are combined into a
|
||||
single set, with each file as an attribute that has the name of
|
||||
the file. Thus, if <filename>~/.nix-defexpr</filename> contains
|
||||
two files, <filename>foo</filename> and <filename>bar</filename>,
|
||||
then the default Nix expression will essentially be
|
||||
|
||||
<programlisting>
|
||||
{
|
||||
foo = import ~/.nix-defexpr/foo.nix;
|
||||
bar = import ~/.nix-defexpr/bar.nix;
|
||||
foo = import ~/.nix-defexpr/foo;
|
||||
bar = import ~/.nix-defexpr/bar;
|
||||
}</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
<para>The file <filename>manifest.nix</filename> is always ignored.
|
||||
Subdirectories without a <filename>default.nix</filename> file
|
||||
are traversed recursively in search of more Nix expressions,
|
||||
but the names of these intermediate directories are not
|
||||
added to the attribute paths of the default Nix expression.</para>
|
||||
|
||||
<para>The command <command>nix-channel</command> places symlinks
|
||||
to the downloaded Nix expressions from each subscribed channel in
|
||||
this directory.</para>
|
||||
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
@@ -516,7 +494,7 @@ source:
|
||||
$ nix-env -f '<nixpkgs>' -iA hello --dry-run
|
||||
(dry run; not doing anything)
|
||||
installing ‘hello-2.10’
|
||||
this path will be fetched (0.04 MiB download, 0.19 MiB unpacked):
|
||||
these paths will be fetched (0.04 MiB download, 0.19 MiB unpacked):
|
||||
/nix/store/wkhdf9jinag5750mqlax6z2zbwhqb76n-hello-2.10
|
||||
<replaceable>...</replaceable></screen>
|
||||
|
||||
@@ -526,10 +504,13 @@ this path will be fetched (0.04 MiB download, 0.19 MiB unpacked):
|
||||
14.12 channel:
|
||||
|
||||
<screen>
|
||||
$ nix-env -f https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz -iA firefox
|
||||
$ nix-env -f https://github.com/NixOS/nixpkgs-channels/archive/nixos-14.12.tar.gz -iA firefox
|
||||
</screen>
|
||||
|
||||
</para>
|
||||
(The GitHub repository <literal>nixpkgs-channels</literal> is updated
|
||||
automatically from the main <literal>nixpkgs</literal> repository
|
||||
after certain tests have succeeded and binaries have been built and
|
||||
uploaded to the binary cache at <uri>cache.nixos.org</uri>.)</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
@@ -656,7 +637,7 @@ upgrading `mozilla-1.2' to `mozilla-1.4'</screen>
|
||||
<literal>gcc-3.3.1</literal> are split into two parts: the package
|
||||
name (<literal>gcc</literal>), and the version
|
||||
(<literal>3.3.1</literal>). The version part starts after the first
|
||||
dash not followed by a letter. <varname>x</varname> is considered an
|
||||
dash not following by a letter. <varname>x</varname> is considered an
|
||||
upgrade of <varname>y</varname> if their package names match, and the
|
||||
version of <varname>y</varname> is higher that that of
|
||||
<varname>x</varname>.</para>
|
||||
@@ -1063,8 +1044,7 @@ user environment elements, etc. -->
|
||||
the derivation, which can be used to unambiguously select it using
|
||||
the <link linkend="opt-attr"><option>--attr</option> option</link>
|
||||
available in commands that install derivations like
|
||||
<literal>nix-env --install</literal>. This option only works
|
||||
together with <option>--available</option></para></listitem>
|
||||
<literal>nix-env --install</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -1368,13 +1348,10 @@ profile. The generations can be a list of generation numbers, the
|
||||
special value <literal>old</literal> to delete all non-current
|
||||
generations, a value such as <literal>30d</literal> to delete all
|
||||
generations older than the specified number of days (except for the
|
||||
generation that was active at that point in time), or a value such as
|
||||
<literal>+5</literal> to keep the last <literal>5</literal> generations
|
||||
ignoring any newer than current, e.g., if <literal>30</literal> is the current
|
||||
generation <literal>+5</literal> will delete generation <literal>25</literal>
|
||||
and all older generations.
|
||||
Periodically deleting old generations is important to make garbage collection
|
||||
effective.</para>
|
||||
generation that was active at that point in time), or a value such as.
|
||||
<literal>+5</literal> to only keep the specified items older than the
|
||||
current generation. Periodically deleting old generations is important
|
||||
to make garbage collection effective.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ avoided.</para>
|
||||
<para>If <replaceable>hash</replaceable> is specified, then a download
|
||||
is not performed if the Nix store already contains a file with the
|
||||
same hash and base name. Otherwise, the file is downloaded, and an
|
||||
error is signaled if the actual hash of the file does not match the
|
||||
error if signaled if the actual hash of the file does not match the
|
||||
specified hash.</para>
|
||||
|
||||
<para>This command prints the hash on standard output. Additionally,
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
<arg choice='plain'><option>--packages</option></arg>
|
||||
<arg choice='plain'><option>-p</option></arg>
|
||||
</group>
|
||||
<arg choice='plain' rep='repeat'>
|
||||
<group choice='req'>
|
||||
<arg choice="plain"><replaceable>packages</replaceable></arg>
|
||||
<arg choice="plain"><replaceable>expressions</replaceable></arg>
|
||||
</group>
|
||||
</arg>
|
||||
<arg choice='plain' rep='repeat'><replaceable>packages</replaceable></arg>
|
||||
</arg>
|
||||
<arg><replaceable>path</replaceable></arg>
|
||||
</group>
|
||||
@@ -194,8 +189,8 @@ also <xref linkend="sec-common-options" />.</phrase></para>
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><envar>NIX_BUILD_SHELL</envar></term>
|
||||
|
||||
<listitem><para>Shell used to start the interactive environment.
|
||||
|
||||
<listitem><para>Shell used to start the interactive environment.
|
||||
Defaults to the <command>bash</command> found in <envar>PATH</envar>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
@@ -227,9 +222,8 @@ $ nix-shell '<nixpkgs>' -A pan --pure \
|
||||
--command 'export NIX_DEBUG=1; export NIX_CORES=8; return'
|
||||
</screen>
|
||||
|
||||
Nix expressions can also be given on the command line using the
|
||||
<command>-E</command> and <command>-p</command> flags.
|
||||
For instance, the following starts a shell containing the packages
|
||||
Nix expressions can also be given on the command line. For instance,
|
||||
the following starts a shell containing the packages
|
||||
<literal>sqlite</literal> and <literal>libX11</literal>:
|
||||
|
||||
<screen>
|
||||
@@ -244,21 +238,13 @@ $ nix-shell -p sqlite xorg.libX11
|
||||
… -L/nix/store/j1zg5v…-sqlite-3.8.0.2/lib -L/nix/store/0gmcz9…-libX11-1.6.1/lib …
|
||||
</screen>
|
||||
|
||||
Note that <command>-p</command> accepts multiple full nix expressions that
|
||||
are valid in the <literal>buildInputs = [ ... ]</literal> shown above,
|
||||
not only package names. So the following is also legal:
|
||||
|
||||
<screen>
|
||||
$ nix-shell -p sqlite 'git.override { withManual = false; }'
|
||||
</screen>
|
||||
|
||||
The <command>-p</command> flag looks up Nixpkgs in the Nix search
|
||||
path. You can override it by passing <option>-I</option> or setting
|
||||
<envar>NIX_PATH</envar>. For example, the following gives you a shell
|
||||
containing the Pan package from a specific revision of Nixpkgs:
|
||||
|
||||
<screen>
|
||||
$ nix-shell -p pan -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/8a3eea054838b55aca962c3fbde9c83c102b8bf2.tar.gz
|
||||
$ nix-shell -p pan -I nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/8a3eea054838b55aca962c3fbde9c83c102b8bf2.tar.gz
|
||||
|
||||
[nix-shell:~]$ pan --version
|
||||
Pan 0.139
|
||||
@@ -351,8 +337,8 @@ following Haskell script uses a specific branch of Nixpkgs/NixOS (the
|
||||
|
||||
<programlisting><![CDATA[
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i runghc -p "haskellPackages.ghcWithPackages (ps: [ps.HTTP ps.tagsoup])"
|
||||
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixos-18.03.tar.gz
|
||||
#! nix-shell -i runghc -p haskellPackages.ghc haskellPackages.HTTP haskellPackages.tagsoup
|
||||
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-18.03.tar.gz
|
||||
|
||||
import Network.HTTP
|
||||
import Text.HTML.TagSoup
|
||||
@@ -370,7 +356,7 @@ If you want to be even more precise, you can specify a specific
|
||||
revision of Nixpkgs:
|
||||
|
||||
<programlisting>
|
||||
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/0672315759b3e15e2121365f067c1c8c56bb4722.tar.gz
|
||||
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/0672315759b3e15e2121365f067c1c8c56bb4722.tar.gz
|
||||
</programlisting>
|
||||
|
||||
</para>
|
||||
|
||||
@@ -215,48 +215,6 @@ printed.)</para>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>Special exit codes:</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><literal>100</literal></term>
|
||||
<listitem><para>Generic build failure, the builder process
|
||||
returned with a non-zero exit code.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>101</literal></term>
|
||||
<listitem><para>Build timeout, the build was aborted because it
|
||||
did not complete within the specified <link
|
||||
linkend='conf-timeout'><literal>timeout</literal></link>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>102</literal></term>
|
||||
<listitem><para>Hash mismatch, the build output was rejected
|
||||
because it does not match the specified <link
|
||||
linkend="fixed-output-drvs"><varname>outputHash</varname></link>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><literal>104</literal></term>
|
||||
<listitem><para>Not deterministic, the build succeeded in check
|
||||
mode but the resulting output is not binary reproducable.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>With the <option>--keep-going</option> flag it's possible for
|
||||
multiple failures to occur, in this case the 1xx status codes are or combined
|
||||
using binary or. <screen>
|
||||
1100100
|
||||
^^^^
|
||||
|||`- timeout
|
||||
||`-- output hash mismatch
|
||||
|`--- build failure
|
||||
`---- not deterministic
|
||||
</screen></para>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
@@ -360,6 +318,7 @@ EOF
|
||||
<arg choice='plain'><option>--print-roots</option></arg>
|
||||
<arg choice='plain'><option>--print-live</option></arg>
|
||||
<arg choice='plain'><option>--print-dead</option></arg>
|
||||
<arg choice='plain'><option>--delete</option></arg>
|
||||
</group>
|
||||
<arg><option>--max-freed</option> <replaceable>bytes</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
@@ -406,6 +365,14 @@ the Nix store not reachable via file system references from a set of
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--delete</option></term>
|
||||
|
||||
<listitem><para>This operation performs an actual garbage
|
||||
collection. All dead paths are removed from the
|
||||
store. This is the default.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
<para>By default, all unreachable paths are deleted. The following
|
||||
@@ -435,10 +402,10 @@ and <link
|
||||
linkend="conf-keep-derivations"><literal>keep-derivations</literal></link>
|
||||
variables in the Nix configuration file.</para>
|
||||
|
||||
<para>By default, the collector prints the total number of freed bytes
|
||||
when it finishes (or when it is interrupted). With
|
||||
<option>--print-dead</option>, it prints the number of bytes that would
|
||||
be freed.</para>
|
||||
<para>With <option>--delete</option>, the collector prints the total
|
||||
number of freed bytes when it finishes (or when it is interrupted).
|
||||
With <option>--print-dead</option>, it prints the number of bytes that
|
||||
would be freed.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
@@ -916,60 +883,6 @@ $ nix-store --add ./foo.c
|
||||
|
||||
</refsection>
|
||||
|
||||
<!--######################################################################-->
|
||||
|
||||
<refsection><title>Operation <option>--add-fixed</option></title>
|
||||
|
||||
<refsection><title>Synopsis</title>
|
||||
|
||||
<cmdsynopsis>
|
||||
<command>nix-store</command>
|
||||
<arg><option>--recursive</option></arg>
|
||||
<arg choice='plain'><option>--add-fixed</option></arg>
|
||||
<arg choice='plain'><replaceable>algorithm</replaceable></arg>
|
||||
<arg choice='plain' rep='repeat'><replaceable>paths</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
|
||||
</refsection>
|
||||
|
||||
<refsection><title>Description</title>
|
||||
|
||||
<para>The operation <option>--add-fixed</option> adds the specified paths to
|
||||
the Nix store. Unlike <option>--add</option> paths are registered using the
|
||||
specified hashing algorithm, resulting in the same output path as a fixed-output
|
||||
derivation. This can be used for sources that are not available from a public
|
||||
url or broke since the download expression was written.
|
||||
</para>
|
||||
|
||||
<para>This operation has the following options:
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term><option>--recursive</option></term>
|
||||
|
||||
<listitem><para>
|
||||
Use recursive instead of flat hashing mode, used when adding directories
|
||||
to the store.
|
||||
</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
<refsection><title>Example</title>
|
||||
|
||||
<screen>
|
||||
$ nix-store --add-fixed sha256 ./hello-2.10.tar.gz
|
||||
/nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz</screen>
|
||||
|
||||
</refsection>
|
||||
|
||||
</refsection>
|
||||
|
||||
|
||||
|
||||
<!--######################################################################-->
|
||||
@@ -1139,7 +1052,7 @@ the information that Nix considers important. For instance,
|
||||
timestamps are elided because all files in the Nix store have their
|
||||
timestamp set to 0 anyway. Likewise, all permissions are left out
|
||||
except for the execute bit, because all files in the Nix store have
|
||||
444 or 555 permission.</para>
|
||||
644 or 755 permission.</para>
|
||||
|
||||
<para>Also, a NAR archive is <emphasis>canonical</emphasis>, meaning
|
||||
that “equal” paths always produce the same NAR archive. For instance,
|
||||
@@ -1369,7 +1282,6 @@ ktorrent-2.2.1/NEWS
|
||||
<cmdsynopsis>
|
||||
<command>nix-store</command>
|
||||
<arg choice='plain'><option>--dump-db</option></arg>
|
||||
<arg rep='repeat'><replaceable>paths</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsection>
|
||||
|
||||
@@ -1380,13 +1292,6 @@ Nix database to standard output. It can be loaded into an empty Nix
|
||||
store using <option>--load-db</option>. This is useful for making
|
||||
backups and when migrating to different database schemas.</para>
|
||||
|
||||
<para>By default, <option>--dump-db</option> will dump the entire Nix
|
||||
database. When one or more store paths is passed, only the subset of
|
||||
the Nix database for those store paths is dumped. As with
|
||||
<option>--export</option>, the user is responsible for passing all the
|
||||
store paths for a closure. See <option>--export</option> for an
|
||||
example.</para>
|
||||
|
||||
</refsection>
|
||||
|
||||
</refsection>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<nop xmlns="http://docbook.org/ns/docbook">
|
||||
|
||||
|
||||
<arg><option>--help</option></arg>
|
||||
<arg><option>--version</option></arg>
|
||||
<arg rep='repeat'>
|
||||
@@ -11,10 +11,6 @@
|
||||
<arg>
|
||||
<arg choice='plain'><option>--quiet</option></arg>
|
||||
</arg>
|
||||
<arg>
|
||||
<option>--log-format</option>
|
||||
<replaceable>format</replaceable>
|
||||
</arg>
|
||||
<arg>
|
||||
<group choice='plain'>
|
||||
<arg choice='plain'><option>--no-build-output</option></arg>
|
||||
|
||||
@@ -92,37 +92,6 @@
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="opt-log-format"><term><option>--log-format</option> <replaceable>format</replaceable></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>This option can be used to change the output of the log format, with
|
||||
<replaceable>format</replaceable> being one of:</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry><term>raw</term>
|
||||
<listitem><para>This is the raw format, as outputted by nix-build.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>internal-json</term>
|
||||
<listitem><para>Outputs the logs in a structured manner. NOTE: the json schema is not guarantees to be stable between releases.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>bar</term>
|
||||
<listitem><para>Only display a progress bar during the builds.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term>bar-with-logs</term>
|
||||
<listitem><para>Display the raw logs, with the progress bar at the bottom.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
</listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><option>--no-build-output</option> / <option>-Q</option></term>
|
||||
|
||||
<listitem><para>By default, output written by builders to standard
|
||||
@@ -138,22 +107,14 @@
|
||||
<varlistentry xml:id="opt-max-jobs"><term><option>--max-jobs</option> / <option>-j</option>
|
||||
<replaceable>number</replaceable></term>
|
||||
|
||||
<listitem>
|
||||
|
||||
<para>Sets the maximum number of build jobs that Nix will
|
||||
<listitem><para>Sets the maximum number of build jobs that Nix will
|
||||
perform in parallel to the specified number. Specify
|
||||
<literal>auto</literal> to use the number of CPUs in the system.
|
||||
The default is specified by the <link
|
||||
linkend='conf-max-jobs'><literal>max-jobs</literal></link>
|
||||
configuration setting, which itself defaults to
|
||||
<literal>1</literal>. A higher value is useful on SMP systems or to
|
||||
exploit I/O latency.</para>
|
||||
|
||||
<para> Setting it to <literal>0</literal> disallows building on the local
|
||||
machine, which is useful when you want builds to happen only on remote
|
||||
builders.</para>
|
||||
|
||||
</listitem>
|
||||
exploit I/O latency.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -274,10 +235,9 @@
|
||||
<varlistentry><term><option>--arg</option> <replaceable>name</replaceable> <replaceable>value</replaceable></term>
|
||||
|
||||
<listitem><para>This option is accepted by
|
||||
<command>nix-env</command>, <command>nix-instantiate</command>,
|
||||
<command>nix-shell</command> and <command>nix-build</command>.
|
||||
When evaluating Nix expressions, the expression evaluator will
|
||||
automatically try to call functions that
|
||||
<command>nix-env</command>, <command>nix-instantiate</command> and
|
||||
<command>nix-build</command>. When evaluating Nix expressions, the
|
||||
expression evaluator will automatically try to call functions that
|
||||
it encounters. It can automatically call functions for which every
|
||||
argument has a <link linkend='ss-functions'>default value</link>
|
||||
(e.g., <literal>{ <replaceable>argName</replaceable> ?
|
||||
@@ -354,14 +314,7 @@
|
||||
Nix expressions to be parsed and evaluated, rather than as a list
|
||||
of file names of Nix expressions.
|
||||
(<command>nix-instantiate</command>, <command>nix-build</command>
|
||||
and <command>nix-shell</command> only.)</para>
|
||||
|
||||
<para>For <command>nix-shell</command>, this option is commonly used
|
||||
to give you a shell in which you can build the packages returned
|
||||
by the expression. If you want to get a shell which contain the
|
||||
<emphasis>built</emphasis> packages ready for use, give your
|
||||
expression to the <command>nix-shell -p</command> convenience flag
|
||||
instead.</para></listitem>
|
||||
and <command>nix-shell</command> only.)</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ attributes.</para>
|
||||
|
||||
<variablelist>
|
||||
|
||||
<varlistentry xml:id="adv-attr-allowedReferences"><term><varname>allowedReferences</varname></term>
|
||||
<varlistentry><term><varname>allowedReferences</varname></term>
|
||||
|
||||
<listitem><para>The optional attribute
|
||||
<varname>allowedReferences</varname> specifies a list of legal
|
||||
@@ -32,7 +32,7 @@ allowedReferences = [];
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="adv-attr-allowedRequisites"><term><varname>allowedRequisites</varname></term>
|
||||
<varlistentry><term><varname>allowedRequisites</varname></term>
|
||||
|
||||
<listitem><para>This attribute is similar to
|
||||
<varname>allowedReferences</varname>, but it specifies the legal
|
||||
@@ -50,7 +50,7 @@ allowedRequisites = [ foobar ];
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id="adv-attr-disallowedReferences"><term><varname>disallowedReferences</varname></term>
|
||||
<varlistentry><term><varname>disallowedReferences</varname></term>
|
||||
|
||||
<listitem><para>The optional attribute
|
||||
<varname>disallowedReferences</varname> specifies a list of illegal
|
||||
@@ -67,7 +67,7 @@ disallowedReferences = [ foo ];
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="adv-attr-disallowedRequisites"><term><varname>disallowedRequisites</varname></term>
|
||||
<varlistentry><term><varname>disallowedRequisites</varname></term>
|
||||
|
||||
<listitem><para>This attribute is similar to
|
||||
<varname>disallowedReferences</varname>, but it specifies illegal
|
||||
@@ -85,7 +85,7 @@ disallowedRequisites = [ foobar ];
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="adv-attr-exportReferencesGraph"><term><varname>exportReferencesGraph</varname></term>
|
||||
<varlistentry><term><varname>exportReferencesGraph</varname></term>
|
||||
|
||||
<listitem><para>This attribute allows builders access to the
|
||||
references graph of their inputs. The attribute is a list of
|
||||
@@ -124,7 +124,7 @@ derivation {
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="adv-attr-impureEnvVars"><term><varname>impureEnvVars</varname></term>
|
||||
<varlistentry><term><varname>impureEnvVars</varname></term>
|
||||
|
||||
<listitem><para>This attribute allows you to specify a list of
|
||||
environment variables that should be passed from the environment
|
||||
@@ -158,9 +158,9 @@ impureEnvVars = [ "http_proxy" "https_proxy" <replaceable>...</replaceable> ];
|
||||
|
||||
|
||||
<varlistentry xml:id="fixed-output-drvs">
|
||||
<term xml:id="adv-attr-outputHash"><varname>outputHash</varname></term>
|
||||
<term xml:id="adv-attr-outputHashAlgo"><varname>outputHashAlgo</varname></term>
|
||||
<term xml:id="adv-attr-outputHashMode"><varname>outputHashMode</varname></term>
|
||||
<term><varname>outputHash</varname></term>
|
||||
<term><varname>outputHashAlgo</varname></term>
|
||||
<term><varname>outputHashMode</varname></term>
|
||||
|
||||
<listitem><para>These attributes declare that the derivation is a
|
||||
so-called <emphasis>fixed-output derivation</emphasis>, which
|
||||
@@ -178,7 +178,7 @@ impureEnvVars = [ "http_proxy" "https_proxy" <replaceable>...</replaceable> ];
|
||||
|
||||
<programlisting>
|
||||
fetchurl {
|
||||
url = "http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz";
|
||||
url = http://ftp.gnu.org/pub/gnu/hello/hello-2.1.1.tar.gz;
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
}
|
||||
</programlisting>
|
||||
@@ -189,7 +189,7 @@ fetchurl {
|
||||
|
||||
<programlisting>
|
||||
fetchurl {
|
||||
url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
|
||||
url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
}
|
||||
</programlisting>
|
||||
@@ -282,7 +282,7 @@ stdenv.mkDerivation {
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="adv-attr-passAsFile"><term><varname>passAsFile</varname></term>
|
||||
<varlistentry><term><varname>passAsFile</varname></term>
|
||||
|
||||
<listitem><para>A list of names of attributes that should be
|
||||
passed via files rather than environment variables. For example,
|
||||
@@ -309,7 +309,7 @@ big = "a very long string";
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="adv-attr-preferLocalBuild"><term><varname>preferLocalBuild</varname></term>
|
||||
<varlistentry><term><varname>preferLocalBuild</varname></term>
|
||||
|
||||
<listitem><para>If this attribute is set to
|
||||
<literal>true</literal> and <link
|
||||
@@ -323,25 +323,14 @@ big = "a very long string";
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id="adv-attr-allowSubstitutes"><term><varname>allowSubstitutes</varname></term>
|
||||
<varlistentry><term><varname>allowSubstitutes</varname></term>
|
||||
|
||||
<listitem>
|
||||
<para>If this attribute is set to
|
||||
<listitem><para>If this attribute is set to
|
||||
<literal>false</literal>, then Nix will always build this
|
||||
derivation; it will not try to substitute its outputs. This is
|
||||
useful for very trivial derivations (such as
|
||||
<function>writeText</function> in Nixpkgs) that are cheaper to
|
||||
build than to substitute from a binary cache.</para>
|
||||
|
||||
<note><para>You need to have a builder configured which satisfies
|
||||
the derivation’s <literal>system</literal> attribute, since the
|
||||
derivation cannot be substituted. Thus it is usually a good idea
|
||||
to align <literal>system</literal> with
|
||||
<literal>builtins.currentSystem</literal> when setting
|
||||
<literal>allowSubstitutes</literal> to <literal>false</literal>.
|
||||
For most trivial derivations this should be the case.
|
||||
</para></note>
|
||||
</listitem>
|
||||
build than to substitute from a binary cache.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -170,6 +170,18 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id='builtin-splitVersion'>
|
||||
<term><function>builtins.splitVersion</function>
|
||||
<replaceable>s</replaceable></term>
|
||||
|
||||
<listitem><para>Split a string representing a version into its
|
||||
components, by the same version splitting logic underlying the
|
||||
version comparison in <link linkend="ssec-version-comparisons">
|
||||
<command>nix-env -u</command></link>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id='builtin-concatLists'>
|
||||
<term><function>builtins.concatLists</function>
|
||||
<replaceable>lists</replaceable></term>
|
||||
@@ -289,7 +301,7 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
|
||||
|
||||
<listitem><para>Return element <replaceable>n</replaceable> from
|
||||
the list <replaceable>xs</replaceable>. Elements are counted
|
||||
starting from 0. A fatal error occurs if the index is out of
|
||||
starting from 0. A fatal error occurs in the index is out of
|
||||
bounds.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
@@ -324,7 +336,7 @@ if builtins ? getEnv then builtins.getEnv "PATH" else ""</programlisting>
|
||||
particular version of Nixpkgs, e.g.
|
||||
|
||||
<programlisting>
|
||||
with import (fetchTarball https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz) {};
|
||||
with import (fetchTarball https://github.com/NixOS/nixpkgs-channels/archive/nixos-14.12.tar.gz) {};
|
||||
|
||||
stdenv.mkDerivation { … }
|
||||
</programlisting>
|
||||
@@ -335,7 +347,7 @@ stdenv.mkDerivation { … }
|
||||
You can change the cache timeout either on the command line with
|
||||
<option>--option tarball-ttl <replaceable>number of seconds</replaceable></option> or
|
||||
in the Nix configuration file with this option:
|
||||
<literal><xref linkend="conf-tarball-ttl" /> <replaceable>number of seconds to cache</replaceable></literal>.
|
||||
<literal>tarball-ttl <replaceable>number of seconds to cache</replaceable></literal>.
|
||||
</para>
|
||||
|
||||
<para>Note that when obtaining the hash with <varname>nix-prefetch-url
|
||||
@@ -349,7 +361,7 @@ stdenv.mkDerivation { … }
|
||||
|
||||
<programlisting>
|
||||
with import (fetchTarball {
|
||||
url = "https://github.com/NixOS/nixpkgs/archive/nixos-14.12.tar.gz";
|
||||
url = https://github.com/NixOS/nixpkgs-channels/archive/nixos-14.12.tar.gz;
|
||||
sha256 = "1jppksrfvbk5ypiqdz4cddxdl8z6zyzdb2srq8fcffr327ld5jj2";
|
||||
}) {};
|
||||
|
||||
@@ -413,23 +425,6 @@ stdenv.mkDerivation { … }
|
||||
This is often a branch or tag name. Defaults to
|
||||
<literal>HEAD</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
By default, the <varname>ref</varname> value is prefixed
|
||||
with <literal>refs/heads/</literal>. As of Nix 2.3.0
|
||||
Nix will not prefix <literal>refs/heads/</literal> if
|
||||
<varname>ref</varname> starts with <literal>refs/</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>submodules</term>
|
||||
<listitem>
|
||||
<para>
|
||||
A Boolean parameter that specifies whether submodules
|
||||
should be checked out. Defaults to
|
||||
<literal>false</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
@@ -443,14 +438,6 @@ stdenv.mkDerivation { … }
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>Fetching an arbitrary ref</title>
|
||||
<programlisting>builtins.fetchGit {
|
||||
url = "https://github.com/NixOS/nix.git";
|
||||
ref = "refs/heads/0.5-release";
|
||||
}</programlisting>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
<title>Fetching a repository's specific commit on an arbitrary branch</title>
|
||||
<para>
|
||||
@@ -497,8 +484,11 @@ stdenv.mkDerivation { … }
|
||||
<title>Fetching a tag</title>
|
||||
<programlisting>builtins.fetchGit {
|
||||
url = "https://github.com/nixos/nix.git";
|
||||
ref = "refs/tags/1.9";
|
||||
ref = "tags/1.9";
|
||||
}</programlisting>
|
||||
<note><para>Due to a bug (<link
|
||||
xlink:href="https://github.com/NixOS/nix/issues/2385">#2385</link>),
|
||||
only non-annotated tags can be fetched.</para></note>
|
||||
</example>
|
||||
|
||||
<example>
|
||||
@@ -508,7 +498,7 @@ stdenv.mkDerivation { … }
|
||||
fetch the latest version of a remote branch.
|
||||
</para>
|
||||
<note><para>Nix will refetch the branch in accordance to
|
||||
<xref linkend="conf-tarball-ttl" />.</para></note>
|
||||
<option>tarball-ttl</option>.</para></note>
|
||||
<note><para>This behavior is disabled in
|
||||
<emphasis>Pure evaluation mode</emphasis>.</para></note>
|
||||
<programlisting>builtins.fetchGit {
|
||||
@@ -709,21 +699,8 @@ builtins.genList (x: x * x) 5
|
||||
<listitem><para>Return a base-16 representation of the
|
||||
cryptographic hash of string <replaceable>s</replaceable>. The
|
||||
hash algorithm specified by <replaceable>type</replaceable> must
|
||||
be one of <literal>"md5"</literal>, <literal>"sha1"</literal>,
|
||||
<literal>"sha256"</literal> or <literal>"sha512"</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id='builtin-hashFile'>
|
||||
<term><function>builtins.hashFile</function>
|
||||
<replaceable>type</replaceable> <replaceable>p</replaceable></term>
|
||||
|
||||
<listitem><para>Return a base-16 representation of the
|
||||
cryptographic hash of the file at path <replaceable>p</replaceable>. The
|
||||
hash algorithm specified by <replaceable>type</replaceable> must
|
||||
be one of <literal>"md5"</literal>, <literal>"sha1"</literal>,
|
||||
<literal>"sha256"</literal> or <literal>"sha512"</literal>.</para></listitem>
|
||||
be one of <literal>"md5"</literal>, <literal>"sha1"</literal> or
|
||||
<literal>"sha256"</literal>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -756,11 +733,6 @@ builtins.genList (x: x * x) 5
|
||||
separate file, and use it from Nix expressions in other
|
||||
files.</para>
|
||||
|
||||
<note><para>Unlike some languages, <function>import</function> is a regular
|
||||
function in Nix. Paths using the angle bracket syntax (e.g., <function>
|
||||
import</function> <replaceable><foo></replaceable>) are normal path
|
||||
values (see <xref linkend='ssec-values' />).</para></note>
|
||||
|
||||
<para>A Nix expression loaded by <function>import</function> must
|
||||
not contain any <emphasis>free variables</emphasis> (identifiers
|
||||
that are not defined in the Nix expression itself and are not
|
||||
@@ -889,14 +861,6 @@ x: x + 456</programlisting>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry><term><function>builtins.isPath</function>
|
||||
<replaceable>e</replaceable></term>
|
||||
|
||||
<listitem><para>Return <literal>true</literal> if
|
||||
<replaceable>e</replaceable> evaluates to a path, and
|
||||
<literal>false</literal> otherwise.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id='builtin-isNull'>
|
||||
<term><function>isNull</function>
|
||||
@@ -1130,16 +1094,6 @@ Evaluates to <literal>[ "foo" ]</literal>.
|
||||
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id='builtin-placeholder'>
|
||||
<term><function>builtins.placeholder</function>
|
||||
<replaceable>output</replaceable></term>
|
||||
|
||||
<listitem><para>Return a placeholder string for the specified
|
||||
<replaceable>output</replaceable> that will be substituted by the
|
||||
corresponding output path at build time. Typical outputs would be
|
||||
<literal>"out"</literal>, <literal>"bin"</literal> or
|
||||
<literal>"dev"</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry xml:id='builtin-readDir'>
|
||||
<term><function>builtins.readDir</function>
|
||||
@@ -1285,19 +1239,6 @@ Evaluates to <literal>[ " " [ "FOO" ] " " ]</literal>.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id='builtin-splitVersion'>
|
||||
<term><function>builtins.splitVersion</function>
|
||||
<replaceable>s</replaceable></term>
|
||||
|
||||
<listitem><para>Split a string representing a version into its
|
||||
components, by the same version splitting logic underlying the
|
||||
version comparison in <link linkend="ssec-version-comparisons">
|
||||
<command>nix-env -u</command></link>.</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
|
||||
<varlistentry xml:id='builtin-stringLength'>
|
||||
<term><function>builtins.stringLength</function>
|
||||
<replaceable>e</replaceable></term>
|
||||
@@ -1406,7 +1347,7 @@ stdenv.mkDerivation {
|
||||
";
|
||||
|
||||
src = fetchurl {
|
||||
url = "http://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
|
||||
url = http://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
};
|
||||
inherit perl;
|
||||
@@ -1491,7 +1432,7 @@ in foo</programlisting>
|
||||
<listitem><para>A set containing <literal>{ __toString = self: ...; }</literal>.</para></listitem>
|
||||
<listitem><para>An integer.</para></listitem>
|
||||
<listitem><para>A list, in which case the string representations of its elements are joined with spaces.</para></listitem>
|
||||
<listitem><para>A Boolean (<literal>false</literal> yields <literal>""</literal>, <literal>true</literal> yields <literal>"1"</literal>).</para></listitem>
|
||||
<listitem><para>A Boolean (<literal>false</literal> yields <literal>""</literal>, <literal>true</literal> yields <literal>"1"</literal>.</para></listitem>
|
||||
<listitem><para><literal>null</literal>, which yields the empty string.</para></listitem>
|
||||
</itemizedlist>
|
||||
</listitem>
|
||||
@@ -1630,18 +1571,12 @@ stdenv.mkDerivation (rec {
|
||||
<term><function>builtins.tryEval</function>
|
||||
<replaceable>e</replaceable></term>
|
||||
|
||||
<listitem><para>Try to shallowly evaluate <replaceable>e</replaceable>.
|
||||
<listitem><para>Try to evaluate <replaceable>e</replaceable>.
|
||||
Return a set containing the attributes <literal>success</literal>
|
||||
(<literal>true</literal> if <replaceable>e</replaceable> evaluated
|
||||
successfully, <literal>false</literal> if an error was thrown) and
|
||||
<literal>value</literal>, equalling <replaceable>e</replaceable>
|
||||
if successful and <literal>false</literal> otherwise. Note that this
|
||||
doesn't evaluate <replaceable>e</replaceable> deeply, so
|
||||
<literal>let e = { x = throw ""; }; in (builtins.tryEval e).success
|
||||
</literal> will be <literal>true</literal>. Using <literal>builtins.deepSeq
|
||||
</literal> one can get the expected result: <literal>let e = { x = throw "";
|
||||
}; in (builtins.tryEval (builtins.deepSeq e e)).success</literal> will be
|
||||
<literal>false</literal>.
|
||||
if successful and <literal>false</literal> otherwise.
|
||||
</para></listitem>
|
||||
|
||||
</varlistentry>
|
||||
|
||||
@@ -15,7 +15,7 @@ stdenv.mkDerivation { <co xml:id='ex-hello-nix-co-2' />
|
||||
name = "hello-2.1.1"; <co xml:id='ex-hello-nix-co-3' />
|
||||
builder = ./builder.sh; <co xml:id='ex-hello-nix-co-4' />
|
||||
src = fetchurl { <co xml:id='ex-hello-nix-co-5' />
|
||||
url = "ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz";
|
||||
url = ftp://ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz;
|
||||
sha256 = "1md7jsfd8pa45z73bz1kszpp01yw6x5ljkjk2hx7wl800any6465";
|
||||
};
|
||||
inherit perl; <co xml:id='ex-hello-nix-co-6' />
|
||||
|
||||
@@ -43,7 +43,7 @@ encountered</quote>).</para></footnote>.</para>
|
||||
|
||||
<simplesect xml:id="sect-let-expressions"><title>Let-expressions</title>
|
||||
|
||||
<para>A let-expression allows you to define local variables for an
|
||||
<para>A let-expression allows you define local variables for an
|
||||
expression. For instance,
|
||||
|
||||
<programlisting>
|
||||
@@ -217,25 +217,7 @@ but can also be written as:
|
||||
ellipsis(<literal>...</literal>) as you can access attribute names as
|
||||
<literal>a</literal>, using <literal>args.a</literal>, which was given as an
|
||||
additional attribute to the function.
|
||||
</para>
|
||||
|
||||
<warning>
|
||||
<para>
|
||||
The <literal>args@</literal> expression is bound to the argument passed to the function which
|
||||
means that attributes with defaults that aren't explicitly specified in the function call
|
||||
won't cause an evaluation error, but won't exist in <literal>args</literal>.
|
||||
</para>
|
||||
<para>
|
||||
For instance
|
||||
<programlisting>
|
||||
let
|
||||
function = args@{ a ? 23, ... }: args;
|
||||
in
|
||||
function {}
|
||||
</programlisting>
|
||||
will evaluate to an empty attribute set.
|
||||
</para>
|
||||
</warning></listitem>
|
||||
</para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
@@ -15,16 +15,13 @@ weakest binding).</para>
|
||||
<tgroup cols='3'>
|
||||
<thead>
|
||||
<row>
|
||||
<entry>Name</entry>
|
||||
<entry>Syntax</entry>
|
||||
<entry>Associativity</entry>
|
||||
<entry>Description</entry>
|
||||
<entry>Precedence</entry>
|
||||
</row>
|
||||
</thead>
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>Select</entry>
|
||||
<entry><replaceable>e</replaceable> <literal>.</literal>
|
||||
<replaceable>attrpath</replaceable>
|
||||
[ <literal>or</literal> <replaceable>def</replaceable> ]
|
||||
@@ -36,25 +33,19 @@ weakest binding).</para>
|
||||
dot-separated list of attribute names.) If the attribute
|
||||
doesn’t exist, return <replaceable>def</replaceable> if
|
||||
provided, otherwise abort evaluation.</entry>
|
||||
<entry>1</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Application</entry>
|
||||
<entry><replaceable>e1</replaceable> <replaceable>e2</replaceable></entry>
|
||||
<entry>left</entry>
|
||||
<entry>Call function <replaceable>e1</replaceable> with
|
||||
argument <replaceable>e2</replaceable>.</entry>
|
||||
<entry>2</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Arithmetic Negation</entry>
|
||||
<entry><literal>-</literal> <replaceable>e</replaceable></entry>
|
||||
<entry>none</entry>
|
||||
<entry>Arithmetic negation.</entry>
|
||||
<entry>3</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Has Attribute</entry>
|
||||
<entry><replaceable>e</replaceable> <literal>?</literal>
|
||||
<replaceable>attrpath</replaceable></entry>
|
||||
<entry>none</entry>
|
||||
@@ -62,69 +53,34 @@ weakest binding).</para>
|
||||
the attribute denoted by <replaceable>attrpath</replaceable>;
|
||||
return <literal>true</literal> or
|
||||
<literal>false</literal>.</entry>
|
||||
<entry>4</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>List Concatenation</entry>
|
||||
<entry><replaceable>e1</replaceable> <literal>++</literal> <replaceable>e2</replaceable></entry>
|
||||
<entry>right</entry>
|
||||
<entry>List concatenation.</entry>
|
||||
<entry>5</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Multiplication</entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>*</literal> <replaceable>e2</replaceable>,
|
||||
</entry>
|
||||
<entry>left</entry>
|
||||
<entry>Arithmetic multiplication.</entry>
|
||||
<entry>6</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Division</entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>/</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>left</entry>
|
||||
<entry>Arithmetic division.</entry>
|
||||
<entry>6</entry>
|
||||
<entry>Arithmetic multiplication and division.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Addition</entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>+</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>left</entry>
|
||||
<entry>Arithmetic addition.</entry>
|
||||
<entry>7</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Subtraction</entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>+</literal> <replaceable>e2</replaceable>,
|
||||
<replaceable>e1</replaceable> <literal>-</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>left</entry>
|
||||
<entry>Arithmetic subtraction.</entry>
|
||||
<entry>7</entry>
|
||||
<entry>Arithmetic addition and subtraction. String or path concatenation (only by <literal>+</literal>).</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>String Concatenation</entry>
|
||||
<entry>
|
||||
<replaceable>string1</replaceable> <literal>+</literal> <replaceable>string2</replaceable>
|
||||
</entry>
|
||||
<entry>left</entry>
|
||||
<entry>String concatenation.</entry>
|
||||
<entry>7</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Not</entry>
|
||||
<entry><literal>!</literal> <replaceable>e</replaceable></entry>
|
||||
<entry>none</entry>
|
||||
<entry>Boolean negation.</entry>
|
||||
<entry>8</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Update</entry>
|
||||
<entry><replaceable>e1</replaceable> <literal>//</literal>
|
||||
<replaceable>e2</replaceable></entry>
|
||||
<entry>right</entry>
|
||||
@@ -133,90 +89,47 @@ weakest binding).</para>
|
||||
<replaceable>e2</replaceable> (with the latter taking
|
||||
precedence over the former in case of equally named
|
||||
attributes).</entry>
|
||||
<entry>9</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Less Than</entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal><</literal> <replaceable>e2</replaceable>,
|
||||
</entry>
|
||||
<entry>none</entry>
|
||||
<entry>Arithmetic comparison.</entry>
|
||||
<entry>10</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Less Than or Equal To</entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal><=</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>none</entry>
|
||||
<entry>Arithmetic comparison.</entry>
|
||||
<entry>10</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Greater Than</entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>></literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>none</entry>
|
||||
<entry>Arithmetic comparison.</entry>
|
||||
<entry>10</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Greater Than or Equal To</entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>></literal> <replaceable>e2</replaceable>,
|
||||
<replaceable>e1</replaceable> <literal><=</literal> <replaceable>e2</replaceable>,
|
||||
<replaceable>e1</replaceable> <literal>>=</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>none</entry>
|
||||
<entry>Arithmetic comparison.</entry>
|
||||
<entry>10</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Equality</entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>==</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>none</entry>
|
||||
<entry>Equality.</entry>
|
||||
<entry>11</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Inequality</entry>
|
||||
<entry>
|
||||
<replaceable>e1</replaceable> <literal>==</literal> <replaceable>e2</replaceable>,
|
||||
<replaceable>e1</replaceable> <literal>!=</literal> <replaceable>e2</replaceable>
|
||||
</entry>
|
||||
<entry>none</entry>
|
||||
<entry>Inequality.</entry>
|
||||
<entry>11</entry>
|
||||
<entry>Equality and inequality.</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Logical AND</entry>
|
||||
<entry><replaceable>e1</replaceable> <literal>&&</literal>
|
||||
<replaceable>e2</replaceable></entry>
|
||||
<entry>left</entry>
|
||||
<entry>Logical AND.</entry>
|
||||
<entry>12</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Logical OR</entry>
|
||||
<entry><replaceable>e1</replaceable> <literal>||</literal>
|
||||
<replaceable>e2</replaceable></entry>
|
||||
<entry>left</entry>
|
||||
<entry>Logical OR.</entry>
|
||||
<entry>13</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>Logical Implication</entry>
|
||||
<entry><replaceable>e1</replaceable> <literal>-></literal>
|
||||
<replaceable>e2</replaceable></entry>
|
||||
<entry>none</entry>
|
||||
<entry>Logical implication (equivalent to
|
||||
<literal>!<replaceable>e1</replaceable> ||
|
||||
<replaceable>e2</replaceable></literal>).</entry>
|
||||
<entry>14</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
</section>
|
||||
</section>
|
||||
@@ -43,7 +43,7 @@ use <command>nix-build</command>’s <option
|
||||
linkend='opt-out-link'>-o</option> switch to give the symlink another
|
||||
name.</para>
|
||||
|
||||
<para>Nix has transactional semantics. Once a build finishes
|
||||
<para>Nix has a transactional semantics. Once a build finishes
|
||||
successfully, Nix makes a note of this in its database: it registers
|
||||
that the path denoted by <envar>out</envar> is now
|
||||
<quote>valid</quote>. If you try to build the derivation again, Nix
|
||||
@@ -73,4 +73,12 @@ waiting for lock on `/nix/store/0h5b7hp8d4hqfrw8igvx97x1xawrjnac-hello-2.1.1x'</
|
||||
So it is always safe to run multiple instances of Nix in parallel
|
||||
(which isn’t the case with, say, <command>make</command>).</para>
|
||||
|
||||
<para>If you have a system with multiple CPUs, you may want to have
|
||||
Nix build different derivations in parallel (insofar as possible).
|
||||
Just pass the option <link linkend='opt-max-jobs'><option>-j
|
||||
<replaceable>N</replaceable></option></link>, where
|
||||
<replaceable>N</replaceable> is the maximum number of jobs to be run
|
||||
in parallel, or set. Typically this should be the number of
|
||||
CPUs.</para>
|
||||
|
||||
</section>
|
||||
|
||||
BIN
doc/manual/images/callouts/1.gif
Normal file
|
After Width: | Height: | Size: 889 B |
BIN
doc/manual/images/callouts/10.gif
Normal file
|
After Width: | Height: | Size: 929 B |
BIN
doc/manual/images/callouts/11.gif
Normal file
|
After Width: | Height: | Size: 202 B |
BIN
doc/manual/images/callouts/12.gif
Normal file
|
After Width: | Height: | Size: 210 B |
BIN
doc/manual/images/callouts/13.gif
Normal file
|
After Width: | Height: | Size: 209 B |
BIN
doc/manual/images/callouts/14.gif
Normal file
|
After Width: | Height: | Size: 205 B |
BIN
doc/manual/images/callouts/15.gif
Normal file
|
After Width: | Height: | Size: 210 B |
BIN
doc/manual/images/callouts/2.gif
Normal file
|
After Width: | Height: | Size: 907 B |
BIN
doc/manual/images/callouts/3.gif
Normal file
|
After Width: | Height: | Size: 914 B |
BIN
doc/manual/images/callouts/4.gif
Normal file
|
After Width: | Height: | Size: 907 B |
BIN
doc/manual/images/callouts/5.gif
Normal file
|
After Width: | Height: | Size: 916 B |
BIN
doc/manual/images/callouts/6.gif
Normal file
|
After Width: | Height: | Size: 218 B |
BIN
doc/manual/images/callouts/7.gif
Normal file
|
After Width: | Height: | Size: 907 B |
BIN
doc/manual/images/callouts/8.gif
Normal file
|
After Width: | Height: | Size: 918 B |
BIN
doc/manual/images/callouts/9.gif
Normal file
|
After Width: | Height: | Size: 923 B |
@@ -39,7 +39,7 @@ bundle.</para>
|
||||
<step><para>Set the environment variable and install Nix</para>
|
||||
<screen>
|
||||
$ export NIX_SSL_CERT_FILE=/etc/ssl/my-certificate-bundle.crt
|
||||
$ sh <(curl -L https://nixos.org/nix/install)
|
||||
$ sh <(curl https://nixos.org/nix/install)
|
||||
</screen></step>
|
||||
|
||||
<step><para>In the shell profile and rc files (for example,
|
||||
@@ -67,23 +67,5 @@ $ sudo launchctl kickstart -k system/org.nixos.nix-daemon
|
||||
</screen>
|
||||
</section>
|
||||
|
||||
<section xml:id="sec-installer-proxy-settings">
|
||||
|
||||
<title>Proxy Environment Variables</title>
|
||||
|
||||
<para>The Nix installer has special handling for these proxy-related
|
||||
environment variables:
|
||||
<varname>http_proxy</varname>, <varname>https_proxy</varname>,
|
||||
<varname>ftp_proxy</varname>, <varname>no_proxy</varname>,
|
||||
<varname>HTTP_PROXY</varname>, <varname>HTTPS_PROXY</varname>,
|
||||
<varname>FTP_PROXY</varname>, <varname>NO_PROXY</varname>.
|
||||
</para>
|
||||
<para>If any of these variables are set when running the Nix installer,
|
||||
then the installer will create an override file at
|
||||
<filename>/etc/systemd/system/nix-daemon.service.d/override.conf</filename>
|
||||
so <command>nix-daemon</command> will use them.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
</chapter>
|
||||
|
||||
@@ -6,30 +6,16 @@
|
||||
|
||||
<title>Installing a Binary Distribution</title>
|
||||
|
||||
<para>
|
||||
If you are using Linux or macOS versions up to 10.14 (Mojave), the
|
||||
easiest way to install Nix is to run the following command:
|
||||
</para>
|
||||
<para>If you are using Linux or macOS, the easiest way to install Nix
|
||||
is to run the following command:
|
||||
|
||||
<screen>
|
||||
$ sh <(curl -L https://nixos.org/nix/install)
|
||||
$ sh <(curl https://nixos.org/nix/install)
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
If you're using macOS 10.15 (Catalina) or newer, consult
|
||||
<link linkend="sect-macos-installation">the macOS installation instructions</link>
|
||||
before installing.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
As of Nix 2.1.0, the Nix installer will always default to creating a
|
||||
single-user installation, however opting in to the multi-user
|
||||
installation is highly recommended.
|
||||
<!-- TODO: this explains *neither* why the default version is
|
||||
single-user, nor why we'd recommend multi-user over the default.
|
||||
True prospective users don't have much basis for evaluating this.
|
||||
What's it to me? Who should pick which? Why? What if I pick wrong?
|
||||
-->
|
||||
As of Nix 2.1.0, the Nix installer will always default to creating a
|
||||
single-user installation, however opting in to the multi-user
|
||||
installation is highly recommended.
|
||||
</para>
|
||||
|
||||
<section xml:id="sect-single-user-installation">
|
||||
@@ -39,7 +25,7 @@
|
||||
To explicitly select a single-user installation on your system:
|
||||
|
||||
<screen>
|
||||
sh <(curl -L https://nixos.org/nix/install) --no-daemon
|
||||
sh <(curl https://nixos.org/nix/install) --no-daemon
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
@@ -50,7 +36,7 @@ run this under your usual user account, <emphasis>not</emphasis> as
|
||||
root. The script will invoke <command>sudo</command> to create
|
||||
<filename>/nix</filename> if it doesn’t already exist. If you don’t
|
||||
have <command>sudo</command>, you should manually create
|
||||
<filename>/nix</filename> first as root, e.g.:
|
||||
<command>/nix</command> first as root, e.g.:
|
||||
|
||||
<screen>
|
||||
$ mkdir /nix
|
||||
@@ -61,7 +47,7 @@ The install script will modify the first writable file from amongst
|
||||
<filename>.bash_profile</filename>, <filename>.bash_login</filename>
|
||||
and <filename>.profile</filename> to source
|
||||
<filename>~/.nix-profile/etc/profile.d/nix.sh</filename>. You can set
|
||||
the <envar>NIX_INSTALLER_NO_MODIFY_PROFILE</envar> environment
|
||||
the <command>NIX_INSTALLER_NO_MODIFY_PROFILE</command> environment
|
||||
variable before executing the install script to disable this
|
||||
behaviour.
|
||||
</para>
|
||||
@@ -95,9 +81,11 @@ $ rm -rf /nix
|
||||
<para>
|
||||
You can instruct the installer to perform a multi-user
|
||||
installation on your system:
|
||||
</para>
|
||||
|
||||
<screen>sh <(curl -L https://nixos.org/nix/install) --daemon</screen>
|
||||
<screen>
|
||||
sh <(curl https://nixos.org/nix/install) --daemon
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The multi-user installation of Nix will create build users between
|
||||
@@ -148,280 +136,13 @@ sudo rm /Library/LaunchDaemons/org.nixos.nix-daemon.plist
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="sect-macos-installation">
|
||||
<title>macOS Installation</title>
|
||||
|
||||
<para>
|
||||
Starting with macOS 10.15 (Catalina), the root filesystem is read-only.
|
||||
This means <filename>/nix</filename> can no longer live on your system
|
||||
volume, and that you'll need a workaround to install Nix.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The recommended approach, which creates an unencrypted APFS volume
|
||||
for your Nix store and a "synthetic" empty directory to mount it
|
||||
over at <filename>/nix</filename>, is least likely to impair Nix
|
||||
or your system.
|
||||
</para>
|
||||
|
||||
<note><para>
|
||||
With all separate-volume approaches, it's possible something on
|
||||
your system (particularly daemons/services and restored apps) may
|
||||
need access to your Nix store before the volume is mounted. Adding
|
||||
additional encryption makes this more likely.
|
||||
</para></note>
|
||||
|
||||
<para>
|
||||
If you're using a recent Mac with a
|
||||
<link xlink:href="https://www.apple.com/euro/mac/shared/docs/Apple_T2_Security_Chip_Overview.pdf">T2 chip</link>,
|
||||
your drive will still be encrypted at rest (in which case "unencrypted"
|
||||
is a bit of a misnomer). To use this approach, just install Nix with:
|
||||
</para>
|
||||
|
||||
<screen>$ sh <(curl -L https://nixos.org/nix/install) --darwin-use-unencrypted-nix-store-volume</screen>
|
||||
|
||||
<para>
|
||||
If you don't like the sound of this, you'll want to weigh the
|
||||
other approaches and tradeoffs detailed in this section.
|
||||
</para>
|
||||
|
||||
<note>
|
||||
<title>Eventual solutions?</title>
|
||||
<para>
|
||||
All of the known workarounds have drawbacks, but we hope
|
||||
better solutions will be available in the future. Some that
|
||||
we have our eye on are:
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
A true firmlink would enable the Nix store to live on the
|
||||
primary data volume without the build problems caused by
|
||||
the symlink approach. End users cannot currently
|
||||
create true firmlinks.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If the Nix store volume shared FileVault encryption
|
||||
with the primary data volume (probably by using the same
|
||||
volume group and role), FileVault encryption could be
|
||||
easily supported by the installer without requiring
|
||||
manual setup by each user.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</note>
|
||||
|
||||
<section xml:id="sect-macos-installation-change-store-prefix">
|
||||
<title>Change the Nix store path prefix</title>
|
||||
<para>
|
||||
Changing the default prefix for the Nix store is a simple
|
||||
approach which enables you to leave it on your root volume,
|
||||
where it can take full advantage of FileVault encryption if
|
||||
enabled. Unfortunately, this approach also opts your device out
|
||||
of some benefits that are enabled by using the same prefix
|
||||
across systems:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
Your system won't be able to take advantage of the binary
|
||||
cache (unless someone is able to stand up and support
|
||||
duplicate caching infrastructure), which means you'll
|
||||
spend more time waiting for builds.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
It's harder to build and deploy packages to Linux systems.
|
||||
</para>
|
||||
</listitem>
|
||||
<!-- TODO: may be more here -->
|
||||
</itemizedlist>
|
||||
|
||||
<!-- TODO: Yes, but how?! -->
|
||||
|
||||
It would also possible (and often requested) to just apply this
|
||||
change ecosystem-wide, but it's an intrusive process that has
|
||||
side effects we want to avoid for now.
|
||||
<!-- magnificent hand-wavy gesture -->
|
||||
</para>
|
||||
<para>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section xml:id="sect-macos-installation-encrypted-volume">
|
||||
<title>Use a separate encrypted volume</title>
|
||||
<para>
|
||||
If you like, you can also add encryption to the recommended
|
||||
approach taken by the installer. You can do this by pre-creating
|
||||
an encrypted volume before you run the installer--or you can
|
||||
run the installer and encrypt the volume it creates later.
|
||||
<!-- TODO: see later note about whether this needs both add-encryption and from-scratch directions -->
|
||||
</para>
|
||||
<para>
|
||||
In either case, adding encryption to a second volume isn't quite
|
||||
as simple as enabling FileVault for your boot volume. Before you
|
||||
dive in, there are a few things to weigh:
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
The additional volume won't be encrypted with your existing
|
||||
FileVault key, so you'll need another mechanism to decrypt
|
||||
the volume.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You can store the password in Keychain to automatically
|
||||
decrypt the volume on boot--but it'll have to wait on Keychain
|
||||
and may not mount before your GUI apps restore. If any of
|
||||
your launchd agents or apps depend on Nix-installed software
|
||||
(for example, if you use a Nix-installed login shell), the
|
||||
restore may fail or break.
|
||||
</para>
|
||||
<para>
|
||||
On a case-by-case basis, you may be able to work around this
|
||||
problem by using <command>wait4path</command> to block
|
||||
execution until your executable is available.
|
||||
</para>
|
||||
<para>
|
||||
It's also possible to decrypt and mount the volume earlier
|
||||
with a login hook--but this mechanism appears to be
|
||||
deprecated and its future is unclear.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
You can hard-code the password in the clear, so that your
|
||||
store volume can be decrypted before Keychain is available.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
<para>
|
||||
If you are comfortable navigating these tradeoffs, you can encrypt the volume with
|
||||
something along the lines of:
|
||||
<!-- TODO:
|
||||
I don't know if this also needs from-scratch instructions?
|
||||
can we just recommend use-the-installer-and-then-encrypt?
|
||||
-->
|
||||
</para>
|
||||
<!--
|
||||
TODO: it looks like this option can be encryptVolume|encrypt|enableFileVault
|
||||
|
||||
It may be more clear to use encryptVolume, here? FileVault seems
|
||||
heavily associated with the boot-volume behavior; I worry
|
||||
a little that it can mislead here, especially as it gets
|
||||
copied around minus doc context...?
|
||||
-->
|
||||
<screen>alice$ diskutil apfs enableFileVault /nix -user disk</screen>
|
||||
|
||||
<!-- TODO: and then go into detail on the mount/decrypt approaches? -->
|
||||
</section>
|
||||
|
||||
<section xml:id="sect-macos-installation-symlink">
|
||||
<!--
|
||||
Maybe a good razor is: if we'd hate having to support someone who
|
||||
installed Nix this way, it shouldn't even be detailed?
|
||||
-->
|
||||
<title>Symlink the Nix store to a custom location</title>
|
||||
<para>
|
||||
Another simple approach is using <filename>/etc/synthetic.conf</filename>
|
||||
to symlink the Nix store to the data volume. This option also
|
||||
enables your store to share any configured FileVault encryption.
|
||||
Unfortunately, builds that resolve the symlink may leak the
|
||||
canonical path or even fail.
|
||||
</para>
|
||||
<para>
|
||||
Because of these downsides, we can't recommend this approach.
|
||||
</para>
|
||||
<!-- Leaving out instructions for this one. -->
|
||||
</section>
|
||||
|
||||
<section xml:id="sect-macos-installation-recommended-notes">
|
||||
<title>Notes on the recommended approach</title>
|
||||
<para>
|
||||
This section goes into a little more detail on the recommended
|
||||
approach. You don't need to understand it to run the installer,
|
||||
but it can serve as a helpful reference if you run into trouble.
|
||||
</para>
|
||||
<orderedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
In order to compose user-writable locations into the new
|
||||
read-only system root, Apple introduced a new concept called
|
||||
<literal>firmlinks</literal>, which it describes as a
|
||||
"bi-directional wormhole" between two filesystems. You can
|
||||
see the current firmlinks in <filename>/usr/share/firmlinks</filename>.
|
||||
Unfortunately, firmlinks aren't (currently?) user-configurable.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
For special cases like NFS mount points or package manager roots,
|
||||
<link xlink:href="https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man5/synthetic.conf.5.html">synthetic.conf(5)</link>
|
||||
supports limited user-controlled file-creation (of symlinks,
|
||||
and synthetic empty directories) at <filename>/</filename>.
|
||||
To create a synthetic empty directory for mounting at <filename>/nix</filename>,
|
||||
add the following line to <filename>/etc/synthetic.conf</filename>
|
||||
(create it if necessary):
|
||||
</para>
|
||||
|
||||
<screen>nix</screen>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
This configuration is applied at boot time, but you can use
|
||||
<command>apfs.util</command> to trigger creation (not deletion)
|
||||
of new entries without a reboot:
|
||||
</para>
|
||||
|
||||
<screen>alice$ /System/Library/Filesystems/apfs.fs/Contents/Resources/apfs.util -B</screen>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Create the new APFS volume with diskutil:
|
||||
</para>
|
||||
|
||||
<screen>alice$ sudo diskutil apfs addVolume diskX APFS 'Nix Store' -mountpoint /nix</screen>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>
|
||||
Using <command>vifs</command>, add the new mount to
|
||||
<filename>/etc/fstab</filename>. If it doesn't already have
|
||||
other entries, it should look something like:
|
||||
</para>
|
||||
|
||||
<screen>
|
||||
#
|
||||
# Warning - this file should only be modified with vifs(8)
|
||||
#
|
||||
# Failure to do so is unsupported and may be destructive.
|
||||
#
|
||||
LABEL=Nix\040Store /nix apfs rw,nobrowse
|
||||
</screen>
|
||||
|
||||
<para>
|
||||
The nobrowse setting will keep Spotlight from indexing this
|
||||
volume, and keep it from showing up on your desktop.
|
||||
</para>
|
||||
</listitem>
|
||||
</orderedlist>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
|
||||
<section xml:id="sect-nix-install-pinned-version-url">
|
||||
<title>Installing a pinned Nix version from a URL</title>
|
||||
|
||||
<para>
|
||||
NixOS.org hosts version-specific installation URLs for all Nix
|
||||
versions since 1.11.16, at
|
||||
<literal>https://releases.nixos.org/nix/nix-<replaceable>version</replaceable>/install</literal>.
|
||||
<literal>https://nixos.org/releases/nix/nix-VERSION/install</literal>.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
@@ -429,7 +150,7 @@ LABEL=Nix\040Store /nix apfs rw,nobrowse
|
||||
NixOS.org installation script:
|
||||
|
||||
<screen>
|
||||
sh <(curl -L https://nixos.org/nix/install)
|
||||
sh <(curl https://nixos.org/nix/install)
|
||||
</screen>
|
||||
</para>
|
||||
|
||||
|
||||
@@ -8,20 +8,12 @@
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>GNU Autoconf
|
||||
(<link xlink:href="https://www.gnu.org/software/autoconf/"/>)
|
||||
and the autoconf-archive macro collection
|
||||
(<link xlink:href="https://www.gnu.org/software/autoconf-archive/"/>).
|
||||
These are only needed to run the bootstrap script, and are not necessary
|
||||
if your source distribution came with a pre-built
|
||||
<literal>./configure</literal> script.</para></listitem>
|
||||
|
||||
<listitem><para>GNU Make.</para></listitem>
|
||||
|
||||
<listitem><para>Bash Shell. The <literal>./configure</literal> script
|
||||
relies on bashisms, so Bash is required.</para></listitem>
|
||||
|
||||
<listitem><para>A version of GCC or Clang that supports C++17.</para></listitem>
|
||||
<listitem><para>A version of GCC or Clang that supports C++14.</para></listitem>
|
||||
|
||||
<listitem><para><command>pkg-config</command> to locate
|
||||
dependencies. If your distribution does not provide it, you can get
|
||||
@@ -70,10 +62,6 @@
|
||||
1.66.0 or higher. It can be obtained from the official web site
|
||||
<link xlink:href="https://www.boost.org/" />.</para></listitem>
|
||||
|
||||
<listitem><para>The <literal>editline</literal> library of version
|
||||
1.14.0 or higher. It can be obtained from the its repository
|
||||
<link xlink:href="https://github.com/troglobit/editline" />.</para></listitem>
|
||||
|
||||
<listitem><para>The <command>xmllint</command> and
|
||||
<command>xsltproc</command> programs to build this manual and the
|
||||
man-pages. These are part of the <literal>libxml2</literal> and
|
||||
|
||||
@@ -17,11 +17,6 @@
|
||||
|
||||
<para>
|
||||
Single-user installations of Nix should run this:
|
||||
<command>nix-channel --update; nix-env -iA nixpkgs.nix nixpkgs.cacert</command>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Multi-user Nix users on Linux should run this with sudo:
|
||||
<command>nix-channel --update; nix-env -iA nixpkgs.nix nixpkgs.cacert; systemctl daemon-reload; systemctl restart nix-daemon</command>
|
||||
<command>nix-channel --update; nix-env -iA nixpkgs.nix</command>
|
||||
</para>
|
||||
</chapter>
|
||||
|
||||
@@ -15,7 +15,7 @@ to subsequent chapters.</para>
|
||||
<step><para>Install single-user Nix by running the following:
|
||||
|
||||
<screen>
|
||||
$ bash <(curl -L https://nixos.org/nix/install)
|
||||
$ bash <(curl https://nixos.org/nix/install)
|
||||
</screen>
|
||||
|
||||
This will install Nix in <filename>/nix</filename>. The install script
|
||||
|
||||
@@ -4,10 +4,11 @@ ifeq ($(doc_generate),yes)
|
||||
XSLTPROC = $(xsltproc) --nonet $(xmlflags) \
|
||||
--param section.autolabel 1 \
|
||||
--param section.label.includes.component.label 1 \
|
||||
--param html.stylesheet \'style.css\' \
|
||||
--param xref.with.number.and.title 1 \
|
||||
--param toc.section.depth 3 \
|
||||
--param admon.style \'\' \
|
||||
--param callout.graphics 0 \
|
||||
--param callout.graphics.extension \'.gif\' \
|
||||
--param contrib.inline.enabled 0 \
|
||||
--stringparam generate.toc "book toc" \
|
||||
--param keep.relative.image.uris 0
|
||||
@@ -65,10 +66,12 @@ $(d)/manual.html: $(d)/manual.xml $(MANUAL_SRCS) $(d)/manual.is-valid
|
||||
$(docbookxsl)/profiling/profile.xsl $< | \
|
||||
$(XSLTPROC) --output $@ $(docbookxsl)/xhtml/docbook.xsl -
|
||||
|
||||
$(foreach file, $(d)/manual.html, $(eval $(call install-data-in, $(file), $(docdir)/manual)))
|
||||
$(foreach file, $(d)/manual.html $(d)/style.css, $(eval $(call install-data-in, $(file), $(docdir)/manual)))
|
||||
|
||||
$(foreach file, $(wildcard $(d)/figures/*.png), $(eval $(call install-data-in, $(file), $(docdir)/manual/figures)))
|
||||
|
||||
$(foreach file, $(wildcard $(d)/images/callouts/*.gif), $(eval $(call install-data-in, $(file), $(docdir)/manual/images/callouts)))
|
||||
|
||||
$(eval $(call install-symlink, manual.html, $(docdir)/manual/index.html))
|
||||
|
||||
|
||||
|
||||
@@ -24,11 +24,11 @@ symlinks to the files of the active applications. </para>
|
||||
<para>Components are installed from a set of <emphasis>Nix
|
||||
expressions</emphasis> that tell Nix how to build those packages,
|
||||
including, if necessary, their dependencies. There is a collection of
|
||||
Nix expressions called the Nixpkgs package collection that contains
|
||||
Nix expressions called the Nix Package collection that contains
|
||||
packages ranging from basic development stuff such as GCC and Glibc,
|
||||
to end-user applications like Mozilla Firefox. (Nix is however not
|
||||
tied to the Nixpkgs package collection; you could write your own Nix
|
||||
expressions based on Nixpkgs, or completely new ones.)</para>
|
||||
tied to the Nix Package collection; you could write your own Nix
|
||||
expressions based on it, or completely new ones.)</para>
|
||||
|
||||
<para>You can manually download the latest version of Nixpkgs from
|
||||
<link xlink:href='http://nixos.org/nixpkgs/download.html'/>. However,
|
||||
|
||||
@@ -17,9 +17,6 @@ a set of Nix expressions and a manifest. Using the command <link
|
||||
linkend="sec-nix-channel"><command>nix-channel</command></link> you
|
||||
can automatically stay up to date with whatever is available at that
|
||||
URL.</para>
|
||||
|
||||
<para>To see the list of official NixOS channels, visit <link
|
||||
xlink:href="https://nixos.org/channels" />.</para>
|
||||
|
||||
<para>You can “subscribe” to a channel using
|
||||
<command>nix-channel --add</command>, e.g.,
|
||||
|
||||
@@ -52,13 +52,12 @@ garbage collector as follows:
|
||||
<screen>
|
||||
$ nix-store --gc</screen>
|
||||
|
||||
The behaviour of the gargage collector is affected by the
|
||||
<literal>keep-derivations</literal> (default: true) and <literal>keep-outputs</literal>
|
||||
The behaviour of the gargage collector is affected by the <literal>keep-
|
||||
derivations</literal> (default: true) and <literal>keep-outputs</literal>
|
||||
(default: false) options in the Nix configuration file. The defaults will ensure
|
||||
that all derivations that are build-time dependencies of garbage collector roots
|
||||
will be kept and that all output paths that are runtime dependencies
|
||||
will be kept as well. All other derivations or paths will be collected.
|
||||
(This is usually what you want, but while you are developing
|
||||
that all derivations that are not build-time dependencies of garbage collector roots
|
||||
will be collected but that all output paths that are not runtime dependencies
|
||||
will be collected. (This is usually what you want, but while you are developing
|
||||
it may make sense to keep outputs to ensure that rebuild times are quick.)
|
||||
|
||||
If you are feeling uncertain, you can also first view what files would
|
||||
|
||||
@@ -113,7 +113,7 @@ the S3 URL:</para>
|
||||
exactly <uri>s3://example-nix-cache</uri>.</para>
|
||||
|
||||
<para>Nix will use the <link
|
||||
xlink:href="https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/credentials.html">default
|
||||
xlink:href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default.">default
|
||||
credential provider chain</link> for authenticating requests to
|
||||
Amazon S3.</para>
|
||||
|
||||
@@ -138,7 +138,7 @@ the S3 URL:</para>
|
||||
be <uri>s3://example-nix-cache</uri>.</para>
|
||||
|
||||
<para>Nix will use the <link
|
||||
xlink:href="https://docs.aws.amazon.com/sdk-for-cpp/v1/developer-guide/credentials.html">default
|
||||
xlink:href="https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/credentials.html#credentials-default.">default
|
||||
credential provider chain</link> for authenticating requests to
|
||||
Amazon S3.</para>
|
||||
|
||||
@@ -159,6 +159,7 @@ the S3 URL:</para>
|
||||
"s3:ListBucket",
|
||||
"s3:ListBucketMultipartUploads",
|
||||
"s3:ListMultipartUploadParts",
|
||||
"s3:ListObjects",
|
||||
"s3:PutObject"
|
||||
],
|
||||
"Resource": [
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
</partintro>
|
||||
-->
|
||||
|
||||
<xi:include href="rl-2.3.xml" />
|
||||
<xi:include href="rl-2.2.xml" />
|
||||
<xi:include href="rl-2.1.xml" />
|
||||
<xi:include href="rl-2.0.xml" />
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<para>NOTE: the hashing scheme in Nix 0.8 changed (as detailed below).
|
||||
As a result, <command>nix-pull</command> manifests and channels built
|
||||
for Nix 0.7 and below will not work anymore. However, the Nix
|
||||
for Nix 0.7 and below will now work anymore. However, the Nix
|
||||
expression language has not changed, so you can still build from
|
||||
source. Also, existing user environments continue to work. Nix 0.8
|
||||
will automatically upgrade the database schema of previous
|
||||
|
||||
@@ -503,14 +503,14 @@
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para><emphasis>Pure evaluation mode</emphasis>. With the
|
||||
<literal>--pure-eval</literal> flag, Nix enables a variant of the existing
|
||||
restricted evaluation mode that forbids access to anything that could cause
|
||||
different evaluations of the same command line arguments to produce a
|
||||
<para><emphasis>Pure evaluation mode</emphasis>. This is a variant
|
||||
of the existing restricted evaluation mode. In pure mode, the Nix
|
||||
evaluator forbids access to anything that could cause different
|
||||
evaluations of the same command line arguments to produce a
|
||||
different result. This includes builtin functions such as
|
||||
<function>builtins.getEnv</function>, but more importantly,
|
||||
<emphasis>all</emphasis> filesystem or network access unless a content hash
|
||||
or commit hash is specified. For example, calls to
|
||||
<emphasis>all</emphasis> filesystem or network access unless a
|
||||
content hash or commit hash is specified. For example, calls to
|
||||
<function>builtins.fetchGit</function> are only allowed if a
|
||||
<varname>rev</varname> attribute is specified.</para>
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
<section xmlns="http://docbook.org/ns/docbook"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude"
|
||||
version="5.0"
|
||||
xml:id="ssec-relnotes-2.3">
|
||||
|
||||
<title>Release 2.3 (2019-09-04)</title>
|
||||
|
||||
<para>This is primarily a bug fix release. However, it makes some
|
||||
incompatible changes:</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>
|
||||
<para>Nix now uses BSD file locks instead of POSIX file
|
||||
locks. Because of this, you should not use Nix 2.3 and previous
|
||||
releases at the same time on a Nix store.</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
<para>It also has the following changes:</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
||||
<listitem>
|
||||
<para><function>builtins.fetchGit</function>'s <varname>ref</varname>
|
||||
argument now allows specifying an absolute remote ref.
|
||||
Nix will automatically prefix <varname>ref</varname> with
|
||||
<literal>refs/heads</literal> only if <varname>ref</varname> doesn't
|
||||
already begin with <literal>refs/</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The installer now enables sandboxing by default on Linux when the
|
||||
system has the necessary kernel support.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The <literal>max-jobs</literal> setting now defaults to 1.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>New builtin functions:
|
||||
<literal>builtins.isPath</literal>,
|
||||
<literal>builtins.hashFile</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>The <command>nix</command> command has a new
|
||||
<option>--print-build-logs</option> (<option>-L</option>) flag to
|
||||
print build log output to stderr, rather than showing the last log
|
||||
line in the progress bar. To distinguish between concurrent
|
||||
builds, log lines are prefixed by the name of the package.
|
||||
</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Builds are now executed in a pseudo-terminal, and the
|
||||
<envar>TERM</envar> environment variable is set to
|
||||
<literal>xterm-256color</literal>. This allows many programs
|
||||
(e.g. <command>gcc</command>, <command>clang</command>,
|
||||
<command>cmake</command>) to print colorized log output.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Add <option>--no-net</option> convenience flag. This flag
|
||||
disables substituters; sets the <literal>tarball-ttl</literal>
|
||||
setting to infinity (ensuring that any previously downloaded files
|
||||
are considered current); and disables retrying downloads and sets
|
||||
the connection timeout to the minimum. This flag is enabled
|
||||
automatically if there are no configured non-loopback network
|
||||
interfaces.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Add a <literal>post-build-hook</literal> setting to run a
|
||||
program after a build has succeeded.</para>
|
||||
</listitem>
|
||||
|
||||
<listitem>
|
||||
<para>Add a <literal>trace-function-calls</literal> setting to log
|
||||
the duration of Nix function calls to stderr.</para>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist>
|
||||
|
||||
</section>
|
||||
263
doc/manual/style.css
Normal file
@@ -0,0 +1,263 @@
|
||||
/* Copied from http://bakefile.sourceforge.net/, which appears
|
||||
licensed under the GNU GPL. */
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Basic headers and text:
|
||||
***************************************************************************/
|
||||
|
||||
body
|
||||
{
|
||||
font-family: "Nimbus Sans L", sans-serif;
|
||||
background: white;
|
||||
margin: 2em 1em 2em 1em;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4
|
||||
{
|
||||
color: #005aa0;
|
||||
}
|
||||
|
||||
h1 /* title */
|
||||
{
|
||||
font-size: 200%;
|
||||
}
|
||||
|
||||
div.part h1
|
||||
{
|
||||
font-size: 240%;
|
||||
}
|
||||
|
||||
h2 /* chapters, appendices, subtitle */
|
||||
{
|
||||
font-size: 180%;
|
||||
}
|
||||
|
||||
div.part
|
||||
{
|
||||
margin-top: 4em;
|
||||
}
|
||||
|
||||
/* Extra space between chapters, appendices. */
|
||||
div.chapter > div.titlepage h2, div.appendix > div.titlepage h2
|
||||
{
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
div.section > div.titlepage h2 /* sections */
|
||||
{
|
||||
font-size: 150%;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
h3 /* subsections */
|
||||
{
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
div.simplesect h2
|
||||
{
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
div.appendix h3
|
||||
{
|
||||
font-size: 150%;
|
||||
margin-top: 1.5em;
|
||||
}
|
||||
|
||||
div.refentry\.separator
|
||||
{
|
||||
margin-top: 2.5em;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
div.refnamediv h2, div.refsynopsisdiv h2, div.refsection h2 /* refentry parts */
|
||||
{
|
||||
margin-top: 1.4em;
|
||||
font-size: 125%;
|
||||
}
|
||||
|
||||
div.refsection h3
|
||||
{
|
||||
font-size: 110%;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Examples:
|
||||
***************************************************************************/
|
||||
|
||||
div.example
|
||||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 6px 6px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
background: #f4f4f8;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
|
||||
div.example p.title
|
||||
{
|
||||
margin-top: 0em;
|
||||
}
|
||||
|
||||
div.example pre
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Screen dumps:
|
||||
***************************************************************************/
|
||||
|
||||
pre.screen, pre.programlisting
|
||||
{
|
||||
padding: 6px 6px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
color: #600000;
|
||||
background: #f4f4f8;
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
div.example pre.programlisting
|
||||
{
|
||||
border: 0px;
|
||||
padding: 0 0;
|
||||
margin: 0 0 0 0;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Notes, warnings etc:
|
||||
***************************************************************************/
|
||||
|
||||
.note, .warning
|
||||
{
|
||||
border: 1px solid #b0b0b0;
|
||||
padding: 3px 3px;
|
||||
margin-left: 1.5em;
|
||||
margin-right: 1.5em;
|
||||
margin-bottom: 1em;
|
||||
padding: 0.3em 0.3em 0.3em 0.3em;
|
||||
background: #fffff5;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
|
||||
div.note, div.warning
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.note h3, div.warning h3
|
||||
{
|
||||
color: red;
|
||||
font-size: 100%;
|
||||
padding-right: 0.5em;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.note p, div.warning p
|
||||
{
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
div.note h3 + p, div.warning h3 + p
|
||||
{
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div.note h3
|
||||
{
|
||||
color: blue;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
div.navfooter *
|
||||
{
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Links colors and highlighting:
|
||||
***************************************************************************/
|
||||
|
||||
a { text-decoration: none; }
|
||||
a:hover { text-decoration: underline; }
|
||||
a:link { color: #0048b3; }
|
||||
a:visited { color: #002a6a; }
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Table of contents:
|
||||
***************************************************************************/
|
||||
|
||||
div.toc
|
||||
{
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
div.toc dl
|
||||
{
|
||||
margin-top: 0em;
|
||||
margin-bottom: 0em;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Special elements:
|
||||
***************************************************************************/
|
||||
|
||||
tt, code
|
||||
{
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
.term
|
||||
{
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
|
||||
div.variablelist dd p, div.glosslist dd p
|
||||
{
|
||||
margin-top: 0em;
|
||||
}
|
||||
|
||||
div.variablelist dd, div.glosslist dd
|
||||
{
|
||||
margin-left: 1.5em;
|
||||
}
|
||||
|
||||
div.glosslist dt
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.varname
|
||||
{
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
span.command strong
|
||||
{
|
||||
font-weight: normal;
|
||||
color: #400000;
|
||||
}
|
||||
|
||||
div.calloutlist table
|
||||
{
|
||||
}
|
||||
|
||||
table
|
||||
{
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
div.affiliation
|
||||
{
|
||||
font-style: italic;
|
||||
}
|
||||
8
local.mk
@@ -2,15 +2,11 @@ ifeq ($(MAKECMDGOALS), dist)
|
||||
dist-files += $(shell cat .dist-files)
|
||||
endif
|
||||
|
||||
dist-files += configure config.h.in perl/configure
|
||||
dist-files += configure config.h.in nix.spec perl/configure
|
||||
|
||||
clean-files += Makefile.config
|
||||
|
||||
GLOBAL_CXXFLAGS += -Wno-deprecated-declarations
|
||||
GLOBAL_CXXFLAGS += -I . -I src -I src/libutil -I src/libstore -I src/libmain -I src/libexpr -I src/nix
|
||||
|
||||
$(foreach i, config.h $(call rwildcard, src/lib*, *.hh), \
|
||||
$(eval $(call install-file-in, $(i), $(includedir)/nix, 0644)))
|
||||
|
||||
$(GCH) $(PCH): src/libutil/util.hh config.h
|
||||
|
||||
GCH_CXXFLAGS = -I src/libutil
|
||||
|
||||
@@ -1,951 +0,0 @@
|
||||
# ===========================================================================
|
||||
# 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
|
||||
|
||||
]])
|
||||
@@ -1,35 +0,0 @@
|
||||
# =============================================================================
|
||||
# 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])])
|
||||
@@ -1,5 +1,5 @@
|
||||
#! /usr/bin/env nix-shell
|
||||
#! nix-shell -i perl -p perl perlPackages.LWPUserAgent perlPackages.LWPProtocolHttps perlPackages.FileSlurp perlPackages.NetAmazonS3 gnupg1
|
||||
#! nix-shell -i perl -p perl perlPackages.LWPUserAgent perlPackages.LWPProtocolHttps perlPackages.FileSlurp gnupg1
|
||||
|
||||
use strict;
|
||||
use Data::Dumper;
|
||||
@@ -9,16 +9,12 @@ 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 $releasesDir = "/home/eelco/mnt/releases";
|
||||
my $nixpkgsDir = "/home/eelco/Dev/nixpkgs-pristine";
|
||||
|
||||
my $TMPDIR = $ENV{'TMPDIR'} // "/tmp";
|
||||
|
||||
# FIXME: cut&paste from nixos-channel-scripts.
|
||||
sub fetch {
|
||||
my ($url, $type) = @_;
|
||||
@@ -46,31 +42,13 @@ my $version = $1;
|
||||
|
||||
print STDERR "Nix revision is $nixRev, version is $version\n";
|
||||
|
||||
my $releaseDir = "nix/$releaseName";
|
||||
File::Path::make_path($releasesDir);
|
||||
if (system("mountpoint -q $releasesDir") != 0) {
|
||||
system("sshfs hydra-mirror:/releases $releasesDir") == 0 or die;
|
||||
}
|
||||
|
||||
my $tmpDir = "$TMPDIR/nix-release/$releaseName";
|
||||
File::Path::make_path($tmpDir);
|
||||
|
||||
# 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;
|
||||
my $releaseDir = "$releasesDir/nix/$releaseName";
|
||||
File::Path::make_path($releaseDir);
|
||||
|
||||
sub downloadFile {
|
||||
my ($jobName, $productNr, $dstName) = @_;
|
||||
@@ -79,49 +57,40 @@ sub downloadFile {
|
||||
|
||||
my $srcFile = $buildInfo->{buildproducts}->{$productNr}->{path} or die "job '$jobName' lacks product $productNr\n";
|
||||
$dstName //= basename($srcFile);
|
||||
my $tmpFile = "$tmpDir/$dstName";
|
||||
my $dstFile = "$releaseDir/" . $dstName;
|
||||
|
||||
if (!-e $tmpFile) {
|
||||
print STDERR "downloading $srcFile to $tmpFile...\n";
|
||||
system("NIX_REMOTE=https://cache.nixos.org/ nix cat-store '$srcFile' > '$tmpFile'") == 0
|
||||
if (! -e $dstFile) {
|
||||
print STDERR "downloading $srcFile to $dstFile...\n";
|
||||
system("NIX_REMOTE=https://cache.nixos.org/ nix cat-store '$srcFile' > '$dstFile.tmp'") == 0
|
||||
or die "unable to fetch $srcFile\n";
|
||||
rename("$dstFile.tmp", $dstFile) or die;
|
||||
}
|
||||
|
||||
my $sha256_expected = $buildInfo->{buildproducts}->{$productNr}->{sha256hash} or die;
|
||||
my $sha256_actual = `nix hash-file --base16 --type sha256 '$tmpFile'`;
|
||||
my $sha256_actual = `nix hash-file --type sha256 '$dstFile'`;
|
||||
chomp $sha256_actual;
|
||||
if ($sha256_expected ne $sha256_actual) {
|
||||
print STDERR "file $tmpFile is corrupt, got $sha256_actual, expected $sha256_expected\n";
|
||||
print STDERR "file $dstFile is corrupt\n";
|
||||
exit 1;
|
||||
}
|
||||
|
||||
write_file("$tmpFile.sha256", $sha256_expected);
|
||||
write_file("$dstFile.sha256", $sha256_expected);
|
||||
|
||||
if (! -e "$tmpFile.asc") {
|
||||
system("gpg2 --detach-sign --armor $tmpFile") == 0 or die "unable to sign $tmpFile\n";
|
||||
if (! -e "$dstFile.asc") {
|
||||
system("gpg2 --detach-sign --armor $dstFile") == 0 or die "unable to sign $dstFile\n";
|
||||
}
|
||||
|
||||
return $sha256_expected;
|
||||
return ($dstFile, $sha256_expected);
|
||||
}
|
||||
|
||||
downloadFile("tarball", "2"); # .tar.bz2
|
||||
my $tarballHash = downloadFile("tarball", "3"); # .tar.xz
|
||||
my ($tarball, $tarballHash) = downloadFile("tarball", "3"); # .tar.xz
|
||||
downloadFile("binaryTarball.i686-linux", "1");
|
||||
downloadFile("binaryTarball.x86_64-linux", "1");
|
||||
downloadFile("binaryTarball.aarch64-linux", "1");
|
||||
downloadFile("binaryTarball.x86_64-darwin", "1");
|
||||
downloadFile("installerScript", "1");
|
||||
|
||||
for my $fn (glob "$tmpDir/*") {
|
||||
my $name = basename($fn);
|
||||
my $dstKey = "$releaseDir/" . $name;
|
||||
unless (defined $releasesBucket->head_key($dstKey)) {
|
||||
print STDERR "uploading $fn to s3://$releasesBucketName/$dstKey...\n";
|
||||
$releasesBucket->add_key_filename($dstKey, $fn)
|
||||
or die $releasesBucket->err . ": " . $releasesBucket->errstr;
|
||||
}
|
||||
}
|
||||
|
||||
exit if $version =~ /pre/;
|
||||
|
||||
# Update Nixpkgs in a very hacky way.
|
||||
@@ -142,12 +111,8 @@ $oldName =~ s/"//g;
|
||||
sub getStorePath {
|
||||
my ($jobName) = @_;
|
||||
my $buildInfo = decode_json(fetch("$evalUrl/job/$jobName", 'application/json'));
|
||||
for my $product (values %{$buildInfo->{buildproducts}}) {
|
||||
next unless $product->{type} eq "nix-build";
|
||||
next if $product->{path} =~ /[a-z]+$/;
|
||||
return $product->{path};
|
||||
}
|
||||
die;
|
||||
die unless $buildInfo->{buildproducts}->{1}->{type} eq "nix-build";
|
||||
return $buildInfo->{buildproducts}->{1}->{path};
|
||||
}
|
||||
|
||||
write_file("$nixpkgsDir/nixos/modules/installer/tools/nix-fallback-paths.nix",
|
||||
@@ -160,11 +125,18 @@ write_file("$nixpkgsDir/nixos/modules/installer/tools/nix-fallback-paths.nix",
|
||||
|
||||
system("cd $nixpkgsDir && git commit -a -m 'nix: $oldName -> $version'") == 0 or die;
|
||||
|
||||
# Extract the HTML manual.
|
||||
File::Path::make_path("$releaseDir/manual");
|
||||
|
||||
system("tar xvf $tarball --strip-components=3 -C $releaseDir/manual --wildcards '*/doc/manual/*.html' '*/doc/manual/*.css' '*/doc/manual/*.gif' '*/doc/manual/*.png'") == 0 or die;
|
||||
|
||||
if (! -e "$releaseDir/manual/index.html") {
|
||||
symlink("manual.html", "$releaseDir/manual/index.html") or die;
|
||||
}
|
||||
|
||||
# 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;
|
||||
symlink("$releaseName", "$releasesDir/nix/latest-tmp") or die;
|
||||
rename("$releasesDir/nix/latest-tmp", "$releasesDir/nix/latest") or die;
|
||||
|
||||
# Tag the release in Git.
|
||||
chdir("/home/eelco/Dev/nix-pristine") or die;
|
||||
|
||||
@@ -13,12 +13,8 @@
|
||||
<true/>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/bin/sh</string>
|
||||
<string>-c</string>
|
||||
<string>/bin/wait4path /nix/var/nix/profiles/default/bin/nix-daemon && /nix/var/nix/profiles/default/bin/nix-daemon</string>
|
||||
</array>
|
||||
<key>Program</key>
|
||||
<string>@bindir@/nix-daemon</string>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/var/log/nix-daemon.log</string>
|
||||
<key>StandardOutPath</key>
|
||||
|
||||
@@ -7,6 +7,3 @@ ConditionPathIsReadWrite=@localstatedir@/nix/daemon-socket
|
||||
[Service]
|
||||
ExecStart=@@bindir@/nix-daemon nix-daemon --daemon
|
||||
KillMode=process
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
||||
6
mk/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
This is a set of helper Makefiles for doing non-recursive builds with
|
||||
GNU Make. The canonical source can be found at
|
||||
https://github.com/edolstra/make-rules. You should copy the files
|
||||
into the `mk` subdirectory of your project.
|
||||
|
||||
TODO: write more documentation.
|
||||
@@ -91,7 +91,7 @@ define build-library
|
||||
$(1)_PATH := $$(_d)/$$($(1)_NAME).$(SO_EXT)
|
||||
|
||||
$$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/
|
||||
$$(trace-ld) $(CXX) -o $$(abspath $$@) -shared $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$($(1)_LDFLAGS_UNINSTALLED)
|
||||
$$(trace-ld) $(CXX) -o $$(abspath $$@) -shared $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE)) $$($(1)_LDFLAGS_UNINSTALLED)
|
||||
|
||||
ifneq ($(OS), Darwin)
|
||||
$(1)_LDFLAGS_USE += -Wl,-rpath,$$(abspath $$(_d))
|
||||
@@ -105,7 +105,7 @@ define build-library
|
||||
$$(eval $$(call create-dir, $$($(1)_INSTALL_DIR)))
|
||||
|
||||
$$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/
|
||||
$$(trace-ld) $(CXX) -o $$@ -shared $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED))
|
||||
$$(trace-ld) $(CXX) -o $$@ -shared $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$($(1)_LDFLAGS_PROPAGATED) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED))
|
||||
|
||||
$(1)_LDFLAGS_USE_INSTALLED += -L$$(DESTDIR)$$($(1)_INSTALL_DIR) -l$$(patsubst lib%,%,$$(strip $$($(1)_NAME)))
|
||||
ifneq ($(OS), Darwin)
|
||||
@@ -125,8 +125,7 @@ define build-library
|
||||
$(1)_PATH := $$(_d)/$$($(1)_NAME).a
|
||||
|
||||
$$($(1)_PATH): $$($(1)_OBJS) | $$(_d)/
|
||||
$(trace-ld) $(LD) -Ur -o $$(_d)/$$($(1)_NAME).o $$?
|
||||
$(trace-ar) $(AR) crs $$@ $$(_d)/$$($(1)_NAME).o
|
||||
$(trace-ar) ar crs $$@ $$?
|
||||
|
||||
$(1)_LDFLAGS_USE += $$($(1)_PATH) $$($(1)_LDFLAGS)
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
$(buildprefix)%.o: %.cc
|
||||
@mkdir -p "$(dir $@)"
|
||||
$(trace-cxx) $(CXX) -o $@ -c $< $(GLOBAL_CXXFLAGS_PCH) $(GLOBAL_CXXFLAGS) $(CXXFLAGS) $($@_CXXFLAGS) -MMD -MF $(call filename-to-dep, $@) -MP
|
||||
$(trace-cxx) $(CXX) -o $@ -c $< $(GLOBAL_CXXFLAGS) $(GLOBAL_CXXFLAGS_PCH) $(CXXFLAGS) $($@_CXXFLAGS) -MMD -MF $(call filename-to-dep, $@) -MP
|
||||
|
||||
$(buildprefix)%.o: %.cpp
|
||||
@mkdir -p "$(dir $@)"
|
||||
$(trace-cxx) $(CXX) -o $@ -c $< $(GLOBAL_CXXFLAGS_PCH) $(GLOBAL_CXXFLAGS) $(CXXFLAGS) $($@_CXXFLAGS) -MMD -MF $(call filename-to-dep, $@) -MP
|
||||
$(trace-cxx) $(CXX) -o $@ -c $< $(GLOBAL_CXXFLAGS) $(GLOBAL_CXXFLAGS_PCH) $(CXXFLAGS) $($@_CXXFLAGS) -MMD -MF $(call filename-to-dep, $@) -MP
|
||||
|
||||
$(buildprefix)%.o: %.c
|
||||
@mkdir -p "$(dir $@)"
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
PRECOMPILE_HEADERS ?= 1
|
||||
|
||||
print-var-help += \
|
||||
echo " PRECOMPILE_HEADERS ($(PRECOMPILE_HEADERS)): Whether to use precompiled headers to speed up the build";
|
||||
|
||||
GCH = $(buildprefix)precompiled-headers.h.gch
|
||||
|
||||
$(GCH): precompiled-headers.h
|
||||
@rm -f $@
|
||||
@mkdir -p "$(dir $@)"
|
||||
$(trace-gen) $(CXX) -x c++-header -o $@ $< $(GLOBAL_CXXFLAGS) $(GCH_CXXFLAGS)
|
||||
|
||||
PCH = $(buildprefix)precompiled-headers.h.pch
|
||||
|
||||
$(PCH): precompiled-headers.h
|
||||
@rm -f $@
|
||||
@mkdir -p "$(dir $@)"
|
||||
$(trace-gen) $(CXX) -x c++-header -o $@ $< $(GLOBAL_CXXFLAGS) $(GCH_CXXFLAGS)
|
||||
|
||||
clean-files += $(GCH) $(PCH)
|
||||
|
||||
ifeq ($(PRECOMPILE_HEADERS), 1)
|
||||
|
||||
ifeq ($(CXX), g++)
|
||||
|
||||
GLOBAL_CXXFLAGS_PCH += -include $(buildprefix)precompiled-headers.h -Winvalid-pch
|
||||
|
||||
GLOBAL_ORDER_AFTER += $(GCH)
|
||||
|
||||
else ifeq ($(CXX), clang++)
|
||||
|
||||
GLOBAL_CXXFLAGS_PCH += -include-pch $(PCH) -Winvalid-pch
|
||||
|
||||
GLOBAL_ORDER_AFTER += $(PCH)
|
||||
|
||||
else
|
||||
|
||||
$(error Don't know how to precompile headers on $(CXX))
|
||||
|
||||
endif
|
||||
|
||||
endif
|
||||
@@ -32,31 +32,27 @@ define build-program
|
||||
$$(eval $$(call create-dir, $$(_d)))
|
||||
|
||||
$$($(1)_PATH): $$($(1)_OBJS) $$(_libs) | $$(_d)/
|
||||
$$(trace-ld) $(CXX) -o $$@ $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE))
|
||||
$$(trace-ld) $(CXX) -o $$@ $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE))
|
||||
|
||||
$(1)_INSTALL_DIR ?= $$(bindir)
|
||||
$(1)_INSTALL_PATH := $$($(1)_INSTALL_DIR)/$(1)
|
||||
|
||||
ifdef $(1)_INSTALL_DIR
|
||||
$$(eval $$(call create-dir, $$($(1)_INSTALL_DIR)))
|
||||
|
||||
$(1)_INSTALL_PATH := $$($(1)_INSTALL_DIR)/$(1)
|
||||
install: $(DESTDIR)$$($(1)_INSTALL_PATH)
|
||||
|
||||
$$(eval $$(call create-dir, $$($(1)_INSTALL_DIR)))
|
||||
ifeq ($(BUILD_SHARED_LIBS), 1)
|
||||
|
||||
install: $(DESTDIR)$$($(1)_INSTALL_PATH)
|
||||
_libs_final := $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_INSTALL_PATH))
|
||||
|
||||
ifeq ($(BUILD_SHARED_LIBS), 1)
|
||||
$(DESTDIR)$$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/
|
||||
$$(trace-ld) $(CXX) -o $$@ $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED))
|
||||
|
||||
_libs_final := $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_INSTALL_PATH))
|
||||
else
|
||||
|
||||
$(DESTDIR)$$($(1)_INSTALL_PATH): $$($(1)_OBJS) $$(_libs_final) | $(DESTDIR)$$($(1)_INSTALL_DIR)/
|
||||
$$(trace-ld) $(CXX) -o $$@ $$(LDFLAGS) $$(GLOBAL_LDFLAGS) $$($(1)_OBJS) $$($(1)_LDFLAGS) $$(foreach lib, $$($(1)_LIBS), $$($$(lib)_LDFLAGS_USE_INSTALLED))
|
||||
|
||||
else
|
||||
|
||||
$(DESTDIR)$$($(1)_INSTALL_PATH): $$($(1)_PATH) | $(DESTDIR)$$($(1)_INSTALL_DIR)/
|
||||
$(DESTDIR)$$($(1)_INSTALL_PATH): $$($(1)_PATH) | $(DESTDIR)$$($(1)_INSTALL_DIR)/
|
||||
install -t $(DESTDIR)$$($(1)_INSTALL_DIR) $$<
|
||||
|
||||
endif
|
||||
endif
|
||||
|
||||
# Propagate CFLAGS and CXXFLAGS to the individual object files.
|
||||
@@ -80,10 +76,4 @@ define build-program
|
||||
programs-list += $$($(1)_PATH)
|
||||
clean-files += $$($(1)_PATH) $$(_d)/*.o $$(_d)/.*.dep $$($(1)_DEPS) $$($(1)_OBJS)
|
||||
dist-files += $$(_srcs)
|
||||
|
||||
# Phony target to run this program (typically as a dependency of 'check').
|
||||
.PHONY: $(1)_RUN
|
||||
$(1)_RUN: $$($(1)_PATH)
|
||||
$(trace-test) $$($(1)_PATH)
|
||||
|
||||
endef
|
||||
|
||||
@@ -11,7 +11,6 @@ ifeq ($(V), 0)
|
||||
trace-javac = @echo " JAVAC " $@;
|
||||
trace-jar = @echo " JAR " $@;
|
||||
trace-mkdir = @echo " MKDIR " $@;
|
||||
trace-test = @echo " TEST " $@;
|
||||
|
||||
suppress = @
|
||||
|
||||
|
||||
399
nix-rust/Cargo.lock
generated
@@ -1,399 +0,0 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "assert_matches"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "c2-chacha"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "nix-rust"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proptest"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rusty-fork 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_hc"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_isaac"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_jitter"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_pcg"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xorshift"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "remove_dir_all"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rusty-fork"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wait-timeout"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum assert_matches 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7deb0a829ca7bcfaf5da70b073a8d128619259a7be8216a355e23f00763059e5"
|
||||
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
|
||||
"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
|
||||
"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
|
||||
"checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
|
||||
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407"
|
||||
"checksum hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||
"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
|
||||
"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
|
||||
"checksum proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf147e022eacf0c8a054ab864914a7602618adba841d800a9a9868a5237a529f"
|
||||
"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
|
||||
"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
|
||||
"checksum rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3ae1b169243eaf61759b8475a998f0a385e42042370f3a7dbaf35246eacc8412"
|
||||
"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
|
||||
"checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853"
|
||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
"checksum rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
"checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4"
|
||||
"checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
|
||||
"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08"
|
||||
"checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b"
|
||||
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
|
||||
"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
|
||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
"checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
|
||||
"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
|
||||
"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
|
||||
"checksum rusty-fork 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd93264e10c577503e926bd1430193eeb5d21b059148910082245309b424fae"
|
||||
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||
"checksum wait-timeout 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
|
||||
"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d"
|
||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
@@ -1,23 +0,0 @@
|
||||
[package]
|
||||
name = "nix-rust"
|
||||
version = "0.1.0"
|
||||
authors = ["Eelco Dolstra <edolstra@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
[lib]
|
||||
name = "nixrust"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2"
|
||||
#futures-preview = { version = "=0.3.0-alpha.19" }
|
||||
#hyper = "0.13.0-alpha.4"
|
||||
#http = "0.1"
|
||||
#tokio = { version = "0.2.0-alpha.6", default-features = false, features = ["rt-full"] }
|
||||
lazy_static = "1.4"
|
||||
#byteorder = "1.3"
|
||||
|
||||
[dev-dependencies]
|
||||
hex = "0.3"
|
||||
assert_matches = "1.3"
|
||||
proptest = "0.9"
|
||||
@@ -1,45 +0,0 @@
|
||||
ifeq ($(OPTIMIZE), 1)
|
||||
RUST_MODE = --release
|
||||
RUST_DIR = release
|
||||
else
|
||||
RUST_MODE =
|
||||
RUST_DIR = debug
|
||||
endif
|
||||
|
||||
libnixrust_PATH := $(d)/target/$(RUST_DIR)/libnixrust.$(SO_EXT)
|
||||
libnixrust_INSTALL_PATH := $(libdir)/libnixrust.$(SO_EXT)
|
||||
libnixrust_LDFLAGS_USE := -L$(d)/target/$(RUST_DIR) -lnixrust -ldl
|
||||
libnixrust_LDFLAGS_USE_INSTALLED := -L$(libdir) -lnixrust -ldl
|
||||
|
||||
ifeq ($(OS), Darwin)
|
||||
libnixrust_BUILD_FLAGS = NIX_LDFLAGS="-undefined dynamic_lookup"
|
||||
else
|
||||
libnixrust_LDFLAGS_USE += -Wl,-rpath,$(abspath $(d)/target/$(RUST_DIR))
|
||||
libnixrust_LDFLAGS_USE_INSTALLED += -Wl,-rpath,$(libdir)
|
||||
endif
|
||||
|
||||
$(libnixrust_PATH): $(call rwildcard, $(d)/src, *.rs) $(d)/Cargo.toml
|
||||
$(trace-gen) cd nix-rust && CARGO_HOME=$$(if [[ -d vendor ]]; then echo vendor; fi) \
|
||||
$(libnixrust_BUILD_FLAGS) \
|
||||
cargo build $(RUST_MODE) $$(if [[ -d vendor ]]; then echo --offline; fi) \
|
||||
&& touch target/$(RUST_DIR)/libnixrust.$(SO_EXT)
|
||||
|
||||
$(libnixrust_INSTALL_PATH): $(libnixrust_PATH)
|
||||
$(target-gen) cp $^ $@
|
||||
ifeq ($(OS), Darwin)
|
||||
install_name_tool -id $@ $@
|
||||
endif
|
||||
|
||||
dist-files += $(d)/vendor
|
||||
|
||||
clean: clean-rust
|
||||
|
||||
clean-rust:
|
||||
$(suppress) rm -rfv nix-rust/target
|
||||
|
||||
ifneq ($(OS), Darwin)
|
||||
check: rust-tests
|
||||
|
||||
rust-tests:
|
||||
$(trace-test) cd nix-rust && CARGO_HOME=$$(if [[ -d vendor ]]; then echo vendor; fi) cargo test --release $$(if [[ -d vendor ]]; then echo --offline; fi)
|
||||
endif
|
||||
@@ -1,77 +0,0 @@
|
||||
use super::{error, store::path, store::StorePath, util};
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ffi_String_new(s: &str, out: *mut String) {
|
||||
// FIXME: check whether 's' is valid UTF-8?
|
||||
out.write(s.to_string())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ffi_String_drop(self_: *mut String) {
|
||||
std::ptr::drop_in_place(self_);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_new(
|
||||
path: &str,
|
||||
store_dir: &str,
|
||||
) -> Result<StorePath, error::CppException> {
|
||||
StorePath::new(std::path::Path::new(path), std::path::Path::new(store_dir))
|
||||
.map_err(|err| err.into())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_new2(
|
||||
hash: &[u8; crate::store::path::STORE_PATH_HASH_BYTES],
|
||||
name: &str,
|
||||
) -> Result<StorePath, error::CppException> {
|
||||
StorePath::from_parts(*hash, name).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_fromBaseName(
|
||||
base_name: &str,
|
||||
) -> Result<StorePath, error::CppException> {
|
||||
StorePath::new_from_base_name(base_name).map_err(|err| err.into())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ffi_StorePath_drop(self_: *mut StorePath) {
|
||||
std::ptr::drop_in_place(self_);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_to_string(self_: &StorePath) -> Vec<u8> {
|
||||
let mut buf = vec![0; path::STORE_PATH_HASH_CHARS + 1 + self_.name.name().len()];
|
||||
util::base32::encode_into(self_.hash.hash(), &mut buf[0..path::STORE_PATH_HASH_CHARS]);
|
||||
buf[path::STORE_PATH_HASH_CHARS] = b'-';
|
||||
buf[path::STORE_PATH_HASH_CHARS + 1..].clone_from_slice(self_.name.name().as_bytes());
|
||||
buf
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_less_than(a: &StorePath, b: &StorePath) -> bool {
|
||||
a < b
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_eq(a: &StorePath, b: &StorePath) -> bool {
|
||||
a == b
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_clone(self_: &StorePath) -> StorePath {
|
||||
self_.clone()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_name(self_: &StorePath) -> &str {
|
||||
self_.name.name()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_StorePath_hash_data(
|
||||
self_: &StorePath,
|
||||
) -> &[u8; crate::store::path::STORE_PATH_HASH_BYTES] {
|
||||
self_.hash.hash()
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
InvalidPath(crate::store::StorePath),
|
||||
BadStorePath(std::path::PathBuf),
|
||||
NotInStore(std::path::PathBuf),
|
||||
BadNarInfo,
|
||||
BadBase32,
|
||||
StorePathNameEmpty,
|
||||
StorePathNameTooLong,
|
||||
BadStorePathName,
|
||||
NarSizeFieldTooBig,
|
||||
BadNarString,
|
||||
BadNarPadding,
|
||||
BadNarVersionMagic,
|
||||
MissingNarOpenTag,
|
||||
MissingNarCloseTag,
|
||||
MissingNarField,
|
||||
BadNarField(String),
|
||||
BadExecutableField,
|
||||
IOError(std::io::Error),
|
||||
#[cfg(unused)]
|
||||
HttpError(hyper::error::Error),
|
||||
Misc(String),
|
||||
#[cfg(not(test))]
|
||||
Foreign(CppException),
|
||||
BadTarFileMemberName(String),
|
||||
}
|
||||
|
||||
impl From<std::io::Error> for Error {
|
||||
fn from(err: std::io::Error) -> Self {
|
||||
Error::IOError(err)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(unused)]
|
||||
impl From<hyper::error::Error> for Error {
|
||||
fn from(err: hyper::error::Error) -> Self {
|
||||
Error::HttpError(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Error::InvalidPath(_) => write!(f, "invalid path"),
|
||||
Error::BadNarInfo => write!(f, ".narinfo file is corrupt"),
|
||||
Error::BadStorePath(path) => write!(f, "path '{}' is not a store path", path.display()),
|
||||
Error::NotInStore(path) => {
|
||||
write!(f, "path '{}' is not in the Nix store", path.display())
|
||||
}
|
||||
Error::BadBase32 => write!(f, "invalid base32 string"),
|
||||
Error::StorePathNameEmpty => write!(f, "store path name is empty"),
|
||||
Error::StorePathNameTooLong => {
|
||||
write!(f, "store path name is longer than 211 characters")
|
||||
}
|
||||
Error::BadStorePathName => write!(f, "store path name contains forbidden character"),
|
||||
Error::NarSizeFieldTooBig => write!(f, "size field in NAR is too big"),
|
||||
Error::BadNarString => write!(f, "NAR string is not valid UTF-8"),
|
||||
Error::BadNarPadding => write!(f, "NAR padding is not zero"),
|
||||
Error::BadNarVersionMagic => write!(f, "unsupported NAR version"),
|
||||
Error::MissingNarOpenTag => write!(f, "NAR open tag is missing"),
|
||||
Error::MissingNarCloseTag => write!(f, "NAR close tag is missing"),
|
||||
Error::MissingNarField => write!(f, "expected NAR field is missing"),
|
||||
Error::BadNarField(s) => write!(f, "unrecognized NAR field '{}'", s),
|
||||
Error::BadExecutableField => write!(f, "bad 'executable' field in NAR"),
|
||||
Error::IOError(err) => write!(f, "I/O error: {}", err),
|
||||
#[cfg(unused)]
|
||||
Error::HttpError(err) => write!(f, "HTTP error: {}", err),
|
||||
#[cfg(not(test))]
|
||||
Error::Foreign(_) => write!(f, "<C++ exception>"), // FIXME
|
||||
Error::Misc(s) => write!(f, "{}", s),
|
||||
Error::BadTarFileMemberName(s) => {
|
||||
write!(f, "tar archive contains illegal file name '{}'", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl From<Error> for CppException {
|
||||
fn from(err: Error) -> Self {
|
||||
match err {
|
||||
Error::Foreign(ex) => ex,
|
||||
_ => CppException::new(&err.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
pub struct CppException(*const libc::c_void); // == std::exception_ptr*
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl CppException {
|
||||
fn new(s: &str) -> Self {
|
||||
Self(unsafe { make_error(s) })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
impl Drop for CppException {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
destroy_error(self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
extern "C" {
|
||||
#[allow(improper_ctypes)] // YOLO
|
||||
fn make_error(s: &str) -> *const libc::c_void;
|
||||
|
||||
fn destroy_error(exc: *const libc::c_void);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#[cfg(not(test))]
|
||||
mod c;
|
||||
mod error;
|
||||
#[cfg(unused)]
|
||||
mod nar;
|
||||
mod store;
|
||||
mod util;
|
||||
|
||||
pub use error::Error;
|
||||
@@ -1,126 +0,0 @@
|
||||
use crate::Error;
|
||||
use byteorder::{LittleEndian, ReadBytesExt};
|
||||
use std::convert::TryFrom;
|
||||
use std::io::Read;
|
||||
|
||||
pub fn parse<R: Read>(input: &mut R) -> Result<(), Error> {
|
||||
if String::read(input)? != NAR_VERSION_MAGIC {
|
||||
return Err(Error::BadNarVersionMagic);
|
||||
}
|
||||
|
||||
parse_file(input)
|
||||
}
|
||||
|
||||
const NAR_VERSION_MAGIC: &str = "nix-archive-1";
|
||||
|
||||
fn parse_file<R: Read>(input: &mut R) -> Result<(), Error> {
|
||||
if String::read(input)? != "(" {
|
||||
return Err(Error::MissingNarOpenTag);
|
||||
}
|
||||
|
||||
if String::read(input)? != "type" {
|
||||
return Err(Error::MissingNarField);
|
||||
}
|
||||
|
||||
match String::read(input)?.as_ref() {
|
||||
"regular" => {
|
||||
let mut _executable = false;
|
||||
let mut tag = String::read(input)?;
|
||||
if tag == "executable" {
|
||||
_executable = true;
|
||||
if String::read(input)? != "" {
|
||||
return Err(Error::BadExecutableField);
|
||||
}
|
||||
tag = String::read(input)?;
|
||||
}
|
||||
if tag != "contents" {
|
||||
return Err(Error::MissingNarField);
|
||||
}
|
||||
let _contents = Vec::<u8>::read(input)?;
|
||||
if String::read(input)? != ")" {
|
||||
return Err(Error::MissingNarCloseTag);
|
||||
}
|
||||
}
|
||||
"directory" => loop {
|
||||
match String::read(input)?.as_ref() {
|
||||
"entry" => {
|
||||
if String::read(input)? != "(" {
|
||||
return Err(Error::MissingNarOpenTag);
|
||||
}
|
||||
if String::read(input)? != "name" {
|
||||
return Err(Error::MissingNarField);
|
||||
}
|
||||
let _name = String::read(input)?;
|
||||
if String::read(input)? != "node" {
|
||||
return Err(Error::MissingNarField);
|
||||
}
|
||||
parse_file(input)?;
|
||||
let tag = String::read(input)?;
|
||||
if tag != ")" {
|
||||
return Err(Error::MissingNarCloseTag);
|
||||
}
|
||||
}
|
||||
")" => break,
|
||||
s => return Err(Error::BadNarField(s.into())),
|
||||
}
|
||||
},
|
||||
"symlink" => {
|
||||
if String::read(input)? != "target" {
|
||||
return Err(Error::MissingNarField);
|
||||
}
|
||||
let _target = String::read(input)?;
|
||||
if String::read(input)? != ")" {
|
||||
return Err(Error::MissingNarCloseTag);
|
||||
}
|
||||
}
|
||||
s => return Err(Error::BadNarField(s.into())),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
trait Deserialize: Sized {
|
||||
fn read<R: Read>(input: &mut R) -> Result<Self, Error>;
|
||||
}
|
||||
|
||||
impl Deserialize for String {
|
||||
fn read<R: Read>(input: &mut R) -> Result<Self, Error> {
|
||||
let buf = Deserialize::read(input)?;
|
||||
Ok(String::from_utf8(buf).map_err(|_| Error::BadNarString)?)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for Vec<u8> {
|
||||
fn read<R: Read>(input: &mut R) -> Result<Self, Error> {
|
||||
let n: usize = Deserialize::read(input)?;
|
||||
let mut buf = vec![0; n];
|
||||
input.read_exact(&mut buf)?;
|
||||
skip_padding(input, n)?;
|
||||
Ok(buf)
|
||||
}
|
||||
}
|
||||
|
||||
fn skip_padding<R: Read>(input: &mut R, len: usize) -> Result<(), Error> {
|
||||
if len % 8 != 0 {
|
||||
let mut buf = [0; 8];
|
||||
let buf = &mut buf[0..8 - (len % 8)];
|
||||
input.read_exact(buf)?;
|
||||
if !buf.iter().all(|b| *b == 0) {
|
||||
return Err(Error::BadNarPadding);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl Deserialize for u64 {
|
||||
fn read<R: Read>(input: &mut R) -> Result<Self, Error> {
|
||||
Ok(input.read_u64::<LittleEndian>()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deserialize for usize {
|
||||
fn read<R: Read>(input: &mut R) -> Result<Self, Error> {
|
||||
let n: u64 = Deserialize::read(input)?;
|
||||
Ok(usize::try_from(n).map_err(|_| Error::NarSizeFieldTooBig)?)
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
use super::{PathInfo, Store, StorePath};
|
||||
use crate::Error;
|
||||
use hyper::client::Client;
|
||||
|
||||
pub struct BinaryCacheStore {
|
||||
base_uri: String,
|
||||
client: Client<hyper::client::HttpConnector, hyper::Body>,
|
||||
}
|
||||
|
||||
impl BinaryCacheStore {
|
||||
pub fn new(base_uri: String) -> Self {
|
||||
Self {
|
||||
base_uri,
|
||||
client: Client::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Store for BinaryCacheStore {
|
||||
fn query_path_info(
|
||||
&self,
|
||||
path: &StorePath,
|
||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<PathInfo, Error>> + Send>> {
|
||||
let uri = format!("{}/{}.narinfo", self.base_uri.clone(), path.hash);
|
||||
let path = path.clone();
|
||||
let client = self.client.clone();
|
||||
let store_dir = self.store_dir().to_string();
|
||||
|
||||
Box::pin(async move {
|
||||
let response = client.get(uri.parse::<hyper::Uri>().unwrap()).await?;
|
||||
|
||||
if response.status() == hyper::StatusCode::NOT_FOUND
|
||||
|| response.status() == hyper::StatusCode::FORBIDDEN
|
||||
{
|
||||
return Err(Error::InvalidPath(path));
|
||||
}
|
||||
|
||||
let mut body = response.into_body();
|
||||
|
||||
let mut bytes = Vec::new();
|
||||
while let Some(next) = body.next().await {
|
||||
bytes.extend(next?);
|
||||
}
|
||||
|
||||
PathInfo::parse_nar_info(std::str::from_utf8(&bytes).unwrap(), &store_dir)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
pub mod path;
|
||||
|
||||
#[cfg(unused)]
|
||||
mod binary_cache_store;
|
||||
#[cfg(unused)]
|
||||
mod path_info;
|
||||
#[cfg(unused)]
|
||||
mod store;
|
||||
|
||||
pub use path::{StorePath, StorePathHash, StorePathName};
|
||||
|
||||
#[cfg(unused)]
|
||||
pub use binary_cache_store::BinaryCacheStore;
|
||||
#[cfg(unused)]
|
||||
pub use path_info::PathInfo;
|
||||
#[cfg(unused)]
|
||||
pub use store::Store;
|
||||
@@ -1,225 +0,0 @@
|
||||
use crate::error::Error;
|
||||
use crate::util::base32;
|
||||
use std::fmt;
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||
pub struct StorePath {
|
||||
pub hash: StorePathHash,
|
||||
pub name: StorePathName,
|
||||
}
|
||||
|
||||
pub const STORE_PATH_HASH_BYTES: usize = 20;
|
||||
pub const STORE_PATH_HASH_CHARS: usize = 32;
|
||||
|
||||
impl StorePath {
|
||||
pub fn new(path: &Path, store_dir: &Path) -> Result<Self, Error> {
|
||||
if path.parent() != Some(store_dir) {
|
||||
return Err(Error::NotInStore(path.into()));
|
||||
}
|
||||
Self::new_from_base_name(
|
||||
path.file_name()
|
||||
.ok_or(Error::BadStorePath(path.into()))?
|
||||
.to_str()
|
||||
.ok_or(Error::BadStorePath(path.into()))?,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn from_parts(hash: [u8; STORE_PATH_HASH_BYTES], name: &str) -> Result<Self, Error> {
|
||||
Ok(StorePath {
|
||||
hash: StorePathHash(hash),
|
||||
name: StorePathName::new(name)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn new_from_base_name(base_name: &str) -> Result<Self, Error> {
|
||||
if base_name.len() < STORE_PATH_HASH_CHARS + 1
|
||||
|| base_name.as_bytes()[STORE_PATH_HASH_CHARS] != '-' as u8
|
||||
{
|
||||
return Err(Error::BadStorePath(base_name.into()));
|
||||
}
|
||||
|
||||
Ok(StorePath {
|
||||
hash: StorePathHash::new(&base_name[0..STORE_PATH_HASH_CHARS])?,
|
||||
name: StorePathName::new(&base_name[STORE_PATH_HASH_CHARS + 1..])?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for StorePath {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}-{}", self.hash, self.name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub struct StorePathHash([u8; STORE_PATH_HASH_BYTES]);
|
||||
|
||||
impl StorePathHash {
|
||||
pub fn new(s: &str) -> Result<Self, Error> {
|
||||
assert_eq!(s.len(), STORE_PATH_HASH_CHARS);
|
||||
let v = base32::decode(s)?;
|
||||
assert_eq!(v.len(), STORE_PATH_HASH_BYTES);
|
||||
let mut bytes: [u8; 20] = Default::default();
|
||||
bytes.copy_from_slice(&v[0..STORE_PATH_HASH_BYTES]);
|
||||
Ok(Self(bytes))
|
||||
}
|
||||
|
||||
pub fn hash<'a>(&'a self) -> &'a [u8; STORE_PATH_HASH_BYTES] {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for StorePathHash {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let mut buf = vec![0; STORE_PATH_HASH_CHARS];
|
||||
base32::encode_into(&self.0, &mut buf);
|
||||
f.write_str(std::str::from_utf8(&buf).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for StorePathHash {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
// Historically we've sorted store paths by their base32
|
||||
// serialization, but our base32 encodes bytes in reverse
|
||||
// order. So compare them in reverse order as well.
|
||||
self.0.iter().rev().cmp(other.0.iter().rev())
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for StorePathHash {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]
|
||||
pub struct StorePathName(String);
|
||||
|
||||
impl StorePathName {
|
||||
pub fn new(s: &str) -> Result<Self, Error> {
|
||||
if s.len() == 0 {
|
||||
return Err(Error::StorePathNameEmpty);
|
||||
}
|
||||
|
||||
if s.len() > 211 {
|
||||
return Err(Error::StorePathNameTooLong);
|
||||
}
|
||||
|
||||
if s.starts_with('.')
|
||||
|| !s.chars().all(|c| {
|
||||
c.is_ascii_alphabetic()
|
||||
|| c.is_ascii_digit()
|
||||
|| c == '+'
|
||||
|| c == '-'
|
||||
|| c == '.'
|
||||
|| c == '_'
|
||||
|| c == '?'
|
||||
|| c == '='
|
||||
})
|
||||
{
|
||||
return Err(Error::BadStorePathName);
|
||||
}
|
||||
|
||||
Ok(Self(s.to_string()))
|
||||
}
|
||||
|
||||
pub fn name<'a>(&'a self) -> &'a str {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for StorePathName {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.write_str(&self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use assert_matches::assert_matches;
|
||||
|
||||
#[test]
|
||||
fn test_parse() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3";
|
||||
let p = StorePath::new_from_base_name(&s).unwrap();
|
||||
assert_eq!(p.name.0, "konsole-18.12.3");
|
||||
assert_eq!(
|
||||
p.hash.0,
|
||||
[
|
||||
0x9f, 0x76, 0x49, 0x20, 0xf6, 0x5d, 0xe9, 0x71, 0xc4, 0xca, 0x46, 0x21, 0xab, 0xff,
|
||||
0x9b, 0x44, 0xef, 0x87, 0x0f, 0x3c
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_name() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::StorePathNameEmpty)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_no_dash() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::BadStorePath(_))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_short_hash() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxl-konsole-18.12.3";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::BadStorePath(_))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_invalid_hash() {
|
||||
let s = "7h7qgvs4kgzsn8e6rb273saxyqh4jxlz-konsole-18.12.3";
|
||||
assert_matches!(StorePath::new_from_base_name(&s), Err(Error::BadBase32));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_long_name() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
assert_matches!(StorePath::new_from_base_name(&s), Ok(_));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_too_long_name() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::StorePathNameTooLong)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_bad_name() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-foo bar";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::BadStorePathName)
|
||||
);
|
||||
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-kónsole";
|
||||
assert_matches!(
|
||||
StorePath::new_from_base_name(&s),
|
||||
Err(Error::BadStorePathName)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_roundtrip() {
|
||||
let s = "7h7qgvs4kgzsn8a6rb273saxyqh4jxlz-konsole-18.12.3";
|
||||
assert_eq!(StorePath::new_from_base_name(&s).unwrap().to_string(), s);
|
||||
}
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
use crate::store::StorePath;
|
||||
use crate::Error;
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct PathInfo {
|
||||
pub path: StorePath,
|
||||
pub references: BTreeSet<StorePath>,
|
||||
pub nar_size: u64,
|
||||
pub deriver: Option<StorePath>,
|
||||
|
||||
// Additional binary cache info.
|
||||
pub url: Option<String>,
|
||||
pub compression: Option<String>,
|
||||
pub file_size: Option<u64>,
|
||||
}
|
||||
|
||||
impl PathInfo {
|
||||
pub fn parse_nar_info(nar_info: &str, store_dir: &str) -> Result<Self, Error> {
|
||||
let mut path = None;
|
||||
let mut references = BTreeSet::new();
|
||||
let mut nar_size = None;
|
||||
let mut deriver = None;
|
||||
let mut url = None;
|
||||
let mut compression = None;
|
||||
let mut file_size = None;
|
||||
|
||||
for line in nar_info.lines() {
|
||||
let colon = line.find(':').ok_or(Error::BadNarInfo)?;
|
||||
|
||||
let (name, value) = line.split_at(colon);
|
||||
|
||||
if !value.starts_with(": ") {
|
||||
return Err(Error::BadNarInfo);
|
||||
}
|
||||
|
||||
let value = &value[2..];
|
||||
|
||||
if name == "StorePath" {
|
||||
path = Some(StorePath::new(std::path::Path::new(value), store_dir)?);
|
||||
} else if name == "NarSize" {
|
||||
nar_size = Some(u64::from_str_radix(value, 10).map_err(|_| Error::BadNarInfo)?);
|
||||
} else if name == "References" {
|
||||
if !value.is_empty() {
|
||||
for r in value.split(' ') {
|
||||
references.insert(StorePath::new_from_base_name(r)?);
|
||||
}
|
||||
}
|
||||
} else if name == "Deriver" {
|
||||
deriver = Some(StorePath::new_from_base_name(value)?);
|
||||
} else if name == "URL" {
|
||||
url = Some(value.into());
|
||||
} else if name == "Compression" {
|
||||
compression = Some(value.into());
|
||||
} else if name == "FileSize" {
|
||||
file_size = Some(u64::from_str_radix(value, 10).map_err(|_| Error::BadNarInfo)?);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(PathInfo {
|
||||
path: path.ok_or(Error::BadNarInfo)?,
|
||||
references,
|
||||
nar_size: nar_size.ok_or(Error::BadNarInfo)?,
|
||||
deriver,
|
||||
url: Some(url.ok_or(Error::BadNarInfo)?),
|
||||
compression,
|
||||
file_size,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
use super::{PathInfo, StorePath};
|
||||
use crate::Error;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::path::Path;
|
||||
|
||||
pub trait Store: Send + Sync {
|
||||
fn store_dir(&self) -> &str {
|
||||
"/nix/store"
|
||||
}
|
||||
|
||||
fn query_path_info(
|
||||
&self,
|
||||
store_path: &StorePath,
|
||||
) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<PathInfo, Error>> + Send>>;
|
||||
}
|
||||
|
||||
impl dyn Store {
|
||||
pub fn parse_store_path(&self, path: &Path) -> Result<StorePath, Error> {
|
||||
StorePath::new(path, self.store_dir())
|
||||
}
|
||||
|
||||
pub async fn compute_path_closure(
|
||||
&self,
|
||||
roots: BTreeSet<StorePath>,
|
||||
) -> Result<BTreeMap<StorePath, PathInfo>, Error> {
|
||||
let mut done = BTreeSet::new();
|
||||
let mut result = BTreeMap::new();
|
||||
let mut pending = vec![];
|
||||
|
||||
for root in roots {
|
||||
pending.push(self.query_path_info(&root));
|
||||
done.insert(root);
|
||||
}
|
||||
|
||||
while !pending.is_empty() {
|
||||
let (info, _, remaining) = futures::future::select_all(pending).await;
|
||||
pending = remaining;
|
||||
|
||||
let info = info?;
|
||||
|
||||
for path in &info.references {
|
||||
if !done.contains(path) {
|
||||
pending.push(self.query_path_info(&path));
|
||||
done.insert(path.clone());
|
||||
}
|
||||
}
|
||||
|
||||
result.insert(info.path.clone(), info);
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
use crate::error::Error;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
pub fn encoded_len(input_len: usize) -> usize {
|
||||
if input_len == 0 {
|
||||
0
|
||||
} else {
|
||||
(input_len * 8 - 1) / 5 + 1
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decoded_len(input_len: usize) -> usize {
|
||||
input_len * 5 / 8
|
||||
}
|
||||
|
||||
static BASE32_CHARS: &'static [u8; 32] = &b"0123456789abcdfghijklmnpqrsvwxyz";
|
||||
|
||||
lazy_static! {
|
||||
static ref BASE32_CHARS_REVERSE: Box<[u8; 256]> = {
|
||||
let mut xs = [0xffu8; 256];
|
||||
for (n, c) in BASE32_CHARS.iter().enumerate() {
|
||||
xs[*c as usize] = n as u8;
|
||||
}
|
||||
Box::new(xs)
|
||||
};
|
||||
}
|
||||
|
||||
pub fn encode(input: &[u8]) -> String {
|
||||
let mut buf = vec![0; encoded_len(input.len())];
|
||||
encode_into(input, &mut buf);
|
||||
std::str::from_utf8(&buf).unwrap().to_string()
|
||||
}
|
||||
|
||||
pub fn encode_into(input: &[u8], output: &mut [u8]) {
|
||||
let len = encoded_len(input.len());
|
||||
assert_eq!(len, output.len());
|
||||
|
||||
let mut nr_bits_left: usize = 0;
|
||||
let mut bits_left: u16 = 0;
|
||||
let mut pos = len;
|
||||
|
||||
for b in input {
|
||||
bits_left |= (*b as u16) << nr_bits_left;
|
||||
nr_bits_left += 8;
|
||||
while nr_bits_left > 5 {
|
||||
output[pos - 1] = BASE32_CHARS[(bits_left & 0x1f) as usize];
|
||||
pos -= 1;
|
||||
bits_left >>= 5;
|
||||
nr_bits_left -= 5;
|
||||
}
|
||||
}
|
||||
|
||||
if nr_bits_left > 0 {
|
||||
output[pos - 1] = BASE32_CHARS[(bits_left & 0x1f) as usize];
|
||||
pos -= 1;
|
||||
}
|
||||
|
||||
assert_eq!(pos, 0);
|
||||
}
|
||||
|
||||
pub fn decode(input: &str) -> Result<Vec<u8>, crate::Error> {
|
||||
let mut res = Vec::with_capacity(decoded_len(input.len()));
|
||||
|
||||
let mut nr_bits_left: usize = 0;
|
||||
let mut bits_left: u16 = 0;
|
||||
|
||||
for c in input.chars().rev() {
|
||||
let b = BASE32_CHARS_REVERSE[c as usize];
|
||||
if b == 0xff {
|
||||
return Err(Error::BadBase32);
|
||||
}
|
||||
bits_left |= (b as u16) << nr_bits_left;
|
||||
nr_bits_left += 5;
|
||||
if nr_bits_left >= 8 {
|
||||
res.push((bits_left & 0xff) as u8);
|
||||
bits_left >>= 8;
|
||||
nr_bits_left -= 8;
|
||||
}
|
||||
}
|
||||
|
||||
if nr_bits_left > 0 && bits_left != 0 {
|
||||
return Err(Error::BadBase32);
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use assert_matches::assert_matches;
|
||||
use hex;
|
||||
use proptest::proptest;
|
||||
|
||||
#[test]
|
||||
fn test_encode() {
|
||||
assert_eq!(encode(&[]), "");
|
||||
|
||||
assert_eq!(
|
||||
encode(&hex::decode("0839703786356bca59b0f4a32987eb2e6de43ae8").unwrap()),
|
||||
"x0xf8v9fxf3jk8zln1cwlsrmhqvp0f88"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode(
|
||||
&hex::decode("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad")
|
||||
.unwrap()
|
||||
),
|
||||
"1b8m03r63zqhnjf7l5wnldhh7c134ap5vpj0850ymkq1iyzicy5s"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
encode(
|
||||
&hex::decode("ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f")
|
||||
.unwrap()
|
||||
),
|
||||
"2gs8k559z4rlahfx0y688s49m2vvszylcikrfinm30ly9rak69236nkam5ydvly1ai7xac99vxfc4ii84hawjbk876blyk1jfhkbbyx"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_decode() {
|
||||
assert_eq!(hex::encode(decode("").unwrap()), "");
|
||||
|
||||
assert_eq!(
|
||||
hex::encode(decode("x0xf8v9fxf3jk8zln1cwlsrmhqvp0f88").unwrap()),
|
||||
"0839703786356bca59b0f4a32987eb2e6de43ae8"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
hex::encode(decode("1b8m03r63zqhnjf7l5wnldhh7c134ap5vpj0850ymkq1iyzicy5s").unwrap()),
|
||||
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
hex::encode(decode("2gs8k559z4rlahfx0y688s49m2vvszylcikrfinm30ly9rak69236nkam5ydvly1ai7xac99vxfc4ii84hawjbk876blyk1jfhkbbyx").unwrap()),
|
||||
"ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f"
|
||||
);
|
||||
|
||||
assert_matches!(
|
||||
decode("xoxf8v9fxf3jk8zln1cwlsrmhqvp0f88"),
|
||||
Err(Error::BadBase32)
|
||||
);
|
||||
assert_matches!(
|
||||
decode("2b8m03r63zqhnjf7l5wnldhh7c134ap5vpj0850ymkq1iyzicy5s"),
|
||||
Err(Error::BadBase32)
|
||||
);
|
||||
assert_matches!(decode("2"), Err(Error::BadBase32));
|
||||
assert_matches!(decode("2gs"), Err(Error::BadBase32));
|
||||
assert_matches!(decode("2gs8"), Err(Error::BadBase32));
|
||||
}
|
||||
|
||||
proptest! {
|
||||
|
||||
#[test]
|
||||
fn roundtrip(s: Vec<u8>) {
|
||||
assert_eq!(s, decode(&encode(&s)).unwrap());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
pub mod base32;
|
||||
173
nix.spec.in
Normal file
@@ -0,0 +1,173 @@
|
||||
%undefine _hardened_build
|
||||
|
||||
%global nixbld_user "nix-builder-"
|
||||
%global nixbld_group "nixbld"
|
||||
|
||||
# NOTE: BUILD on EL7 requires
|
||||
# - Centos / RHEL7 software collection repository
|
||||
# yum install centos-release-scl
|
||||
#
|
||||
# - Recent boost backport
|
||||
# curl https://copr.fedorainfracloud.org/coprs/whosthere/boost/repo/epel-7/whosthere-boost-epel-7.repo -o /etc/yum.repos.d/whosthere-boost-epel-7.repo
|
||||
#
|
||||
|
||||
# Disable documentation generation
|
||||
# necessary on some platforms
|
||||
%bcond_without docgen
|
||||
|
||||
Summary: The Nix software deployment system
|
||||
Name: nix
|
||||
Version: @PACKAGE_VERSION@
|
||||
Release: 2%{?dist}
|
||||
License: LGPLv2+
|
||||
Group: Applications/System
|
||||
URL: http://nixos.org/
|
||||
Source0: %{name}-%{version}.tar.bz2
|
||||
|
||||
Requires: curl
|
||||
Requires: bzip2
|
||||
Requires: gzip
|
||||
Requires: xz
|
||||
BuildRequires: bison
|
||||
BuildRequires: boost-devel >= 1.60
|
||||
BuildRequires: bzip2-devel
|
||||
|
||||
# for RHEL <= 7, we need software collections for a C++14 compatible compatible compiler
|
||||
%if 0%{?rhel}
|
||||
BuildRequires: devtoolset-7-gcc
|
||||
BuildRequires: devtoolset-7-gcc-c++
|
||||
%endif
|
||||
|
||||
BuildRequires: flex
|
||||
BuildRequires: libcurl-devel
|
||||
BuildRequires: libseccomp-devel
|
||||
BuildRequires: openssl-devel
|
||||
BuildRequires: sqlite-devel
|
||||
BuildRequires: xz-devel
|
||||
|
||||
%description
|
||||
Nix is a purely functional package manager. It allows multiple
|
||||
versions of a package to be installed side-by-side, ensures that
|
||||
dependency specifications are complete, supports atomic upgrades and
|
||||
rollbacks, allows non-root users to install software, and has many
|
||||
other features. It is the basis of the NixOS Linux distribution, but
|
||||
it can be used equally well under other Unix systems.
|
||||
|
||||
%package devel
|
||||
Summary: Development files for %{name}
|
||||
Requires: %{name}%{?_isa} = %{version}-%{release}
|
||||
|
||||
%description devel
|
||||
The %{name}-devel package contains libraries and header files for
|
||||
developing applications that use %{name}.
|
||||
|
||||
|
||||
%package doc
|
||||
Summary: Documentation files for %{name}
|
||||
BuildArch: noarch
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
|
||||
%description doc
|
||||
The %{name}-doc package contains documentation files for %{name}.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
|
||||
%build
|
||||
%if 0%{?rhel}
|
||||
source /opt/rh/devtoolset-7/enable
|
||||
%endif
|
||||
extraFlags=
|
||||
# - override docdir so large documentation files are owned by the
|
||||
# -doc subpackage
|
||||
# - set localstatedir by hand to the preferred nix value
|
||||
%configure --localstatedir=/nix/var \
|
||||
%{!?without_docgen:--disable-doc-gen} \
|
||||
--docdir=%{_defaultdocdir}/%{name}-doc-%{version} \
|
||||
$extraFlags
|
||||
make V=1 %{?_smp_mflags}
|
||||
|
||||
|
||||
%install
|
||||
%if 0%{?rhel}
|
||||
source /opt/rh/devtoolset-7/enable
|
||||
%endif
|
||||
|
||||
make DESTDIR=$RPM_BUILD_ROOT install
|
||||
|
||||
find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';'
|
||||
|
||||
# make the store
|
||||
mkdir -p $RPM_BUILD_ROOT/nix/store
|
||||
chmod 1775 $RPM_BUILD_ROOT/nix/store
|
||||
|
||||
# make per-user directories
|
||||
for d in profiles gcroots;
|
||||
do
|
||||
mkdir -p $RPM_BUILD_ROOT/nix/var/nix/$d/per-user
|
||||
chmod 1777 $RPM_BUILD_ROOT/nix/var/nix/$d/per-user
|
||||
done
|
||||
|
||||
# fix permission of nix profile
|
||||
# (until this is fixed in the relevant Makefile)
|
||||
chmod -x $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/nix.sh
|
||||
|
||||
# we ship this file in the base package
|
||||
rm -f $RPM_BUILD_ROOT%{_defaultdocdir}/%{name}-doc-%{version}/README
|
||||
|
||||
# Get rid of Upstart job.
|
||||
rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/init
|
||||
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
|
||||
%pre
|
||||
getent group %{nixbld_group} >/dev/null || groupadd -r %{nixbld_group}
|
||||
for i in $(seq 10);
|
||||
do
|
||||
getent passwd %{nixbld_user}$i >/dev/null || \
|
||||
useradd -r -g %{nixbld_group} -G %{nixbld_group} -d /var/empty \
|
||||
-s %{_sbindir}/nologin \
|
||||
-c "Nix build user $i" %{nixbld_user}$i
|
||||
done
|
||||
|
||||
%post
|
||||
chgrp %{nixbld_group} /nix/store
|
||||
%if ! 0%{?rhel} || 0%{?rhel} >= 7
|
||||
# Enable and start Nix worker
|
||||
systemctl enable nix-daemon.socket nix-daemon.service
|
||||
systemctl start nix-daemon.socket
|
||||
%endif
|
||||
|
||||
%files
|
||||
%license COPYING
|
||||
%{_bindir}/nix*
|
||||
%{_libdir}/*.so
|
||||
%{_prefix}/libexec/*
|
||||
%if ! 0%{?rhel} || 0%{?rhel} >= 7
|
||||
%{_prefix}/lib/systemd/system/nix-daemon.socket
|
||||
%{_prefix}/lib/systemd/system/nix-daemon.service
|
||||
%endif
|
||||
%{_datadir}/nix
|
||||
#%if ! %{without docgen}
|
||||
#%{_mandir}/man1/*.1*
|
||||
#%{_mandir}/man5/*.5*
|
||||
#%{_mandir}/man8/*.8*
|
||||
#%endif
|
||||
%config(noreplace) %{_sysconfdir}/profile.d/nix.sh
|
||||
%config(noreplace) %{_sysconfdir}/profile.d/nix-daemon.sh
|
||||
/nix
|
||||
|
||||
%files devel
|
||||
%{_includedir}/nix
|
||||
%{_prefix}/lib/pkgconfig/*.pc
|
||||
|
||||
|
||||
#%if ! %{without docgen}
|
||||
#%files doc
|
||||
#%docdir %{_defaultdocdir}/%{name}-doc-%{version}
|
||||
#%{_defaultdocdir}/%{name}-doc-%{version}
|
||||
#%endif
|
||||
@@ -7,9 +7,8 @@ GLOBAL_CXXFLAGS += -g -Wall
|
||||
OPTIMIZE = 1
|
||||
|
||||
ifeq ($(OPTIMIZE), 1)
|
||||
GLOBAL_CFLAGS += -O3
|
||||
GLOBAL_CXXFLAGS += -O3
|
||||
else
|
||||
GLOBAL_CXXFLAGS += -O0
|
||||
endif
|
||||
|
||||
include mk/lib.mk
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
AC_INIT(nix-perl, m4_esyscmd([bash -c "echo -n $(cat ../.version)$VERSION_SUFFIX"]))
|
||||
AC_INIT(nix-perl, m4_esyscmd([bash -c "echo -n $(cat ../version)$VERSION_SUFFIX"]))
|
||||
AC_CONFIG_SRCDIR(MANIFEST)
|
||||
AC_CONFIG_AUX_DIR(../config)
|
||||
|
||||
@@ -6,6 +6,7 @@ CFLAGS=
|
||||
CXXFLAGS=
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AX_CXX_COMPILE_STDCXX_11
|
||||
|
||||
# Use 64-bit file system calls so that we can support files > 2 GiB.
|
||||
AC_SYS_LARGEFILE
|
||||
@@ -68,15 +69,14 @@ AC_SUBST(perlFlags)
|
||||
|
||||
PKG_CHECK_MODULES([NIX], [nix-store])
|
||||
|
||||
NEED_PROG([NIX], [nix])
|
||||
NEED_PROG([NIX_INSTANTIATE_PROGRAM], [nix-instantiate])
|
||||
|
||||
# Get nix configure values
|
||||
export NIX_REMOTE=daemon
|
||||
nixbindir=$("$NIX" --experimental-features nix-command eval --raw -f '<nix/config.nix>' nixBinDir)
|
||||
nixlibexecdir=$("$NIX" --experimental-features nix-command eval --raw -f '<nix/config.nix>' nixLibexecDir)
|
||||
nixlocalstatedir=$("$NIX" --experimental-features nix-command eval --raw -f '<nix/config.nix>' nixLocalstateDir)
|
||||
nixsysconfdir=$("$NIX" --experimental-features nix-command eval --raw -f '<nix/config.nix>' nixSysconfDir)
|
||||
nixstoredir=$("$NIX" --experimental-features nix-command eval --raw -f '<nix/config.nix>' nixStoreDir)
|
||||
nixbindir=$("$NIX_INSTANTIATE_PROGRAM" --eval '<nix/config.nix>' -A nixBinDir | tr -d \")
|
||||
nixlibexecdir=$("$NIX_INSTANTIATE_PROGRAM" --eval '<nix/config.nix>' -A nixLibexecDir | tr -d \")
|
||||
nixlocalstatedir=$("$NIX_INSTANTIATE_PROGRAM" --eval '<nix/config.nix>' -A nixLocalstateDir | tr -d \")
|
||||
nixsysconfdir=$("$NIX_INSTANTIATE_PROGRAM" --eval '<nix/config.nix>' -A nixSysconfDir | tr -d \")
|
||||
nixstoredir=$("$NIX_INSTANTIATE_PROGRAM" --eval '<nix/config.nix>' -A nixStoreDir | tr -d \")
|
||||
AC_SUBST(nixbindir)
|
||||
AC_SUBST(nixlibexecdir)
|
||||
AC_SUBST(nixlocalstatedir)
|
||||
|
||||
@@ -11,6 +11,10 @@ $logDir = $ENV{"NIX_LOG_DIR"} || "@nixlocalstatedir@/log/nix";
|
||||
$confDir = $ENV{"NIX_CONF_DIR"} || "@nixsysconfdir@/nix";
|
||||
$storeDir = $ENV{"NIX_STORE_DIR"} || "@nixstoredir@";
|
||||
|
||||
$bzip2 = "@bzip2@";
|
||||
$xz = "@xz@";
|
||||
$curl = "@curl@";
|
||||
|
||||
$useBindings = 1;
|
||||
|
||||
%config = ();
|
||||
|
||||
@@ -59,7 +59,7 @@ void setVerbosity(int level)
|
||||
int isValidPath(char * path)
|
||||
CODE:
|
||||
try {
|
||||
RETVAL = store()->isValidPath(store()->parseStorePath(path));
|
||||
RETVAL = store()->isValidPath(path);
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -70,8 +70,9 @@ int isValidPath(char * path)
|
||||
SV * queryReferences(char * path)
|
||||
PPCODE:
|
||||
try {
|
||||
for (auto & i : store()->queryPathInfo(store()->parseStorePath(path))->references)
|
||||
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(i).c_str(), 0)));
|
||||
PathSet paths = store()->queryPathInfo(path)->references;
|
||||
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
|
||||
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -80,7 +81,7 @@ SV * queryReferences(char * path)
|
||||
SV * queryPathHash(char * path)
|
||||
PPCODE:
|
||||
try {
|
||||
auto s = store()->queryPathInfo(store()->parseStorePath(path))->narHash.to_string(Base32, true);
|
||||
auto s = store()->queryPathInfo(path)->narHash.to_string();
|
||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
@@ -90,9 +91,9 @@ SV * queryPathHash(char * path)
|
||||
SV * queryDeriver(char * path)
|
||||
PPCODE:
|
||||
try {
|
||||
auto info = store()->queryPathInfo(store()->parseStorePath(path));
|
||||
if (!info->deriver) XSRETURN_UNDEF;
|
||||
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(*info->deriver).c_str(), 0)));
|
||||
auto deriver = store()->queryPathInfo(path)->deriver;
|
||||
if (deriver == "") XSRETURN_UNDEF;
|
||||
XPUSHs(sv_2mortal(newSVpv(deriver.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -101,18 +102,18 @@ SV * queryDeriver(char * path)
|
||||
SV * queryPathInfo(char * path, int base32)
|
||||
PPCODE:
|
||||
try {
|
||||
auto info = store()->queryPathInfo(store()->parseStorePath(path));
|
||||
if (!info->deriver)
|
||||
auto info = store()->queryPathInfo(path);
|
||||
if (info->deriver == "")
|
||||
XPUSHs(&PL_sv_undef);
|
||||
else
|
||||
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(*info->deriver).c_str(), 0)));
|
||||
auto s = info->narHash.to_string(base32 ? Base32 : Base16, true);
|
||||
XPUSHs(sv_2mortal(newSVpv(info->deriver.c_str(), 0)));
|
||||
auto s = info->narHash.to_string(base32 ? Base32 : Base16);
|
||||
XPUSHs(sv_2mortal(newSVpv(s.c_str(), 0)));
|
||||
mXPUSHi(info->registrationTime);
|
||||
mXPUSHi(info->narSize);
|
||||
AV * arr = newAV();
|
||||
for (auto & i : info->references)
|
||||
av_push(arr, newSVpv(store()->printStorePath(i).c_str(), 0));
|
||||
for (PathSet::iterator i = info->references.begin(); i != info->references.end(); ++i)
|
||||
av_push(arr, newSVpv(i->c_str(), 0));
|
||||
XPUSHs(sv_2mortal(newRV((SV *) arr)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
@@ -122,8 +123,8 @@ SV * queryPathInfo(char * path, int base32)
|
||||
SV * queryPathFromHashPart(char * hashPart)
|
||||
PPCODE:
|
||||
try {
|
||||
auto path = store()->queryPathFromHashPart(hashPart);
|
||||
XPUSHs(sv_2mortal(newSVpv(path ? store()->printStorePath(*path).c_str() : "", 0)));
|
||||
Path path = store()->queryPathFromHashPart(hashPart);
|
||||
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -132,11 +133,11 @@ SV * queryPathFromHashPart(char * hashPart)
|
||||
SV * computeFSClosure(int flipDirection, int includeOutputs, ...)
|
||||
PPCODE:
|
||||
try {
|
||||
StorePathSet paths;
|
||||
PathSet paths;
|
||||
for (int n = 2; n < items; ++n)
|
||||
store()->computeFSClosure(store()->parseStorePath(SvPV_nolen(ST(n))), paths, flipDirection, includeOutputs);
|
||||
for (auto & i : paths)
|
||||
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(i).c_str(), 0)));
|
||||
store()->computeFSClosure(SvPV_nolen(ST(n)), paths, flipDirection, includeOutputs);
|
||||
for (PathSet::iterator i = paths.begin(); i != paths.end(); ++i)
|
||||
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -145,11 +146,11 @@ SV * computeFSClosure(int flipDirection, int includeOutputs, ...)
|
||||
SV * topoSortPaths(...)
|
||||
PPCODE:
|
||||
try {
|
||||
StorePathSet paths;
|
||||
for (int n = 0; n < items; ++n) paths.insert(store()->parseStorePath(SvPV_nolen(ST(n))));
|
||||
auto sorted = store()->topoSortPaths(paths);
|
||||
for (auto & i : sorted)
|
||||
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(i).c_str(), 0)));
|
||||
PathSet paths;
|
||||
for (int n = 0; n < items; ++n) paths.insert(SvPV_nolen(ST(n)));
|
||||
Paths sorted = store()->topoSortPaths(paths);
|
||||
for (Paths::iterator i = sorted.begin(); i != sorted.end(); ++i)
|
||||
XPUSHs(sv_2mortal(newSVpv(i->c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -158,7 +159,7 @@ SV * topoSortPaths(...)
|
||||
SV * followLinksToStorePath(char * path)
|
||||
CODE:
|
||||
try {
|
||||
RETVAL = newSVpv(store()->printStorePath(store()->followLinksToStorePath(path)).c_str(), 0);
|
||||
RETVAL = newSVpv(store()->followLinksToStorePath(path).c_str(), 0);
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -169,8 +170,8 @@ SV * followLinksToStorePath(char * path)
|
||||
void exportPaths(int fd, ...)
|
||||
PPCODE:
|
||||
try {
|
||||
StorePathSet paths;
|
||||
for (int n = 1; n < items; ++n) paths.insert(store()->parseStorePath(SvPV_nolen(ST(n))));
|
||||
Paths paths;
|
||||
for (int n = 1; n < items; ++n) paths.push_back(SvPV_nolen(ST(n)));
|
||||
FdSink sink(fd);
|
||||
store()->exportPaths(paths, sink);
|
||||
} catch (Error & e) {
|
||||
@@ -274,9 +275,8 @@ int checkSignature(SV * publicKey_, SV * sig_, char * msg)
|
||||
SV * addToStore(char * srcPath, int recursive, char * algo)
|
||||
PPCODE:
|
||||
try {
|
||||
auto method = recursive ? FileIngestionMethod::Recursive : FileIngestionMethod::Flat;
|
||||
auto path = store()->addToStore(std::string(baseNameOf(srcPath)), srcPath, method, parseHashType(algo));
|
||||
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(path).c_str(), 0)));
|
||||
Path path = store()->addToStore(baseNameOf(srcPath), srcPath, recursive, parseHashType(algo));
|
||||
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -286,9 +286,8 @@ SV * makeFixedOutputPath(int recursive, char * algo, char * hash, char * name)
|
||||
PPCODE:
|
||||
try {
|
||||
Hash h(hash, parseHashType(algo));
|
||||
auto method = recursive ? FileIngestionMethod::Recursive : FileIngestionMethod::Flat;
|
||||
auto path = store()->makeFixedOutputPath(method, h, name);
|
||||
XPUSHs(sv_2mortal(newSVpv(store()->printStorePath(path).c_str(), 0)));
|
||||
Path path = store()->makeFixedOutputPath(recursive, h, name);
|
||||
XPUSHs(sv_2mortal(newSVpv(path.c_str(), 0)));
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
@@ -299,35 +298,35 @@ SV * derivationFromPath(char * drvPath)
|
||||
HV *hash;
|
||||
CODE:
|
||||
try {
|
||||
Derivation drv = store()->derivationFromPath(store()->parseStorePath(drvPath));
|
||||
Derivation drv = store()->derivationFromPath(drvPath);
|
||||
hash = newHV();
|
||||
|
||||
HV * outputs = newHV();
|
||||
for (auto & i : drv.outputs)
|
||||
hv_store(outputs, i.first.c_str(), i.first.size(), newSVpv(store()->printStorePath(i.second.path).c_str(), 0), 0);
|
||||
for (DerivationOutputs::iterator i = drv.outputs.begin(); i != drv.outputs.end(); ++i)
|
||||
hv_store(outputs, i->first.c_str(), i->first.size(), newSVpv(i->second.path.c_str(), 0), 0);
|
||||
hv_stores(hash, "outputs", newRV((SV *) outputs));
|
||||
|
||||
AV * inputDrvs = newAV();
|
||||
for (auto & i : drv.inputDrvs)
|
||||
av_push(inputDrvs, newSVpv(store()->printStorePath(i.first).c_str(), 0)); // !!! ignores i->second
|
||||
for (DerivationInputs::iterator i = drv.inputDrvs.begin(); i != drv.inputDrvs.end(); ++i)
|
||||
av_push(inputDrvs, newSVpv(i->first.c_str(), 0)); // !!! ignores i->second
|
||||
hv_stores(hash, "inputDrvs", newRV((SV *) inputDrvs));
|
||||
|
||||
AV * inputSrcs = newAV();
|
||||
for (auto & i : drv.inputSrcs)
|
||||
av_push(inputSrcs, newSVpv(store()->printStorePath(i).c_str(), 0));
|
||||
for (PathSet::iterator i = drv.inputSrcs.begin(); i != drv.inputSrcs.end(); ++i)
|
||||
av_push(inputSrcs, newSVpv(i->c_str(), 0));
|
||||
hv_stores(hash, "inputSrcs", newRV((SV *) inputSrcs));
|
||||
|
||||
hv_stores(hash, "platform", newSVpv(drv.platform.c_str(), 0));
|
||||
hv_stores(hash, "builder", newSVpv(drv.builder.c_str(), 0));
|
||||
|
||||
AV * args = newAV();
|
||||
for (auto & i : drv.args)
|
||||
av_push(args, newSVpv(i.c_str(), 0));
|
||||
for (Strings::iterator i = drv.args.begin(); i != drv.args.end(); ++i)
|
||||
av_push(args, newSVpv(i->c_str(), 0));
|
||||
hv_stores(hash, "args", newRV((SV *) args));
|
||||
|
||||
HV * env = newHV();
|
||||
for (auto & i : drv.env)
|
||||
hv_store(env, i.first.c_str(), i.first.size(), newSVpv(i.second.c_str(), 0), 0);
|
||||
for (StringPairs::iterator i = drv.env.begin(); i != drv.env.end(); ++i)
|
||||
hv_store(env, i->first.c_str(), i->first.size(), newSVpv(i->second.c_str(), 0), 0);
|
||||
hv_stores(hash, "env", newRV((SV *) env));
|
||||
|
||||
RETVAL = newRV_noinc((SV *)hash);
|
||||
@@ -341,7 +340,7 @@ SV * derivationFromPath(char * drvPath)
|
||||
void addTempRoot(char * storePath)
|
||||
PPCODE:
|
||||
try {
|
||||
store()->addTempRoot(store()->parseStorePath(storePath));
|
||||
store()->addTempRoot(storePath);
|
||||
} catch (Error & e) {
|
||||
croak("%s", e.what());
|
||||
}
|
||||
|
||||