mirror of
https://github.com/NixOS/nix.git
synced 2024-11-25 16:23:02 +00:00
Merge branch 'rm-createdirs' of github.com:siddhantk232/nix into rm-createdirs
This commit is contained in:
commit
857e380c7d
2
.gitignore
vendored
2
.gitignore
vendored
@ -11,6 +11,8 @@ perl/Makefile.config
|
|||||||
/svn-revision
|
/svn-revision
|
||||||
/libtool
|
/libtool
|
||||||
/config/config.*
|
/config/config.*
|
||||||
|
# Default meson build dir
|
||||||
|
/build
|
||||||
|
|
||||||
# /doc/manual/
|
# /doc/manual/
|
||||||
/doc/manual/*.1
|
/doc/manual/*.1
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
external-sources=true
|
external-sources=true
|
||||||
source-path=SCRIPTDIR
|
source-path=SCRIPTDIR
|
||||||
|
# Hack for scripts in e.g. tests/functional/ca
|
||||||
|
source-path=SCRIPTDIR/..
|
||||||
|
17
README.md
17
README.md
@ -13,7 +13,7 @@ Visit [nix.dev](https://nix.dev) for [installation instructions](https://nix.dev
|
|||||||
|
|
||||||
Full reference documentation can be found in the [Nix manual](https://nixos.org/nix/manual).
|
Full reference documentation can be found in the [Nix manual](https://nixos.org/nix/manual).
|
||||||
|
|
||||||
## Building And Developing
|
## Building and developing
|
||||||
|
|
||||||
See our [Hacking guide](https://nixos.org/manual/nix/unstable/contributing/hacking.html) in our manual for instruction on how to
|
See our [Hacking guide](https://nixos.org/manual/nix/unstable/contributing/hacking.html) in our manual for instruction on how to
|
||||||
set up a development environment and build Nix from source.
|
set up a development environment and build Nix from source.
|
||||||
@ -22,12 +22,17 @@ See our [Hacking guide](https://nixos.org/manual/nix/unstable/contributing/hacki
|
|||||||
|
|
||||||
Check the [contributing guide](./CONTRIBUTING.md) if you want to get involved with developing Nix.
|
Check the [contributing guide](./CONTRIBUTING.md) if you want to get involved with developing Nix.
|
||||||
|
|
||||||
## Additional Resources
|
## Additional resources
|
||||||
|
|
||||||
- [Nix manual](https://nixos.org/nix/manual)
|
Nix was created by Eelco Dolstra and developed as the subject of his PhD thesis [The Purely Functional Software Deployment Model](https://edolstra.github.io/pubs/phd-thesis.pdf), published 2006.
|
||||||
- [Nix jobsets on hydra.nixos.org](https://hydra.nixos.org/project/nix)
|
Today, a world-wide developer community contributes to Nix and the ecosystem that has grown around it.
|
||||||
- [NixOS Discourse](https://discourse.nixos.org/)
|
|
||||||
- [Matrix - #nix:nixos.org](https://matrix.to/#/#nix:nixos.org)
|
- [The Nix, Nixpkgs, NixOS Community on nixos.org](https://nixos.org/)
|
||||||
|
- [Official documentation on nix.dev](https://nix.dev)
|
||||||
|
- [Nixpkgs](https://github.com/NixOS/nixpkgs) is [the largest, most up-to-date free software repository in the world](https://repology.org/repositories/graphs)
|
||||||
|
- [NixOS](https://github.com/NixOS/nixpkgs/tree/master/nixos) is a Linux distribution that can be configured fully declaratively
|
||||||
|
- [Discourse](https://discourse.nixos.org/)
|
||||||
|
- [Matrix](https://matrix.to/#/#nix:nixos.org)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
@ -369,6 +369,14 @@ if test "$gc" = yes; then
|
|||||||
PKG_CHECK_MODULES([BDW_GC], [bdw-gc])
|
PKG_CHECK_MODULES([BDW_GC], [bdw-gc])
|
||||||
CXXFLAGS="$BDW_GC_CFLAGS $CXXFLAGS"
|
CXXFLAGS="$BDW_GC_CFLAGS $CXXFLAGS"
|
||||||
AC_DEFINE(HAVE_BOEHMGC, 1, [Whether to use the Boehm garbage collector.])
|
AC_DEFINE(HAVE_BOEHMGC, 1, [Whether to use the Boehm garbage collector.])
|
||||||
|
|
||||||
|
# See `fixupBoehmStackPointer`, for the integration between Boehm GC
|
||||||
|
# and Boost coroutines.
|
||||||
|
old_CFLAGS="$CFLAGS"
|
||||||
|
# Temporary set `-pthread` just for the next check
|
||||||
|
CFLAGS="$CFLAGS -pthread"
|
||||||
|
AC_CHECK_FUNCS([pthread_attr_get_np pthread_getattr_np])
|
||||||
|
CFLAGS="$old_CFLAGS"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AS_IF([test "$ENABLE_UNIT_TESTS" == "yes"],[
|
AS_IF([test "$ENABLE_UNIT_TESTS" == "yes"],[
|
||||||
|
92
flake.nix
92
flake.nix
@ -160,21 +160,34 @@
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
nix =
|
nix-util = final.callPackage ./src/libutil/package.nix {
|
||||||
let
|
inherit
|
||||||
officialRelease = false;
|
fileset
|
||||||
versionSuffix =
|
stdenv
|
||||||
if officialRelease
|
officialRelease
|
||||||
then ""
|
versionSuffix
|
||||||
else "pre${builtins.substring 0 8 (self.lastModifiedDate or self.lastModified or "19700101")}_${self.shortRev or "dirty"}";
|
;
|
||||||
|
};
|
||||||
|
|
||||||
in final.callPackage ./package.nix {
|
nix-store = final.callPackage ./src/libstore/package.nix {
|
||||||
|
inherit
|
||||||
|
fileset
|
||||||
|
stdenv
|
||||||
|
officialRelease
|
||||||
|
versionSuffix
|
||||||
|
;
|
||||||
|
libseccomp = final.libseccomp-nix;
|
||||||
|
busybox-sandbox-shell = final.busybox-sandbox-shell or final.default-busybox-sandbox-shell;
|
||||||
|
};
|
||||||
|
|
||||||
|
nix =
|
||||||
|
final.callPackage ./package.nix {
|
||||||
inherit
|
inherit
|
||||||
fileset
|
fileset
|
||||||
stdenv
|
stdenv
|
||||||
|
officialRelease
|
||||||
versionSuffix
|
versionSuffix
|
||||||
;
|
;
|
||||||
officialRelease = false;
|
|
||||||
boehmgc = final.boehmgc-nix;
|
boehmgc = final.boehmgc-nix;
|
||||||
libgit2 = final.libgit2-nix;
|
libgit2 = final.libgit2-nix;
|
||||||
libseccomp = final.libseccomp-nix;
|
libseccomp = final.libseccomp-nix;
|
||||||
@ -203,7 +216,7 @@
|
|||||||
# 'nix.perl-bindings' packages.
|
# 'nix.perl-bindings' packages.
|
||||||
overlays.default = overlayFor (p: p.stdenv);
|
overlays.default = overlayFor (p: p.stdenv);
|
||||||
|
|
||||||
hydraJobs = import ./build/hydra.nix {
|
hydraJobs = import ./maintainers/hydra.nix {
|
||||||
inherit
|
inherit
|
||||||
inputs
|
inputs
|
||||||
binaryTarball
|
binaryTarball
|
||||||
@ -236,11 +249,34 @@
|
|||||||
} // devFlake.checks.${system} or {}
|
} // devFlake.checks.${system} or {}
|
||||||
);
|
);
|
||||||
|
|
||||||
packages = forAllSystems (system: rec {
|
packages = forAllSystems (system: {
|
||||||
inherit (nixpkgsFor.${system}.native) nix changelog-d;
|
inherit (nixpkgsFor.${system}.native)
|
||||||
default = nix;
|
changelog-d;
|
||||||
} // (lib.optionalAttrs (builtins.elem system linux64BitSystems) {
|
default = self.packages.${system}.nix;
|
||||||
nix-static = nixpkgsFor.${system}.static.nix;
|
} // lib.concatMapAttrs
|
||||||
|
# We need to flatten recursive attribute sets of derivations to pass `flake check`.
|
||||||
|
(pkgName: {}: {
|
||||||
|
"${pkgName}" = nixpkgsFor.${system}.native.${pkgName};
|
||||||
|
"${pkgName}-static" = nixpkgsFor.${system}.static.${pkgName};
|
||||||
|
} // lib.concatMapAttrs
|
||||||
|
(crossSystem: {}: {
|
||||||
|
"${pkgName}-${crossSystem}" = nixpkgsFor.${system}.cross.${crossSystem}.${pkgName};
|
||||||
|
})
|
||||||
|
(lib.genAttrs crossSystems (_: { }))
|
||||||
|
// lib.concatMapAttrs
|
||||||
|
(stdenvName: {}: {
|
||||||
|
"${pkgName}-${stdenvName}" = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".${pkgName};
|
||||||
|
})
|
||||||
|
(lib.genAttrs stdenvs (_: { })))
|
||||||
|
{
|
||||||
|
"nix" = { };
|
||||||
|
# Temporarily disabled because GitHub Actions OOM issues. Once
|
||||||
|
# the old build system is gone and we are back to one build
|
||||||
|
# system, we should reenable these.
|
||||||
|
#"nix-util" = { };
|
||||||
|
#"nix-store" = { };
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs (builtins.elem system linux64BitSystems) {
|
||||||
dockerImage =
|
dockerImage =
|
||||||
let
|
let
|
||||||
pkgs = nixpkgsFor.${system}.native;
|
pkgs = nixpkgsFor.${system}.native;
|
||||||
@ -255,18 +291,7 @@
|
|||||||
ln -s ${image} $image
|
ln -s ${image} $image
|
||||||
echo "file binary-dist $image" >> $out/nix-support/hydra-build-products
|
echo "file binary-dist $image" >> $out/nix-support/hydra-build-products
|
||||||
'';
|
'';
|
||||||
} // builtins.listToAttrs (map
|
});
|
||||||
(crossSystem: {
|
|
||||||
name = "nix-${crossSystem}";
|
|
||||||
value = nixpkgsFor.${system}.cross.${crossSystem}.nix;
|
|
||||||
})
|
|
||||||
crossSystems)
|
|
||||||
// builtins.listToAttrs (map
|
|
||||||
(stdenvName: {
|
|
||||||
name = "nix-${stdenvName}";
|
|
||||||
value = nixpkgsFor.${system}.stdenvs."${stdenvName}Packages".nix;
|
|
||||||
})
|
|
||||||
stdenvs)));
|
|
||||||
|
|
||||||
devShells = let
|
devShells = let
|
||||||
makeShell = pkgs: stdenv: (pkgs.nix.override { inherit stdenv; forDevShell = true; }).overrideAttrs (attrs:
|
makeShell = pkgs: stdenv: (pkgs.nix.override { inherit stdenv; forDevShell = true; }).overrideAttrs (attrs:
|
||||||
@ -274,6 +299,11 @@
|
|||||||
modular = devFlake.getSystem stdenv.buildPlatform.system;
|
modular = devFlake.getSystem stdenv.buildPlatform.system;
|
||||||
in {
|
in {
|
||||||
pname = "shell-for-" + attrs.pname;
|
pname = "shell-for-" + attrs.pname;
|
||||||
|
|
||||||
|
# Remove the version suffix to avoid unnecessary attempts to substitute in nix develop
|
||||||
|
version = lib.fileContents ./.version;
|
||||||
|
name = attrs.pname;
|
||||||
|
|
||||||
installFlags = "sysconfdir=$(out)/etc";
|
installFlags = "sysconfdir=$(out)/etc";
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
PATH=$prefix/bin:$PATH
|
PATH=$prefix/bin:$PATH
|
||||||
@ -288,12 +318,20 @@
|
|||||||
src = null;
|
src = null;
|
||||||
|
|
||||||
env = {
|
env = {
|
||||||
|
# Needed for Meson to find Boost.
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/86131.
|
||||||
|
BOOST_INCLUDEDIR = "${lib.getDev pkgs.boost}/include";
|
||||||
|
BOOST_LIBRARYDIR = "${lib.getLib pkgs.boost}/lib";
|
||||||
# For `make format`, to work without installing pre-commit
|
# For `make format`, to work without installing pre-commit
|
||||||
_NIX_PRE_COMMIT_HOOKS_CONFIG =
|
_NIX_PRE_COMMIT_HOOKS_CONFIG =
|
||||||
"${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml" modular.pre-commit.settings.rawConfig}";
|
"${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml" modular.pre-commit.settings.rawConfig}";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
mesonFlags = pkgs.nix-util.mesonFlags ++ pkgs.nix-store.mesonFlags;
|
||||||
|
|
||||||
nativeBuildInputs = attrs.nativeBuildInputs or []
|
nativeBuildInputs = attrs.nativeBuildInputs or []
|
||||||
|
++ pkgs.nix-util.nativeBuildInputs
|
||||||
|
++ pkgs.nix-store.nativeBuildInputs
|
||||||
++ [
|
++ [
|
||||||
modular.pre-commit.settings.package
|
modular.pre-commit.settings.package
|
||||||
(pkgs.writeScriptBin "pre-commit-hooks-install"
|
(pkgs.writeScriptBin "pre-commit-hooks-install"
|
||||||
|
@ -507,50 +507,30 @@
|
|||||||
''^scripts/install-nix-from-closure\.sh$''
|
''^scripts/install-nix-from-closure\.sh$''
|
||||||
''^scripts/install-systemd-multi-user\.sh$''
|
''^scripts/install-systemd-multi-user\.sh$''
|
||||||
''^src/nix/get-env\.sh$''
|
''^src/nix/get-env\.sh$''
|
||||||
''^tests/functional/bash-profile\.sh$''
|
|
||||||
''^tests/functional/binary-cache-build-remote\.sh$''
|
|
||||||
''^tests/functional/binary-cache\.sh$''
|
|
||||||
''^tests/functional/brotli\.sh$''
|
|
||||||
''^tests/functional/build-delete\.sh$''
|
|
||||||
''^tests/functional/build-dry\.sh$''
|
|
||||||
''^tests/functional/build\.sh$''
|
''^tests/functional/build\.sh$''
|
||||||
''^tests/functional/ca/build-cache\.sh$''
|
|
||||||
''^tests/functional/ca/build-dry\.sh$''
|
''^tests/functional/ca/build-dry\.sh$''
|
||||||
''^tests/functional/ca/build-with-garbage-path\.sh$''
|
''^tests/functional/ca/build-with-garbage-path\.sh$''
|
||||||
''^tests/functional/ca/build\.sh$''
|
|
||||||
''^tests/functional/ca/common\.sh$''
|
''^tests/functional/ca/common\.sh$''
|
||||||
''^tests/functional/ca/concurrent-builds\.sh$''
|
''^tests/functional/ca/concurrent-builds\.sh$''
|
||||||
''^tests/functional/ca/derivation-json\.sh$''
|
|
||||||
''^tests/functional/ca/duplicate-realisation-in-closure\.sh$''
|
|
||||||
''^tests/functional/ca/eval-store\.sh$''
|
''^tests/functional/ca/eval-store\.sh$''
|
||||||
''^tests/functional/ca/gc\.sh$''
|
''^tests/functional/ca/gc\.sh$''
|
||||||
''^tests/functional/ca/import-derivation\.sh$''
|
''^tests/functional/ca/import-derivation\.sh$''
|
||||||
''^tests/functional/ca/new-build-cmd\.sh$''
|
''^tests/functional/ca/new-build-cmd\.sh$''
|
||||||
''^tests/functional/ca/nix-copy\.sh$''
|
|
||||||
''^tests/functional/ca/nix-run\.sh$''
|
|
||||||
''^tests/functional/ca/nix-shell\.sh$''
|
''^tests/functional/ca/nix-shell\.sh$''
|
||||||
''^tests/functional/ca/post-hook\.sh$''
|
''^tests/functional/ca/post-hook\.sh$''
|
||||||
''^tests/functional/ca/recursive\.sh$''
|
''^tests/functional/ca/recursive\.sh$''
|
||||||
''^tests/functional/ca/repl\.sh$''
|
''^tests/functional/ca/repl\.sh$''
|
||||||
''^tests/functional/ca/selfref-gc\.sh$''
|
''^tests/functional/ca/selfref-gc\.sh$''
|
||||||
''^tests/functional/ca/signatures\.sh$''
|
|
||||||
''^tests/functional/ca/substitute\.sh$''
|
|
||||||
''^tests/functional/ca/why-depends\.sh$''
|
''^tests/functional/ca/why-depends\.sh$''
|
||||||
''^tests/functional/case-hack\.sh$''
|
|
||||||
''^tests/functional/check-refs\.sh$''
|
|
||||||
''^tests/functional/check-reqs\.sh$''
|
|
||||||
''^tests/functional/check\.sh$''
|
''^tests/functional/check\.sh$''
|
||||||
''^tests/functional/chroot-store\.sh$''
|
|
||||||
''^tests/functional/common/vars-and-functions\.sh$''
|
''^tests/functional/common/vars-and-functions\.sh$''
|
||||||
''^tests/functional/completions\.sh$''
|
''^tests/functional/completions\.sh$''
|
||||||
''^tests/functional/compression-levels\.sh$''
|
|
||||||
''^tests/functional/compute-levels\.sh$''
|
''^tests/functional/compute-levels\.sh$''
|
||||||
''^tests/functional/config\.sh$''
|
''^tests/functional/config\.sh$''
|
||||||
''^tests/functional/db-migration\.sh$''
|
''^tests/functional/db-migration\.sh$''
|
||||||
''^tests/functional/debugger\.sh$''
|
''^tests/functional/debugger\.sh$''
|
||||||
''^tests/functional/dependencies\.builder0\.sh$''
|
''^tests/functional/dependencies\.builder0\.sh$''
|
||||||
''^tests/functional/dependencies\.sh$''
|
''^tests/functional/dependencies\.sh$''
|
||||||
''^tests/functional/derivation-json\.sh$''
|
|
||||||
''^tests/functional/dump-db\.sh$''
|
''^tests/functional/dump-db\.sh$''
|
||||||
''^tests/functional/dyn-drv/build-built-drv\.sh$''
|
''^tests/functional/dyn-drv/build-built-drv\.sh$''
|
||||||
''^tests/functional/dyn-drv/common\.sh$''
|
''^tests/functional/dyn-drv/common\.sh$''
|
||||||
@ -558,10 +538,8 @@
|
|||||||
''^tests/functional/dyn-drv/eval-outputOf\.sh$''
|
''^tests/functional/dyn-drv/eval-outputOf\.sh$''
|
||||||
''^tests/functional/dyn-drv/old-daemon-error-hack\.sh$''
|
''^tests/functional/dyn-drv/old-daemon-error-hack\.sh$''
|
||||||
''^tests/functional/dyn-drv/recursive-mod-json\.sh$''
|
''^tests/functional/dyn-drv/recursive-mod-json\.sh$''
|
||||||
''^tests/functional/dyn-drv/text-hashed-output\.sh$''
|
|
||||||
''^tests/functional/eval-store\.sh$''
|
''^tests/functional/eval-store\.sh$''
|
||||||
''^tests/functional/eval\.sh$''
|
''^tests/functional/eval\.sh$''
|
||||||
''^tests/functional/experimental-features\.sh$''
|
|
||||||
''^tests/functional/export-graph\.sh$''
|
''^tests/functional/export-graph\.sh$''
|
||||||
''^tests/functional/export\.sh$''
|
''^tests/functional/export\.sh$''
|
||||||
''^tests/functional/extra-sandbox-profile\.sh$''
|
''^tests/functional/extra-sandbox-profile\.sh$''
|
||||||
@ -571,49 +549,32 @@
|
|||||||
''^tests/functional/fetchGitSubmodules\.sh$''
|
''^tests/functional/fetchGitSubmodules\.sh$''
|
||||||
''^tests/functional/fetchGitVerification\.sh$''
|
''^tests/functional/fetchGitVerification\.sh$''
|
||||||
''^tests/functional/fetchMercurial\.sh$''
|
''^tests/functional/fetchMercurial\.sh$''
|
||||||
''^tests/functional/fetchPath\.sh$''
|
|
||||||
''^tests/functional/fetchTree-file\.sh$''
|
|
||||||
''^tests/functional/fetchurl\.sh$''
|
''^tests/functional/fetchurl\.sh$''
|
||||||
''^tests/functional/filter-source\.sh$''
|
|
||||||
''^tests/functional/fixed\.builder1\.sh$''
|
''^tests/functional/fixed\.builder1\.sh$''
|
||||||
''^tests/functional/fixed\.builder2\.sh$''
|
''^tests/functional/fixed\.builder2\.sh$''
|
||||||
''^tests/functional/fixed\.sh$''
|
''^tests/functional/fixed\.sh$''
|
||||||
''^tests/functional/flakes/absolute-attr-paths\.sh$''
|
|
||||||
''^tests/functional/flakes/absolute-paths\.sh$''
|
''^tests/functional/flakes/absolute-paths\.sh$''
|
||||||
''^tests/functional/flakes/build-paths\.sh$''
|
|
||||||
''^tests/functional/flakes/bundle\.sh$''
|
|
||||||
''^tests/functional/flakes/check\.sh$''
|
''^tests/functional/flakes/check\.sh$''
|
||||||
''^tests/functional/flakes/circular\.sh$''
|
|
||||||
''^tests/functional/flakes/common\.sh$''
|
''^tests/functional/flakes/common\.sh$''
|
||||||
''^tests/functional/flakes/config\.sh$''
|
''^tests/functional/flakes/config\.sh$''
|
||||||
''^tests/functional/flakes/develop\.sh$''
|
''^tests/functional/flakes/develop\.sh$''
|
||||||
''^tests/functional/flakes/flake-in-submodule\.sh$''
|
|
||||||
''^tests/functional/flakes/flakes\.sh$''
|
''^tests/functional/flakes/flakes\.sh$''
|
||||||
''^tests/functional/flakes/follow-paths\.sh$''
|
''^tests/functional/flakes/follow-paths\.sh$''
|
||||||
''^tests/functional/flakes/init\.sh$''
|
|
||||||
''^tests/functional/flakes/inputs\.sh$''
|
|
||||||
''^tests/functional/flakes/mercurial\.sh$''
|
|
||||||
''^tests/functional/flakes/prefetch\.sh$''
|
''^tests/functional/flakes/prefetch\.sh$''
|
||||||
''^tests/functional/flakes/run\.sh$''
|
''^tests/functional/flakes/run\.sh$''
|
||||||
''^tests/functional/flakes/search-root\.sh$''
|
|
||||||
''^tests/functional/flakes/show\.sh$''
|
''^tests/functional/flakes/show\.sh$''
|
||||||
''^tests/functional/flakes/unlocked-override\.sh$''
|
|
||||||
''^tests/functional/fmt\.sh$''
|
''^tests/functional/fmt\.sh$''
|
||||||
''^tests/functional/fmt\.simple\.sh$''
|
''^tests/functional/fmt\.simple\.sh$''
|
||||||
''^tests/functional/function-trace\.sh$''
|
|
||||||
''^tests/functional/gc-auto\.sh$''
|
''^tests/functional/gc-auto\.sh$''
|
||||||
''^tests/functional/gc-concurrent\.builder\.sh$''
|
''^tests/functional/gc-concurrent\.builder\.sh$''
|
||||||
''^tests/functional/gc-concurrent\.sh$''
|
''^tests/functional/gc-concurrent\.sh$''
|
||||||
''^tests/functional/gc-concurrent2\.builder\.sh$''
|
''^tests/functional/gc-concurrent2\.builder\.sh$''
|
||||||
''^tests/functional/gc-non-blocking\.sh$''
|
''^tests/functional/gc-non-blocking\.sh$''
|
||||||
''^tests/functional/gc-runtime\.sh$''
|
|
||||||
''^tests/functional/gc\.sh$''
|
''^tests/functional/gc\.sh$''
|
||||||
''^tests/functional/git-hashing/common\.sh$''
|
''^tests/functional/git-hashing/common\.sh$''
|
||||||
''^tests/functional/git-hashing/simple\.sh$''
|
''^tests/functional/git-hashing/simple\.sh$''
|
||||||
''^tests/functional/hash-convert\.sh$''
|
''^tests/functional/hash-convert\.sh$''
|
||||||
''^tests/functional/hash-path\.sh$''
|
|
||||||
''^tests/functional/help\.sh$''
|
''^tests/functional/help\.sh$''
|
||||||
''^tests/functional/import-derivation\.sh$''
|
|
||||||
''^tests/functional/impure-derivations\.sh$''
|
''^tests/functional/impure-derivations\.sh$''
|
||||||
''^tests/functional/impure-env\.sh$''
|
''^tests/functional/impure-env\.sh$''
|
||||||
''^tests/functional/impure-eval\.sh$''
|
''^tests/functional/impure-eval\.sh$''
|
||||||
|
@ -32,17 +32,26 @@ let
|
|||||||
|
|
||||||
doBuild = false;
|
doBuild = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
forAllPackages = lib.genAttrs [
|
||||||
|
"nix"
|
||||||
|
"nix-util"
|
||||||
|
"nix-store"
|
||||||
|
];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# Binary package for various platforms.
|
# Binary package for various platforms.
|
||||||
build = forAllSystems (system: self.packages.${system}.nix);
|
build = forAllPackages (pkgName:
|
||||||
|
forAllSystems (system: nixpkgsFor.${system}.native.${pkgName}));
|
||||||
|
|
||||||
shellInputs = forAllSystems (system: self.devShells.${system}.default.inputDerivation);
|
shellInputs = forAllSystems (system: self.devShells.${system}.default.inputDerivation);
|
||||||
|
|
||||||
buildStatic = lib.genAttrs linux64BitSystems (system: self.packages.${system}.nix-static);
|
buildStatic = forAllPackages (pkgName:
|
||||||
|
lib.genAttrs linux64BitSystems (system: nixpkgsFor.${system}.static.${pkgName}));
|
||||||
|
|
||||||
buildCross = forAllCrossSystems (crossSystem:
|
buildCross = forAllPackages (pkgName:
|
||||||
lib.genAttrs [ "x86_64-linux" ] (system: self.packages.${system}."nix-${crossSystem}"));
|
forAllCrossSystems (crossSystem:
|
||||||
|
lib.genAttrs [ "x86_64-linux" ] (system: nixpkgsFor.${system}.cross.${crossSystem}.${pkgName})));
|
||||||
|
|
||||||
buildNoGc = forAllSystems (system:
|
buildNoGc = forAllSystems (system:
|
||||||
self.packages.${system}.nix.override { enableGC = false; }
|
self.packages.${system}.nix.override { enableGC = false; }
|
||||||
@ -76,7 +85,7 @@ in
|
|||||||
binaryTarballCross = lib.genAttrs [ "x86_64-linux" ] (system:
|
binaryTarballCross = lib.genAttrs [ "x86_64-linux" ] (system:
|
||||||
forAllCrossSystems (crossSystem:
|
forAllCrossSystems (crossSystem:
|
||||||
binaryTarball
|
binaryTarball
|
||||||
self.packages.${system}."nix-${crossSystem}"
|
nixpkgsFor.${system}.cross.${crossSystem}.nix
|
||||||
nixpkgsFor.${system}.cross.${crossSystem}));
|
nixpkgsFor.${system}.cross.${crossSystem}));
|
||||||
|
|
||||||
# The first half of the installation script. This is uploaded
|
# The first half of the installation script. This is uploaded
|
10
meson.build
Normal file
10
meson.build
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# This is just a stub project to include all the others as subprojects
|
||||||
|
# for development shell purposes
|
||||||
|
|
||||||
|
project('nix-dev-shell', 'cpp',
|
||||||
|
version : files('.version'),
|
||||||
|
subproject_dir : 'src',
|
||||||
|
)
|
||||||
|
|
||||||
|
subproject('libutil')
|
||||||
|
subproject('libstore')
|
@ -8,7 +8,7 @@ GCH = $(buildprefix)precompiled-headers.h.gch
|
|||||||
$(GCH): precompiled-headers.h
|
$(GCH): precompiled-headers.h
|
||||||
@rm -f $@
|
@rm -f $@
|
||||||
@mkdir -p "$(dir $@)"
|
@mkdir -p "$(dir $@)"
|
||||||
$(trace-gen) $(CXX) -x c++-header -o $@ $< $(GLOBAL_CXXFLAGS) $(GCH_CXXFLAGS)
|
$(trace-gen) $(CXX) -c -x c++-header -o $@ $< $(GLOBAL_CXXFLAGS) $(GCH_CXXFLAGS)
|
||||||
|
|
||||||
clean-files += $(GCH)
|
clean-files += $(GCH)
|
||||||
|
|
||||||
|
11
package.nix
11
package.nix
@ -208,7 +208,9 @@ in {
|
|||||||
# If we are doing just build or just docs, the one thing will use
|
# If we are doing just build or just docs, the one thing will use
|
||||||
# "out". We only need additional outputs if we are doing both.
|
# "out". We only need additional outputs if we are doing both.
|
||||||
++ lib.optional (doBuild && (enableManual || enableInternalAPIDocs || enableExternalAPIDocs)) "doc"
|
++ lib.optional (doBuild && (enableManual || enableInternalAPIDocs || enableExternalAPIDocs)) "doc"
|
||||||
++ lib.optional installUnitTests "check";
|
++ lib.optional installUnitTests "check"
|
||||||
|
++ lib.optional doCheck "testresults"
|
||||||
|
;
|
||||||
|
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = [
|
||||||
autoconf-archive
|
autoconf-archive
|
||||||
@ -317,6 +319,10 @@ in {
|
|||||||
|
|
||||||
makeFlags = "profiledir=$(out)/etc/profile.d PRECOMPILE_HEADERS=1";
|
makeFlags = "profiledir=$(out)/etc/profile.d PRECOMPILE_HEADERS=1";
|
||||||
|
|
||||||
|
preCheck = ''
|
||||||
|
mkdir $testresults
|
||||||
|
'';
|
||||||
|
|
||||||
installTargets = lib.optional doBuild "install"
|
installTargets = lib.optional doBuild "install"
|
||||||
++ lib.optional enableInternalAPIDocs "internal-api-html"
|
++ lib.optional enableInternalAPIDocs "internal-api-html"
|
||||||
++ lib.optional enableExternalAPIDocs "external-api-html";
|
++ lib.optional enableExternalAPIDocs "external-api-html";
|
||||||
@ -385,8 +391,7 @@ in {
|
|||||||
|
|
||||||
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||||
|
|
||||||
# TODO `releaseTools.coverageAnalysis` in Nixpkgs needs to be updated
|
# TODO Always true after https://github.com/NixOS/nixpkgs/issues/318564
|
||||||
# to work with `strictDeps`.
|
|
||||||
strictDeps = !withCoverageChecks;
|
strictDeps = !withCoverageChecks;
|
||||||
|
|
||||||
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||||
|
@ -754,7 +754,7 @@ I will:
|
|||||||
(if it does, I will tell you how to clean them up.)
|
(if it does, I will tell you how to clean them up.)
|
||||||
- create local users (see the list above for the users I'll make)
|
- create local users (see the list above for the users I'll make)
|
||||||
- create a local group ($NIX_BUILD_GROUP_NAME)
|
- create a local group ($NIX_BUILD_GROUP_NAME)
|
||||||
- install Nix in to $NIX_ROOT
|
- install Nix in $NIX_ROOT
|
||||||
- create a configuration file in /etc/nix
|
- create a configuration file in /etc/nix
|
||||||
- set up the "default profile" by creating some Nix-related files in
|
- set up the "default profile" by creating some Nix-related files in
|
||||||
$ROOT_HOME
|
$ROOT_HOME
|
||||||
|
@ -42,56 +42,56 @@ nix_err nix_libexpr_init(nix_c_context * context)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_expr_eval_from_string(
|
nix_err nix_expr_eval_from_string(
|
||||||
nix_c_context * context, EvalState * state, const char * expr, const char * path, Value * value)
|
nix_c_context * context, EvalState * state, const char * expr, const char * path, nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
nix::Expr * parsedExpr = state->state.parseExprFromString(expr, state->state.rootPath(nix::CanonPath(path)));
|
nix::Expr * parsedExpr = state->state.parseExprFromString(expr, state->state.rootPath(nix::CanonPath(path)));
|
||||||
state->state.eval(parsedExpr, *(nix::Value *) value);
|
state->state.eval(parsedExpr, value->value);
|
||||||
state->state.forceValue(*(nix::Value *) value, nix::noPos);
|
state->state.forceValue(value->value, nix::noPos);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, Value * arg, Value * value)
|
nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, nix_value * arg, nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
state->state.callFunction(*(nix::Value *) fn, *(nix::Value *) arg, *(nix::Value *) value, nix::noPos);
|
state->state.callFunction(fn->value, arg->value, value->value, nix::noPos);
|
||||||
state->state.forceValue(*(nix::Value *) value, nix::noPos);
|
state->state.forceValue(value->value, nix::noPos);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_value_call_multi(nix_c_context * context, EvalState * state, Value * fn, size_t nargs, Value ** args, Value * value)
|
nix_err nix_value_call_multi(nix_c_context * context, EvalState * state, nix_value * fn, size_t nargs, nix_value ** args, nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
state->state.callFunction(*(nix::Value *) fn, nargs, (nix::Value * *)args, *(nix::Value *) value, nix::noPos);
|
state->state.callFunction(fn->value, nargs, (nix::Value * *)args, value->value, nix::noPos);
|
||||||
state->state.forceValue(*(nix::Value *) value, nix::noPos);
|
state->state.forceValue(value->value, nix::noPos);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_value_force(nix_c_context * context, EvalState * state, Value * value)
|
nix_err nix_value_force(nix_c_context * context, EvalState * state, nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
state->state.forceValue(*(nix::Value *) value, nix::noPos);
|
state->state.forceValue(value->value, nix::noPos);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, Value * value)
|
nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
state->state.forceValueDeep(*(nix::Value *) value);
|
state->state.forceValueDeep(value->value);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
@ -181,6 +181,15 @@ nix_err nix_gc_decref(nix_c_context * context, const void *)
|
|||||||
void nix_gc_now() {}
|
void nix_gc_now() {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
nix_err nix_value_incref(nix_c_context * context, nix_value *x)
|
||||||
|
{
|
||||||
|
return nix_gc_incref(context, (const void *) x);
|
||||||
|
}
|
||||||
|
nix_err nix_value_decref(nix_c_context * context, nix_value *x)
|
||||||
|
{
|
||||||
|
return nix_gc_decref(context, (const void *) x);
|
||||||
|
}
|
||||||
|
|
||||||
void nix_gc_register_finalizer(void * obj, void * cd, void (*finalizer)(void * obj, void * cd))
|
void nix_gc_register_finalizer(void * obj, void * cd, void (*finalizer)(void * obj, void * cd))
|
||||||
{
|
{
|
||||||
#ifdef HAVE_BOEHMGC
|
#ifdef HAVE_BOEHMGC
|
||||||
|
@ -29,14 +29,23 @@ extern "C" {
|
|||||||
* @see nix_state_create
|
* @see nix_state_create
|
||||||
*/
|
*/
|
||||||
typedef struct EvalState EvalState; // nix::EvalState
|
typedef struct EvalState EvalState; // nix::EvalState
|
||||||
/**
|
|
||||||
* @brief Represents a value in the Nix language.
|
/** @brief A Nix language value, or thunk that may evaluate to a value.
|
||||||
|
*
|
||||||
|
* Values are the primary objects manipulated in the Nix language.
|
||||||
|
* They are considered to be immutable from a user's perspective, but the process of evaluating a value changes its
|
||||||
|
* ValueType if it was a thunk. After a value has been evaluated, its ValueType does not change.
|
||||||
|
*
|
||||||
|
* Evaluation in this context refers to the process of evaluating a single value object, also called "forcing" the
|
||||||
|
* value; see `nix_value_force`.
|
||||||
|
*
|
||||||
|
* The evaluator manages its own memory, but your use of the C API must follow the reference counting rules.
|
||||||
*
|
*
|
||||||
* Owned by the garbage collector.
|
|
||||||
* @struct Value
|
|
||||||
* @see value_manip
|
* @see value_manip
|
||||||
|
* @see nix_value_incref, nix_value_decref
|
||||||
*/
|
*/
|
||||||
typedef void Value; // nix::Value
|
typedef struct nix_value nix_value;
|
||||||
|
[[deprecated("use nix_value instead")]] typedef nix_value Value;
|
||||||
|
|
||||||
// Function prototypes
|
// Function prototypes
|
||||||
/**
|
/**
|
||||||
@ -65,7 +74,7 @@ nix_err nix_libexpr_init(nix_c_context * context);
|
|||||||
* @return NIX_OK if the evaluation was successful, an error code otherwise.
|
* @return NIX_OK if the evaluation was successful, an error code otherwise.
|
||||||
*/
|
*/
|
||||||
nix_err nix_expr_eval_from_string(
|
nix_err nix_expr_eval_from_string(
|
||||||
nix_c_context * context, EvalState * state, const char * expr, const char * path, Value * value);
|
nix_c_context * context, EvalState * state, const char * expr, const char * path, nix_value * value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calls a Nix function with an argument.
|
* @brief Calls a Nix function with an argument.
|
||||||
@ -79,7 +88,7 @@ nix_err nix_expr_eval_from_string(
|
|||||||
* @see nix_init_apply() for a similar function that does not performs the call immediately, but stores it as a thunk.
|
* @see nix_init_apply() for a similar function that does not performs the call immediately, but stores it as a thunk.
|
||||||
* Note the different argument order.
|
* Note the different argument order.
|
||||||
*/
|
*/
|
||||||
nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, Value * arg, Value * value);
|
nix_err nix_value_call(nix_c_context * context, EvalState * state, nix_value * fn, nix_value * arg, nix_value * value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calls a Nix function with multiple arguments.
|
* @brief Calls a Nix function with multiple arguments.
|
||||||
@ -98,7 +107,7 @@ nix_err nix_value_call(nix_c_context * context, EvalState * state, Value * fn, V
|
|||||||
* @see NIX_VALUE_CALL For a macro that wraps this function for convenience.
|
* @see NIX_VALUE_CALL For a macro that wraps this function for convenience.
|
||||||
*/
|
*/
|
||||||
nix_err nix_value_call_multi(
|
nix_err nix_value_call_multi(
|
||||||
nix_c_context * context, EvalState * state, Value * fn, size_t nargs, Value ** args, Value * value);
|
nix_c_context * context, EvalState * state, nix_value * fn, size_t nargs, nix_value ** args, nix_value * value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Calls a Nix function with multiple arguments.
|
* @brief Calls a Nix function with multiple arguments.
|
||||||
@ -116,7 +125,7 @@ nix_err nix_value_call_multi(
|
|||||||
*/
|
*/
|
||||||
#define NIX_VALUE_CALL(context, state, value, fn, ...) \
|
#define NIX_VALUE_CALL(context, state, value, fn, ...) \
|
||||||
do { \
|
do { \
|
||||||
Value * args_array[] = {__VA_ARGS__}; \
|
nix_value * args_array[] = {__VA_ARGS__}; \
|
||||||
size_t nargs = sizeof(args_array) / sizeof(args_array[0]); \
|
size_t nargs = sizeof(args_array) / sizeof(args_array[0]); \
|
||||||
nix_value_call_multi(context, state, fn, nargs, args_array, value); \
|
nix_value_call_multi(context, state, fn, nargs, args_array, value); \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -124,12 +133,10 @@ nix_err nix_value_call_multi(
|
|||||||
/**
|
/**
|
||||||
* @brief Forces the evaluation of a Nix value.
|
* @brief Forces the evaluation of a Nix value.
|
||||||
*
|
*
|
||||||
* The Nix interpreter is lazy, and not-yet-evaluated Values can be
|
* The Nix interpreter is lazy, and not-yet-evaluated values can be
|
||||||
* of type NIX_TYPE_THUNK instead of their actual value.
|
* of type NIX_TYPE_THUNK instead of their actual value.
|
||||||
*
|
*
|
||||||
* This function converts these Values into their final type.
|
* This function mutates such a `nix_value`, so that, if successful, it has its final type.
|
||||||
*
|
|
||||||
* @note This function is mainly needed before calling @ref getters, but not for API calls that return a `Value`.
|
|
||||||
*
|
*
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] state The state of the evaluation.
|
* @param[in] state The state of the evaluation.
|
||||||
@ -138,7 +145,7 @@ nix_err nix_value_call_multi(
|
|||||||
* @return NIX_OK if the force operation was successful, an error code
|
* @return NIX_OK if the force operation was successful, an error code
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
nix_err nix_value_force(nix_c_context * context, EvalState * state, Value * value);
|
nix_err nix_value_force(nix_c_context * context, EvalState * state, nix_value * value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Forces the deep evaluation of a Nix value.
|
* @brief Forces the deep evaluation of a Nix value.
|
||||||
@ -154,7 +161,7 @@ nix_err nix_value_force(nix_c_context * context, EvalState * state, Value * valu
|
|||||||
* @return NIX_OK if the deep force operation was successful, an error code
|
* @return NIX_OK if the deep force operation was successful, an error code
|
||||||
* otherwise.
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, Value * value);
|
nix_err nix_value_force_deep(nix_c_context * context, EvalState * state, nix_value * value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Create a new Nix language evaluator state.
|
* @brief Create a new Nix language evaluator state.
|
||||||
@ -188,6 +195,11 @@ void nix_state_free(EvalState * state);
|
|||||||
* you're done with a value returned by the evaluator.
|
* you're done with a value returned by the evaluator.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO: Deprecate nix_gc_incref in favor of the type-specific reference counting functions?
|
||||||
|
// e.g. nix_value_incref.
|
||||||
|
// It gives implementors more flexibility, and adds safety, so that generated
|
||||||
|
// bindings can be used without fighting the host type system (where applicable).
|
||||||
/**
|
/**
|
||||||
* @brief Increment the garbage collector reference counter for the given object.
|
* @brief Increment the garbage collector reference counter for the given object.
|
||||||
*
|
*
|
||||||
|
@ -20,6 +20,11 @@ struct ListBuilder
|
|||||||
nix::ListBuilder builder;
|
nix::ListBuilder builder;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nix_value
|
||||||
|
{
|
||||||
|
nix::Value value;
|
||||||
|
};
|
||||||
|
|
||||||
struct nix_string_return
|
struct nix_string_return
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
|
@ -21,49 +21,54 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Internal helper functions to check [in] and [out] `Value *` parameters
|
// Internal helper functions to check [in] and [out] `Value *` parameters
|
||||||
static const nix::Value & check_value_not_null(const Value * value)
|
static const nix::Value & check_value_not_null(const nix_value * value)
|
||||||
{
|
{
|
||||||
if (!value) {
|
if (!value) {
|
||||||
throw std::runtime_error("Value is null");
|
throw std::runtime_error("nix_value is null");
|
||||||
}
|
}
|
||||||
return *((const nix::Value *) value);
|
return *((const nix::Value *) value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static nix::Value & check_value_not_null(Value * value)
|
static nix::Value & check_value_not_null(nix_value * value)
|
||||||
{
|
{
|
||||||
if (!value) {
|
if (!value) {
|
||||||
throw std::runtime_error("Value is null");
|
throw std::runtime_error("nix_value is null");
|
||||||
}
|
}
|
||||||
return *((nix::Value *) value);
|
return value->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const nix::Value & check_value_in(const Value * value)
|
static const nix::Value & check_value_in(const nix_value * value)
|
||||||
{
|
{
|
||||||
auto & v = check_value_not_null(value);
|
auto & v = check_value_not_null(value);
|
||||||
if (!v.isValid()) {
|
if (!v.isValid()) {
|
||||||
throw std::runtime_error("Uninitialized Value");
|
throw std::runtime_error("Uninitialized nix_value");
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nix::Value & check_value_in(Value * value)
|
static nix::Value & check_value_in(nix_value * value)
|
||||||
{
|
{
|
||||||
auto & v = check_value_not_null(value);
|
auto & v = check_value_not_null(value);
|
||||||
if (!v.isValid()) {
|
if (!v.isValid()) {
|
||||||
throw std::runtime_error("Uninitialized Value");
|
throw std::runtime_error("Uninitialized nix_value");
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static nix::Value & check_value_out(Value * value)
|
static nix::Value & check_value_out(nix_value * value)
|
||||||
{
|
{
|
||||||
auto & v = check_value_not_null(value);
|
auto & v = check_value_not_null(value);
|
||||||
if (v.isValid()) {
|
if (v.isValid()) {
|
||||||
throw std::runtime_error("Value already initialized. Variables are immutable");
|
throw std::runtime_error("nix_value already initialized. Variables are immutable");
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline nix_value * as_nix_value_ptr(nix::Value * v)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<nix_value *>(v);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to convert calls from nix into C API.
|
* Helper function to convert calls from nix into C API.
|
||||||
*
|
*
|
||||||
@ -87,7 +92,7 @@ static void nix_c_primop_wrapper(
|
|||||||
// or maybe something to make blackholes work better; we don't know).
|
// or maybe something to make blackholes work better; we don't know).
|
||||||
nix::Value vTmp;
|
nix::Value vTmp;
|
||||||
|
|
||||||
f(userdata, &ctx, (EvalState *) &state, (Value **) args, (Value *) &vTmp);
|
f(userdata, &ctx, (EvalState *) &state, (nix_value **) args, (nix_value *) &vTmp);
|
||||||
|
|
||||||
if (ctx.last_err_code != NIX_OK) {
|
if (ctx.last_err_code != NIX_OK) {
|
||||||
/* TODO: Throw different errors depending on the error code */
|
/* TODO: Throw different errors depending on the error code */
|
||||||
@ -154,19 +159,19 @@ nix_err nix_register_primop(nix_c_context * context, PrimOp * primOp)
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
Value * nix_alloc_value(nix_c_context * context, EvalState * state)
|
nix_value * nix_alloc_value(nix_c_context * context, EvalState * state)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
try {
|
try {
|
||||||
Value * res = state->state.allocValue();
|
nix_value * res = as_nix_value_ptr(state->state.allocValue());
|
||||||
nix_gc_incref(nullptr, res);
|
nix_gc_incref(nullptr, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType nix_get_type(nix_c_context * context, const Value * value)
|
ValueType nix_get_type(nix_c_context * context, const nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -202,7 +207,7 @@ ValueType nix_get_type(nix_c_context * context, const Value * value)
|
|||||||
NIXC_CATCH_ERRS_RES(NIX_TYPE_NULL);
|
NIXC_CATCH_ERRS_RES(NIX_TYPE_NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * nix_get_typename(nix_c_context * context, const Value * value)
|
const char * nix_get_typename(nix_c_context * context, const nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -214,7 +219,7 @@ const char * nix_get_typename(nix_c_context * context, const Value * value)
|
|||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nix_get_bool(nix_c_context * context, const Value * value)
|
bool nix_get_bool(nix_c_context * context, const nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -226,7 +231,8 @@ bool nix_get_bool(nix_c_context * context, const Value * value)
|
|||||||
NIXC_CATCH_ERRS_RES(false);
|
NIXC_CATCH_ERRS_RES(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_get_string(nix_c_context * context, const Value * value, nix_get_string_callback callback, void * user_data)
|
nix_err
|
||||||
|
nix_get_string(nix_c_context * context, const nix_value * value, nix_get_string_callback callback, void * user_data)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -238,7 +244,7 @@ nix_err nix_get_string(nix_c_context * context, const Value * value, nix_get_str
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * nix_get_path_string(nix_c_context * context, const Value * value)
|
const char * nix_get_path_string(nix_c_context * context, const nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -257,7 +263,7 @@ const char * nix_get_path_string(nix_c_context * context, const Value * value)
|
|||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int nix_get_list_size(nix_c_context * context, const Value * value)
|
unsigned int nix_get_list_size(nix_c_context * context, const nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -269,7 +275,7 @@ unsigned int nix_get_list_size(nix_c_context * context, const Value * value)
|
|||||||
NIXC_CATCH_ERRS_RES(0);
|
NIXC_CATCH_ERRS_RES(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int nix_get_attrs_size(nix_c_context * context, const Value * value)
|
unsigned int nix_get_attrs_size(nix_c_context * context, const nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -281,7 +287,7 @@ unsigned int nix_get_attrs_size(nix_c_context * context, const Value * value)
|
|||||||
NIXC_CATCH_ERRS_RES(0);
|
NIXC_CATCH_ERRS_RES(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
double nix_get_float(nix_c_context * context, const Value * value)
|
double nix_get_float(nix_c_context * context, const nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -293,7 +299,7 @@ double nix_get_float(nix_c_context * context, const Value * value)
|
|||||||
NIXC_CATCH_ERRS_RES(0.0);
|
NIXC_CATCH_ERRS_RES(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t nix_get_int(nix_c_context * context, const Value * value)
|
int64_t nix_get_int(nix_c_context * context, const nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -305,7 +311,7 @@ int64_t nix_get_int(nix_c_context * context, const Value * value)
|
|||||||
NIXC_CATCH_ERRS_RES(0);
|
NIXC_CATCH_ERRS_RES(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExternalValue * nix_get_external(nix_c_context * context, Value * value)
|
ExternalValue * nix_get_external(nix_c_context * context, nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -317,7 +323,7 @@ ExternalValue * nix_get_external(nix_c_context * context, Value * value)
|
|||||||
NIXC_CATCH_ERRS_NULL;
|
NIXC_CATCH_ERRS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int ix)
|
nix_value * nix_get_list_byidx(nix_c_context * context, const nix_value * value, EvalState * state, unsigned int ix)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -328,12 +334,12 @@ Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalSta
|
|||||||
nix_gc_incref(nullptr, p);
|
nix_gc_incref(nullptr, p);
|
||||||
if (p != nullptr)
|
if (p != nullptr)
|
||||||
state->state.forceValue(*p, nix::noPos);
|
state->state.forceValue(*p, nix::noPos);
|
||||||
return (Value *) p;
|
return as_nix_value_ptr(p);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name)
|
nix_value * nix_get_attr_byname(nix_c_context * context, const nix_value * value, EvalState * state, const char * name)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -345,7 +351,7 @@ Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalSt
|
|||||||
if (attr) {
|
if (attr) {
|
||||||
nix_gc_incref(nullptr, attr->value);
|
nix_gc_incref(nullptr, attr->value);
|
||||||
state->state.forceValue(*attr->value, nix::noPos);
|
state->state.forceValue(*attr->value, nix::noPos);
|
||||||
return attr->value;
|
return as_nix_value_ptr(attr->value);
|
||||||
}
|
}
|
||||||
nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute");
|
nix_set_err_msg(context, NIX_ERR_KEY, "missing attribute");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -353,7 +359,7 @@ Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalSt
|
|||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name)
|
bool nix_has_attr_byname(nix_c_context * context, const nix_value * value, EvalState * state, const char * name)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -369,8 +375,8 @@ bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState
|
|||||||
NIXC_CATCH_ERRS_RES(false);
|
NIXC_CATCH_ERRS_RES(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value *
|
nix_value * nix_get_attr_byidx(
|
||||||
nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i, const char ** name)
|
nix_c_context * context, const nix_value * value, EvalState * state, unsigned int i, const char ** name)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -380,12 +386,13 @@ nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * sta
|
|||||||
*name = ((const std::string &) (state->state.symbols[a.name])).c_str();
|
*name = ((const std::string &) (state->state.symbols[a.name])).c_str();
|
||||||
nix_gc_incref(nullptr, a.value);
|
nix_gc_incref(nullptr, a.value);
|
||||||
state->state.forceValue(*a.value, nix::noPos);
|
state->state.forceValue(*a.value, nix::noPos);
|
||||||
return a.value;
|
return as_nix_value_ptr(a.value);
|
||||||
}
|
}
|
||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i)
|
const char *
|
||||||
|
nix_get_attr_name_byidx(nix_c_context * context, const nix_value * value, EvalState * state, unsigned int i)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -397,7 +404,7 @@ const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * valu
|
|||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_init_bool(nix_c_context * context, Value * value, bool b)
|
nix_err nix_init_bool(nix_c_context * context, nix_value * value, bool b)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -409,7 +416,7 @@ nix_err nix_init_bool(nix_c_context * context, Value * value, bool b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// todo string context
|
// todo string context
|
||||||
nix_err nix_init_string(nix_c_context * context, Value * value, const char * str)
|
nix_err nix_init_string(nix_c_context * context, nix_value * value, const char * str)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -420,7 +427,7 @@ nix_err nix_init_string(nix_c_context * context, Value * value, const char * str
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_init_path_string(nix_c_context * context, EvalState * s, Value * value, const char * str)
|
nix_err nix_init_path_string(nix_c_context * context, EvalState * s, nix_value * value, const char * str)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -431,7 +438,7 @@ nix_err nix_init_path_string(nix_c_context * context, EvalState * s, Value * val
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_init_float(nix_c_context * context, Value * value, double d)
|
nix_err nix_init_float(nix_c_context * context, nix_value * value, double d)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -442,7 +449,7 @@ nix_err nix_init_float(nix_c_context * context, Value * value, double d)
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_init_int(nix_c_context * context, Value * value, int64_t i)
|
nix_err nix_init_int(nix_c_context * context, nix_value * value, int64_t i)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -453,7 +460,7 @@ nix_err nix_init_int(nix_c_context * context, Value * value, int64_t i)
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_init_null(nix_c_context * context, Value * value)
|
nix_err nix_init_null(nix_c_context * context, nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -464,7 +471,7 @@ nix_err nix_init_null(nix_c_context * context, Value * value)
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_init_apply(nix_c_context * context, Value * value, Value * fn, Value * arg)
|
nix_err nix_init_apply(nix_c_context * context, nix_value * value, nix_value * fn, nix_value * arg)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -477,7 +484,7 @@ nix_err nix_init_apply(nix_c_context * context, Value * value, Value * fn, Value
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_init_external(nix_c_context * context, Value * value, ExternalValue * val)
|
nix_err nix_init_external(nix_c_context * context, nix_value * value, ExternalValue * val)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -504,7 +511,8 @@ ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state,
|
|||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, unsigned int index, Value * value)
|
nix_err
|
||||||
|
nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, unsigned int index, nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -524,7 +532,7 @@ void nix_list_builder_free(ListBuilder * list_builder)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_make_list(nix_c_context * context, ListBuilder * list_builder, Value * value)
|
nix_err nix_make_list(nix_c_context * context, ListBuilder * list_builder, nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -535,7 +543,7 @@ nix_err nix_make_list(nix_c_context * context, ListBuilder * list_builder, Value
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_init_primop(nix_c_context * context, Value * value, PrimOp * p)
|
nix_err nix_init_primop(nix_c_context * context, nix_value * value, PrimOp * p)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -546,7 +554,7 @@ nix_err nix_init_primop(nix_c_context * context, Value * value, PrimOp * p)
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_copy_value(nix_c_context * context, Value * value, const Value * source)
|
nix_err nix_copy_value(nix_c_context * context, nix_value * value, const nix_value * source)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -558,7 +566,7 @@ nix_err nix_copy_value(nix_c_context * context, Value * value, const Value * sou
|
|||||||
NIXC_CATCH_ERRS
|
NIXC_CATCH_ERRS
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder * b)
|
nix_err nix_make_attrs(nix_c_context * context, nix_value * value, BindingsBuilder * b)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -584,7 +592,7 @@ BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState *
|
|||||||
NIXC_CATCH_ERRS_NULL
|
NIXC_CATCH_ERRS_NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_err nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * bb, const char * name, Value * value)
|
nix_err nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * bb, const char * name, nix_value * value)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
@ -605,7 +613,7 @@ void nix_bindings_builder_free(BindingsBuilder * bb)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * state, Value * value, bool isIFD)
|
nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * state, nix_value * value, bool isIFD)
|
||||||
{
|
{
|
||||||
if (context)
|
if (context)
|
||||||
context->last_err_code = NIX_OK;
|
context->last_err_code = NIX_OK;
|
||||||
|
@ -35,8 +35,11 @@ typedef enum {
|
|||||||
} ValueType;
|
} ValueType;
|
||||||
|
|
||||||
// forward declarations
|
// forward declarations
|
||||||
typedef void Value;
|
typedef struct nix_value nix_value;
|
||||||
typedef struct EvalState EvalState;
|
typedef struct EvalState EvalState;
|
||||||
|
|
||||||
|
[[deprecated("use nix_value instead")]] typedef nix_value Value;
|
||||||
|
|
||||||
// type defs
|
// type defs
|
||||||
/** @brief Stores an under-construction set of bindings
|
/** @brief Stores an under-construction set of bindings
|
||||||
* @ingroup value_manip
|
* @ingroup value_manip
|
||||||
@ -90,7 +93,8 @@ typedef struct nix_realised_string nix_realised_string;
|
|||||||
* @param[out] ret return value
|
* @param[out] ret return value
|
||||||
* @see nix_alloc_primop, nix_init_primop
|
* @see nix_alloc_primop, nix_init_primop
|
||||||
*/
|
*/
|
||||||
typedef void (*PrimOpFun)(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret);
|
typedef void (*PrimOpFun)(
|
||||||
|
void * user_data, nix_c_context * context, EvalState * state, nix_value ** args, nix_value * ret);
|
||||||
|
|
||||||
/** @brief Allocate a PrimOp
|
/** @brief Allocate a PrimOp
|
||||||
*
|
*
|
||||||
@ -142,10 +146,29 @@ nix_err nix_register_primop(nix_c_context * context, PrimOp * primOp);
|
|||||||
* @return value, or null in case of errors
|
* @return value, or null in case of errors
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
Value * nix_alloc_value(nix_c_context * context, EvalState * state);
|
nix_value * nix_alloc_value(nix_c_context * context, EvalState * state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Increment the garbage collector reference counter for the given `nix_value`.
|
||||||
|
*
|
||||||
|
* The Nix language evaluator C API keeps track of alive objects by reference counting.
|
||||||
|
* When you're done with a refcounted pointer, call nix_value_decref().
|
||||||
|
*
|
||||||
|
* @param[out] context Optional, stores error information
|
||||||
|
* @param[in] value The object to keep alive
|
||||||
|
*/
|
||||||
|
nix_err nix_value_incref(nix_c_context * context, nix_value * value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Decrement the garbage collector reference counter for the given object
|
||||||
|
*
|
||||||
|
* @param[out] context Optional, stores error information
|
||||||
|
* @param[in] value The object to stop referencing
|
||||||
|
*/
|
||||||
|
nix_err nix_value_decref(nix_c_context * context, nix_value * value);
|
||||||
|
|
||||||
/** @addtogroup value_manip Manipulating values
|
/** @addtogroup value_manip Manipulating values
|
||||||
* @brief Functions to inspect and change Nix language values, represented by Value.
|
* @brief Functions to inspect and change Nix language values, represented by nix_value.
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** @anchor getters
|
/** @anchor getters
|
||||||
@ -157,7 +180,7 @@ Value * nix_alloc_value(nix_c_context * context, EvalState * state);
|
|||||||
* @param[in] value Nix value to inspect
|
* @param[in] value Nix value to inspect
|
||||||
* @return type of nix value
|
* @return type of nix value
|
||||||
*/
|
*/
|
||||||
ValueType nix_get_type(nix_c_context * context, const Value * value);
|
ValueType nix_get_type(nix_c_context * context, const nix_value * value);
|
||||||
|
|
||||||
/** @brief Get type name of value as defined in the evaluator
|
/** @brief Get type name of value as defined in the evaluator
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -165,14 +188,14 @@ ValueType nix_get_type(nix_c_context * context, const Value * value);
|
|||||||
* @return type name, owned string
|
* @return type name, owned string
|
||||||
* @todo way to free the result
|
* @todo way to free the result
|
||||||
*/
|
*/
|
||||||
const char * nix_get_typename(nix_c_context * context, const Value * value);
|
const char * nix_get_typename(nix_c_context * context, const nix_value * value);
|
||||||
|
|
||||||
/** @brief Get boolean value
|
/** @brief Get boolean value
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] value Nix value to inspect
|
* @param[in] value Nix value to inspect
|
||||||
* @return true or false, error info via context
|
* @return true or false, error info via context
|
||||||
*/
|
*/
|
||||||
bool nix_get_bool(nix_c_context * context, const Value * value);
|
bool nix_get_bool(nix_c_context * context, const nix_value * value);
|
||||||
|
|
||||||
/** @brief Get the raw string
|
/** @brief Get the raw string
|
||||||
*
|
*
|
||||||
@ -186,7 +209,7 @@ bool nix_get_bool(nix_c_context * context, const Value * value);
|
|||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err
|
nix_err
|
||||||
nix_get_string(nix_c_context * context, const Value * value, nix_get_string_callback callback, void * user_data);
|
nix_get_string(nix_c_context * context, const nix_value * value, nix_get_string_callback callback, void * user_data);
|
||||||
|
|
||||||
/** @brief Get path as string
|
/** @brief Get path as string
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -194,42 +217,42 @@ nix_get_string(nix_c_context * context, const Value * value, nix_get_string_call
|
|||||||
* @return string
|
* @return string
|
||||||
* @return NULL in case of error.
|
* @return NULL in case of error.
|
||||||
*/
|
*/
|
||||||
const char * nix_get_path_string(nix_c_context * context, const Value * value);
|
const char * nix_get_path_string(nix_c_context * context, const nix_value * value);
|
||||||
|
|
||||||
/** @brief Get the length of a list
|
/** @brief Get the length of a list
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] value Nix value to inspect
|
* @param[in] value Nix value to inspect
|
||||||
* @return length of list, error info via context
|
* @return length of list, error info via context
|
||||||
*/
|
*/
|
||||||
unsigned int nix_get_list_size(nix_c_context * context, const Value * value);
|
unsigned int nix_get_list_size(nix_c_context * context, const nix_value * value);
|
||||||
|
|
||||||
/** @brief Get the element count of an attrset
|
/** @brief Get the element count of an attrset
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] value Nix value to inspect
|
* @param[in] value Nix value to inspect
|
||||||
* @return attrset element count, error info via context
|
* @return attrset element count, error info via context
|
||||||
*/
|
*/
|
||||||
unsigned int nix_get_attrs_size(nix_c_context * context, const Value * value);
|
unsigned int nix_get_attrs_size(nix_c_context * context, const nix_value * value);
|
||||||
|
|
||||||
/** @brief Get float value in 64 bits
|
/** @brief Get float value in 64 bits
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] value Nix value to inspect
|
* @param[in] value Nix value to inspect
|
||||||
* @return float contents, error info via context
|
* @return float contents, error info via context
|
||||||
*/
|
*/
|
||||||
double nix_get_float(nix_c_context * context, const Value * value);
|
double nix_get_float(nix_c_context * context, const nix_value * value);
|
||||||
|
|
||||||
/** @brief Get int value
|
/** @brief Get int value
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] value Nix value to inspect
|
* @param[in] value Nix value to inspect
|
||||||
* @return int contents, error info via context
|
* @return int contents, error info via context
|
||||||
*/
|
*/
|
||||||
int64_t nix_get_int(nix_c_context * context, const Value * value);
|
int64_t nix_get_int(nix_c_context * context, const nix_value * value);
|
||||||
|
|
||||||
/** @brief Get external reference
|
/** @brief Get external reference
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[in] value Nix value to inspect
|
* @param[in] value Nix value to inspect
|
||||||
* @return reference to external, NULL in case of error
|
* @return reference to external, NULL in case of error
|
||||||
*/
|
*/
|
||||||
ExternalValue * nix_get_external(nix_c_context * context, Value *);
|
ExternalValue * nix_get_external(nix_c_context * context, nix_value *);
|
||||||
|
|
||||||
/** @brief Get the ix'th element of a list
|
/** @brief Get the ix'th element of a list
|
||||||
*
|
*
|
||||||
@ -240,7 +263,7 @@ ExternalValue * nix_get_external(nix_c_context * context, Value *);
|
|||||||
* @param[in] ix list element to get
|
* @param[in] ix list element to get
|
||||||
* @return value, NULL in case of errors
|
* @return value, NULL in case of errors
|
||||||
*/
|
*/
|
||||||
Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int ix);
|
nix_value * nix_get_list_byidx(nix_c_context * context, const nix_value * value, EvalState * state, unsigned int ix);
|
||||||
|
|
||||||
/** @brief Get an attr by name
|
/** @brief Get an attr by name
|
||||||
*
|
*
|
||||||
@ -251,7 +274,7 @@ Value * nix_get_list_byidx(nix_c_context * context, const Value * value, EvalSta
|
|||||||
* @param[in] name attribute name
|
* @param[in] name attribute name
|
||||||
* @return value, NULL in case of errors
|
* @return value, NULL in case of errors
|
||||||
*/
|
*/
|
||||||
Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name);
|
nix_value * nix_get_attr_byname(nix_c_context * context, const nix_value * value, EvalState * state, const char * name);
|
||||||
|
|
||||||
/** @brief Check if an attribute name exists on a value
|
/** @brief Check if an attribute name exists on a value
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -260,7 +283,7 @@ Value * nix_get_attr_byname(nix_c_context * context, const Value * value, EvalSt
|
|||||||
* @param[in] name attribute name
|
* @param[in] name attribute name
|
||||||
* @return value, error info via context
|
* @return value, error info via context
|
||||||
*/
|
*/
|
||||||
bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState * state, const char * name);
|
bool nix_has_attr_byname(nix_c_context * context, const nix_value * value, EvalState * state, const char * name);
|
||||||
|
|
||||||
/** @brief Get an attribute by index in the sorted bindings
|
/** @brief Get an attribute by index in the sorted bindings
|
||||||
*
|
*
|
||||||
@ -274,8 +297,8 @@ bool nix_has_attr_byname(nix_c_context * context, const Value * value, EvalState
|
|||||||
* @param[out] name will store a pointer to the attribute name
|
* @param[out] name will store a pointer to the attribute name
|
||||||
* @return value, NULL in case of errors
|
* @return value, NULL in case of errors
|
||||||
*/
|
*/
|
||||||
Value *
|
nix_value * nix_get_attr_byidx(
|
||||||
nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i, const char ** name);
|
nix_c_context * context, const nix_value * value, EvalState * state, unsigned int i, const char ** name);
|
||||||
|
|
||||||
/** @brief Get an attribute name by index in the sorted bindings
|
/** @brief Get an attribute name by index in the sorted bindings
|
||||||
*
|
*
|
||||||
@ -288,7 +311,8 @@ nix_get_attr_byidx(nix_c_context * context, const Value * value, EvalState * sta
|
|||||||
* @param[in] i attribute index
|
* @param[in] i attribute index
|
||||||
* @return name, NULL in case of errors
|
* @return name, NULL in case of errors
|
||||||
*/
|
*/
|
||||||
const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * value, EvalState * state, unsigned int i);
|
const char *
|
||||||
|
nix_get_attr_name_byidx(nix_c_context * context, const nix_value * value, EvalState * state, unsigned int i);
|
||||||
|
|
||||||
/**@}*/
|
/**@}*/
|
||||||
/** @name Initializers
|
/** @name Initializers
|
||||||
@ -305,7 +329,7 @@ const char * nix_get_attr_name_byidx(nix_c_context * context, const Value * valu
|
|||||||
* @param[in] b the boolean value
|
* @param[in] b the boolean value
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_init_bool(nix_c_context * context, Value * value, bool b);
|
nix_err nix_init_bool(nix_c_context * context, nix_value * value, bool b);
|
||||||
|
|
||||||
/** @brief Set a string
|
/** @brief Set a string
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -313,7 +337,7 @@ nix_err nix_init_bool(nix_c_context * context, Value * value, bool b);
|
|||||||
* @param[in] str the string, copied
|
* @param[in] str the string, copied
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_init_string(nix_c_context * context, Value * value, const char * str);
|
nix_err nix_init_string(nix_c_context * context, nix_value * value, const char * str);
|
||||||
|
|
||||||
/** @brief Set a path
|
/** @brief Set a path
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -321,7 +345,7 @@ nix_err nix_init_string(nix_c_context * context, Value * value, const char * str
|
|||||||
* @param[in] str the path string, copied
|
* @param[in] str the path string, copied
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_init_path_string(nix_c_context * context, EvalState * s, Value * value, const char * str);
|
nix_err nix_init_path_string(nix_c_context * context, EvalState * s, nix_value * value, const char * str);
|
||||||
|
|
||||||
/** @brief Set a float
|
/** @brief Set a float
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -329,7 +353,7 @@ nix_err nix_init_path_string(nix_c_context * context, EvalState * s, Value * val
|
|||||||
* @param[in] d the float, 64-bits
|
* @param[in] d the float, 64-bits
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_init_float(nix_c_context * context, Value * value, double d);
|
nix_err nix_init_float(nix_c_context * context, nix_value * value, double d);
|
||||||
|
|
||||||
/** @brief Set an int
|
/** @brief Set an int
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -338,13 +362,13 @@ nix_err nix_init_float(nix_c_context * context, Value * value, double d);
|
|||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
nix_err nix_init_int(nix_c_context * context, Value * value, int64_t i);
|
nix_err nix_init_int(nix_c_context * context, nix_value * value, int64_t i);
|
||||||
/** @brief Set null
|
/** @brief Set null
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[out] value Nix value to modify
|
* @param[out] value Nix value to modify
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_init_null(nix_c_context * context, Value * value);
|
nix_err nix_init_null(nix_c_context * context, nix_value * value);
|
||||||
|
|
||||||
/** @brief Set the value to a thunk that will perform a function application when needed.
|
/** @brief Set the value to a thunk that will perform a function application when needed.
|
||||||
*
|
*
|
||||||
@ -360,7 +384,7 @@ nix_err nix_init_null(nix_c_context * context, Value * value);
|
|||||||
* @see nix_value_call() for a similar function that performs the call immediately and only stores the return value.
|
* @see nix_value_call() for a similar function that performs the call immediately and only stores the return value.
|
||||||
* Note the different argument order.
|
* Note the different argument order.
|
||||||
*/
|
*/
|
||||||
nix_err nix_init_apply(nix_c_context * context, Value * value, Value * fn, Value * arg);
|
nix_err nix_init_apply(nix_c_context * context, nix_value * value, nix_value * fn, nix_value * arg);
|
||||||
|
|
||||||
/** @brief Set an external value
|
/** @brief Set an external value
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -368,7 +392,7 @@ nix_err nix_init_apply(nix_c_context * context, Value * value, Value * fn, Value
|
|||||||
* @param[in] val the external value to set. Will be GC-referenced by the value.
|
* @param[in] val the external value to set. Will be GC-referenced by the value.
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_init_external(nix_c_context * context, Value * value, ExternalValue * val);
|
nix_err nix_init_external(nix_c_context * context, nix_value * value, ExternalValue * val);
|
||||||
|
|
||||||
/** @brief Create a list from a list builder
|
/** @brief Create a list from a list builder
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -376,7 +400,7 @@ nix_err nix_init_external(nix_c_context * context, Value * value, ExternalValue
|
|||||||
* @param[out] value Nix value to modify
|
* @param[out] value Nix value to modify
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_make_list(nix_c_context * context, ListBuilder * list_builder, Value * value);
|
nix_err nix_make_list(nix_c_context * context, ListBuilder * list_builder, nix_value * value);
|
||||||
|
|
||||||
/** @brief Create a list builder
|
/** @brief Create a list builder
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -393,7 +417,8 @@ ListBuilder * nix_make_list_builder(nix_c_context * context, EvalState * state,
|
|||||||
* @param[in] value value to insert
|
* @param[in] value value to insert
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, unsigned int index, Value * value);
|
nix_err
|
||||||
|
nix_list_builder_insert(nix_c_context * context, ListBuilder * list_builder, unsigned int index, nix_value * value);
|
||||||
|
|
||||||
/** @brief Free a list builder
|
/** @brief Free a list builder
|
||||||
*
|
*
|
||||||
@ -408,7 +433,7 @@ void nix_list_builder_free(ListBuilder * list_builder);
|
|||||||
* @param[in] b bindings builder to use. Make sure to unref this afterwards.
|
* @param[in] b bindings builder to use. Make sure to unref this afterwards.
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder * b);
|
nix_err nix_make_attrs(nix_c_context * context, nix_value * value, BindingsBuilder * b);
|
||||||
|
|
||||||
/** @brief Set primop
|
/** @brief Set primop
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
@ -417,14 +442,14 @@ nix_err nix_make_attrs(nix_c_context * context, Value * value, BindingsBuilder *
|
|||||||
* @see nix_alloc_primop
|
* @see nix_alloc_primop
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_init_primop(nix_c_context * context, Value * value, PrimOp * op);
|
nix_err nix_init_primop(nix_c_context * context, nix_value * value, PrimOp * op);
|
||||||
/** @brief Copy from another value
|
/** @brief Copy from another value
|
||||||
* @param[out] context Optional, stores error information
|
* @param[out] context Optional, stores error information
|
||||||
* @param[out] value Nix value to modify
|
* @param[out] value Nix value to modify
|
||||||
* @param[in] source value to copy from
|
* @param[in] source value to copy from
|
||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err nix_copy_value(nix_c_context * context, Value * value, const Value * source);
|
nix_err nix_copy_value(nix_c_context * context, nix_value * value, const nix_value * source);
|
||||||
/**@}*/
|
/**@}*/
|
||||||
|
|
||||||
/** @brief Create a bindings builder
|
/** @brief Create a bindings builder
|
||||||
@ -444,7 +469,7 @@ BindingsBuilder * nix_make_bindings_builder(nix_c_context * context, EvalState *
|
|||||||
* @return error code, NIX_OK on success.
|
* @return error code, NIX_OK on success.
|
||||||
*/
|
*/
|
||||||
nix_err
|
nix_err
|
||||||
nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * builder, const char * name, Value * value);
|
nix_bindings_builder_insert(nix_c_context * context, BindingsBuilder * builder, const char * name, nix_value * value);
|
||||||
|
|
||||||
/** @brief Free a bindings builder
|
/** @brief Free a bindings builder
|
||||||
*
|
*
|
||||||
@ -471,7 +496,7 @@ void nix_bindings_builder_free(BindingsBuilder * builder);
|
|||||||
You should set this to false when building for your application's purpose.
|
You should set this to false when building for your application's purpose.
|
||||||
* @return NULL if failed, are a new nix_realised_string, which must be freed with nix_realised_string_free
|
* @return NULL if failed, are a new nix_realised_string, which must be freed with nix_realised_string_free
|
||||||
*/
|
*/
|
||||||
nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * state, Value * value, bool isIFD);
|
nix_realised_string * nix_string_realise(nix_c_context * context, EvalState * state, nix_value * value, bool isIFD);
|
||||||
|
|
||||||
/** @brief Start of the string
|
/** @brief Start of the string
|
||||||
* @param[in] realised_string
|
* @param[in] realised_string
|
||||||
|
226
src/libexpr/eval-gc.cc
Normal file
226
src/libexpr/eval-gc.cc
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
#include "error.hh"
|
||||||
|
#include "environment-variables.hh"
|
||||||
|
#include "serialise.hh"
|
||||||
|
#include "eval-gc.hh"
|
||||||
|
|
||||||
|
#if HAVE_BOEHMGC
|
||||||
|
|
||||||
|
# include <pthread.h>
|
||||||
|
# if __FreeBSD__
|
||||||
|
# include <pthread_np.h>
|
||||||
|
# endif
|
||||||
|
|
||||||
|
# include <gc/gc.h>
|
||||||
|
# include <gc/gc_cpp.h>
|
||||||
|
# include <gc/gc_allocator.h>
|
||||||
|
|
||||||
|
# include <boost/coroutine2/coroutine.hpp>
|
||||||
|
# include <boost/coroutine2/protected_fixedsize_stack.hpp>
|
||||||
|
# include <boost/context/stack_context.hpp>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
#if HAVE_BOEHMGC
|
||||||
|
/* Called when the Boehm GC runs out of memory. */
|
||||||
|
static void * oomHandler(size_t requested)
|
||||||
|
{
|
||||||
|
/* Convert this to a proper C++ exception. */
|
||||||
|
throw std::bad_alloc();
|
||||||
|
}
|
||||||
|
|
||||||
|
class BoehmGCStackAllocator : public StackAllocator
|
||||||
|
{
|
||||||
|
boost::coroutines2::protected_fixedsize_stack stack{
|
||||||
|
// We allocate 8 MB, the default max stack size on NixOS.
|
||||||
|
// A smaller stack might be quicker to allocate but reduces the stack
|
||||||
|
// depth available for source filter expressions etc.
|
||||||
|
std::max(boost::context::stack_traits::default_size(), static_cast<std::size_t>(8 * 1024 * 1024))};
|
||||||
|
|
||||||
|
// This is specific to boost::coroutines2::protected_fixedsize_stack.
|
||||||
|
// The stack protection page is included in sctx.size, so we have to
|
||||||
|
// subtract one page size from the stack size.
|
||||||
|
std::size_t pfss_usable_stack_size(boost::context::stack_context & sctx)
|
||||||
|
{
|
||||||
|
return sctx.size - boost::context::stack_traits::page_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
boost::context::stack_context allocate() override
|
||||||
|
{
|
||||||
|
auto sctx = stack.allocate();
|
||||||
|
|
||||||
|
// Stacks generally start at a high address and grow to lower addresses.
|
||||||
|
// Architectures that do the opposite are rare; in fact so rare that
|
||||||
|
// boost_routine does not implement it.
|
||||||
|
// So we subtract the stack size.
|
||||||
|
GC_add_roots(static_cast<char *>(sctx.sp) - pfss_usable_stack_size(sctx), sctx.sp);
|
||||||
|
return sctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(boost::context::stack_context sctx) override
|
||||||
|
{
|
||||||
|
GC_remove_roots(static_cast<char *>(sctx.sp) - pfss_usable_stack_size(sctx), sctx.sp);
|
||||||
|
stack.deallocate(sctx);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static BoehmGCStackAllocator boehmGCStackAllocator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a thread goes into a coroutine, we lose its original sp until
|
||||||
|
* control flow returns to the thread.
|
||||||
|
* While in the coroutine, the sp points outside the thread stack,
|
||||||
|
* so we can detect this and push the entire thread stack instead,
|
||||||
|
* as an approximation.
|
||||||
|
* The coroutine's stack is covered by `BoehmGCStackAllocator`.
|
||||||
|
* This is not an optimal solution, because the garbage is scanned when a
|
||||||
|
* coroutine is active, for both the coroutine and the original thread stack.
|
||||||
|
* However, the implementation is quite lean, and usually we don't have active
|
||||||
|
* coroutines during evaluation, so this is acceptable.
|
||||||
|
*/
|
||||||
|
void fixupBoehmStackPointer(void ** sp_ptr, void * _pthread_id)
|
||||||
|
{
|
||||||
|
void *& sp = *sp_ptr;
|
||||||
|
auto pthread_id = reinterpret_cast<pthread_t>(_pthread_id);
|
||||||
|
pthread_attr_t pattr;
|
||||||
|
size_t osStackSize;
|
||||||
|
void * osStackLow;
|
||||||
|
void * osStackBase;
|
||||||
|
|
||||||
|
# ifdef __APPLE__
|
||||||
|
osStackSize = pthread_get_stacksize_np(pthread_id);
|
||||||
|
osStackLow = pthread_get_stackaddr_np(pthread_id);
|
||||||
|
# else
|
||||||
|
if (pthread_attr_init(&pattr)) {
|
||||||
|
throw Error("fixupBoehmStackPointer: pthread_attr_init failed");
|
||||||
|
}
|
||||||
|
# ifdef HAVE_PTHREAD_GETATTR_NP
|
||||||
|
if (pthread_getattr_np(pthread_id, &pattr)) {
|
||||||
|
throw Error("fixupBoehmStackPointer: pthread_getattr_np failed");
|
||||||
|
}
|
||||||
|
# elif HAVE_PTHREAD_ATTR_GET_NP
|
||||||
|
if (!pthread_attr_init(&pattr)) {
|
||||||
|
throw Error("fixupBoehmStackPointer: pthread_attr_init failed");
|
||||||
|
}
|
||||||
|
if (!pthread_attr_get_np(pthread_id, &pattr)) {
|
||||||
|
throw Error("fixupBoehmStackPointer: pthread_attr_get_np failed");
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
# error "Need one of `pthread_attr_get_np` or `pthread_getattr_np`"
|
||||||
|
# endif
|
||||||
|
if (pthread_attr_getstack(&pattr, &osStackLow, &osStackSize)) {
|
||||||
|
throw Error("fixupBoehmStackPointer: pthread_attr_getstack failed");
|
||||||
|
}
|
||||||
|
if (pthread_attr_destroy(&pattr)) {
|
||||||
|
throw Error("fixupBoehmStackPointer: pthread_attr_destroy failed");
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
osStackBase = (char *) osStackLow + osStackSize;
|
||||||
|
// NOTE: We assume the stack grows down, as it does on all architectures we support.
|
||||||
|
// Architectures that grow the stack up are rare.
|
||||||
|
if (sp >= osStackBase || sp < osStackLow) { // lo is outside the os stack
|
||||||
|
sp = osStackBase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disable GC while this object lives. Used by CoroutineContext.
|
||||||
|
*
|
||||||
|
* Boehm keeps a count of GC_disable() and GC_enable() calls,
|
||||||
|
* and only enables GC when the count matches.
|
||||||
|
*/
|
||||||
|
class BoehmDisableGC
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BoehmDisableGC()
|
||||||
|
{
|
||||||
|
GC_disable();
|
||||||
|
};
|
||||||
|
~BoehmDisableGC()
|
||||||
|
{
|
||||||
|
GC_enable();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void initGCReal()
|
||||||
|
{
|
||||||
|
/* Initialise the Boehm garbage collector. */
|
||||||
|
|
||||||
|
/* Don't look for interior pointers. This reduces the odds of
|
||||||
|
misdetection a bit. */
|
||||||
|
GC_set_all_interior_pointers(0);
|
||||||
|
|
||||||
|
/* We don't have any roots in data segments, so don't scan from
|
||||||
|
there. */
|
||||||
|
GC_set_no_dls(1);
|
||||||
|
|
||||||
|
GC_INIT();
|
||||||
|
|
||||||
|
GC_set_oom_fn(oomHandler);
|
||||||
|
|
||||||
|
StackAllocator::defaultAllocator = &boehmGCStackAllocator;
|
||||||
|
|
||||||
|
// TODO: Remove __APPLE__ condition.
|
||||||
|
// Comment suggests an implementation that works on darwin and windows
|
||||||
|
// https://github.com/ivmai/bdwgc/issues/362#issuecomment-1936672196
|
||||||
|
# if GC_VERSION_MAJOR >= 8 && GC_VERSION_MINOR >= 2 && GC_VERSION_MICRO >= 4 && !defined(__APPLE__)
|
||||||
|
GC_set_sp_corrector(&fixupBoehmStackPointer);
|
||||||
|
|
||||||
|
if (!GC_get_sp_corrector()) {
|
||||||
|
printTalkative("BoehmGC on this platform does not support sp_corrector; will disable GC inside coroutines");
|
||||||
|
/* Used to disable GC when entering coroutines on macOS */
|
||||||
|
create_coro_gc_hook = []() -> std::shared_ptr<void> { return std::make_shared<BoehmDisableGC>(); };
|
||||||
|
}
|
||||||
|
# else
|
||||||
|
# warning \
|
||||||
|
"BoehmGC version does not support GC while coroutine exists. GC will be disabled inside coroutines. Consider updating bdw-gc to 8.2.4 or later."
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* Set the initial heap size to something fairly big (25% of
|
||||||
|
physical RAM, up to a maximum of 384 MiB) so that in most cases
|
||||||
|
we don't need to garbage collect at all. (Collection has a
|
||||||
|
fairly significant overhead.) The heap size can be overridden
|
||||||
|
through libgc's GC_INITIAL_HEAP_SIZE environment variable. We
|
||||||
|
should probably also provide a nix.conf setting for this. Note
|
||||||
|
that GC_expand_hp() causes a lot of virtual, but not physical
|
||||||
|
(resident) memory to be allocated. This might be a problem on
|
||||||
|
systems that don't overcommit. */
|
||||||
|
if (!getEnv("GC_INITIAL_HEAP_SIZE")) {
|
||||||
|
size_t size = 32 * 1024 * 1024;
|
||||||
|
# if HAVE_SYSCONF && defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
|
||||||
|
size_t maxSize = 384 * 1024 * 1024;
|
||||||
|
long pageSize = sysconf(_SC_PAGESIZE);
|
||||||
|
long pages = sysconf(_SC_PHYS_PAGES);
|
||||||
|
if (pageSize != -1)
|
||||||
|
size = (pageSize * pages) / 4; // 25% of RAM
|
||||||
|
if (size > maxSize)
|
||||||
|
size = maxSize;
|
||||||
|
# endif
|
||||||
|
debug("setting initial heap size to %1% bytes", size);
|
||||||
|
GC_expand_hp(size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool gcInitialised = false;
|
||||||
|
|
||||||
|
void initGC()
|
||||||
|
{
|
||||||
|
if (gcInitialised)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if HAVE_BOEHMGC
|
||||||
|
initGCReal();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
gcInitialised = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertGCInitialized()
|
||||||
|
{
|
||||||
|
assert(gcInitialised);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
16
src/libexpr/eval-gc.hh
Normal file
16
src/libexpr/eval-gc.hh
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
///@file
|
||||||
|
|
||||||
|
namespace nix {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the Boehm GC, if applicable.
|
||||||
|
*/
|
||||||
|
void initGC();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make sure `initGC` has already been called.
|
||||||
|
*/
|
||||||
|
void assertGCInitialized();
|
||||||
|
|
||||||
|
}
|
@ -40,22 +40,16 @@
|
|||||||
#include <boost/container/small_vector.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
|
|
||||||
#ifndef _WIN32 // TODO use portable implementation
|
#ifndef _WIN32 // TODO use portable implementation
|
||||||
# include <sys/resource.h>
|
# include <sys/resource.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_BOEHMGC
|
#if HAVE_BOEHMGC
|
||||||
|
|
||||||
#define GC_INCLUDE_NEW
|
# define GC_INCLUDE_NEW
|
||||||
|
|
||||||
#include <pthread.h>
|
# include <gc/gc.h>
|
||||||
|
# include <gc/gc_cpp.h>
|
||||||
#include <gc/gc.h>
|
# include <gc/gc_allocator.h>
|
||||||
#include <gc/gc_cpp.h>
|
|
||||||
#include <gc/gc_allocator.h>
|
|
||||||
|
|
||||||
#include <boost/coroutine2/coroutine.hpp>
|
|
||||||
#include <boost/coroutine2/protected_fixedsize_stack.hpp>
|
|
||||||
#include <boost/context/stack_context.hpp>
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -208,97 +202,6 @@ bool Value::isTrivial() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if HAVE_BOEHMGC
|
|
||||||
/* Called when the Boehm GC runs out of memory. */
|
|
||||||
static void * oomHandler(size_t requested)
|
|
||||||
{
|
|
||||||
/* Convert this to a proper C++ exception. */
|
|
||||||
throw std::bad_alloc();
|
|
||||||
}
|
|
||||||
|
|
||||||
class BoehmGCStackAllocator : public StackAllocator {
|
|
||||||
boost::coroutines2::protected_fixedsize_stack stack {
|
|
||||||
// We allocate 8 MB, the default max stack size on NixOS.
|
|
||||||
// A smaller stack might be quicker to allocate but reduces the stack
|
|
||||||
// depth available for source filter expressions etc.
|
|
||||||
std::max(boost::context::stack_traits::default_size(), static_cast<std::size_t>(8 * 1024 * 1024))
|
|
||||||
};
|
|
||||||
|
|
||||||
// This is specific to boost::coroutines2::protected_fixedsize_stack.
|
|
||||||
// The stack protection page is included in sctx.size, so we have to
|
|
||||||
// subtract one page size from the stack size.
|
|
||||||
std::size_t pfss_usable_stack_size(boost::context::stack_context &sctx) {
|
|
||||||
return sctx.size - boost::context::stack_traits::page_size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
boost::context::stack_context allocate() override {
|
|
||||||
auto sctx = stack.allocate();
|
|
||||||
|
|
||||||
// Stacks generally start at a high address and grow to lower addresses.
|
|
||||||
// Architectures that do the opposite are rare; in fact so rare that
|
|
||||||
// boost_routine does not implement it.
|
|
||||||
// So we subtract the stack size.
|
|
||||||
GC_add_roots(static_cast<char *>(sctx.sp) - pfss_usable_stack_size(sctx), sctx.sp);
|
|
||||||
return sctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void deallocate(boost::context::stack_context sctx) override {
|
|
||||||
GC_remove_roots(static_cast<char *>(sctx.sp) - pfss_usable_stack_size(sctx), sctx.sp);
|
|
||||||
stack.deallocate(sctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static BoehmGCStackAllocator boehmGCStackAllocator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When a thread goes into a coroutine, we lose its original sp until
|
|
||||||
* control flow returns to the thread.
|
|
||||||
* While in the coroutine, the sp points outside the thread stack,
|
|
||||||
* so we can detect this and push the entire thread stack instead,
|
|
||||||
* as an approximation.
|
|
||||||
* The coroutine's stack is covered by `BoehmGCStackAllocator`.
|
|
||||||
* This is not an optimal solution, because the garbage is scanned when a
|
|
||||||
* coroutine is active, for both the coroutine and the original thread stack.
|
|
||||||
* However, the implementation is quite lean, and usually we don't have active
|
|
||||||
* coroutines during evaluation, so this is acceptable.
|
|
||||||
*/
|
|
||||||
void fixupBoehmStackPointer(void ** sp_ptr, void * pthread_id) {
|
|
||||||
void *& sp = *sp_ptr;
|
|
||||||
pthread_attr_t pattr;
|
|
||||||
size_t osStackSize;
|
|
||||||
void * osStackLow;
|
|
||||||
void * osStackBase;
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
osStackSize = pthread_get_stacksize_np((pthread_t)pthread_id);
|
|
||||||
osStackLow = pthread_get_stackaddr_np((pthread_t)pthread_id);
|
|
||||||
#else
|
|
||||||
if (pthread_attr_init(&pattr)) {
|
|
||||||
throw Error("fixupBoehmStackPointer: pthread_attr_init failed");
|
|
||||||
}
|
|
||||||
if (pthread_getattr_np((pthread_t)pthread_id, &pattr)) {
|
|
||||||
throw Error("fixupBoehmStackPointer: pthread_getattr_np failed");
|
|
||||||
}
|
|
||||||
if (pthread_attr_getstack(&pattr, &osStackLow, &osStackSize)) {
|
|
||||||
throw Error("fixupBoehmStackPointer: pthread_attr_getstack failed");
|
|
||||||
}
|
|
||||||
if (pthread_attr_destroy(&pattr)) {
|
|
||||||
throw Error("fixupBoehmStackPointer: pthread_attr_destroy failed");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
osStackBase = (char *)osStackLow + osStackSize;
|
|
||||||
// NOTE: We assume the stack grows down, as it does on all architectures we support.
|
|
||||||
// Architectures that grow the stack up are rare.
|
|
||||||
if (sp >= osStackBase || sp < osStackLow) { // lo is outside the os stack
|
|
||||||
sp = osStackBase;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static Symbol getName(const AttrName & name, EvalState & state, Env & env)
|
static Symbol getName(const AttrName & name, EvalState & state, Env & env)
|
||||||
{
|
{
|
||||||
if (name.symbol) {
|
if (name.symbol) {
|
||||||
@ -311,92 +214,6 @@ static Symbol getName(const AttrName & name, EvalState & state, Env & env)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if HAVE_BOEHMGC
|
|
||||||
/* Disable GC while this object lives. Used by CoroutineContext.
|
|
||||||
*
|
|
||||||
* Boehm keeps a count of GC_disable() and GC_enable() calls,
|
|
||||||
* and only enables GC when the count matches.
|
|
||||||
*/
|
|
||||||
class BoehmDisableGC {
|
|
||||||
public:
|
|
||||||
BoehmDisableGC() {
|
|
||||||
GC_disable();
|
|
||||||
};
|
|
||||||
~BoehmDisableGC() {
|
|
||||||
GC_enable();
|
|
||||||
};
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool gcInitialised = false;
|
|
||||||
|
|
||||||
void initGC()
|
|
||||||
{
|
|
||||||
if (gcInitialised) return;
|
|
||||||
|
|
||||||
#if HAVE_BOEHMGC
|
|
||||||
/* Initialise the Boehm garbage collector. */
|
|
||||||
|
|
||||||
/* Don't look for interior pointers. This reduces the odds of
|
|
||||||
misdetection a bit. */
|
|
||||||
GC_set_all_interior_pointers(0);
|
|
||||||
|
|
||||||
/* We don't have any roots in data segments, so don't scan from
|
|
||||||
there. */
|
|
||||||
GC_set_no_dls(1);
|
|
||||||
|
|
||||||
GC_INIT();
|
|
||||||
|
|
||||||
GC_set_oom_fn(oomHandler);
|
|
||||||
|
|
||||||
StackAllocator::defaultAllocator = &boehmGCStackAllocator;
|
|
||||||
|
|
||||||
// TODO: Remove __APPLE__ condition.
|
|
||||||
// Comment suggests an implementation that works on darwin and windows
|
|
||||||
// https://github.com/ivmai/bdwgc/issues/362#issuecomment-1936672196
|
|
||||||
#if GC_VERSION_MAJOR >= 8 && GC_VERSION_MINOR >= 2 && GC_VERSION_MICRO >= 4 && !defined(__APPLE__)
|
|
||||||
GC_set_sp_corrector(&fixupBoehmStackPointer);
|
|
||||||
|
|
||||||
if (!GC_get_sp_corrector()) {
|
|
||||||
printTalkative("BoehmGC on this platform does not support sp_corrector; will disable GC inside coroutines");
|
|
||||||
/* Used to disable GC when entering coroutines on macOS */
|
|
||||||
create_coro_gc_hook = []() -> std::shared_ptr<void> {
|
|
||||||
return std::make_shared<BoehmDisableGC>();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#warning "BoehmGC version does not support GC while coroutine exists. GC will be disabled inside coroutines. Consider updating bdw-gc to 8.2.4 or later."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Set the initial heap size to something fairly big (25% of
|
|
||||||
physical RAM, up to a maximum of 384 MiB) so that in most cases
|
|
||||||
we don't need to garbage collect at all. (Collection has a
|
|
||||||
fairly significant overhead.) The heap size can be overridden
|
|
||||||
through libgc's GC_INITIAL_HEAP_SIZE environment variable. We
|
|
||||||
should probably also provide a nix.conf setting for this. Note
|
|
||||||
that GC_expand_hp() causes a lot of virtual, but not physical
|
|
||||||
(resident) memory to be allocated. This might be a problem on
|
|
||||||
systems that don't overcommit. */
|
|
||||||
if (!getEnv("GC_INITIAL_HEAP_SIZE")) {
|
|
||||||
size_t size = 32 * 1024 * 1024;
|
|
||||||
#if HAVE_SYSCONF && defined(_SC_PAGESIZE) && defined(_SC_PHYS_PAGES)
|
|
||||||
size_t maxSize = 384 * 1024 * 1024;
|
|
||||||
long pageSize = sysconf(_SC_PAGESIZE);
|
|
||||||
long pages = sysconf(_SC_PHYS_PAGES);
|
|
||||||
if (pageSize != -1)
|
|
||||||
size = (pageSize * pages) / 4; // 25% of RAM
|
|
||||||
if (size > maxSize) size = maxSize;
|
|
||||||
#endif
|
|
||||||
debug("setting initial heap size to %1% bytes", size);
|
|
||||||
GC_expand_hp(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
gcInitialised = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr size_t BASE_ENV_SIZE = 128;
|
static constexpr size_t BASE_ENV_SIZE = 128;
|
||||||
|
|
||||||
EvalState::EvalState(
|
EvalState::EvalState(
|
||||||
@ -493,7 +310,7 @@ EvalState::EvalState(
|
|||||||
|
|
||||||
countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
|
countCalls = getEnv("NIX_COUNT_CALLS").value_or("0") != "0";
|
||||||
|
|
||||||
assert(gcInitialised);
|
assertGCInitialized();
|
||||||
|
|
||||||
static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes");
|
static_assert(sizeof(Env) <= 16, "environment must be <= 16 bytes");
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include "attr-set.hh"
|
#include "attr-set.hh"
|
||||||
#include "eval-error.hh"
|
#include "eval-error.hh"
|
||||||
|
#include "eval-gc.hh"
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
#include "value.hh"
|
#include "value.hh"
|
||||||
#include "nixexpr.hh"
|
#include "nixexpr.hh"
|
||||||
@ -146,12 +147,6 @@ std::string printValue(EvalState & state, Value & v);
|
|||||||
std::ostream & operator << (std::ostream & os, const ValueType t);
|
std::ostream & operator << (std::ostream & os, const ValueType t);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initialise the Boehm GC, if applicable.
|
|
||||||
*/
|
|
||||||
void initGC();
|
|
||||||
|
|
||||||
|
|
||||||
struct RegexCache;
|
struct RegexCache;
|
||||||
|
|
||||||
std::shared_ptr<RegexCache> makeRegexCache();
|
std::shared_ptr<RegexCache> makeRegexCache();
|
||||||
|
1
src/libstore/.version
Symbolic link
1
src/libstore/.version
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../.version
|
@ -25,6 +25,10 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32 // TODO abstract over proc exit status
|
||||||
|
# include <sys/wait.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
@ -1033,7 +1037,7 @@ void DerivationGoal::buildDone()
|
|||||||
|
|
||||||
BuildResult::Status st = BuildResult::MiscFailure;
|
BuildResult::Status st = BuildResult::MiscFailure;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32 // TODO abstract over proc exit status
|
||||||
if (hook && WIFEXITED(status) && WEXITSTATUS(status) == 101)
|
if (hook && WIFEXITED(status) && WEXITSTATUS(status) == 101)
|
||||||
st = BuildResult::TimedOut;
|
st = BuildResult::TimedOut;
|
||||||
|
|
||||||
|
10
src/libstore/linux/meson.build
Normal file
10
src/libstore/linux/meson.build
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
sources += files(
|
||||||
|
'personality.cc',
|
||||||
|
)
|
||||||
|
|
||||||
|
include_dirs += include_directories('.')
|
||||||
|
|
||||||
|
headers += files(
|
||||||
|
'fchmodat2-compat.hh',
|
||||||
|
'personality.hh',
|
||||||
|
)
|
@ -233,7 +233,7 @@ LocalStore::LocalStore(const Params & params)
|
|||||||
struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
|
struct group * gr = getgrnam(settings.buildUsersGroup.get().c_str());
|
||||||
if (!gr)
|
if (!gr)
|
||||||
printError("warning: the group '%1%' specified in 'build-users-group' does not exist", settings.buildUsersGroup);
|
printError("warning: the group '%1%' specified in 'build-users-group' does not exist", settings.buildUsersGroup);
|
||||||
else {
|
else if (!readOnly) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(realStoreDir.get().c_str(), &st))
|
if (stat(realStoreDir.get().c_str(), &st))
|
||||||
throw SysError("getting attributes of path '%1%'", realStoreDir);
|
throw SysError("getting attributes of path '%1%'", realStoreDir);
|
||||||
|
452
src/libstore/meson.build
Normal file
452
src/libstore/meson.build
Normal file
@ -0,0 +1,452 @@
|
|||||||
|
project('nix-store', 'cpp',
|
||||||
|
version : files('.version'),
|
||||||
|
default_options : [
|
||||||
|
'cpp_std=c++2a',
|
||||||
|
# TODO(Qyriad): increase the warning level
|
||||||
|
'warning_level=1',
|
||||||
|
'debug=true',
|
||||||
|
'optimization=2',
|
||||||
|
'errorlogs=true', # Please print logs for tests that fail
|
||||||
|
],
|
||||||
|
meson_version : '>= 1.1',
|
||||||
|
license : 'LGPL-2.1-or-later',
|
||||||
|
)
|
||||||
|
|
||||||
|
cxx = meson.get_compiler('cpp')
|
||||||
|
|
||||||
|
# See note in ../nix-util/meson.build
|
||||||
|
deps_private = [ ]
|
||||||
|
|
||||||
|
# See note in ../nix-util/meson.build
|
||||||
|
deps_public = [ ]
|
||||||
|
|
||||||
|
# See note in ../nix-util/meson.build
|
||||||
|
deps_other = [ ]
|
||||||
|
|
||||||
|
configdata = configuration_data()
|
||||||
|
|
||||||
|
# TODO rename, because it will conflict with downstream projects
|
||||||
|
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())
|
||||||
|
|
||||||
|
configdata.set_quoted('SYSTEM', host_machine.system())
|
||||||
|
|
||||||
|
nix_util = dependency('nix-util')
|
||||||
|
if nix_util.type_name() == 'internal'
|
||||||
|
# subproject sadly no good for pkg-config module
|
||||||
|
deps_other += nix_util
|
||||||
|
else
|
||||||
|
deps_public += nix_util
|
||||||
|
endif
|
||||||
|
|
||||||
|
run_command('ln', '-s',
|
||||||
|
meson.project_build_root() / '__nothing_link_target',
|
||||||
|
meson.project_build_root() / '__nothing_symlink',
|
||||||
|
check : true,
|
||||||
|
)
|
||||||
|
can_link_symlink = run_command('ln',
|
||||||
|
meson.project_build_root() / '__nothing_symlink',
|
||||||
|
meson.project_build_root() / '__nothing_hardlink',
|
||||||
|
check : false,
|
||||||
|
).returncode() == 0
|
||||||
|
run_command('rm', '-f',
|
||||||
|
meson.project_build_root() / '__nothing_symlink',
|
||||||
|
meson.project_build_root() / '__nothing_hardlink',
|
||||||
|
check : true,
|
||||||
|
)
|
||||||
|
summary('can hardlink to symlink', can_link_symlink, bool_yn : true)
|
||||||
|
configdata.set('CAN_LINK_SYMLINK', can_link_symlink.to_int())
|
||||||
|
|
||||||
|
# Check for each of these functions, and create a define like `#define HAVE_LCHOWN 1`.
|
||||||
|
#
|
||||||
|
# Only need to do functions that deps (like `libnixutil`) didn't already
|
||||||
|
# check for.
|
||||||
|
check_funcs = [
|
||||||
|
# Optionally used for canonicalising files from the build
|
||||||
|
'lchown',
|
||||||
|
]
|
||||||
|
foreach funcspec : check_funcs
|
||||||
|
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
|
||||||
|
define_value = cxx.has_function(funcspec).to_int()
|
||||||
|
configdata.set(define_name, define_value)
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
has_acl_support = cxx.has_header('sys/xattr.h') \
|
||||||
|
and cxx.has_function('llistxattr') \
|
||||||
|
and cxx.has_function('lremovexattr')
|
||||||
|
configdata.set('HAVE_ACL_SUPPORT', has_acl_support.to_int())
|
||||||
|
|
||||||
|
# This is only conditional to work around
|
||||||
|
# https://github.com/mesonbuild/meson/issues/13293. It should be
|
||||||
|
# unconditional.
|
||||||
|
if not (host_machine.system() == 'windows' and cxx.get_id() == 'gcc')
|
||||||
|
deps_private += dependency('threads')
|
||||||
|
endif
|
||||||
|
|
||||||
|
boost = dependency(
|
||||||
|
'boost',
|
||||||
|
modules : ['container'],
|
||||||
|
)
|
||||||
|
# boost is a public dependency, but not a pkg-config dependency unfortunately, so we
|
||||||
|
# put in `deps_other`.
|
||||||
|
deps_other += boost
|
||||||
|
|
||||||
|
curl = dependency('libcurl', 'curl')
|
||||||
|
deps_private += curl
|
||||||
|
|
||||||
|
# seccomp only makes sense on Linux
|
||||||
|
is_linux = host_machine.system() == 'linux'
|
||||||
|
seccomp_required = get_option('seccomp-sandboxing')
|
||||||
|
if not is_linux and seccomp_required.enabled()
|
||||||
|
warning('Force-enabling seccomp on non-Linux does not make sense')
|
||||||
|
endif
|
||||||
|
seccomp = dependency('libseccomp', 'seccomp', required : seccomp_required, version : '>=2.5.5')
|
||||||
|
if is_linux and not seccomp.found()
|
||||||
|
warning('Sandbox security is reduced because libseccomp has not been found! Please provide libseccomp if it supports your CPU architecture.')
|
||||||
|
endif
|
||||||
|
configdata.set('HAVE_SECCOMP', seccomp.found().to_int())
|
||||||
|
deps_private += seccomp
|
||||||
|
|
||||||
|
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
|
||||||
|
deps_public += nlohmann_json
|
||||||
|
|
||||||
|
sqlite = dependency('sqlite3', 'sqlite', version : '>=3.6.19')
|
||||||
|
deps_private += sqlite
|
||||||
|
|
||||||
|
|
||||||
|
enable_embedded_sandbox_shell = get_option('embedded-sandbox-shell')
|
||||||
|
if enable_embedded_sandbox_shell
|
||||||
|
# This one goes in config.h
|
||||||
|
# The path to busybox is passed as a -D flag when compiling this_library.
|
||||||
|
# Idk why, ask the old buildsystem.
|
||||||
|
configdata.set('HAVE_EMBEDDED_SANDBOX_SHELL', 1)
|
||||||
|
endif
|
||||||
|
|
||||||
|
generated_headers = []
|
||||||
|
foreach header : [ 'schema.sql', 'ca-specific-schema.sql' ]
|
||||||
|
generated_headers += custom_target(
|
||||||
|
command : [ 'bash', '-c', '{ echo \'R"__NIX_STR(\' && cat @INPUT@ && echo \')__NIX_STR"\'; } > "$1"', '_ignored_argv0', '@OUTPUT@' ],
|
||||||
|
input : header,
|
||||||
|
output : '@PLAINNAME@.gen.hh',
|
||||||
|
install : true,
|
||||||
|
install_dir : get_option('includedir') / 'nix'
|
||||||
|
)
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
if enable_embedded_sandbox_shell
|
||||||
|
hexdump = find_program('hexdump', native : true)
|
||||||
|
embedded_sandbox_shell_gen = custom_target(
|
||||||
|
'embedded-sandbox-shell.gen.hh',
|
||||||
|
command : [
|
||||||
|
hexdump,
|
||||||
|
'-v',
|
||||||
|
'-e',
|
||||||
|
'1/1 "0x%x," "\n"'
|
||||||
|
],
|
||||||
|
input : busybox.full_path(),
|
||||||
|
output : 'embedded-sandbox-shell.gen.hh',
|
||||||
|
capture : true,
|
||||||
|
feed : true,
|
||||||
|
)
|
||||||
|
generated_headers += embedded_sandbox_shell_gen
|
||||||
|
endif
|
||||||
|
|
||||||
|
config_h = configure_file(
|
||||||
|
configuration : configdata,
|
||||||
|
output : 'config-store.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
add_project_arguments(
|
||||||
|
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||||
|
# It would be nice for our headers to be idempotent instead.
|
||||||
|
'-include', 'config-util.h',
|
||||||
|
'-include', 'config-store.h',
|
||||||
|
'-Wno-deprecated-declarations',
|
||||||
|
'-Wimplicit-fallthrough',
|
||||||
|
'-Werror=switch',
|
||||||
|
'-Werror=switch-enum',
|
||||||
|
'-Wdeprecated-copy',
|
||||||
|
'-Wignored-qualifiers',
|
||||||
|
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
|
||||||
|
# at ~1% overhead in `nix search`.
|
||||||
|
#
|
||||||
|
# FIXME: remove when we get meson 1.4.0 which will default this to on for us:
|
||||||
|
# https://mesonbuild.com/Release-notes-for-1-4-0.html#ndebug-setting-now-controls-c-stdlib-assertions
|
||||||
|
'-D_GLIBCXX_ASSERTIONS=1',
|
||||||
|
language : 'cpp',
|
||||||
|
)
|
||||||
|
|
||||||
|
sources = files(
|
||||||
|
'binary-cache-store.cc',
|
||||||
|
'build-result.cc',
|
||||||
|
'build/derivation-goal.cc',
|
||||||
|
'build/drv-output-substitution-goal.cc',
|
||||||
|
'build/entry-points.cc',
|
||||||
|
'build/goal.cc',
|
||||||
|
'build/substitution-goal.cc',
|
||||||
|
'build/worker.cc',
|
||||||
|
'builtins/buildenv.cc',
|
||||||
|
'builtins/fetchurl.cc',
|
||||||
|
'builtins/unpack-channel.cc',
|
||||||
|
'common-protocol.cc',
|
||||||
|
'content-address.cc',
|
||||||
|
'daemon.cc',
|
||||||
|
'derivations.cc',
|
||||||
|
'derived-path-map.cc',
|
||||||
|
'derived-path.cc',
|
||||||
|
'downstream-placeholder.cc',
|
||||||
|
'dummy-store.cc',
|
||||||
|
'export-import.cc',
|
||||||
|
'filetransfer.cc',
|
||||||
|
'gc.cc',
|
||||||
|
'globals.cc',
|
||||||
|
'http-binary-cache-store.cc',
|
||||||
|
'indirect-root-store.cc',
|
||||||
|
'keys.cc',
|
||||||
|
'legacy-ssh-store.cc',
|
||||||
|
'local-binary-cache-store.cc',
|
||||||
|
'local-fs-store.cc',
|
||||||
|
'local-overlay-store.cc',
|
||||||
|
'local-store.cc',
|
||||||
|
'log-store.cc',
|
||||||
|
'machines.cc',
|
||||||
|
'make-content-addressed.cc',
|
||||||
|
'misc.cc',
|
||||||
|
'names.cc',
|
||||||
|
'nar-accessor.cc',
|
||||||
|
'nar-info-disk-cache.cc',
|
||||||
|
'nar-info.cc',
|
||||||
|
'optimise-store.cc',
|
||||||
|
'outputs-spec.cc',
|
||||||
|
'parsed-derivations.cc',
|
||||||
|
'path-info.cc',
|
||||||
|
'path-references.cc',
|
||||||
|
'path-with-outputs.cc',
|
||||||
|
'path.cc',
|
||||||
|
'pathlocks.cc',
|
||||||
|
'posix-fs-canonicalise.cc',
|
||||||
|
'profiles.cc',
|
||||||
|
'realisation.cc',
|
||||||
|
'remote-fs-accessor.cc',
|
||||||
|
'remote-store.cc',
|
||||||
|
's3-binary-cache-store.cc',
|
||||||
|
'serve-protocol-connection.cc',
|
||||||
|
'serve-protocol.cc',
|
||||||
|
'sqlite.cc',
|
||||||
|
'ssh-store-config.cc',
|
||||||
|
'ssh-store.cc',
|
||||||
|
'ssh.cc',
|
||||||
|
'store-api.cc',
|
||||||
|
'store-reference.cc',
|
||||||
|
'uds-remote-store.cc',
|
||||||
|
'worker-protocol-connection.cc',
|
||||||
|
'worker-protocol.cc',
|
||||||
|
)
|
||||||
|
|
||||||
|
include_dirs = [
|
||||||
|
include_directories('.'),
|
||||||
|
include_directories('build'),
|
||||||
|
]
|
||||||
|
|
||||||
|
headers = [config_h] +files(
|
||||||
|
'binary-cache-store.hh',
|
||||||
|
'build-result.hh',
|
||||||
|
'build/derivation-goal.hh',
|
||||||
|
'build/drv-output-substitution-goal.hh',
|
||||||
|
'build/goal.hh',
|
||||||
|
'build/substitution-goal.hh',
|
||||||
|
'build/worker.hh',
|
||||||
|
'builtins.hh',
|
||||||
|
'builtins/buildenv.hh',
|
||||||
|
'common-protocol-impl.hh',
|
||||||
|
'common-protocol.hh',
|
||||||
|
'content-address.hh',
|
||||||
|
'daemon.hh',
|
||||||
|
'derivations.hh',
|
||||||
|
'derived-path-map.hh',
|
||||||
|
'derived-path.hh',
|
||||||
|
'downstream-placeholder.hh',
|
||||||
|
'filetransfer.hh',
|
||||||
|
'gc-store.hh',
|
||||||
|
'globals.hh',
|
||||||
|
'indirect-root-store.hh',
|
||||||
|
'keys.hh',
|
||||||
|
'legacy-ssh-store.hh',
|
||||||
|
'length-prefixed-protocol-helper.hh',
|
||||||
|
'local-fs-store.hh',
|
||||||
|
'local-overlay-store.hh',
|
||||||
|
'local-store.hh',
|
||||||
|
'log-store.hh',
|
||||||
|
'machines.hh',
|
||||||
|
'make-content-addressed.hh',
|
||||||
|
'names.hh',
|
||||||
|
'nar-accessor.hh',
|
||||||
|
'nar-info-disk-cache.hh',
|
||||||
|
'nar-info.hh',
|
||||||
|
'outputs-spec.hh',
|
||||||
|
'parsed-derivations.hh',
|
||||||
|
'path-info.hh',
|
||||||
|
'path-references.hh',
|
||||||
|
'path-regex.hh',
|
||||||
|
'path-with-outputs.hh',
|
||||||
|
'path.hh',
|
||||||
|
'pathlocks.hh',
|
||||||
|
'posix-fs-canonicalise.hh',
|
||||||
|
'profiles.hh',
|
||||||
|
'realisation.hh',
|
||||||
|
'remote-fs-accessor.hh',
|
||||||
|
'remote-store-connection.hh',
|
||||||
|
'remote-store.hh',
|
||||||
|
's3-binary-cache-store.hh',
|
||||||
|
's3.hh',
|
||||||
|
'serve-protocol-connection.hh',
|
||||||
|
'serve-protocol-impl.hh',
|
||||||
|
'serve-protocol.hh',
|
||||||
|
'sqlite.hh',
|
||||||
|
'ssh-store-config.hh',
|
||||||
|
'ssh.hh',
|
||||||
|
'store-api.hh',
|
||||||
|
'store-cast.hh',
|
||||||
|
'store-dir-config.hh',
|
||||||
|
'store-reference.hh',
|
||||||
|
'uds-remote-store.hh',
|
||||||
|
'worker-protocol-connection.hh',
|
||||||
|
'worker-protocol-impl.hh',
|
||||||
|
'worker-protocol.hh',
|
||||||
|
)
|
||||||
|
|
||||||
|
if host_machine.system() == 'linux'
|
||||||
|
subdir('linux')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if host_machine.system() == 'windows'
|
||||||
|
subdir('windows')
|
||||||
|
else
|
||||||
|
subdir('unix')
|
||||||
|
endif
|
||||||
|
|
||||||
|
fs = import('fs')
|
||||||
|
|
||||||
|
prefix = get_option('prefix')
|
||||||
|
# For each of these paths, assume that it is relative to the prefix unless
|
||||||
|
# it is already an absolute path (which is the default for store-dir, state-dir, and log-dir).
|
||||||
|
path_opts = [
|
||||||
|
# Meson built-ins.
|
||||||
|
'datadir',
|
||||||
|
'bindir',
|
||||||
|
'mandir',
|
||||||
|
'libdir',
|
||||||
|
'includedir',
|
||||||
|
'libexecdir',
|
||||||
|
# Homecooked Nix directories.
|
||||||
|
'store-dir',
|
||||||
|
'state-dir',
|
||||||
|
'log-dir',
|
||||||
|
]
|
||||||
|
# For your grepping pleasure, this loop sets the following variables that aren't mentioned
|
||||||
|
# literally above:
|
||||||
|
# store_dir
|
||||||
|
# state_dir
|
||||||
|
# log_dir
|
||||||
|
# profile_dir
|
||||||
|
foreach optname : path_opts
|
||||||
|
varname = optname.replace('-', '_')
|
||||||
|
path = get_option(optname)
|
||||||
|
if fs.is_absolute(path)
|
||||||
|
set_variable(varname, path)
|
||||||
|
else
|
||||||
|
set_variable(varname, prefix / path)
|
||||||
|
endif
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
# sysconfdir doesn't get anything installed to directly, and is only used to
|
||||||
|
# tell Nix where to look for nix.conf, so it doesn't get appended to prefix.
|
||||||
|
sysconfdir = get_option('sysconfdir')
|
||||||
|
if not fs.is_absolute(sysconfdir)
|
||||||
|
sysconfdir = '/' / sysconfdir
|
||||||
|
endif
|
||||||
|
|
||||||
|
lsof = find_program('lsof', required : false)
|
||||||
|
|
||||||
|
# Aside from prefix itself, each of these was made into an absolute path
|
||||||
|
# by joining it with prefix, unless it was already an absolute path
|
||||||
|
# (which is the default for store-dir, state-dir, and log-dir).
|
||||||
|
cpp_str_defines = {
|
||||||
|
'NIX_PREFIX': prefix,
|
||||||
|
'NIX_STORE_DIR': store_dir,
|
||||||
|
'NIX_DATA_DIR': datadir,
|
||||||
|
'NIX_STATE_DIR': state_dir / 'nix',
|
||||||
|
'NIX_LOG_DIR': log_dir,
|
||||||
|
'NIX_CONF_DIR': sysconfdir / 'nix',
|
||||||
|
'NIX_BIN_DIR': bindir,
|
||||||
|
'NIX_MAN_DIR': mandir,
|
||||||
|
}
|
||||||
|
|
||||||
|
if lsof.found()
|
||||||
|
lsof_path = lsof.full_path()
|
||||||
|
else
|
||||||
|
# Just look up on the PATH
|
||||||
|
lsof_path = 'lsof'
|
||||||
|
endif
|
||||||
|
cpp_str_defines += {
|
||||||
|
'LSOF': lsof_path
|
||||||
|
}
|
||||||
|
|
||||||
|
#if busybox.found()
|
||||||
|
cpp_str_defines += {
|
||||||
|
# 'SANDBOX_SHELL': busybox.full_path()
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cpp_args = []
|
||||||
|
|
||||||
|
foreach name, value : cpp_str_defines
|
||||||
|
cpp_args += [
|
||||||
|
'-D' + name + '=' + '"' + value + '"'
|
||||||
|
]
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
|
||||||
|
# See note in `../nix-util/meson.build`
|
||||||
|
linker_export_flags = ['-Wl,--export-all-symbols']
|
||||||
|
else
|
||||||
|
linker_export_flags = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
this_library = library(
|
||||||
|
'nixstore',
|
||||||
|
generated_headers,
|
||||||
|
sources,
|
||||||
|
dependencies : deps_public + deps_private + deps_other,
|
||||||
|
include_directories : include_dirs,
|
||||||
|
cpp_args : cpp_args,
|
||||||
|
link_args: linker_export_flags,
|
||||||
|
install : true,
|
||||||
|
)
|
||||||
|
|
||||||
|
install_headers(headers, subdir : 'nix', preserve_path : true)
|
||||||
|
|
||||||
|
requires = deps_public
|
||||||
|
if nix_util.type_name() == 'internal'
|
||||||
|
# `requires` cannot contain declared dependencies (from the
|
||||||
|
# subproject), so we need to do this manually
|
||||||
|
requires = [ 'nix-util' ] + requires
|
||||||
|
endif
|
||||||
|
|
||||||
|
import('pkgconfig').generate(
|
||||||
|
this_library,
|
||||||
|
filebase : meson.project_name(),
|
||||||
|
name : 'Nix',
|
||||||
|
description : 'Nix Package Manager',
|
||||||
|
subdirs : ['nix'],
|
||||||
|
extra_cflags : ['-std=c++2a'],
|
||||||
|
requires : requires,
|
||||||
|
requires_private : deps_private,
|
||||||
|
libraries_private : ['-lboost_container'],
|
||||||
|
)
|
||||||
|
|
||||||
|
meson.override_dependency(meson.project_name(), declare_dependency(
|
||||||
|
include_directories : include_dirs,
|
||||||
|
link_with : this_library,
|
||||||
|
compile_args : ['-std=c++2a'],
|
||||||
|
dependencies : [nix_util],
|
||||||
|
))
|
25
src/libstore/meson.options
Normal file
25
src/libstore/meson.options
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
# vim: filetype=meson
|
||||||
|
|
||||||
|
option('embedded-sandbox-shell', type : 'boolean', value : false,
|
||||||
|
description : 'include the sandbox shell in the Nix binary',
|
||||||
|
)
|
||||||
|
|
||||||
|
option('seccomp-sandboxing', type : 'feature',
|
||||||
|
description : 'build support for seccomp sandboxing (recommended unless your arch doesn\'t support libseccomp, only relevant on Linux)',
|
||||||
|
)
|
||||||
|
|
||||||
|
option('sandbox-shell', type : 'string', value : 'busybox',
|
||||||
|
description : 'path to a statically-linked shell to use as /bin/sh in sandboxes (usually busybox)',
|
||||||
|
)
|
||||||
|
|
||||||
|
option('store-dir', type : 'string', value : '/nix/store',
|
||||||
|
description : 'path of the Nix store',
|
||||||
|
)
|
||||||
|
|
||||||
|
option('state-dir', type : 'string', value : '/nix/var',
|
||||||
|
description : 'path to store state in for Nix',
|
||||||
|
)
|
||||||
|
|
||||||
|
option('log-dir', type : 'string', value : '/nix/var/log/nix',
|
||||||
|
description : 'path to store logs in for Nix',
|
||||||
|
)
|
142
src/libstore/package.nix
Normal file
142
src/libstore/package.nix
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
{ lib
|
||||||
|
, stdenv
|
||||||
|
, releaseTools
|
||||||
|
, fileset
|
||||||
|
|
||||||
|
, meson
|
||||||
|
, ninja
|
||||||
|
, pkg-config
|
||||||
|
|
||||||
|
, nix-util
|
||||||
|
, boost
|
||||||
|
, curl
|
||||||
|
, aws-sdk-cpp
|
||||||
|
, libseccomp
|
||||||
|
, nlohmann_json
|
||||||
|
, man
|
||||||
|
, sqlite
|
||||||
|
|
||||||
|
, busybox-sandbox-shell ? null
|
||||||
|
|
||||||
|
# Configuration Options
|
||||||
|
|
||||||
|
, versionSuffix ? ""
|
||||||
|
, officialRelease ? false
|
||||||
|
|
||||||
|
# Check test coverage of Nix. Probably want to use with at least
|
||||||
|
# one of `doCheck` or `doInstallCheck` enabled.
|
||||||
|
, withCoverageChecks ? false
|
||||||
|
|
||||||
|
# Avoid setting things that would interfere with a functioning devShell
|
||||||
|
, forDevShell ? false
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
version = lib.fileContents ./.version + versionSuffix;
|
||||||
|
|
||||||
|
mkDerivation =
|
||||||
|
if withCoverageChecks
|
||||||
|
then
|
||||||
|
# TODO support `finalAttrs` args function in
|
||||||
|
# `releaseTools.coverageAnalysis`.
|
||||||
|
argsFun:
|
||||||
|
releaseTools.coverageAnalysis (let args = argsFun args; in args)
|
||||||
|
else stdenv.mkDerivation;
|
||||||
|
in
|
||||||
|
|
||||||
|
mkDerivation (finalAttrs: {
|
||||||
|
pname = "nix-store";
|
||||||
|
inherit version;
|
||||||
|
|
||||||
|
src = fileset.toSource {
|
||||||
|
root = ./.;
|
||||||
|
fileset = fileset.unions [
|
||||||
|
./meson.build
|
||||||
|
./meson.options
|
||||||
|
./linux/meson.build
|
||||||
|
./unix/meson.build
|
||||||
|
./windows/meson.build
|
||||||
|
(fileset.fileFilter (file: file.hasExt "cc") ./.)
|
||||||
|
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||||
|
(fileset.fileFilter (file: file.hasExt "sb") ./.)
|
||||||
|
(fileset.fileFilter (file: file.hasExt "md") ./.)
|
||||||
|
(fileset.fileFilter (file: file.hasExt "sql") ./.)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = [ "out" "dev" ];
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
meson
|
||||||
|
ninja
|
||||||
|
pkg-config
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
boost
|
||||||
|
curl
|
||||||
|
sqlite
|
||||||
|
] ++ lib.optional stdenv.hostPlatform.isLinux libseccomp
|
||||||
|
# There have been issues building these dependencies
|
||||||
|
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin))
|
||||||
|
(aws-sdk-cpp.override {
|
||||||
|
apis = ["s3" "transfer"];
|
||||||
|
customMemoryManagement = false;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
||||||
|
propagatedBuildInputs = [
|
||||||
|
nix-util
|
||||||
|
nlohmann_json
|
||||||
|
];
|
||||||
|
|
||||||
|
disallowedReferences = [ boost ];
|
||||||
|
|
||||||
|
preConfigure =
|
||||||
|
# "Inline" .version so it's not a symlink, and includes the suffix
|
||||||
|
''
|
||||||
|
echo ${version} > .version
|
||||||
|
'';
|
||||||
|
|
||||||
|
mesonFlags = [
|
||||||
|
(lib.mesonEnable "seccomp-sandboxing" stdenv.hostPlatform.isLinux)
|
||||||
|
(lib.mesonBool "embedded-sandbox-shell" stdenv.hostPlatform.isStatic)
|
||||||
|
] ++ lib.optionals stdenv.hostPlatform.isLinux [
|
||||||
|
(lib.mesonOption "sandbox-shell" "${busybox-sandbox-shell}/bin/busybox")
|
||||||
|
];
|
||||||
|
|
||||||
|
env = {
|
||||||
|
# Needed for Meson to find Boost.
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/86131.
|
||||||
|
BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
|
||||||
|
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
|
||||||
|
} // lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||||
|
LDFLAGS = "-fuse-ld=gold";
|
||||||
|
};
|
||||||
|
|
||||||
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
|
postInstall =
|
||||||
|
# Remove absolute path to boost libs that ends up in `Libs.private`
|
||||||
|
# by default, and would clash with out `disallowedReferences`. Part
|
||||||
|
# of the https://github.com/NixOS/nixpkgs/issues/45462 workaround.
|
||||||
|
''
|
||||||
|
sed -i "$out/lib/pkgconfig/nix-store.pc" -e 's, ${lib.getLib boost}[^ ]*,,g'
|
||||||
|
'';
|
||||||
|
|
||||||
|
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||||
|
|
||||||
|
# TODO Always true after https://github.com/NixOS/nixpkgs/issues/318564
|
||||||
|
strictDeps = !withCoverageChecks;
|
||||||
|
|
||||||
|
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // lib.optionalAttrs withCoverageChecks {
|
||||||
|
lcovFilter = [ "*/boost/*" "*-tab.*" ];
|
||||||
|
|
||||||
|
hardeningDisable = [ "fortify" ];
|
||||||
|
})
|
@ -1500,7 +1500,7 @@ void LocalDerivationGoal::startDaemon()
|
|||||||
throw SysError("accepting connection");
|
throw SysError("accepting connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
closeOnExec(remote.get());
|
unix::closeOnExec(remote.get());
|
||||||
|
|
||||||
debug("received daemon connection");
|
debug("received daemon connection");
|
||||||
|
|
||||||
@ -1961,7 +1961,7 @@ void LocalDerivationGoal::runChild()
|
|||||||
throw SysError("changing into '%1%'", tmpDir);
|
throw SysError("changing into '%1%'", tmpDir);
|
||||||
|
|
||||||
/* Close all other file descriptors. */
|
/* Close all other file descriptors. */
|
||||||
closeMostFDs({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO});
|
unix::closeMostFDs({STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO});
|
||||||
|
|
||||||
#if __linux__
|
#if __linux__
|
||||||
linux::setPersonality(drv->platform);
|
linux::setPersonality(drv->platform);
|
||||||
|
@ -17,6 +17,9 @@ R""(
|
|||||||
; Allow POSIX semaphores and shared memory.
|
; Allow POSIX semaphores and shared memory.
|
||||||
(allow ipc-posix*)
|
(allow ipc-posix*)
|
||||||
|
|
||||||
|
; Allow SYSV semaphores and shared memory.
|
||||||
|
(allow ipc-sysv*)
|
||||||
|
|
||||||
; Allow socket creation.
|
; Allow socket creation.
|
||||||
(allow system-socket)
|
(allow system-socket)
|
||||||
|
|
||||||
|
19
src/libstore/unix/meson.build
Normal file
19
src/libstore/unix/meson.build
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
sources += files(
|
||||||
|
'build/child.cc',
|
||||||
|
'build/hook-instance.cc',
|
||||||
|
'build/local-derivation-goal.cc',
|
||||||
|
'pathlocks.cc',
|
||||||
|
'user-lock.cc',
|
||||||
|
)
|
||||||
|
|
||||||
|
include_dirs += include_directories(
|
||||||
|
'.',
|
||||||
|
'build',
|
||||||
|
)
|
||||||
|
|
||||||
|
headers += files(
|
||||||
|
'build/child.hh',
|
||||||
|
'build/hook-instance.hh',
|
||||||
|
'build/local-derivation-goal.hh',
|
||||||
|
'user-lock.hh',
|
||||||
|
)
|
11
src/libstore/windows/meson.build
Normal file
11
src/libstore/windows/meson.build
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
sources += files(
|
||||||
|
'pathlocks.cc',
|
||||||
|
)
|
||||||
|
|
||||||
|
include_dirs += include_directories(
|
||||||
|
'.',
|
||||||
|
#'build',
|
||||||
|
)
|
||||||
|
|
||||||
|
headers += files(
|
||||||
|
)
|
1
src/libutil/.version
Symbolic link
1
src/libutil/.version
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../../.version
|
@ -140,6 +140,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifndef _WIN32 // Not needed on Windows, where we don't fork
|
#ifndef _WIN32 // Not needed on Windows, where we don't fork
|
||||||
|
namespace unix {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close all file descriptors except those listed in the given set.
|
* Close all file descriptors except those listed in the given set.
|
||||||
@ -152,13 +153,16 @@ void closeMostFDs(const std::set<Descriptor> & exceptions);
|
|||||||
*/
|
*/
|
||||||
void closeOnExec(Descriptor fd);
|
void closeOnExec(Descriptor fd);
|
||||||
|
|
||||||
|
} // namespace unix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#if defined(_WIN32) && _WIN32_WINNT >= 0x0600
|
||||||
# if _WIN32_WINNT >= 0x0600
|
namespace windows {
|
||||||
|
|
||||||
Path handleToPath(Descriptor handle);
|
Path handleToPath(Descriptor handle);
|
||||||
std::wstring handleToFileName(Descriptor handle);
|
std::wstring handleToFileName(Descriptor handle);
|
||||||
# endif
|
|
||||||
|
} // namespace windows
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MakeError(EndOfFile, Error);
|
MakeError(EndOfFile, Error);
|
||||||
|
@ -525,7 +525,7 @@ std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix)
|
|||||||
if (!fd)
|
if (!fd)
|
||||||
throw SysError("creating temporary file '%s'", tmpl);
|
throw SysError("creating temporary file '%s'", tmpl);
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
closeOnExec(fd.get());
|
unix::closeOnExec(fd.get());
|
||||||
#endif
|
#endif
|
||||||
return {std::move(fd), tmpl};
|
return {std::move(fd), tmpl};
|
||||||
}
|
}
|
||||||
|
@ -52,11 +52,11 @@ bool Hash::operator == (const Hash & h2) const
|
|||||||
|
|
||||||
std::strong_ordering Hash::operator <=> (const Hash & h) const
|
std::strong_ordering Hash::operator <=> (const Hash & h) const
|
||||||
{
|
{
|
||||||
if (auto cmp = algo <=> h.algo; cmp != 0) return cmp;
|
|
||||||
if (auto cmp = hashSize <=> h.hashSize; cmp != 0) return cmp;
|
if (auto cmp = hashSize <=> h.hashSize; cmp != 0) return cmp;
|
||||||
for (unsigned int i = 0; i < hashSize; i++) {
|
for (unsigned int i = 0; i < hashSize; i++) {
|
||||||
if (auto cmp = hash[i] <=> h.hash[i]; cmp != 0) return cmp;
|
if (auto cmp = hash[i] <=> h.hash[i]; cmp != 0) return cmp;
|
||||||
}
|
}
|
||||||
|
if (auto cmp = algo <=> h.algo; cmp != 0) return cmp;
|
||||||
return std::strong_ordering::equivalent;
|
return std::strong_ordering::equivalent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
src/libutil/linux/meson.build
Normal file
11
src/libutil/linux/meson.build
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
sources += files(
|
||||||
|
'cgroup.cc',
|
||||||
|
'namespaces.cc',
|
||||||
|
)
|
||||||
|
|
||||||
|
include_dirs += include_directories('.')
|
||||||
|
|
||||||
|
headers += files(
|
||||||
|
'cgroup.hh',
|
||||||
|
'namespaces.hh',
|
||||||
|
)
|
332
src/libutil/meson.build
Normal file
332
src/libutil/meson.build
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
project('nix-util', 'cpp',
|
||||||
|
version : files('.version'),
|
||||||
|
default_options : [
|
||||||
|
'cpp_std=c++2a',
|
||||||
|
# TODO(Qyriad): increase the warning level
|
||||||
|
'warning_level=1',
|
||||||
|
'debug=true',
|
||||||
|
'optimization=2',
|
||||||
|
'errorlogs=true', # Please print logs for tests that fail
|
||||||
|
],
|
||||||
|
meson_version : '>= 1.1',
|
||||||
|
license : 'LGPL-2.1-or-later',
|
||||||
|
)
|
||||||
|
|
||||||
|
cxx = meson.get_compiler('cpp')
|
||||||
|
|
||||||
|
# These are private dependencies with pkg-config files. What private
|
||||||
|
# means is that the dependencies are used by the library but they are
|
||||||
|
# *not* used (e.g. `#include`-ed) in any installed header file, and only
|
||||||
|
# in regular source code (`*.cc`) or private, uninstalled headers. They
|
||||||
|
# are thus part of the *implementation* of the library, but not its
|
||||||
|
# *interface*.
|
||||||
|
#
|
||||||
|
# See `man pkg-config` for some details.
|
||||||
|
deps_private = [ ]
|
||||||
|
|
||||||
|
# These are public dependencies with pkg-config files. Public is the
|
||||||
|
# opposite of private: these dependencies are used in installed header
|
||||||
|
# files. They are part of the interface (and implementation) of the
|
||||||
|
# library.
|
||||||
|
#
|
||||||
|
# N.B. This concept is mostly unrelated to our own concept of a public
|
||||||
|
# (stable) API, for consumption outside of the Nix repository.
|
||||||
|
# `libnixutil` is an unstable C++ library, whose public interface is
|
||||||
|
# likewise unstable. `libutilc` conversely is a hopefully-soon stable
|
||||||
|
# C library, whose public interface --- including public but not private
|
||||||
|
# dependencies --- will also likewise soon be stable.
|
||||||
|
#
|
||||||
|
# N.B. For distributions that care about "ABI" stablity and not just
|
||||||
|
# "API" stability, the private dependencies also matter as they can
|
||||||
|
# potentially affect the public ABI.
|
||||||
|
deps_public = [ ]
|
||||||
|
|
||||||
|
# These are dependencencies without pkg-config files. Ideally they are
|
||||||
|
# just private, but they may also be public (e.g. boost).
|
||||||
|
deps_other = [ ]
|
||||||
|
|
||||||
|
configdata = configuration_data()
|
||||||
|
|
||||||
|
# Check for each of these functions, and create a define like `#define
|
||||||
|
# HAVE_LUTIMES 1`. The `#define` is unconditional, 0 for not found and 1
|
||||||
|
# for found. One therefore uses it with `#if` not `#ifdef`.
|
||||||
|
check_funcs = [
|
||||||
|
# Optionally used for changing the mtime of symlinks.
|
||||||
|
'lutimes',
|
||||||
|
# Optionally used for creating pipes on Unix
|
||||||
|
'pipe2',
|
||||||
|
# Optionally used to preallocate files to be large enough before
|
||||||
|
# writing to them.
|
||||||
|
'posix_fallocate',
|
||||||
|
# Optionally used to get more information about processes failing due
|
||||||
|
# to a signal on Unix.
|
||||||
|
'strsignal',
|
||||||
|
# Optionally used to try to close more file descriptors (e.g. before
|
||||||
|
# forking) on Unix.
|
||||||
|
'sysconf',
|
||||||
|
]
|
||||||
|
foreach funcspec : check_funcs
|
||||||
|
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
|
||||||
|
define_value = cxx.has_function(funcspec).to_int()
|
||||||
|
configdata.set(define_name, define_value)
|
||||||
|
endforeach
|
||||||
|
|
||||||
|
# This is only conditional to work around
|
||||||
|
# https://github.com/mesonbuild/meson/issues/13293. It should be
|
||||||
|
# unconditional.
|
||||||
|
if not (host_machine.system() == 'windows' and cxx.get_id() == 'gcc')
|
||||||
|
deps_private += dependency('threads')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if host_machine.system() == 'windows'
|
||||||
|
socket = cxx.find_library('ws2_32')
|
||||||
|
deps_other += socket
|
||||||
|
elif host_machine.system() == 'sunos'
|
||||||
|
socket = cxx.find_library('socket')
|
||||||
|
network_service_library = cxx.find_library('nsl')
|
||||||
|
deps_other += [socket, network_service_library]
|
||||||
|
endif
|
||||||
|
|
||||||
|
boost = dependency(
|
||||||
|
'boost',
|
||||||
|
modules : ['context', 'coroutine'],
|
||||||
|
)
|
||||||
|
# boost is a public dependency, but not a pkg-config dependency unfortunately, so we
|
||||||
|
# put in `deps_other`.
|
||||||
|
deps_other += boost
|
||||||
|
|
||||||
|
openssl = dependency(
|
||||||
|
'libcrypto',
|
||||||
|
'openssl',
|
||||||
|
version : '>= 1.1.1',
|
||||||
|
)
|
||||||
|
deps_private += openssl
|
||||||
|
|
||||||
|
libarchive = dependency('libarchive', version : '>= 3.1.2')
|
||||||
|
deps_public += libarchive
|
||||||
|
if get_option('default_library') == 'static'
|
||||||
|
# Workaround until https://github.com/libarchive/libarchive/issues/1446 is fixed
|
||||||
|
add_project_arguments('-lz', language : 'cpp')
|
||||||
|
endif
|
||||||
|
|
||||||
|
sodium = dependency('libsodium', 'sodium')
|
||||||
|
deps_private += sodium
|
||||||
|
|
||||||
|
brotli = [
|
||||||
|
dependency('libbrotlicommon'),
|
||||||
|
dependency('libbrotlidec'),
|
||||||
|
dependency('libbrotlienc'),
|
||||||
|
]
|
||||||
|
deps_private += brotli
|
||||||
|
|
||||||
|
cpuid_required = get_option('cpuid')
|
||||||
|
if host_machine.cpu_family() != 'x86_64' and cpuid_required.enabled()
|
||||||
|
warning('Force-enabling seccomp on non-x86_64 does not make sense')
|
||||||
|
endif
|
||||||
|
cpuid = dependency('libcpuid', 'cpuid', required : cpuid_required)
|
||||||
|
configdata.set('HAVE_LIBCPUID', cpuid.found().to_int())
|
||||||
|
deps_private += cpuid
|
||||||
|
|
||||||
|
nlohmann_json = dependency('nlohmann_json', version : '>= 3.9')
|
||||||
|
deps_public += nlohmann_json
|
||||||
|
|
||||||
|
config_h = configure_file(
|
||||||
|
configuration : configdata,
|
||||||
|
output : 'config-util.h',
|
||||||
|
)
|
||||||
|
|
||||||
|
add_project_arguments(
|
||||||
|
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
|
||||||
|
# It would be nice for our headers to be idempotent instead.
|
||||||
|
'-include', 'config-util.h',
|
||||||
|
'-Wno-deprecated-declarations',
|
||||||
|
'-Wimplicit-fallthrough',
|
||||||
|
'-Werror=switch',
|
||||||
|
'-Werror=switch-enum',
|
||||||
|
'-Wdeprecated-copy',
|
||||||
|
'-Wignored-qualifiers',
|
||||||
|
# Enable assertions in libstdc++ by default. Harmless on libc++. Benchmarked
|
||||||
|
# at ~1% overhead in `nix search`.
|
||||||
|
#
|
||||||
|
# FIXME: remove when we get meson 1.4.0 which will default this to on for us:
|
||||||
|
# https://mesonbuild.com/Release-notes-for-1-4-0.html#ndebug-setting-now-controls-c-stdlib-assertions
|
||||||
|
'-D_GLIBCXX_ASSERTIONS=1',
|
||||||
|
language : 'cpp',
|
||||||
|
)
|
||||||
|
|
||||||
|
sources = files(
|
||||||
|
'archive.cc',
|
||||||
|
'args.cc',
|
||||||
|
'canon-path.cc',
|
||||||
|
'compression.cc',
|
||||||
|
'compute-levels.cc',
|
||||||
|
'config.cc',
|
||||||
|
'current-process.cc',
|
||||||
|
'english.cc',
|
||||||
|
'environment-variables.cc',
|
||||||
|
'error.cc',
|
||||||
|
'exit.cc',
|
||||||
|
'experimental-features.cc',
|
||||||
|
'file-content-address.cc',
|
||||||
|
'file-descriptor.cc',
|
||||||
|
'file-system.cc',
|
||||||
|
'fs-sink.cc',
|
||||||
|
'git.cc',
|
||||||
|
'hash.cc',
|
||||||
|
'hilite.cc',
|
||||||
|
'json-utils.cc',
|
||||||
|
'logging.cc',
|
||||||
|
'memory-source-accessor.cc',
|
||||||
|
'position.cc',
|
||||||
|
'posix-source-accessor.cc',
|
||||||
|
'references.cc',
|
||||||
|
'serialise.cc',
|
||||||
|
'signature/local-keys.cc',
|
||||||
|
'signature/signer.cc',
|
||||||
|
'source-accessor.cc',
|
||||||
|
'source-path.cc',
|
||||||
|
'suggestions.cc',
|
||||||
|
'tarfile.cc',
|
||||||
|
'terminal.cc',
|
||||||
|
'thread-pool.cc',
|
||||||
|
'unix-domain-socket.cc',
|
||||||
|
'url.cc',
|
||||||
|
'users.cc',
|
||||||
|
'util.cc',
|
||||||
|
'xml-writer.cc',
|
||||||
|
)
|
||||||
|
|
||||||
|
include_dirs = [include_directories('.')]
|
||||||
|
|
||||||
|
headers = [config_h] + files(
|
||||||
|
'abstract-setting-to-json.hh',
|
||||||
|
'ansicolor.hh',
|
||||||
|
'archive.hh',
|
||||||
|
'args.hh',
|
||||||
|
'args/root.hh',
|
||||||
|
'callback.hh',
|
||||||
|
'canon-path.hh',
|
||||||
|
'chunked-vector.hh',
|
||||||
|
'closure.hh',
|
||||||
|
'comparator.hh',
|
||||||
|
'compression.hh',
|
||||||
|
'compute-levels.hh',
|
||||||
|
'config-impl.hh',
|
||||||
|
'config.hh',
|
||||||
|
'current-process.hh',
|
||||||
|
'english.hh',
|
||||||
|
'environment-variables.hh',
|
||||||
|
'error.hh',
|
||||||
|
'exit.hh',
|
||||||
|
'experimental-features.hh',
|
||||||
|
'file-content-address.hh',
|
||||||
|
'file-descriptor.hh',
|
||||||
|
'file-path-impl.hh',
|
||||||
|
'file-path.hh',
|
||||||
|
'file-system.hh',
|
||||||
|
'finally.hh',
|
||||||
|
'fmt.hh',
|
||||||
|
'fs-sink.hh',
|
||||||
|
'git.hh',
|
||||||
|
'hash.hh',
|
||||||
|
'hilite.hh',
|
||||||
|
'json-impls.hh',
|
||||||
|
'json-utils.hh',
|
||||||
|
'logging.hh',
|
||||||
|
'lru-cache.hh',
|
||||||
|
'memory-source-accessor.hh',
|
||||||
|
'muxable-pipe.hh',
|
||||||
|
'pool.hh',
|
||||||
|
'position.hh',
|
||||||
|
'posix-source-accessor.hh',
|
||||||
|
'processes.hh',
|
||||||
|
'ref.hh',
|
||||||
|
'references.hh',
|
||||||
|
'regex-combinators.hh',
|
||||||
|
'repair-flag.hh',
|
||||||
|
'serialise.hh',
|
||||||
|
'signals.hh',
|
||||||
|
'signature/local-keys.hh',
|
||||||
|
'signature/signer.hh',
|
||||||
|
'source-accessor.hh',
|
||||||
|
'source-path.hh',
|
||||||
|
'split.hh',
|
||||||
|
'suggestions.hh',
|
||||||
|
'sync.hh',
|
||||||
|
'tarfile.hh',
|
||||||
|
'terminal.hh',
|
||||||
|
'thread-pool.hh',
|
||||||
|
'topo-sort.hh',
|
||||||
|
'types.hh',
|
||||||
|
'unix-domain-socket.hh',
|
||||||
|
'url-parts.hh',
|
||||||
|
'url.hh',
|
||||||
|
'users.hh',
|
||||||
|
'util.hh',
|
||||||
|
'variant-wrapper.hh',
|
||||||
|
'xml-writer.hh',
|
||||||
|
)
|
||||||
|
|
||||||
|
if host_machine.system() == 'linux'
|
||||||
|
subdir('linux')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if host_machine.system() == 'windows'
|
||||||
|
subdir('windows')
|
||||||
|
else
|
||||||
|
subdir('unix')
|
||||||
|
endif
|
||||||
|
|
||||||
|
if host_machine.system() == 'cygwin' or host_machine.system() == 'windows'
|
||||||
|
# Windows DLLs are stricter about symbol visibility than Unix shared
|
||||||
|
# objects --- see https://gcc.gnu.org/wiki/Visibility for details.
|
||||||
|
# This is a temporary sledgehammer to export everything like on Unix,
|
||||||
|
# and not detail with this yet.
|
||||||
|
#
|
||||||
|
# TODO do not do this, and instead do fine-grained export annotations.
|
||||||
|
linker_export_flags = ['-Wl,--export-all-symbols']
|
||||||
|
else
|
||||||
|
linker_export_flags = []
|
||||||
|
endif
|
||||||
|
|
||||||
|
this_library = library(
|
||||||
|
'nixutil',
|
||||||
|
sources,
|
||||||
|
dependencies : deps_public + deps_private + deps_other,
|
||||||
|
include_directories : include_dirs,
|
||||||
|
link_args: linker_export_flags,
|
||||||
|
install : true,
|
||||||
|
)
|
||||||
|
|
||||||
|
install_headers(headers, subdir : 'nix', preserve_path : true)
|
||||||
|
|
||||||
|
# Part of how we copy boost libraries to a separate installation to
|
||||||
|
# reduce closure size. These libraries will be copied to our `$out/bin`,
|
||||||
|
# and these `-l` flags will pick them up there.
|
||||||
|
#
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/45462
|
||||||
|
libraries_private = ['-lboost_context', '-lboost_coroutine']
|
||||||
|
if host_machine.system() == 'windows'
|
||||||
|
# `libraries_private` cannot contain ad-hoc dependencies (from
|
||||||
|
# `find_library), so we need to do this manually
|
||||||
|
libraries_private += ['-lws2_32']
|
||||||
|
endif
|
||||||
|
|
||||||
|
import('pkgconfig').generate(
|
||||||
|
this_library,
|
||||||
|
filebase : meson.project_name(),
|
||||||
|
name : 'Nix',
|
||||||
|
description : 'Nix Package Manager',
|
||||||
|
subdirs : ['nix'],
|
||||||
|
extra_cflags : ['-std=c++2a'],
|
||||||
|
requires : deps_public,
|
||||||
|
requires_private : deps_private,
|
||||||
|
libraries_private : libraries_private,
|
||||||
|
)
|
||||||
|
|
||||||
|
meson.override_dependency(meson.project_name(), declare_dependency(
|
||||||
|
include_directories : include_dirs,
|
||||||
|
link_with : this_library,
|
||||||
|
compile_args : ['-std=c++2a'],
|
||||||
|
dependencies : [],
|
||||||
|
))
|
5
src/libutil/meson.options
Normal file
5
src/libutil/meson.options
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# vim: filetype=meson
|
||||||
|
|
||||||
|
option('cpuid', type : 'feature',
|
||||||
|
description : 'determine microarchitecture levels with libcpuid (only relevant on x86_64)',
|
||||||
|
)
|
149
src/libutil/package.nix
Normal file
149
src/libutil/package.nix
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
{ lib
|
||||||
|
, stdenv
|
||||||
|
, releaseTools
|
||||||
|
, fileset
|
||||||
|
|
||||||
|
, meson
|
||||||
|
, ninja
|
||||||
|
, pkg-config
|
||||||
|
|
||||||
|
, boost
|
||||||
|
, brotli
|
||||||
|
, libarchive
|
||||||
|
, libcpuid
|
||||||
|
, libsodium
|
||||||
|
, nlohmann_json
|
||||||
|
, openssl
|
||||||
|
|
||||||
|
# Configuration Options
|
||||||
|
|
||||||
|
, versionSuffix ? ""
|
||||||
|
, officialRelease ? false
|
||||||
|
|
||||||
|
# Check test coverage of Nix. Probably want to use with at least
|
||||||
|
# one of `doCheck` or `doInstallCheck` enabled.
|
||||||
|
, withCoverageChecks ? false
|
||||||
|
}:
|
||||||
|
|
||||||
|
let
|
||||||
|
version = lib.fileContents ./.version + versionSuffix;
|
||||||
|
|
||||||
|
mkDerivation =
|
||||||
|
if withCoverageChecks
|
||||||
|
then
|
||||||
|
# TODO support `finalAttrs` args function in
|
||||||
|
# `releaseTools.coverageAnalysis`.
|
||||||
|
argsFun:
|
||||||
|
releaseTools.coverageAnalysis (let args = argsFun args; in args)
|
||||||
|
else stdenv.mkDerivation;
|
||||||
|
in
|
||||||
|
|
||||||
|
mkDerivation (finalAttrs: {
|
||||||
|
pname = "nix-util";
|
||||||
|
inherit version;
|
||||||
|
|
||||||
|
src = fileset.toSource {
|
||||||
|
root = ./.;
|
||||||
|
fileset = fileset.unions [
|
||||||
|
./meson.build
|
||||||
|
./meson.options
|
||||||
|
./linux/meson.build
|
||||||
|
./unix/meson.build
|
||||||
|
./windows/meson.build
|
||||||
|
(fileset.fileFilter (file: file.hasExt "cc") ./.)
|
||||||
|
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = [ "out" "dev" ];
|
||||||
|
|
||||||
|
nativeBuildInputs = [
|
||||||
|
meson
|
||||||
|
ninja
|
||||||
|
pkg-config
|
||||||
|
];
|
||||||
|
|
||||||
|
buildInputs = [
|
||||||
|
boost
|
||||||
|
brotli
|
||||||
|
libsodium
|
||||||
|
openssl
|
||||||
|
] ++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
|
||||||
|
;
|
||||||
|
|
||||||
|
propagatedBuildInputs = [
|
||||||
|
libarchive
|
||||||
|
nlohmann_json
|
||||||
|
];
|
||||||
|
|
||||||
|
disallowedReferences = [ boost ];
|
||||||
|
|
||||||
|
preConfigure =
|
||||||
|
# "Inline" .version so it's not a symlink, and includes the suffix
|
||||||
|
''
|
||||||
|
echo ${version} > .version
|
||||||
|
''
|
||||||
|
# Copy some boost libraries so we don't get all of Boost in our
|
||||||
|
# closure. https://github.com/NixOS/nixpkgs/issues/45462
|
||||||
|
+ lib.optionalString (!stdenv.hostPlatform.isStatic) (''
|
||||||
|
mkdir -p $out/lib
|
||||||
|
cp -pd ${boost}/lib/{libboost_context*,libboost_thread*,libboost_system*} $out/lib
|
||||||
|
rm -f $out/lib/*.a
|
||||||
|
'' + lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||||
|
chmod u+w $out/lib/*.so.*
|
||||||
|
patchelf --set-rpath $out/lib:${stdenv.cc.cc.lib}/lib $out/lib/libboost_thread.so.*
|
||||||
|
'' + lib.optionalString stdenv.hostPlatform.isDarwin ''
|
||||||
|
for LIB in $out/lib/*.dylib; do
|
||||||
|
chmod u+w $LIB
|
||||||
|
install_name_tool -id $LIB $LIB
|
||||||
|
install_name_tool -delete_rpath ${boost}/lib/ $LIB || true
|
||||||
|
done
|
||||||
|
install_name_tool -change ${boost}/lib/libboost_system.dylib $out/lib/libboost_system.dylib $out/lib/libboost_thread.dylib
|
||||||
|
''
|
||||||
|
);
|
||||||
|
|
||||||
|
mesonFlags = [
|
||||||
|
(lib.mesonEnable "cpuid" stdenv.hostPlatform.isx86_64)
|
||||||
|
];
|
||||||
|
|
||||||
|
env = {
|
||||||
|
# Needed for Meson to find Boost.
|
||||||
|
# https://github.com/NixOS/nixpkgs/issues/86131.
|
||||||
|
BOOST_INCLUDEDIR = "${lib.getDev boost}/include";
|
||||||
|
BOOST_LIBRARYDIR = "${lib.getLib boost}/lib";
|
||||||
|
} // lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
|
||||||
|
LDFLAGS = "-fuse-ld=gold";
|
||||||
|
};
|
||||||
|
|
||||||
|
enableParallelBuilding = true;
|
||||||
|
|
||||||
|
postInstall =
|
||||||
|
# Remove absolute path to boost libs that ends up in `Libs.private`
|
||||||
|
# by default, and would clash with out `disallowedReferences`. Part
|
||||||
|
# of the https://github.com/NixOS/nixpkgs/issues/45462 workaround.
|
||||||
|
''
|
||||||
|
sed -i "$out/lib/pkgconfig/nix-util.pc" -e 's, ${lib.getLib boost}[^ ]*,,g'
|
||||||
|
''
|
||||||
|
+ lib.optionalString stdenv.isDarwin ''
|
||||||
|
install_name_tool \
|
||||||
|
-change ${boost}/lib/libboost_context.dylib \
|
||||||
|
$out/lib/libboost_context.dylib \
|
||||||
|
$out/lib/libnixutil.dylib
|
||||||
|
'';
|
||||||
|
|
||||||
|
separateDebugInfo = !stdenv.hostPlatform.isStatic;
|
||||||
|
|
||||||
|
# TODO Always true after https://github.com/NixOS/nixpkgs/issues/318564
|
||||||
|
strictDeps = !withCoverageChecks;
|
||||||
|
|
||||||
|
hardeningDisable = lib.optional stdenv.hostPlatform.isStatic "pie";
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
platforms = lib.platforms.unix ++ lib.platforms.windows;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // lib.optionalAttrs withCoverageChecks {
|
||||||
|
lcovFilter = [ "*/boost/*" "*-tab.*" ];
|
||||||
|
|
||||||
|
hardeningDisable = [ "fortify" ];
|
||||||
|
})
|
@ -79,7 +79,8 @@ TarArchive::TarArchive(Source & source, bool raw, std::optional<std::string> com
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!raw) {
|
if (!raw) {
|
||||||
archive_read_support_format_all(archive);
|
archive_read_support_format_tar(archive);
|
||||||
|
archive_read_support_format_zip(archive);
|
||||||
} else {
|
} else {
|
||||||
archive_read_support_format_raw(archive);
|
archive_read_support_format_raw(archive);
|
||||||
archive_read_support_format_empty(archive);
|
archive_read_support_format_empty(archive);
|
||||||
@ -96,7 +97,8 @@ TarArchive::TarArchive(const Path & path)
|
|||||||
, buffer(defaultBufferSize)
|
, buffer(defaultBufferSize)
|
||||||
{
|
{
|
||||||
archive_read_support_filter_all(archive);
|
archive_read_support_filter_all(archive);
|
||||||
archive_read_support_format_all(archive);
|
archive_read_support_format_tar(archive);
|
||||||
|
archive_read_support_format_zip(archive);
|
||||||
archive_read_set_option(archive, NULL, "mac-ext", NULL);
|
archive_read_set_option(archive, NULL, "mac-ext", NULL);
|
||||||
check(archive_read_open_filename(archive, path.c_str(), 16384), "failed to open archive: %s");
|
check(archive_read_open_filename(archive, path.c_str(), 16384), "failed to open archive: %s");
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ AutoCloseFD createUnixDomainSocket()
|
|||||||
if (!fdSocket)
|
if (!fdSocket)
|
||||||
throw SysError("cannot create Unix domain socket");
|
throw SysError("cannot create Unix domain socket");
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
closeOnExec(fdSocket.get());
|
unix::closeOnExec(fdSocket.get());
|
||||||
#endif
|
#endif
|
||||||
return fdSocket;
|
return fdSocket;
|
||||||
}
|
}
|
||||||
|
@ -110,8 +110,8 @@ void Pipe::create()
|
|||||||
if (pipe2(fds, O_CLOEXEC) != 0) throw SysError("creating pipe");
|
if (pipe2(fds, O_CLOEXEC) != 0) throw SysError("creating pipe");
|
||||||
#else
|
#else
|
||||||
if (pipe(fds) != 0) throw SysError("creating pipe");
|
if (pipe(fds) != 0) throw SysError("creating pipe");
|
||||||
closeOnExec(fds[0]);
|
unix::closeOnExec(fds[0]);
|
||||||
closeOnExec(fds[1]);
|
unix::closeOnExec(fds[1]);
|
||||||
#endif
|
#endif
|
||||||
readSide = fds[0];
|
readSide = fds[0];
|
||||||
writeSide = fds[1];
|
writeSide = fds[1];
|
||||||
@ -120,7 +120,7 @@ void Pipe::create()
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void closeMostFDs(const std::set<int> & exceptions)
|
void unix::closeMostFDs(const std::set<int> & exceptions)
|
||||||
{
|
{
|
||||||
#if __linux__
|
#if __linux__
|
||||||
try {
|
try {
|
||||||
@ -139,14 +139,16 @@ void closeMostFDs(const std::set<int> & exceptions)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
int maxFD = 0;
|
int maxFD = 0;
|
||||||
|
#if HAVE_SYSCONF
|
||||||
maxFD = sysconf(_SC_OPEN_MAX);
|
maxFD = sysconf(_SC_OPEN_MAX);
|
||||||
|
#endif
|
||||||
for (int fd = 0; fd < maxFD; ++fd)
|
for (int fd = 0; fd < maxFD; ++fd)
|
||||||
if (!exceptions.count(fd))
|
if (!exceptions.count(fd))
|
||||||
close(fd); /* ignore result */
|
close(fd); /* ignore result */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void closeOnExec(int fd)
|
void unix::closeOnExec(int fd)
|
||||||
{
|
{
|
||||||
int prev;
|
int prev;
|
||||||
if ((prev = fcntl(fd, F_GETFD, 0)) == -1 ||
|
if ((prev = fcntl(fd, F_GETFD, 0)) == -1 ||
|
||||||
|
17
src/libutil/unix/meson.build
Normal file
17
src/libutil/unix/meson.build
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
sources += files(
|
||||||
|
'environment-variables.cc',
|
||||||
|
'file-descriptor.cc',
|
||||||
|
'file-path.cc',
|
||||||
|
'file-system.cc',
|
||||||
|
'muxable-pipe.cc',
|
||||||
|
'processes.cc',
|
||||||
|
'signals.cc',
|
||||||
|
'users.cc',
|
||||||
|
)
|
||||||
|
|
||||||
|
include_dirs += include_directories('.')
|
||||||
|
|
||||||
|
headers += files(
|
||||||
|
'monitor-fd.hh',
|
||||||
|
'signals-impl.hh',
|
||||||
|
)
|
@ -122,7 +122,7 @@ void Pipe::create()
|
|||||||
|
|
||||||
#if _WIN32_WINNT >= 0x0600
|
#if _WIN32_WINNT >= 0x0600
|
||||||
|
|
||||||
std::wstring handleToFileName(HANDLE handle) {
|
std::wstring windows::handleToFileName(HANDLE handle) {
|
||||||
std::vector<wchar_t> buf(0x100);
|
std::vector<wchar_t> buf(0x100);
|
||||||
DWORD dw = GetFinalPathNameByHandleW(handle, buf.data(), buf.size(), FILE_NAME_OPENED);
|
DWORD dw = GetFinalPathNameByHandleW(handle, buf.data(), buf.size(), FILE_NAME_OPENED);
|
||||||
if (dw == 0) {
|
if (dw == 0) {
|
||||||
@ -141,7 +141,7 @@ std::wstring handleToFileName(HANDLE handle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Path handleToPath(HANDLE handle) {
|
Path windows::handleToPath(HANDLE handle) {
|
||||||
return os_string_to_string(handleToFileName(handle));
|
return os_string_to_string(handleToFileName(handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
19
src/libutil/windows/meson.build
Normal file
19
src/libutil/windows/meson.build
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
sources += files(
|
||||||
|
'environment-variables.cc',
|
||||||
|
'file-descriptor.cc',
|
||||||
|
'file-path.cc',
|
||||||
|
'file-system.cc',
|
||||||
|
'muxable-pipe.cc',
|
||||||
|
'processes.cc',
|
||||||
|
'users.cc',
|
||||||
|
'windows-async-pipe.cc',
|
||||||
|
'windows-error.cc',
|
||||||
|
)
|
||||||
|
|
||||||
|
include_dirs += include_directories('.')
|
||||||
|
|
||||||
|
headers += files(
|
||||||
|
'signals-impl.hh',
|
||||||
|
'windows-async-pipe.hh',
|
||||||
|
'windows-error.hh',
|
||||||
|
)
|
@ -295,7 +295,7 @@ static void daemonLoop(std::optional<TrustedFlag> forceTrustClientOpt)
|
|||||||
if (getEnv("LISTEN_PID") != std::to_string(getpid()) || listenFds != "1")
|
if (getEnv("LISTEN_PID") != std::to_string(getpid()) || listenFds != "1")
|
||||||
throw Error("unexpected systemd environment variables");
|
throw Error("unexpected systemd environment variables");
|
||||||
fdSocket = SD_LISTEN_FDS_START;
|
fdSocket = SD_LISTEN_FDS_START;
|
||||||
closeOnExec(fdSocket.get());
|
unix::closeOnExec(fdSocket.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, create and bind to a Unix domain socket.
|
// Otherwise, create and bind to a Unix domain socket.
|
||||||
@ -323,7 +323,7 @@ static void daemonLoop(std::optional<TrustedFlag> forceTrustClientOpt)
|
|||||||
throw SysError("accepting connection");
|
throw SysError("accepting connection");
|
||||||
}
|
}
|
||||||
|
|
||||||
closeOnExec(remote.get());
|
unix::closeOnExec(remote.get());
|
||||||
|
|
||||||
PeerInfo peer { .pidKnown = false };
|
PeerInfo peer { .pidKnown = false };
|
||||||
TrustedFlag trusted;
|
TrustedFlag trusted;
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
sed -e "s|@localstatedir@|$TEST_ROOT/profile-var|g" -e "s|@coreutils@|$coreutils|g" < ../../scripts/nix-profile.sh.in > $TEST_ROOT/nix-profile.sh
|
sed -e "s|@localstatedir@|$TEST_ROOT/profile-var|g" -e "s|@coreutils@|$coreutils|g" < ../../scripts/nix-profile.sh.in > "$TEST_ROOT"/nix-profile.sh
|
||||||
|
|
||||||
user=$(whoami)
|
user=$(whoami)
|
||||||
rm -rf $TEST_HOME $TEST_ROOT/profile-var
|
rm -rf "$TEST_HOME" "$TEST_ROOT/profile-var"
|
||||||
mkdir -p $TEST_HOME
|
mkdir -p "$TEST_HOME"
|
||||||
USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh; set"
|
USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh; set"
|
||||||
USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh" # test idempotency
|
USER=$user $SHELL -e -c ". $TEST_ROOT/nix-profile.sh" # test idempotency
|
||||||
|
@ -12,7 +12,7 @@ clearCacheCache
|
|||||||
outPath=$(nix-build --store "file://$cacheDir" --builders 'auto - - 1 1' -j0 dependencies.nix)
|
outPath=$(nix-build --store "file://$cacheDir" --builders 'auto - - 1 1' -j0 dependencies.nix)
|
||||||
|
|
||||||
# Test that the path exactly exists in the destination store.
|
# Test that the path exactly exists in the destination store.
|
||||||
nix path-info --store "file://$cacheDir" $outPath
|
nix path-info --store "file://$cacheDir" "$outPath"
|
||||||
|
|
||||||
# Succeeds without any build capability because no-op
|
# Succeeds without any build capability because no-op
|
||||||
nix-build --store "file://$cacheDir" -j0 dependencies.nix
|
nix-build --store "file://$cacheDir" -j0 dependencies.nix
|
||||||
|
@ -14,9 +14,9 @@ clearStore
|
|||||||
clearCache
|
clearCache
|
||||||
outPath=$(nix-build dependencies.nix --no-out-link)
|
outPath=$(nix-build dependencies.nix --no-out-link)
|
||||||
|
|
||||||
nix copy --to file://$cacheDir $outPath
|
nix copy --to "file://$cacheDir" "$outPath"
|
||||||
|
|
||||||
readarray -t paths < <(nix path-info --all --json --store file://$cacheDir | jq 'keys|sort|.[]' -r)
|
readarray -t paths < <(nix path-info --all --json --store "file://$cacheDir" | jq 'keys|sort|.[]' -r)
|
||||||
[[ "${#paths[@]}" -eq 3 ]]
|
[[ "${#paths[@]}" -eq 3 ]]
|
||||||
for path in "${paths[@]}"; do
|
for path in "${paths[@]}"; do
|
||||||
[[ "$path" =~ -dependencies-input-0$ ]] \
|
[[ "$path" =~ -dependencies-input-0$ ]] \
|
||||||
@ -25,16 +25,16 @@ for path in "${paths[@]}"; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
# Test copying build logs to the binary cache.
|
# Test copying build logs to the binary cache.
|
||||||
expect 1 nix log --store file://$cacheDir $outPath 2>&1 | grep 'is not available'
|
expect 1 nix log --store "file://$cacheDir" "$outPath" 2>&1 | grep 'is not available'
|
||||||
nix store copy-log --to file://$cacheDir $outPath
|
nix store copy-log --to "file://$cacheDir" "$outPath"
|
||||||
nix log --store file://$cacheDir $outPath | grep FOO
|
nix log --store "file://$cacheDir" "$outPath" | grep FOO
|
||||||
rm -rf $TEST_ROOT/var/log/nix
|
rm -rf "$TEST_ROOT/var/log/nix"
|
||||||
expect 1 nix log $outPath 2>&1 | grep 'is not available'
|
expect 1 nix log "$outPath" 2>&1 | grep 'is not available'
|
||||||
nix log --substituters file://$cacheDir $outPath | grep FOO
|
nix log --substituters "file://$cacheDir" "$outPath" | grep FOO
|
||||||
|
|
||||||
# Test copying build logs from the binary cache.
|
# Test copying build logs from the binary cache.
|
||||||
nix store copy-log --from file://$cacheDir $(nix-store -qd $outPath)^'*'
|
nix store copy-log --from "file://$cacheDir" "$(nix-store -qd "$outPath")"^'*'
|
||||||
nix log $outPath | grep FOO
|
nix log "$outPath" | grep FOO
|
||||||
|
|
||||||
basicDownloadTests() {
|
basicDownloadTests() {
|
||||||
# No uploading tests bcause upload with force HTTP doesn't work.
|
# No uploading tests bcause upload with force HTTP doesn't work.
|
||||||
@ -46,15 +46,15 @@ basicDownloadTests() {
|
|||||||
|
|
||||||
nix-env --substituters "file://$cacheDir" -f dependencies.nix -qas \* | grep -- "---"
|
nix-env --substituters "file://$cacheDir" -f dependencies.nix -qas \* | grep -- "---"
|
||||||
|
|
||||||
nix-store --substituters "file://$cacheDir" --no-require-sigs -r $outPath
|
nix-store --substituters "file://$cacheDir" --no-require-sigs -r "$outPath"
|
||||||
|
|
||||||
[ -x $outPath/program ]
|
[ -x "$outPath/program" ]
|
||||||
|
|
||||||
|
|
||||||
# But with the right configuration, "nix-env -qas" should also work.
|
# But with the right configuration, "nix-env -qas" should also work.
|
||||||
clearStore
|
clearStore
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
echo "WantMassQuery: 1" >> $cacheDir/nix-cache-info
|
echo "WantMassQuery: 1" >> "$cacheDir/nix-cache-info"
|
||||||
|
|
||||||
nix-env --substituters "file://$cacheDir" -f dependencies.nix -qas \* | grep -- "--S"
|
nix-env --substituters "file://$cacheDir" -f dependencies.nix -qas \* | grep -- "--S"
|
||||||
nix-env --substituters "file://$cacheDir" -f dependencies.nix -qas \* | grep -- "--S"
|
nix-env --substituters "file://$cacheDir" -f dependencies.nix -qas \* | grep -- "--S"
|
||||||
@ -62,12 +62,12 @@ basicDownloadTests() {
|
|||||||
x=$(nix-env -f dependencies.nix -qas \* --prebuilt-only)
|
x=$(nix-env -f dependencies.nix -qas \* --prebuilt-only)
|
||||||
[ -z "$x" ]
|
[ -z "$x" ]
|
||||||
|
|
||||||
nix-store --substituters "file://$cacheDir" --no-require-sigs -r $outPath
|
nix-store --substituters "file://$cacheDir" --no-require-sigs -r "$outPath"
|
||||||
|
|
||||||
nix-store --check-validity $outPath
|
nix-store --check-validity "$outPath"
|
||||||
nix-store -qR $outPath | grep input-2
|
nix-store -qR "$outPath" | grep input-2
|
||||||
|
|
||||||
echo "WantMassQuery: 0" >> $cacheDir/nix-cache-info
|
echo "WantMassQuery: 0" >> "$cacheDir/nix-cache-info"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -83,22 +83,22 @@ basicDownloadTests
|
|||||||
# Test whether Nix notices if the NAR doesn't match the hash in the NAR info.
|
# Test whether Nix notices if the NAR doesn't match the hash in the NAR info.
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
nar=$(ls $cacheDir/nar/*.nar.xz | head -n1)
|
nar=$(find "$cacheDir/nar/" -type f -name "*.nar.xz" | head -n1)
|
||||||
mv $nar $nar.good
|
mv "$nar" "$nar".good
|
||||||
mkdir -p $TEST_ROOT/empty
|
mkdir -p "$TEST_ROOT/empty"
|
||||||
nix-store --dump $TEST_ROOT/empty | xz > $nar
|
nix-store --dump "$TEST_ROOT/empty" | xz > "$nar"
|
||||||
|
|
||||||
expect 1 nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result 2>&1 | tee $TEST_ROOT/log
|
expect 1 nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result" 2>&1 | tee "$TEST_ROOT/log"
|
||||||
grepQuiet "hash mismatch" $TEST_ROOT/log
|
grepQuiet "hash mismatch" "$TEST_ROOT/log"
|
||||||
|
|
||||||
mv $nar.good $nar
|
mv "$nar".good "$nar"
|
||||||
|
|
||||||
|
|
||||||
# Test whether this unsigned cache is rejected if the user requires signed caches.
|
# Test whether this unsigned cache is rejected if the user requires signed caches.
|
||||||
clearStore
|
clearStore
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
|
|
||||||
if nix-store --substituters "file://$cacheDir" -r $outPath; then
|
if nix-store --substituters "file://$cacheDir" -r "$outPath"; then
|
||||||
echo "unsigned binary cache incorrectly accepted"
|
echo "unsigned binary cache incorrectly accepted"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
@ -107,131 +107,134 @@ fi
|
|||||||
# Test whether fallback works if a NAR has disappeared. This does not require --fallback.
|
# Test whether fallback works if a NAR has disappeared. This does not require --fallback.
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
mv $cacheDir/nar $cacheDir/nar2
|
mv "$cacheDir/nar" "$cacheDir/nar2"
|
||||||
|
|
||||||
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result
|
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result"
|
||||||
|
|
||||||
mv $cacheDir/nar2 $cacheDir/nar
|
mv "$cacheDir/nar2" "$cacheDir/nar"
|
||||||
|
|
||||||
|
|
||||||
# Test whether fallback works if a NAR is corrupted. This does require --fallback.
|
# Test whether fallback works if a NAR is corrupted. This does require --fallback.
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
mv $cacheDir/nar $cacheDir/nar2
|
mv "$cacheDir/nar" "$cacheDir/nar2"
|
||||||
mkdir $cacheDir/nar
|
mkdir "$cacheDir/nar"
|
||||||
for i in $(cd $cacheDir/nar2 && echo *); do touch $cacheDir/nar/$i; done
|
for i in $(cd "$cacheDir/nar2" && echo *); do touch "$cacheDir"/nar/"$i"; done
|
||||||
|
|
||||||
(! nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result)
|
(! nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result")
|
||||||
|
|
||||||
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result --fallback
|
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result" --fallback
|
||||||
|
|
||||||
rm -rf $cacheDir/nar
|
rm -rf "$cacheDir/nar"
|
||||||
mv $cacheDir/nar2 $cacheDir/nar
|
mv "$cacheDir/nar2" "$cacheDir/nar"
|
||||||
|
|
||||||
|
|
||||||
# Test whether building works if the binary cache contains an
|
# Test whether building works if the binary cache contains an
|
||||||
# incomplete closure.
|
# incomplete closure.
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
rm -v $(grep -l "StorePath:.*dependencies-input-2" $cacheDir/*.narinfo)
|
rm -v "$(grep -l "StorePath:.*dependencies-input-2" "$cacheDir"/*.narinfo)"
|
||||||
|
|
||||||
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result 2>&1 | tee $TEST_ROOT/log
|
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result" 2>&1 | tee "$TEST_ROOT/log"
|
||||||
grepQuiet "copying path.*input-0" $TEST_ROOT/log
|
grepQuiet "copying path.*input-0" "$TEST_ROOT/log"
|
||||||
grepQuiet "copying path.*input-2" $TEST_ROOT/log
|
grepQuiet "copying path.*input-2" "$TEST_ROOT/log"
|
||||||
grepQuiet "copying path.*top" $TEST_ROOT/log
|
grepQuiet "copying path.*top" "$TEST_ROOT/log"
|
||||||
|
|
||||||
|
|
||||||
# Idem, but without cached .narinfo.
|
# Idem, but without cached .narinfo.
|
||||||
clearStore
|
clearStore
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
|
|
||||||
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o $TEST_ROOT/result 2>&1 | tee $TEST_ROOT/log
|
nix-build --substituters "file://$cacheDir" --no-require-sigs dependencies.nix -o "$TEST_ROOT/result" 2>&1 | tee "$TEST_ROOT/log"
|
||||||
grepQuiet "don't know how to build" $TEST_ROOT/log
|
grepQuiet "don't know how to build" "$TEST_ROOT/log"
|
||||||
grepQuiet "building.*input-1" $TEST_ROOT/log
|
grepQuiet "building.*input-1" "$TEST_ROOT/log"
|
||||||
grepQuiet "building.*input-2" $TEST_ROOT/log
|
grepQuiet "building.*input-2" "$TEST_ROOT/log"
|
||||||
grepQuiet "copying path.*input-0" $TEST_ROOT/log
|
grepQuiet "copying path.*input-0" "$TEST_ROOT/log"
|
||||||
grepQuiet "copying path.*top" $TEST_ROOT/log
|
grepQuiet "copying path.*top" "$TEST_ROOT/log"
|
||||||
|
|
||||||
|
|
||||||
# Create a signed binary cache.
|
# Create a signed binary cache.
|
||||||
clearCache
|
clearCache
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
|
|
||||||
nix key generate-secret --key-name test.nixos.org-1 > $TEST_ROOT/sk1
|
nix key generate-secret --key-name test.nixos.org-1 > "$TEST_ROOT/sk1"
|
||||||
publicKey=$(nix key convert-secret-to-public < $TEST_ROOT/sk1)
|
publicKey=$(nix key convert-secret-to-public < "$TEST_ROOT/sk1")
|
||||||
|
|
||||||
nix key generate-secret --key-name test.nixos.org-1 > $TEST_ROOT/sk2
|
nix key generate-secret --key-name test.nixos.org-1 > "$TEST_ROOT/sk2"
|
||||||
badKey=$(nix key convert-secret-to-public < $TEST_ROOT/sk2)
|
badKey=$(nix key convert-secret-to-public < "$TEST_ROOT/sk2")
|
||||||
|
|
||||||
nix key generate-secret --key-name foo.nixos.org-1 > $TEST_ROOT/sk3
|
nix key generate-secret --key-name foo.nixos.org-1 > "$TEST_ROOT/sk3"
|
||||||
otherKey=$(nix key convert-secret-to-public < $TEST_ROOT/sk3)
|
otherKey=$(nix key convert-secret-to-public < "$TEST_ROOT/sk3")
|
||||||
|
|
||||||
_NIX_FORCE_HTTP= nix copy --to file://$cacheDir?secret-key=$TEST_ROOT/sk1 $outPath
|
_NIX_FORCE_HTTP='' nix copy --to "file://$cacheDir"?secret-key="$TEST_ROOT"/sk1 "$outPath"
|
||||||
|
|
||||||
|
|
||||||
# Downloading should fail if we don't provide a key.
|
# Downloading should fail if we don't provide a key.
|
||||||
clearStore
|
clearStore
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
|
|
||||||
(! nix-store -r $outPath --substituters "file://$cacheDir")
|
(! nix-store -r "$outPath" --substituters "file://$cacheDir")
|
||||||
|
|
||||||
|
|
||||||
# And it should fail if we provide an incorrect key.
|
# And it should fail if we provide an incorrect key.
|
||||||
clearStore
|
clearStore
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
|
|
||||||
(! nix-store -r $outPath --substituters "file://$cacheDir" --trusted-public-keys "$badKey")
|
(! nix-store -r "$outPath" --substituters "file://$cacheDir" --trusted-public-keys "$badKey")
|
||||||
|
|
||||||
|
|
||||||
# It should succeed if we provide the correct key.
|
# It should succeed if we provide the correct key.
|
||||||
nix-store -r $outPath --substituters "file://$cacheDir" --trusted-public-keys "$otherKey $publicKey"
|
nix-store -r "$outPath" --substituters "file://$cacheDir" --trusted-public-keys "$otherKey $publicKey"
|
||||||
|
|
||||||
|
|
||||||
# It should fail if we corrupt the .narinfo.
|
# It should fail if we corrupt the .narinfo.
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
cacheDir2=$TEST_ROOT/binary-cache-2
|
cacheDir2=$TEST_ROOT/binary-cache-2
|
||||||
rm -rf $cacheDir2
|
rm -rf "$cacheDir2"
|
||||||
cp -r $cacheDir $cacheDir2
|
cp -r "$cacheDir" "$cacheDir2"
|
||||||
|
|
||||||
for i in $cacheDir2/*.narinfo; do
|
for i in "$cacheDir2"/*.narinfo; do
|
||||||
grep -v References $i > $i.tmp
|
grep -v References "$i" > "$i".tmp
|
||||||
mv $i.tmp $i
|
mv "$i".tmp "$i"
|
||||||
done
|
done
|
||||||
|
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
|
|
||||||
(! nix-store -r $outPath --substituters "file://$cacheDir2" --trusted-public-keys "$publicKey")
|
(! nix-store -r "$outPath" --substituters "file://$cacheDir2" --trusted-public-keys "$publicKey")
|
||||||
|
|
||||||
# If we provide a bad and a good binary cache, it should succeed.
|
# If we provide a bad and a good binary cache, it should succeed.
|
||||||
|
|
||||||
nix-store -r $outPath --substituters "file://$cacheDir2 file://$cacheDir" --trusted-public-keys "$publicKey"
|
nix-store -r "$outPath" --substituters "file://$cacheDir2 file://$cacheDir" --trusted-public-keys "$publicKey"
|
||||||
|
|
||||||
|
|
||||||
unset _NIX_FORCE_HTTP
|
unset _NIX_FORCE_HTTP
|
||||||
|
|
||||||
|
|
||||||
# Test 'nix verify --all' on a binary cache.
|
# Test 'nix verify --all' on a binary cache.
|
||||||
nix store verify -vvvvv --all --store file://$cacheDir --no-trust
|
nix store verify -vvvvv --all --store "file://$cacheDir" --no-trust
|
||||||
|
|
||||||
|
|
||||||
# Test local NAR caching.
|
# Test local NAR caching.
|
||||||
narCache=$TEST_ROOT/nar-cache
|
narCache=$TEST_ROOT/nar-cache
|
||||||
rm -rf $narCache
|
rm -rf "$narCache"
|
||||||
mkdir $narCache
|
mkdir "$narCache"
|
||||||
|
|
||||||
[[ $(nix store cat --store "file://$cacheDir?local-nar-cache=$narCache" $outPath/foobar) = FOOBAR ]]
|
[[ $(nix store cat --store "file://$cacheDir?local-nar-cache=$narCache" "$outPath/foobar") = FOOBAR ]]
|
||||||
|
|
||||||
rm -rfv "$cacheDir/nar"
|
rm -rfv "$cacheDir/nar"
|
||||||
|
|
||||||
[[ $(nix store cat --store "file://$cacheDir?local-nar-cache=$narCache" $outPath/foobar) = FOOBAR ]]
|
[[ $(nix store cat --store "file://$cacheDir?local-nar-cache=$narCache" "$outPath/foobar") = FOOBAR ]]
|
||||||
|
|
||||||
(! nix store cat --store file://$cacheDir $outPath/foobar)
|
(! nix store cat --store "file://$cacheDir" "$outPath/foobar")
|
||||||
|
|
||||||
|
|
||||||
# Test NAR listing generation.
|
# Test NAR listing generation.
|
||||||
clearCache
|
clearCache
|
||||||
|
|
||||||
|
|
||||||
|
# preserve quotes variables in the single-quoted string
|
||||||
|
# shellcheck disable=SC2016
|
||||||
outPath=$(nix-build --no-out-link -E '
|
outPath=$(nix-build --no-out-link -E '
|
||||||
with import ./config.nix;
|
with import ./config.nix;
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
@ -240,16 +243,18 @@ outPath=$(nix-build --no-out-link -E '
|
|||||||
}
|
}
|
||||||
')
|
')
|
||||||
|
|
||||||
nix copy --to file://$cacheDir?write-nar-listing=1 $outPath
|
nix copy --to "file://$cacheDir"?write-nar-listing=1 "$outPath"
|
||||||
|
|
||||||
diff -u \
|
diff -u \
|
||||||
<(jq -S < $cacheDir/$(basename $outPath | cut -c1-32).ls) \
|
<(jq -S < "$cacheDir/$(basename "$outPath" | cut -c1-32).ls") \
|
||||||
<(echo '{"version":1,"root":{"type":"directory","entries":{"bar":{"type":"regular","size":4,"narOffset":232},"link":{"type":"symlink","target":"xyzzy"}}}}' | jq -S)
|
<(echo '{"version":1,"root":{"type":"directory","entries":{"bar":{"type":"regular","size":4,"narOffset":232},"link":{"type":"symlink","target":"xyzzy"}}}}' | jq -S)
|
||||||
|
|
||||||
|
|
||||||
# Test debug info index generation.
|
# Test debug info index generation.
|
||||||
clearCache
|
clearCache
|
||||||
|
|
||||||
|
# preserve quotes variables in the single-quoted string
|
||||||
|
# shellcheck disable=SC2016
|
||||||
outPath=$(nix-build --no-out-link -E '
|
outPath=$(nix-build --no-out-link -E '
|
||||||
with import ./config.nix;
|
with import ./config.nix;
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
@ -258,14 +263,16 @@ outPath=$(nix-build --no-out-link -E '
|
|||||||
}
|
}
|
||||||
')
|
')
|
||||||
|
|
||||||
nix copy --to "file://$cacheDir?index-debug-info=1&compression=none" $outPath
|
nix copy --to "file://$cacheDir?index-debug-info=1&compression=none" "$outPath"
|
||||||
|
|
||||||
diff -u \
|
diff -u \
|
||||||
<(cat $cacheDir/debuginfo/02623eda209c26a59b1a8638ff7752f6b945c26b.debug | jq -S) \
|
<(jq -S < "$cacheDir"/debuginfo/02623eda209c26a59b1a8638ff7752f6b945c26b.debug) \
|
||||||
<(echo '{"archive":"../nar/100vxs724qr46phz8m24iswmg9p3785hsyagz0kchf6q6gf06sw6.nar","member":"lib/debug/.build-id/02/623eda209c26a59b1a8638ff7752f6b945c26b.debug"}' | jq -S)
|
<(echo '{"archive":"../nar/100vxs724qr46phz8m24iswmg9p3785hsyagz0kchf6q6gf06sw6.nar","member":"lib/debug/.build-id/02/623eda209c26a59b1a8638ff7752f6b945c26b.debug"}' | jq -S)
|
||||||
|
|
||||||
# Test against issue https://github.com/NixOS/nix/issues/3964
|
# Test against issue https://github.com/NixOS/nix/issues/3964
|
||||||
#
|
|
||||||
|
# preserve quotes variables in the single-quoted string
|
||||||
|
# shellcheck disable=SC2016
|
||||||
expr='
|
expr='
|
||||||
with import ./config.nix;
|
with import ./config.nix;
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
@ -275,22 +282,22 @@ expr='
|
|||||||
}
|
}
|
||||||
'
|
'
|
||||||
outPath=$(nix-build --no-out-link -E "$expr")
|
outPath=$(nix-build --no-out-link -E "$expr")
|
||||||
docPath=$(nix-store -q --references $outPath)
|
docPath=$(nix-store -q --references "$outPath")
|
||||||
|
|
||||||
# $ nix-store -q --tree $outPath
|
# $ nix-store -q --tree $outPath
|
||||||
# ...-multi-output
|
# ...-multi-output
|
||||||
# +---...-multi-output-doc
|
# +---...-multi-output-doc
|
||||||
|
|
||||||
nix copy --to "file://$cacheDir" $outPath
|
nix copy --to "file://$cacheDir" "$outPath"
|
||||||
|
|
||||||
hashpart() {
|
hashpart() {
|
||||||
basename "$1" | cut -c1-32
|
basename "$1" | cut -c1-32
|
||||||
}
|
}
|
||||||
|
|
||||||
# break the closure of out by removing doc
|
# break the closure of out by removing doc
|
||||||
rm $cacheDir/$(hashpart $docPath).narinfo
|
rm "$cacheDir/$(hashpart "$docPath")".narinfo
|
||||||
|
|
||||||
nix-store --delete $outPath $docPath
|
nix-store --delete "$outPath" "$docPath"
|
||||||
# -vvv is the level that logs during the loop
|
# -vvv is the level that logs during the loop
|
||||||
timeout 60 nix-build --no-out-link -E "$expr" --option substituters "file://$cacheDir" \
|
timeout 60 nix-build --no-out-link -E "$expr" --option substituters "file://$cacheDir" \
|
||||||
--option trusted-binary-caches "file://$cacheDir" --no-require-sigs
|
--option trusted-binary-caches "file://$cacheDir" --no-require-sigs
|
||||||
|
@ -9,15 +9,15 @@ cacheURI="file://$cacheDir?compression=br"
|
|||||||
|
|
||||||
outPath=$(nix-build dependencies.nix --no-out-link)
|
outPath=$(nix-build dependencies.nix --no-out-link)
|
||||||
|
|
||||||
nix copy --to $cacheURI $outPath
|
nix copy --to "$cacheURI" "$outPath"
|
||||||
|
|
||||||
HASH=$(nix hash path $outPath)
|
HASH=$(nix hash path "$outPath")
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
|
|
||||||
nix copy --from $cacheURI $outPath --no-check-sigs
|
nix copy --from "$cacheURI" "$outPath" --no-check-sigs
|
||||||
|
|
||||||
HASH2=$(nix hash path $outPath)
|
HASH2=$(nix hash path "$outPath")
|
||||||
|
|
||||||
[[ $HASH = $HASH2 ]]
|
[[ $HASH == "$HASH2" ]]
|
||||||
|
@ -6,25 +6,25 @@ clearStore
|
|||||||
|
|
||||||
# https://github.com/NixOS/nix/issues/6572
|
# https://github.com/NixOS/nix/issues/6572
|
||||||
issue_6572_independent_outputs() {
|
issue_6572_independent_outputs() {
|
||||||
nix build -f multiple-outputs.nix --json independent --no-link > $TEST_ROOT/independent.json
|
nix build -f multiple-outputs.nix --json independent --no-link > "$TEST_ROOT"/independent.json
|
||||||
|
|
||||||
# Make sure that 'nix build' can build a derivation that depends on both outputs of another derivation.
|
# Make sure that 'nix build' can build a derivation that depends on both outputs of another derivation.
|
||||||
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
|
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
|
||||||
nix-store --delete "$p" # Clean up for next test
|
nix-store --delete "$p" # Clean up for next test
|
||||||
|
|
||||||
# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
|
# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
|
||||||
nix-store --delete "$(jq -r <$TEST_ROOT/independent.json .[0].outputs.first)"
|
nix-store --delete "$(jq -r <"$TEST_ROOT"/independent.json .[0].outputs.first)"
|
||||||
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
|
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
|
||||||
cmp $p <<EOF
|
cmp "$p" <<EOF
|
||||||
first
|
first
|
||||||
second
|
second
|
||||||
EOF
|
EOF
|
||||||
nix-store --delete "$p" # Clean up for next test
|
nix-store --delete "$p" # Clean up for next test
|
||||||
|
|
||||||
# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
|
# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
|
||||||
nix-store --delete "$(jq -r <$TEST_ROOT/independent.json .[0].outputs.second)"
|
nix-store --delete "$(jq -r <"$TEST_ROOT"/independent.json .[0].outputs.second)"
|
||||||
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
|
p=$(nix build -f multiple-outputs.nix use-independent --no-link --print-out-paths)
|
||||||
cmp $p <<EOF
|
cmp "$p" <<EOF
|
||||||
first
|
first
|
||||||
second
|
second
|
||||||
EOF
|
EOF
|
||||||
@ -36,16 +36,16 @@ issue_6572_independent_outputs
|
|||||||
# https://github.com/NixOS/nix/issues/6572
|
# https://github.com/NixOS/nix/issues/6572
|
||||||
issue_6572_dependent_outputs() {
|
issue_6572_dependent_outputs() {
|
||||||
|
|
||||||
nix build -f multiple-outputs.nix --json a --no-link > $TEST_ROOT/a.json
|
nix build -f multiple-outputs.nix --json a --no-link > "$TEST_ROOT"/a.json
|
||||||
|
|
||||||
# # Make sure that 'nix build' can build a derivation that depends on both outputs of another derivation.
|
# # Make sure that 'nix build' can build a derivation that depends on both outputs of another derivation.
|
||||||
p=$(nix build -f multiple-outputs.nix use-a --no-link --print-out-paths)
|
p=$(nix build -f multiple-outputs.nix use-a --no-link --print-out-paths)
|
||||||
nix-store --delete "$p" # Clean up for next test
|
nix-store --delete "$p" # Clean up for next test
|
||||||
|
|
||||||
# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
|
# Make sure that 'nix build' tracks input-outputs correctly when a single output is already present.
|
||||||
nix-store --delete "$(jq -r <$TEST_ROOT/a.json .[0].outputs.second)"
|
nix-store --delete "$(jq -r <"$TEST_ROOT"/a.json .[0].outputs.second)"
|
||||||
p=$(nix build -f multiple-outputs.nix use-a --no-link --print-out-paths)
|
p=$(nix build -f multiple-outputs.nix use-a --no-link --print-out-paths)
|
||||||
cmp $p <<EOF
|
cmp "$p" <<EOF
|
||||||
first
|
first
|
||||||
second
|
second
|
||||||
EOF
|
EOF
|
||||||
|
@ -35,17 +35,17 @@ clearStore
|
|||||||
clearCache
|
clearCache
|
||||||
|
|
||||||
RESULT=$TEST_ROOT/result-link
|
RESULT=$TEST_ROOT/result-link
|
||||||
rm -f $RESULT
|
rm -f "$RESULT"
|
||||||
|
|
||||||
nix-build dependencies.nix -o $RESULT --dry-run
|
nix-build dependencies.nix -o "$RESULT" --dry-run
|
||||||
|
|
||||||
[[ ! -h $RESULT ]] || fail "nix-build --dry-run created output link"
|
[[ ! -h $RESULT ]] || fail "nix-build --dry-run created output link"
|
||||||
|
|
||||||
nix build -f dependencies.nix -o $RESULT --dry-run
|
nix build -f dependencies.nix -o "$RESULT" --dry-run
|
||||||
|
|
||||||
[[ ! -h $RESULT ]] || fail "nix build --dry-run created output link"
|
[[ ! -h $RESULT ]] || fail "nix build --dry-run created output link"
|
||||||
|
|
||||||
nix build -f dependencies.nix -o $RESULT
|
nix build -f dependencies.nix -o "$RESULT"
|
||||||
|
|
||||||
[[ -h $RESULT ]]
|
[[ -h $RESULT ]]
|
||||||
|
|
||||||
@ -58,12 +58,12 @@ RES=$(nix build -f dependencies.nix --dry-run --json)
|
|||||||
|
|
||||||
if [[ -z "${NIX_TESTS_CA_BY_DEFAULT-}" ]]; then
|
if [[ -z "${NIX_TESTS_CA_BY_DEFAULT-}" ]]; then
|
||||||
echo "$RES" | jq '.[0] | [
|
echo "$RES" | jq '.[0] | [
|
||||||
(.drvPath | test("'$NIX_STORE_DIR'.*\\.drv")),
|
(.drvPath | test("'"$NIX_STORE_DIR"'.*\\.drv")),
|
||||||
(.outputs.out | test("'$NIX_STORE_DIR'"))
|
(.outputs.out | test("'"$NIX_STORE_DIR"'"))
|
||||||
] | all'
|
] | all'
|
||||||
else
|
else
|
||||||
echo "$RES" | jq '.[0] | [
|
echo "$RES" | jq '.[0] | [
|
||||||
(.drvPath | test("'$NIX_STORE_DIR'.*\\.drv")),
|
(.drvPath | test("'"$NIX_STORE_DIR"'.*\\.drv")),
|
||||||
.outputs.out == null
|
.outputs.out == null
|
||||||
] | all'
|
] | all'
|
||||||
fi
|
fi
|
||||||
|
@ -26,7 +26,8 @@ copyAttr () {
|
|||||||
# Note: to copy CA derivations, we need to copy the realisations, which
|
# Note: to copy CA derivations, we need to copy the realisations, which
|
||||||
# currently requires naming the installables, not just the derivation output
|
# currently requires naming the installables, not just the derivation output
|
||||||
# path.
|
# path.
|
||||||
nix copy --to file://$cacheDir "${args[@]}"
|
|
||||||
|
nix copy --to "file://$cacheDir" "${args[@]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
testRemoteCacheFor () {
|
testRemoteCacheFor () {
|
||||||
@ -35,7 +36,7 @@ testRemoteCacheFor () {
|
|||||||
copyAttr "$derivationPath" 1
|
copyAttr "$derivationPath" 1
|
||||||
clearStore
|
clearStore
|
||||||
# Check nothing gets built.
|
# Check nothing gets built.
|
||||||
buildAttr "$derivationPath" 1 --option substituters file://$cacheDir --no-require-sigs |& grepQuietInverse " will be built:"
|
buildAttr "$derivationPath" 1 --option substituters "file://$cacheDir" --no-require-sigs |& grepQuietInverse " will be built:"
|
||||||
}
|
}
|
||||||
|
|
||||||
testRemoteCache () {
|
testRemoteCache () {
|
||||||
@ -48,4 +49,4 @@ testRemoteCache () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
testRemoteCache
|
testRemoteCache
|
||||||
|
@ -20,11 +20,11 @@ testDeterministicCA () {
|
|||||||
|
|
||||||
testCutoffFor () {
|
testCutoffFor () {
|
||||||
local out1 out2
|
local out1 out2
|
||||||
out1=$(buildAttr $1 1)
|
out1=$(buildAttr "$1" 1)
|
||||||
# The seed only changes the root derivation, and not it's output, so the
|
# The seed only changes the root derivation, and not it's output, so the
|
||||||
# dependent derivations should only need to be built once.
|
# dependent derivations should only need to be built once.
|
||||||
buildAttr rootCA 2
|
buildAttr rootCA 2
|
||||||
out2=$(buildAttr $1 2 -j0)
|
out2=$(buildAttr "$1" 2 -j0)
|
||||||
test "$out1" == "$out2"
|
test "$out1" == "$out2"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +41,7 @@ testGC () {
|
|||||||
nix-instantiate ./content-addressed.nix -A rootCA --arg seed 5
|
nix-instantiate ./content-addressed.nix -A rootCA --arg seed 5
|
||||||
nix-collect-garbage --option keep-derivations true
|
nix-collect-garbage --option keep-derivations true
|
||||||
clearStore
|
clearStore
|
||||||
buildAttr rootCA 1 --out-link $TEST_ROOT/rootCA
|
buildAttr rootCA 1 --out-link "$TEST_ROOT"/rootCA
|
||||||
nix-collect-garbage
|
nix-collect-garbage
|
||||||
buildAttr rootCA 1 -j0
|
buildAttr rootCA 1 -j0
|
||||||
}
|
}
|
||||||
@ -55,7 +55,7 @@ testNixCommand () {
|
|||||||
testNormalization () {
|
testNormalization () {
|
||||||
clearStore
|
clearStore
|
||||||
outPath=$(buildAttr rootCA 1)
|
outPath=$(buildAttr rootCA 1)
|
||||||
test "$(stat -c %Y $outPath)" -eq 1
|
test "$(stat -c %Y "$outPath")" -eq 1
|
||||||
}
|
}
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
|
@ -1,29 +1,31 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
export NIX_TESTS_CA_BY_DEFAULT=1
|
export NIX_TESTS_CA_BY_DEFAULT=1
|
||||||
|
|
||||||
drvPath=$(nix-instantiate ../simple.nix)
|
drvPath=$(nix-instantiate ../simple.nix)
|
||||||
|
|
||||||
nix derivation show $drvPath | jq .[] > $TEST_HOME/simple.json
|
nix derivation show "$drvPath" | jq .[] > "$TEST_HOME"/simple.json
|
||||||
|
|
||||||
drvPath2=$(nix derivation add < $TEST_HOME/simple.json)
|
drvPath2=$(nix derivation add < "$TEST_HOME"/simple.json)
|
||||||
|
|
||||||
[[ "$drvPath" = "$drvPath2" ]]
|
[[ "$drvPath" = "$drvPath2" ]]
|
||||||
|
|
||||||
# Content-addressed derivations can be renamed.
|
# Content-addressed derivations can be renamed.
|
||||||
jq '.name = "foo"' < $TEST_HOME/simple.json > $TEST_HOME/foo.json
|
jq '.name = "foo"' < "$TEST_HOME"/simple.json > "$TEST_HOME"/foo.json
|
||||||
drvPath3=$(nix derivation add --dry-run < $TEST_HOME/foo.json)
|
drvPath3=$(nix derivation add --dry-run < "$TEST_HOME"/foo.json)
|
||||||
# With --dry-run nothing is actually written
|
# With --dry-run nothing is actually written
|
||||||
[[ ! -e "$drvPath3" ]]
|
[[ ! -e "$drvPath3" ]]
|
||||||
|
|
||||||
# But the JSON is rejected without the experimental feature
|
# But the JSON is rejected without the experimental feature
|
||||||
expectStderr 1 nix derivation add < $TEST_HOME/foo.json --experimental-features nix-command | grepQuiet "experimental Nix feature 'ca-derivations' is disabled"
|
expectStderr 1 nix derivation add < "$TEST_HOME"/foo.json --experimental-features nix-command | grepQuiet "experimental Nix feature 'ca-derivations' is disabled"
|
||||||
|
|
||||||
# Without --dry-run it is actually written
|
# Without --dry-run it is actually written
|
||||||
drvPath4=$(nix derivation add < $TEST_HOME/foo.json)
|
drvPath4=$(nix derivation add < "$TEST_HOME"/foo.json)
|
||||||
[[ "$drvPath4" = "$drvPath3" ]]
|
[[ "$drvPath4" = "$drvPath3" ]]
|
||||||
[[ -e "$drvPath3" ]]
|
[[ -e "$drvPath3" ]]
|
||||||
|
|
||||||
# The modified derivation read back as JSON matches
|
# The modified derivation read back as JSON matches
|
||||||
nix derivation show $drvPath3 | jq .[] > $TEST_HOME/foo-read.json
|
nix derivation show "$drvPath3" | jq .[] > "$TEST_HOME"/foo-read.json
|
||||||
diff $TEST_HOME/foo.json $TEST_HOME/foo-read.json
|
diff "$TEST_HOME"/foo.json "$TEST_HOME"/foo-read.json
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
source ./common.sh
|
source ./common.sh
|
||||||
|
|
||||||
requireDaemonNewerThan "2.4pre20210625"
|
requireDaemonNewerThan "2.4pre20210625"
|
||||||
@ -5,7 +7,7 @@ requireDaemonNewerThan "2.4pre20210625"
|
|||||||
export REMOTE_STORE_DIR="$TEST_ROOT/remote_store"
|
export REMOTE_STORE_DIR="$TEST_ROOT/remote_store"
|
||||||
export REMOTE_STORE="file://$REMOTE_STORE_DIR"
|
export REMOTE_STORE="file://$REMOTE_STORE_DIR"
|
||||||
|
|
||||||
rm -rf $REMOTE_STORE_DIR
|
rm -rf "$REMOTE_STORE_DIR"
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
# Build dep1 and push that to the binary cache.
|
# Build dep1 and push that to the binary cache.
|
||||||
|
@ -15,13 +15,13 @@ testOneCopy () {
|
|||||||
rm -rf "$REMOTE_STORE_DIR"
|
rm -rf "$REMOTE_STORE_DIR"
|
||||||
|
|
||||||
attrPath="$1"
|
attrPath="$1"
|
||||||
nix copy --to $REMOTE_STORE "$attrPath" --file ./content-addressed.nix
|
nix copy --to "$REMOTE_STORE" "$attrPath" --file ./content-addressed.nix
|
||||||
|
|
||||||
ensureCorrectlyCopied "$attrPath"
|
ensureCorrectlyCopied "$attrPath"
|
||||||
|
|
||||||
# Ensure that we can copy back what we put in the store
|
# Ensure that we can copy back what we put in the store
|
||||||
clearStore
|
clearStore
|
||||||
nix copy --from $REMOTE_STORE \
|
nix copy --from "$REMOTE_STORE" \
|
||||||
--file ./content-addressed.nix "$attrPath" \
|
--file ./content-addressed.nix "$attrPath" \
|
||||||
--no-check-sigs
|
--no-check-sigs
|
||||||
}
|
}
|
||||||
|
@ -4,4 +4,4 @@ source common.sh
|
|||||||
|
|
||||||
FLAKE_PATH=path:$PWD
|
FLAKE_PATH=path:$PWD
|
||||||
|
|
||||||
nix run --no-write-lock-file $FLAKE_PATH#runnable
|
nix run --no-write-lock-file "$FLAKE_PATH#runnable"
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
clearCache
|
clearCache
|
||||||
|
|
||||||
nix-store --generate-binary-cache-key cache1.example.org $TEST_ROOT/sk1 $TEST_ROOT/pk1
|
nix-store --generate-binary-cache-key cache1.example.org "$TEST_ROOT/sk1" "$TEST_ROOT/pk1"
|
||||||
pk1=$(cat $TEST_ROOT/pk1)
|
pk1=$(cat "$TEST_ROOT/pk1")
|
||||||
|
|
||||||
export REMOTE_STORE_DIR="$TEST_ROOT/remote_store"
|
export REMOTE_STORE_DIR="$TEST_ROOT/remote_store"
|
||||||
export REMOTE_STORE="file://$REMOTE_STORE_DIR"
|
export REMOTE_STORE="file://$REMOTE_STORE_DIR"
|
||||||
@ -19,16 +21,16 @@ testOneCopy () {
|
|||||||
rm -rf "$REMOTE_STORE_DIR"
|
rm -rf "$REMOTE_STORE_DIR"
|
||||||
|
|
||||||
attrPath="$1"
|
attrPath="$1"
|
||||||
nix copy -vvvv --to $REMOTE_STORE "$attrPath" --file ./content-addressed.nix \
|
nix copy -vvvv --to "$REMOTE_STORE" "$attrPath" --file ./content-addressed.nix \
|
||||||
--secret-key-files "$TEST_ROOT/sk1" --show-trace
|
--secret-key-files "$TEST_ROOT/sk1" --show-trace
|
||||||
|
|
||||||
ensureCorrectlyCopied "$attrPath"
|
ensureCorrectlyCopied "$attrPath"
|
||||||
|
|
||||||
# Ensure that we can copy back what we put in the store
|
# Ensure that we can copy back what we put in the store
|
||||||
clearStore
|
clearStore
|
||||||
nix copy --from $REMOTE_STORE \
|
nix copy --from "$REMOTE_STORE" \
|
||||||
--file ./content-addressed.nix "$attrPath" \
|
--file ./content-addressed.nix "$attrPath" \
|
||||||
--trusted-public-keys $pk1
|
--trusted-public-keys "$pk1"
|
||||||
}
|
}
|
||||||
|
|
||||||
for attrPath in rootCA dependentCA transitivelyDependentCA dependentNonCA dependentFixedOutput; do
|
for attrPath in rootCA dependentCA transitivelyDependentCA dependentNonCA dependentFixedOutput; do
|
||||||
|
@ -4,9 +4,10 @@
|
|||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
|
# shellcheck disable=SC1111
|
||||||
needLocalStore "“--no-require-sigs” can’t be used with the daemon"
|
needLocalStore "“--no-require-sigs” can’t be used with the daemon"
|
||||||
|
|
||||||
rm -rf $TEST_ROOT/binary_cache
|
rm -rf "$TEST_ROOT/binary_cache"
|
||||||
|
|
||||||
export REMOTE_STORE_DIR=$TEST_ROOT/binary_cache
|
export REMOTE_STORE_DIR=$TEST_ROOT/binary_cache
|
||||||
export REMOTE_STORE=file://$REMOTE_STORE_DIR
|
export REMOTE_STORE=file://$REMOTE_STORE_DIR
|
||||||
@ -17,11 +18,11 @@ buildDrvs () {
|
|||||||
|
|
||||||
# Populate the remote cache
|
# Populate the remote cache
|
||||||
clearStore
|
clearStore
|
||||||
nix copy --to $REMOTE_STORE --file ./content-addressed.nix
|
nix copy --to "$REMOTE_STORE" --file ./content-addressed.nix
|
||||||
|
|
||||||
# Restart the build on an empty store, ensuring that we don't build
|
# Restart the build on an empty store, ensuring that we don't build
|
||||||
clearStore
|
clearStore
|
||||||
buildDrvs --substitute --substituters $REMOTE_STORE --no-require-sigs -j0 transitivelyDependentCA
|
buildDrvs --substitute --substituters "$REMOTE_STORE" --no-require-sigs -j0 transitivelyDependentCA
|
||||||
# Check that the thing we’ve just substituted has its realisation stored
|
# Check that the thing we’ve just substituted has its realisation stored
|
||||||
nix realisation info --file ./content-addressed.nix transitivelyDependentCA
|
nix realisation info --file ./content-addressed.nix transitivelyDependentCA
|
||||||
# Check that its dependencies have it too
|
# Check that its dependencies have it too
|
||||||
@ -63,9 +64,9 @@ clearStore
|
|||||||
# Add the realisations of rootCA to the cachecache
|
# Add the realisations of rootCA to the cachecache
|
||||||
clearCacheCache
|
clearCacheCache
|
||||||
export _NIX_FORCE_HTTP=1
|
export _NIX_FORCE_HTTP=1
|
||||||
buildDrvs --substitute --substituters $REMOTE_STORE --no-require-sigs -j0
|
buildDrvs --substitute --substituters "$REMOTE_STORE" --no-require-sigs -j0
|
||||||
# Try rebuilding, but remove the realisations from the remote cache to force
|
# Try rebuilding, but remove the realisations from the remote cache to force
|
||||||
# using the cachecache
|
# using the cachecache
|
||||||
clearStore
|
clearStore
|
||||||
rm $REMOTE_STORE_DIR/realisations/*
|
rm "$REMOTE_STORE_DIR"/realisations/*
|
||||||
buildDrvs --substitute --substituters $REMOTE_STORE --no-require-sigs -j0
|
buildDrvs --substitute --substituters "$REMOTE_STORE" --no-require-sigs -j0
|
||||||
|
@ -4,18 +4,19 @@ source common.sh
|
|||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
rm -rf $TEST_ROOT/case
|
rm -rf "$TEST_ROOT/case"
|
||||||
|
|
||||||
opts="--option use-case-hack true"
|
opts=("--option" "use-case-hack" "true")
|
||||||
|
|
||||||
# Check whether restoring and dumping a NAR that contains case
|
# Check whether restoring and dumping a NAR that contains case
|
||||||
# collisions is round-tripping, even on a case-insensitive system.
|
# collisions is round-tripping, even on a case-insensitive system.
|
||||||
nix-store $opts --restore $TEST_ROOT/case < case.nar
|
|
||||||
nix-store $opts --dump $TEST_ROOT/case > $TEST_ROOT/case.nar
|
nix-store "${opts[@]}" --restore "$TEST_ROOT/case" < case.nar
|
||||||
cmp case.nar $TEST_ROOT/case.nar
|
nix-store "${opts[@]}" --dump "$TEST_ROOT/case" > "$TEST_ROOT/case.nar"
|
||||||
[ "$(nix-hash $opts --type sha256 $TEST_ROOT/case)" = "$(nix-hash --flat --type sha256 case.nar)" ]
|
cmp case.nar "$TEST_ROOT/case.nar"
|
||||||
|
[ "$(nix-hash "${opts[@]}" --type sha256 "$TEST_ROOT/case")" = "$(nix-hash --flat --type sha256 case.nar)" ]
|
||||||
|
|
||||||
# Check whether we detect true collisions (e.g. those remaining after
|
# Check whether we detect true collisions (e.g. those remaining after
|
||||||
# removal of the suffix).
|
# removal of the suffix).
|
||||||
touch "$TEST_ROOT/case/xt_CONNMARK.h~nix~case~hack~3"
|
touch "$TEST_ROOT/case/xt_CONNMARK.h~nix~case~hack~3"
|
||||||
(! nix-store $opts --dump $TEST_ROOT/case > /dev/null)
|
(! nix-store "${opts[@]}" --dump "$TEST_ROOT/case" > /dev/null)
|
||||||
|
@ -6,42 +6,42 @@ clearStore
|
|||||||
|
|
||||||
RESULT=$TEST_ROOT/result
|
RESULT=$TEST_ROOT/result
|
||||||
|
|
||||||
dep=$(nix-build -o $RESULT check-refs.nix -A dep)
|
dep=$(nix-build -o "$RESULT" check-refs.nix -A dep)
|
||||||
|
|
||||||
# test1 references dep, not itself.
|
# test1 references dep, not itself.
|
||||||
test1=$(nix-build -o $RESULT check-refs.nix -A test1)
|
test1=$(nix-build -o "$RESULT" check-refs.nix -A test1)
|
||||||
nix-store -q --references $test1 | grepQuietInverse $test1
|
nix-store -q --references "$test1" | grepQuietInverse "$test1"
|
||||||
nix-store -q --references $test1 | grepQuiet $dep
|
nix-store -q --references "$test1" | grepQuiet "$dep"
|
||||||
|
|
||||||
# test2 references src, not itself nor dep.
|
# test2 references src, not itself nor dep.
|
||||||
test2=$(nix-build -o $RESULT check-refs.nix -A test2)
|
test2=$(nix-build -o "$RESULT" check-refs.nix -A test2)
|
||||||
nix-store -q --references $test2 | grepQuietInverse $test2
|
nix-store -q --references "$test2" | grepQuietInverse "$test2"
|
||||||
nix-store -q --references $test2 | grepQuietInverse $dep
|
nix-store -q --references "$test2" | grepQuietInverse "$dep"
|
||||||
nix-store -q --references $test2 | grepQuiet aux-ref
|
nix-store -q --references "$test2" | grepQuiet aux-ref
|
||||||
|
|
||||||
# test3 should fail (unallowed ref).
|
# test3 should fail (unallowed ref).
|
||||||
(! nix-build -o $RESULT check-refs.nix -A test3)
|
(! nix-build -o "$RESULT" check-refs.nix -A test3)
|
||||||
|
|
||||||
# test4 should succeed.
|
# test4 should succeed.
|
||||||
nix-build -o $RESULT check-refs.nix -A test4
|
nix-build -o "$RESULT" check-refs.nix -A test4
|
||||||
|
|
||||||
# test5 should succeed.
|
# test5 should succeed.
|
||||||
nix-build -o $RESULT check-refs.nix -A test5
|
nix-build -o "$RESULT" check-refs.nix -A test5
|
||||||
|
|
||||||
# test6 should fail (unallowed self-ref).
|
# test6 should fail (unallowed self-ref).
|
||||||
(! nix-build -o $RESULT check-refs.nix -A test6)
|
(! nix-build -o "$RESULT" check-refs.nix -A test6)
|
||||||
|
|
||||||
# test7 should succeed (allowed self-ref).
|
# test7 should succeed (allowed self-ref).
|
||||||
nix-build -o $RESULT check-refs.nix -A test7
|
nix-build -o "$RESULT" check-refs.nix -A test7
|
||||||
|
|
||||||
# test8 should fail (toFile depending on derivation output).
|
# test8 should fail (toFile depending on derivation output).
|
||||||
(! nix-build -o $RESULT check-refs.nix -A test8)
|
(! nix-build -o "$RESULT" check-refs.nix -A test8)
|
||||||
|
|
||||||
# test9 should fail (disallowed reference).
|
# test9 should fail (disallowed reference).
|
||||||
(! nix-build -o $RESULT check-refs.nix -A test9)
|
(! nix-build -o "$RESULT" check-refs.nix -A test9)
|
||||||
|
|
||||||
# test10 should succeed (no disallowed references).
|
# test10 should succeed (no disallowed references).
|
||||||
nix-build -o $RESULT check-refs.nix -A test10
|
nix-build -o "$RESULT" check-refs.nix -A test10
|
||||||
|
|
||||||
if isDaemonNewer 2.12pre20230103; then
|
if isDaemonNewer 2.12pre20230103; then
|
||||||
if ! isDaemonNewer 2.16.0; then
|
if ! isDaemonNewer 2.16.0; then
|
||||||
@ -50,6 +50,6 @@ if isDaemonNewer 2.12pre20230103; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# test11 should succeed.
|
# test11 should succeed.
|
||||||
test11=$(nix-build -o $RESULT check-refs.nix -A test11)
|
test11=$(nix-build -o "$RESULT" check-refs.nix -A test11)
|
||||||
[[ -z $(nix-store -q --references "$test11") ]]
|
[[ -z $(nix-store -q --references "$test11") ]]
|
||||||
fi
|
fi
|
||||||
|
@ -6,13 +6,13 @@ clearStore
|
|||||||
|
|
||||||
RESULT=$TEST_ROOT/result
|
RESULT=$TEST_ROOT/result
|
||||||
|
|
||||||
nix-build -o $RESULT check-reqs.nix -A test1
|
nix-build -o "$RESULT" check-reqs.nix -A test1
|
||||||
|
|
||||||
(! nix-build -o $RESULT check-reqs.nix -A test2)
|
(! nix-build -o "$RESULT" check-reqs.nix -A test2)
|
||||||
(! nix-build -o $RESULT check-reqs.nix -A test3)
|
(! nix-build -o "$RESULT" check-reqs.nix -A test3)
|
||||||
(! nix-build -o $RESULT check-reqs.nix -A test4) 2>&1 | grepQuiet 'check-reqs-dep1'
|
(! nix-build -o "$RESULT" check-reqs.nix -A test4) 2>&1 | grepQuiet 'check-reqs-dep1'
|
||||||
(! nix-build -o $RESULT check-reqs.nix -A test4) 2>&1 | grepQuiet 'check-reqs-dep2'
|
(! nix-build -o "$RESULT" check-reqs.nix -A test4) 2>&1 | grepQuiet 'check-reqs-dep2'
|
||||||
(! nix-build -o $RESULT check-reqs.nix -A test5)
|
(! nix-build -o "$RESULT" check-reqs.nix -A test5)
|
||||||
(! nix-build -o $RESULT check-reqs.nix -A test6)
|
(! nix-build -o "$RESULT" check-reqs.nix -A test6)
|
||||||
|
|
||||||
nix-build -o $RESULT check-reqs.nix -A test7
|
nix-build -o "$RESULT" check-reqs.nix -A test7
|
||||||
|
@ -2,34 +2,34 @@
|
|||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
echo example > $TEST_ROOT/example.txt
|
echo example > "$TEST_ROOT"/example.txt
|
||||||
mkdir -p $TEST_ROOT/x
|
mkdir -p "$TEST_ROOT/x"
|
||||||
|
|
||||||
export NIX_STORE_DIR=/nix2/store
|
export NIX_STORE_DIR=/nix2/store
|
||||||
|
|
||||||
CORRECT_PATH=$(cd $TEST_ROOT && nix-store --store ./x --add example.txt)
|
CORRECT_PATH=$(cd "$TEST_ROOT" && nix-store --store ./x --add example.txt)
|
||||||
|
|
||||||
[[ $CORRECT_PATH =~ ^/nix2/store/.*-example.txt$ ]]
|
[[ $CORRECT_PATH =~ ^/nix2/store/.*-example.txt$ ]]
|
||||||
|
|
||||||
PATH1=$(cd $TEST_ROOT && nix path-info --store ./x $CORRECT_PATH)
|
PATH1=$(cd "$TEST_ROOT" && nix path-info --store ./x "$CORRECT_PATH")
|
||||||
[ $CORRECT_PATH == $PATH1 ]
|
[ "$CORRECT_PATH" == "$PATH1" ]
|
||||||
|
|
||||||
PATH2=$(nix path-info --store "$TEST_ROOT/x" $CORRECT_PATH)
|
PATH2=$(nix path-info --store "$TEST_ROOT/x" "$CORRECT_PATH")
|
||||||
[ $CORRECT_PATH == $PATH2 ]
|
[ "$CORRECT_PATH" == "$PATH2" ]
|
||||||
|
|
||||||
PATH3=$(nix path-info --store "local?root=$TEST_ROOT/x" $CORRECT_PATH)
|
PATH3=$(nix path-info --store "local?root=$TEST_ROOT/x" "$CORRECT_PATH")
|
||||||
[ $CORRECT_PATH == $PATH3 ]
|
[ "$CORRECT_PATH" == "$PATH3" ]
|
||||||
|
|
||||||
# Ensure store info trusted works with local store
|
# Ensure store info trusted works with local store
|
||||||
nix --store $TEST_ROOT/x store info --json | jq -e '.trusted'
|
nix --store "$TEST_ROOT/x" store info --json | jq -e '.trusted'
|
||||||
|
|
||||||
# Test building in a chroot store.
|
# Test building in a chroot store.
|
||||||
if canUseSandbox; then
|
if canUseSandbox; then
|
||||||
|
|
||||||
flakeDir=$TEST_ROOT/flake
|
flakeDir=$TEST_ROOT/flake
|
||||||
mkdir -p $flakeDir
|
mkdir -p "$flakeDir"
|
||||||
|
|
||||||
cat > $flakeDir/flake.nix <<EOF
|
cat > "$flakeDir"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
outputs = inputs: rec {
|
outputs = inputs: rec {
|
||||||
packages.$system.default = import ./simple.nix;
|
packages.$system.default = import ./simple.nix;
|
||||||
@ -37,11 +37,12 @@ if canUseSandbox; then
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cp simple.nix shell.nix simple.builder.sh config.nix $flakeDir/
|
cp simple.nix shell.nix simple.builder.sh config.nix "$flakeDir/"
|
||||||
|
|
||||||
outPath=$(nix build --print-out-paths --no-link --sandbox-paths '/nix? /bin? /lib? /lib64? /usr?' --store $TEST_ROOT/x path:$flakeDir)
|
outPath=$(nix build --print-out-paths --no-link --sandbox-paths '/nix? /bin? /lib? /lib64? /usr?' --store "$TEST_ROOT/x" path:"$flakeDir")
|
||||||
|
|
||||||
[[ $outPath =~ ^/nix2/store/.*-simple$ ]]
|
[[ $outPath =~ ^/nix2/store/.*-simple$ ]]
|
||||||
|
|
||||||
[[ $(cat $TEST_ROOT/x/nix/store/$(basename $outPath)/hello) = 'Hello World!' ]]
|
base=$(basename "$outPath")
|
||||||
|
[[ $(cat "$TEST_ROOT"/x/nix/store/"$base"/hello) = 'Hello World!' ]]
|
||||||
fi
|
fi
|
||||||
|
@ -13,7 +13,7 @@ mkdir "$TEST_HOME"
|
|||||||
|
|
||||||
mkdir "$NIX_STORE_DIR"
|
mkdir "$NIX_STORE_DIR"
|
||||||
mkdir "$NIX_LOCALSTATE_DIR"
|
mkdir "$NIX_LOCALSTATE_DIR"
|
||||||
mkdir -p "$NIX_LOG_DIR"/drvs
|
mkdir -p "$NIX_LOG_DIR/drvs"
|
||||||
mkdir "$NIX_STATE_DIR"
|
mkdir "$NIX_STATE_DIR"
|
||||||
mkdir "$NIX_CONF_DIR"
|
mkdir "$NIX_CONF_DIR"
|
||||||
|
|
||||||
|
@ -9,16 +9,16 @@ outPath=$(nix-build dependencies.nix --no-out-link)
|
|||||||
|
|
||||||
cacheURI="file://$cacheDir?compression=xz&compression-level=0"
|
cacheURI="file://$cacheDir?compression=xz&compression-level=0"
|
||||||
|
|
||||||
nix copy --to $cacheURI $outPath
|
nix copy --to "$cacheURI" "$outPath"
|
||||||
|
|
||||||
FILESIZES=$(cat ${cacheDir}/*.narinfo | awk '/FileSize: /{sum+=$2}END{print sum}')
|
FILESIZES=$(cat "${cacheDir}"/*.narinfo | awk '/FileSize: /{sum+=$2}END{print sum}')
|
||||||
|
|
||||||
clearCache
|
clearCache
|
||||||
|
|
||||||
cacheURI="file://$cacheDir?compression=xz&compression-level=5"
|
cacheURI="file://$cacheDir?compression=xz&compression-level=5"
|
||||||
|
|
||||||
nix copy --to $cacheURI $outPath
|
nix copy --to "$cacheURI" "$outPath"
|
||||||
|
|
||||||
FILESIZES2=$(cat ${cacheDir}/*.narinfo | awk '/FileSize: /{sum+=$2}END{print sum}')
|
FILESIZES2=$(cat "${cacheDir}"/*.narinfo | awk '/FileSize: /{sum+=$2}END{print sum}')
|
||||||
|
|
||||||
[[ $FILESIZES -gt $FILESIZES2 ]]
|
[[ $FILESIZES -gt $FILESIZES2 ]]
|
||||||
|
@ -33,7 +33,7 @@ nix-store -q --tree "$outPath" | grep '───.*dependencies-input-2'
|
|||||||
|
|
||||||
echo "output path is $outPath"
|
echo "output path is $outPath"
|
||||||
|
|
||||||
text=$(cat "$outPath"/foobar)
|
text=$(cat "$outPath/foobar")
|
||||||
if test "$text" != "FOOBAR"; then exit 1; fi
|
if test "$text" != "FOOBAR"; then exit 1; fi
|
||||||
|
|
||||||
deps=$(nix-store -quR "$drvPath")
|
deps=$(nix-store -quR "$drvPath")
|
||||||
|
@ -4,11 +4,11 @@ source common.sh
|
|||||||
|
|
||||||
drvPath=$(nix-instantiate simple.nix)
|
drvPath=$(nix-instantiate simple.nix)
|
||||||
|
|
||||||
nix derivation show $drvPath | jq .[] > $TEST_HOME/simple.json
|
nix derivation show "$drvPath" | jq .[] > "$TEST_HOME"/simple.json
|
||||||
|
|
||||||
drvPath2=$(nix derivation add < $TEST_HOME/simple.json)
|
drvPath2=$(nix derivation add < "$TEST_HOME"/simple.json)
|
||||||
|
|
||||||
[[ "$drvPath" = "$drvPath2" ]]
|
[[ "$drvPath" = "$drvPath2" ]]
|
||||||
|
|
||||||
# Input addressed derivations cannot be renamed.
|
# Input addressed derivations cannot be renamed.
|
||||||
jq '.name = "foo"' < $TEST_HOME/simple.json | expectStderr 1 nix derivation add | grepQuiet "has incorrect output"
|
jq '.name = "foo"' < "$TEST_HOME"/simple.json | expectStderr 1 nix derivation add | grepQuiet "has incorrect output"
|
||||||
|
@ -20,7 +20,7 @@ nix show-derivation "$drvProducingDrv"
|
|||||||
|
|
||||||
out1=$(nix-build ./text-hashed-output.nix -A producingDrv --no-out-link)
|
out1=$(nix-build ./text-hashed-output.nix -A producingDrv --no-out-link)
|
||||||
|
|
||||||
nix path-info $drv --derivation --json | jq
|
nix path-info "$drv" --derivation --json | jq
|
||||||
nix path-info $out1 --derivation --json | jq
|
nix path-info "$out1" --derivation --json | jq
|
||||||
|
|
||||||
test $out1 == $drv
|
test "$out1" == "$drv"
|
||||||
|
@ -33,35 +33,35 @@ source common.sh
|
|||||||
NIX_CONFIG='
|
NIX_CONFIG='
|
||||||
experimental-features = nix-command
|
experimental-features = nix-command
|
||||||
accept-flake-config = true
|
accept-flake-config = true
|
||||||
' expect 1 nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
' expect 1 nix config show accept-flake-config 1>"$TEST_ROOT"/stdout 2>"$TEST_ROOT"/stderr
|
||||||
[[ $(cat $TEST_ROOT/stdout) = '' ]]
|
[[ $(cat "$TEST_ROOT/stdout") = '' ]]
|
||||||
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" $TEST_ROOT/stderr
|
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" "$TEST_ROOT/stderr"
|
||||||
grepQuiet "error: could not find setting 'accept-flake-config'" $TEST_ROOT/stderr
|
grepQuiet "error: could not find setting 'accept-flake-config'" "$TEST_ROOT/stderr"
|
||||||
|
|
||||||
# 'flakes' experimental-feature is disabled after, ignore and warn
|
# 'flakes' experimental-feature is disabled after, ignore and warn
|
||||||
NIX_CONFIG='
|
NIX_CONFIG='
|
||||||
accept-flake-config = true
|
accept-flake-config = true
|
||||||
experimental-features = nix-command
|
experimental-features = nix-command
|
||||||
' expect 1 nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
' expect 1 nix config show accept-flake-config 1>"$TEST_ROOT"/stdout 2>"$TEST_ROOT"/stderr
|
||||||
[[ $(cat $TEST_ROOT/stdout) = '' ]]
|
[[ $(cat "$TEST_ROOT/stdout") = '' ]]
|
||||||
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" $TEST_ROOT/stderr
|
grepQuiet "Ignoring setting 'accept-flake-config' because experimental feature 'flakes' is not enabled" "$TEST_ROOT/stderr"
|
||||||
grepQuiet "error: could not find setting 'accept-flake-config'" $TEST_ROOT/stderr
|
grepQuiet "error: could not find setting 'accept-flake-config'" "$TEST_ROOT/stderr"
|
||||||
|
|
||||||
# 'flakes' experimental-feature is enabled before, process
|
# 'flakes' experimental-feature is enabled before, process
|
||||||
NIX_CONFIG='
|
NIX_CONFIG='
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
accept-flake-config = true
|
accept-flake-config = true
|
||||||
' nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
' nix config show accept-flake-config 1>"$TEST_ROOT"/stdout 2>"$TEST_ROOT"/stderr
|
||||||
grepQuiet "true" $TEST_ROOT/stdout
|
grepQuiet "true" "$TEST_ROOT/stdout"
|
||||||
grepQuietInverse "Ignoring setting 'accept-flake-config'" $TEST_ROOT/stderr
|
grepQuietInverse "Ignoring setting 'accept-flake-config'" "$TEST_ROOT/stderr"
|
||||||
|
|
||||||
# 'flakes' experimental-feature is enabled after, process
|
# 'flakes' experimental-feature is enabled after, process
|
||||||
NIX_CONFIG='
|
NIX_CONFIG='
|
||||||
accept-flake-config = true
|
accept-flake-config = true
|
||||||
experimental-features = nix-command flakes
|
experimental-features = nix-command flakes
|
||||||
' nix config show accept-flake-config 1>$TEST_ROOT/stdout 2>$TEST_ROOT/stderr
|
' nix config show accept-flake-config 1>"$TEST_ROOT"/stdout 2>"$TEST_ROOT"/stderr
|
||||||
grepQuiet "true" $TEST_ROOT/stdout
|
grepQuiet "true" "$TEST_ROOT/stdout"
|
||||||
grepQuietInverse "Ignoring setting 'accept-flake-config'" $TEST_ROOT/stderr
|
grepQuietInverse "Ignoring setting 'accept-flake-config'" "$TEST_ROOT/stderr"
|
||||||
|
|
||||||
function exit_code_both_ways {
|
function exit_code_both_ways {
|
||||||
expect 1 nix --experimental-features 'nix-command' "$@" 1>/dev/null
|
expect 1 nix --experimental-features 'nix-command' "$@" 1>/dev/null
|
||||||
|
@ -14,7 +14,7 @@ git init "$repo"
|
|||||||
git -C "$repo" config user.email "foobar@example.com"
|
git -C "$repo" config user.email "foobar@example.com"
|
||||||
git -C "$repo" config user.name "Foobar"
|
git -C "$repo" config user.name "Foobar"
|
||||||
|
|
||||||
echo utrecht > "$repo"/hello
|
echo utrecht > "$repo/hello"
|
||||||
git -C "$repo" add hello
|
git -C "$repo" add hello
|
||||||
git -C "$repo" commit -m 'Bla1'
|
git -C "$repo" commit -m 'Bla1'
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
touch $TEST_ROOT/foo -t 202211111111
|
touch "$TEST_ROOT/foo" -t 202211111111
|
||||||
# We only check whether 2022-11-1* **:**:** is the last modified date since
|
# We only check whether 2022-11-1* **:**:** is the last modified date since
|
||||||
# `lastModified` is transformed into UTC in `builtins.fetchTarball`.
|
# `lastModified` is transformed into UTC in `builtins.fetchTarball`.
|
||||||
[[ "$(nix eval --impure --raw --expr "(builtins.fetchTree \"path://$TEST_ROOT/foo\").lastModifiedDate")" =~ 2022111.* ]]
|
[[ "$(nix eval --impure --raw --expr "(builtins.fetchTree \"path://$TEST_ROOT/foo\").lastModifiedDate")" =~ 2022111.* ]]
|
||||||
|
@ -90,7 +90,7 @@ EOF
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Test tarball URLs on the command line.
|
# Test tarball URLs on the command line.
|
||||||
[[ $(nix flake metadata --json file://$PWD/test_input_no_ext | jq -r .resolved.type) = tarball ]]
|
[[ $(nix flake metadata --json "file://$PWD/test_input_no_ext" | jq -r .resolved.type) = tarball ]]
|
||||||
|
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
@ -2,26 +2,26 @@
|
|||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
rm -rf $TEST_ROOT/filterin
|
rm -rf "$TEST_ROOT/filterin"
|
||||||
mkdir $TEST_ROOT/filterin
|
mkdir "$TEST_ROOT/filterin"
|
||||||
mkdir $TEST_ROOT/filterin/foo
|
mkdir "$TEST_ROOT/filterin/foo"
|
||||||
touch $TEST_ROOT/filterin/foo/bar
|
touch "$TEST_ROOT/filterin/foo/bar"
|
||||||
touch $TEST_ROOT/filterin/xyzzy
|
touch "$TEST_ROOT/filterin/xyzzy"
|
||||||
touch $TEST_ROOT/filterin/b
|
touch "$TEST_ROOT/filterin/b"
|
||||||
touch $TEST_ROOT/filterin/bak
|
touch "$TEST_ROOT/filterin/bak"
|
||||||
touch $TEST_ROOT/filterin/bla.c.bak
|
touch "$TEST_ROOT"/filterin/bla.c.bak
|
||||||
ln -s xyzzy $TEST_ROOT/filterin/link
|
ln -s xyzzy "$TEST_ROOT/filterin/link"
|
||||||
|
|
||||||
checkFilter() {
|
checkFilter() {
|
||||||
test ! -e $1/foo/bar
|
test ! -e "$1/foo/bar"
|
||||||
test -e $1/xyzzy
|
test -e "$1/xyzzy"
|
||||||
test -e $1/bak
|
test -e "$1/bak"
|
||||||
test ! -e $1/bla.c.bak
|
test ! -e "$1"/bla.c.bak
|
||||||
test ! -L $1/link
|
test ! -L "$1/link"
|
||||||
}
|
}
|
||||||
|
|
||||||
nix-build ./filter-source.nix -o $TEST_ROOT/filterout1
|
nix-build ./filter-source.nix -o "$TEST_ROOT/filterout1"
|
||||||
checkFilter $TEST_ROOT/filterout1
|
checkFilter "$TEST_ROOT/filterout1"
|
||||||
|
|
||||||
nix-build ./path.nix -o $TEST_ROOT/filterout2
|
nix-build ./path.nix -o "$TEST_ROOT/filterout2"
|
||||||
checkFilter $TEST_ROOT/filterout2
|
checkFilter "$TEST_ROOT/filterout2"
|
||||||
|
@ -4,8 +4,8 @@ source ./common.sh
|
|||||||
|
|
||||||
flake1Dir=$TEST_ROOT/flake1
|
flake1Dir=$TEST_ROOT/flake1
|
||||||
|
|
||||||
mkdir -p $flake1Dir
|
mkdir -p "$flake1Dir"
|
||||||
cat > $flake1Dir/flake.nix <<EOF
|
cat > "$flake1Dir"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
outputs = { self }: {
|
outputs = { self }: {
|
||||||
x = 1;
|
x = 1;
|
||||||
@ -14,6 +14,6 @@ cat > $flake1Dir/flake.nix <<EOF
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
[ "$(nix eval --impure --json $flake1Dir#.x)" -eq 1 ]
|
[ "$(nix eval --impure --json "$flake1Dir"#.x)" -eq 1 ]
|
||||||
[ "$(nix eval --impure --json $flake1Dir#x)" -eq 2 ]
|
[ "$(nix eval --impure --json "$flake1Dir#x")" -eq 2 ]
|
||||||
[ "$(nix eval --impure --json $flake1Dir#.packages.$system.x)" -eq 2 ]
|
[ "$(nix eval --impure --json "$flake1Dir"#.packages."$system".x)" -eq 2 ]
|
||||||
|
@ -5,15 +5,15 @@ source ./common.sh
|
|||||||
flake1Dir=$TEST_ROOT/flake1
|
flake1Dir=$TEST_ROOT/flake1
|
||||||
flake2Dir=$TEST_ROOT/flake2
|
flake2Dir=$TEST_ROOT/flake2
|
||||||
|
|
||||||
mkdir -p $flake1Dir $flake2Dir
|
mkdir -p "$flake1Dir" "$flake2Dir"
|
||||||
|
|
||||||
writeSimpleFlake $flake2Dir
|
writeSimpleFlake "$flake2Dir"
|
||||||
tar cfz $TEST_ROOT/flake.tar.gz -C $TEST_ROOT flake2
|
tar cfz "$TEST_ROOT"/flake.tar.gz -C "$TEST_ROOT" flake2
|
||||||
hash=$(nix hash path $flake2Dir)
|
hash=$(nix hash path "$flake2Dir")
|
||||||
|
|
||||||
dep=$(nix store add-path ./common.sh)
|
dep=$(nix store add-path ./common.sh)
|
||||||
|
|
||||||
cat > $flake1Dir/flake.nix <<EOF
|
cat > "$flake1Dir"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
inputs.flake2.url = "file://$TEST_ROOT/flake.tar.gz";
|
inputs.flake2.url = "file://$TEST_ROOT/flake.tar.gz";
|
||||||
|
|
||||||
@ -79,43 +79,43 @@ cat > $flake1Dir/flake.nix <<EOF
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cp ../simple.nix ../simple.builder.sh ../config.nix $flake1Dir/
|
cp ../simple.nix ../simple.builder.sh ../config.nix "$flake1Dir/"
|
||||||
|
|
||||||
echo bar > $flake1Dir/foo
|
echo bar > "$flake1Dir/foo"
|
||||||
|
|
||||||
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a1
|
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a1"
|
||||||
[[ -e $TEST_ROOT/result/simple.nix ]]
|
[[ -e $TEST_ROOT/result/simple.nix ]]
|
||||||
|
|
||||||
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a2
|
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a2"
|
||||||
[[ $(cat $TEST_ROOT/result) = bar ]]
|
[[ $(cat "$TEST_ROOT/result") = bar ]]
|
||||||
|
|
||||||
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a3
|
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a3"
|
||||||
|
|
||||||
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a4
|
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a4"
|
||||||
|
|
||||||
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a6
|
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a6"
|
||||||
[[ -e $TEST_ROOT/result/simple.nix ]]
|
[[ -e $TEST_ROOT/result/simple.nix ]]
|
||||||
|
|
||||||
nix build --impure --json --out-link $TEST_ROOT/result $flake1Dir#a8
|
nix build --impure --json --out-link "$TEST_ROOT/result" "$flake1Dir#a8"
|
||||||
diff common.sh $TEST_ROOT/result
|
diff common.sh "$TEST_ROOT/result"
|
||||||
|
|
||||||
expectStderr 1 nix build --impure --json --out-link $TEST_ROOT/result $flake1Dir#a9 \
|
expectStderr 1 nix build --impure --json --out-link "$TEST_ROOT/result" "$flake1Dir#a9" \
|
||||||
| grepQuiet "has 0 entries in its context. It should only have exactly one entry"
|
| grepQuiet "has 0 entries in its context. It should only have exactly one entry"
|
||||||
|
|
||||||
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a10
|
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir"#a10
|
||||||
[[ $(readlink -e $TEST_ROOT/result) = *simple.drv ]]
|
[[ $(readlink -e "$TEST_ROOT/result") = *simple.drv ]]
|
||||||
|
|
||||||
expectStderr 1 nix build --json --out-link $TEST_ROOT/result $flake1Dir#a11 \
|
expectStderr 1 nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a11" \
|
||||||
| grepQuiet "has a context which refers to a complete source and binary closure"
|
| grepQuiet "has a context which refers to a complete source and binary closure"
|
||||||
|
|
||||||
nix build --json --out-link $TEST_ROOT/result $flake1Dir#a12
|
nix build --json --out-link "$TEST_ROOT/result" "$flake1Dir#a12"
|
||||||
[[ -e $TEST_ROOT/result/hello ]]
|
[[ -e $TEST_ROOT/result/hello ]]
|
||||||
|
|
||||||
expectStderr 1 nix build --impure --json --out-link $TEST_ROOT/result $flake1Dir#a13 \
|
expectStderr 1 nix build --impure --json --out-link "$TEST_ROOT/result" "$flake1Dir#a13" \
|
||||||
| grepQuiet "has 2 entries in its context. It should only have exactly one entry"
|
| grepQuiet "has 2 entries in its context. It should only have exactly one entry"
|
||||||
|
|
||||||
# Test accessing output in installables with `.` (foobarbaz.<output>)
|
# Test accessing output in installables with `.` (foobarbaz.<output>)
|
||||||
nix build --json --no-link $flake1Dir#a14.foo | jq --exit-status '
|
nix build --json --no-link "$flake1Dir"#a14.foo | jq --exit-status '
|
||||||
(.[0] |
|
(.[0] |
|
||||||
(.drvPath | match(".*dot-installable.drv")) and
|
(.drvPath | match(".*dot-installable.drv")) and
|
||||||
(.outputs | keys == ["foo"]))
|
(.outputs | keys == ["foo"]))
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
cp ../simple.nix ../simple.builder.sh ../config.nix $TEST_HOME
|
cp ../simple.nix ../simple.builder.sh ../config.nix "$TEST_HOME"
|
||||||
|
|
||||||
cd $TEST_HOME
|
cd "$TEST_HOME"
|
||||||
|
|
||||||
cat <<EOF > flake.nix
|
cat <<EOF > flake.nix
|
||||||
{
|
{
|
||||||
@ -27,8 +27,8 @@ EOF
|
|||||||
|
|
||||||
nix build .#
|
nix build .#
|
||||||
nix bundle --bundler .# .#
|
nix bundle --bundler .# .#
|
||||||
nix bundle --bundler .#bundlers.$system.default .#packages.$system.default
|
nix bundle --bundler .#bundlers."$system".default .#packages."$system".default
|
||||||
nix bundle --bundler .#bundlers.$system.simple .#packages.$system.default
|
nix bundle --bundler .#bundlers."$system".simple .#packages."$system".default
|
||||||
|
|
||||||
nix bundle --bundler .#bundlers.$system.default .#apps.$system.default
|
nix bundle --bundler .#bundlers."$system".default .#apps."$system".default
|
||||||
nix bundle --bundler .#bundlers.$system.simple .#apps.$system.default
|
nix bundle --bundler .#bundlers."$system".simple .#apps."$system".default
|
||||||
|
@ -8,10 +8,10 @@ requireGit
|
|||||||
flakeA=$TEST_ROOT/flakeA
|
flakeA=$TEST_ROOT/flakeA
|
||||||
flakeB=$TEST_ROOT/flakeB
|
flakeB=$TEST_ROOT/flakeB
|
||||||
|
|
||||||
createGitRepo $flakeA
|
createGitRepo "$flakeA"
|
||||||
createGitRepo $flakeB
|
createGitRepo "$flakeB"
|
||||||
|
|
||||||
cat > $flakeA/flake.nix <<EOF
|
cat > "$flakeA"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
inputs.b.url = git+file://$flakeB;
|
inputs.b.url = git+file://$flakeB;
|
||||||
inputs.b.inputs.a.follows = "/";
|
inputs.b.inputs.a.follows = "/";
|
||||||
@ -23,9 +23,9 @@ cat > $flakeA/flake.nix <<EOF
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git -C $flakeA add flake.nix
|
git -C "$flakeA" add flake.nix
|
||||||
|
|
||||||
cat > $flakeB/flake.nix <<EOF
|
cat > "$flakeB"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
inputs.a.url = git+file://$flakeA;
|
inputs.a.url = git+file://$flakeA;
|
||||||
|
|
||||||
@ -35,18 +35,18 @@ cat > $flakeB/flake.nix <<EOF
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
git -C $flakeB add flake.nix
|
git -C "$flakeB" add flake.nix
|
||||||
git -C $flakeB commit -a -m 'Foo'
|
git -C "$flakeB" commit -a -m 'Foo'
|
||||||
|
|
||||||
[[ $(nix eval $flakeA#foo) = 1579 ]]
|
[[ $(nix eval "$flakeA#foo") = 1579 ]]
|
||||||
[[ $(nix eval $flakeA#foo) = 1579 ]]
|
[[ $(nix eval "$flakeA#foo") = 1579 ]]
|
||||||
|
|
||||||
sed -i $flakeB/flake.nix -e 's/456/789/'
|
sed -i "$flakeB"/flake.nix -e 's/456/789/'
|
||||||
git -C $flakeB commit -a -m 'Foo'
|
git -C "$flakeB" commit -a -m 'Foo'
|
||||||
|
|
||||||
nix flake update b --flake $flakeA
|
nix flake update b --flake "$flakeA"
|
||||||
[[ $(nix eval $flakeA#foo) = 1912 ]]
|
[[ $(nix eval "$flakeA#foo") = 1912 ]]
|
||||||
|
|
||||||
# Test list-inputs with circular dependencies
|
# Test list-inputs with circular dependencies
|
||||||
nix flake metadata $flakeA
|
nix flake metadata "$flakeA"
|
||||||
|
|
||||||
|
@ -27,8 +27,8 @@ rootRepo=$TEST_ROOT/rootRepo
|
|||||||
subRepo=$TEST_ROOT/submodule
|
subRepo=$TEST_ROOT/submodule
|
||||||
|
|
||||||
|
|
||||||
createGitRepo $subRepo
|
createGitRepo "$subRepo"
|
||||||
cat > $subRepo/flake.nix <<EOF
|
cat > "$subRepo"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
outputs = { self }: {
|
outputs = { self }: {
|
||||||
sub = import ./sub.nix;
|
sub = import ./sub.nix;
|
||||||
@ -36,28 +36,28 @@ cat > $subRepo/flake.nix <<EOF
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
echo '"expression in submodule"' > $subRepo/sub.nix
|
echo '"expression in submodule"' > "$subRepo"/sub.nix
|
||||||
git -C $subRepo add flake.nix sub.nix
|
git -C "$subRepo" add flake.nix sub.nix
|
||||||
git -C $subRepo commit -m Initial
|
git -C "$subRepo" commit -m Initial
|
||||||
|
|
||||||
createGitRepo $rootRepo
|
createGitRepo "$rootRepo"
|
||||||
|
|
||||||
git -C $rootRepo submodule init
|
git -C "$rootRepo" submodule init
|
||||||
git -C $rootRepo submodule add $subRepo submodule
|
git -C "$rootRepo" submodule add "$subRepo" submodule
|
||||||
echo '"expression in root repo"' > $rootRepo/root.nix
|
echo '"expression in root repo"' > "$rootRepo"/root.nix
|
||||||
git -C $rootRepo add root.nix
|
git -C "$rootRepo" add root.nix
|
||||||
git -C $rootRepo commit -m "Add root.nix"
|
git -C "$rootRepo" commit -m "Add root.nix"
|
||||||
|
|
||||||
flakeref=git+file://$rootRepo\?submodules=1\&dir=submodule
|
flakeref=git+file://$rootRepo\?submodules=1\&dir=submodule
|
||||||
|
|
||||||
# Flake can live inside a submodule and can be accessed via ?dir=submodule
|
# Flake can live inside a submodule and can be accessed via ?dir=submodule
|
||||||
[[ $(nix eval --json $flakeref#sub ) = '"expression in submodule"' ]]
|
[[ $(nix eval --json "$flakeref#sub" ) = '"expression in submodule"' ]]
|
||||||
|
|
||||||
# The flake can access content outside of the submodule
|
# The flake can access content outside of the submodule
|
||||||
[[ $(nix eval --json $flakeref#root ) = '"expression in root repo"' ]]
|
[[ $(nix eval --json "$flakeref#root" ) = '"expression in root repo"' ]]
|
||||||
|
|
||||||
# Check that dirtying a submodule makes the entire thing dirty.
|
# Check that dirtying a submodule makes the entire thing dirty.
|
||||||
[[ $(nix flake metadata --json $flakeref | jq -r .locked.rev) != null ]]
|
[[ $(nix flake metadata --json "$flakeref" | jq -r .locked.rev) != null ]]
|
||||||
echo '"foo"' > $rootRepo/submodule/sub.nix
|
echo '"foo"' > "$rootRepo"/submodule/sub.nix
|
||||||
[[ $(nix eval --json $flakeref#sub ) = '"foo"' ]]
|
[[ $(nix eval --json "$flakeref#sub" ) = '"foo"' ]]
|
||||||
[[ $(nix flake metadata --json $flakeref | jq -r .locked.rev) = null ]]
|
[[ $(nix flake metadata --json "$flakeref" | jq -r .locked.rev) = null ]]
|
||||||
|
@ -8,16 +8,16 @@ templatesDir=$TEST_ROOT/templates
|
|||||||
flakeDir=$TEST_ROOT/flake
|
flakeDir=$TEST_ROOT/flake
|
||||||
nixpkgsDir=$TEST_ROOT/nixpkgs
|
nixpkgsDir=$TEST_ROOT/nixpkgs
|
||||||
|
|
||||||
nix registry add --registry $registry templates git+file://$templatesDir
|
nix registry add --registry "$registry" templates "git+file://$templatesDir"
|
||||||
nix registry add --registry $registry nixpkgs git+file://$nixpkgsDir
|
nix registry add --registry "$registry" nixpkgs "git+file://$nixpkgsDir"
|
||||||
|
|
||||||
createGitRepo $nixpkgsDir
|
createGitRepo "$nixpkgsDir"
|
||||||
createSimpleGitFlake $nixpkgsDir
|
createSimpleGitFlake "$nixpkgsDir"
|
||||||
|
|
||||||
# Test 'nix flake init'.
|
# Test 'nix flake init'.
|
||||||
createGitRepo $templatesDir
|
createGitRepo "$templatesDir"
|
||||||
|
|
||||||
cat > $templatesDir/flake.nix <<EOF
|
cat > "$templatesDir"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
description = "Some templates";
|
description = "Some templates";
|
||||||
|
|
||||||
@ -36,9 +36,9 @@ cat > $templatesDir/flake.nix <<EOF
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
mkdir $templatesDir/trivial
|
mkdir "$templatesDir/trivial"
|
||||||
|
|
||||||
cat > $templatesDir/trivial/flake.nix <<EOF
|
cat > "$templatesDir"/trivial/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
description = "A flake for building Hello World";
|
description = "A flake for building Hello World";
|
||||||
|
|
||||||
@ -50,40 +50,40 @@ cat > $templatesDir/trivial/flake.nix <<EOF
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
echo a > $templatesDir/trivial/a
|
echo a > "$templatesDir/trivial/a"
|
||||||
echo b > $templatesDir/trivial/b
|
echo b > "$templatesDir/trivial/b"
|
||||||
|
|
||||||
git -C $templatesDir add flake.nix trivial/
|
git -C "$templatesDir" add flake.nix trivial/
|
||||||
git -C $templatesDir commit -m 'Initial'
|
git -C "$templatesDir" commit -m 'Initial'
|
||||||
|
|
||||||
nix flake check templates
|
nix flake check templates
|
||||||
nix flake show templates
|
nix flake show templates
|
||||||
nix flake show templates --json | jq
|
nix flake show templates --json | jq
|
||||||
|
|
||||||
createGitRepo $flakeDir
|
createGitRepo "$flakeDir"
|
||||||
(cd $flakeDir && nix flake init)
|
(cd "$flakeDir" && nix flake init)
|
||||||
(cd $flakeDir && nix flake init) # check idempotence
|
(cd "$flakeDir" && nix flake init) # check idempotence
|
||||||
git -C $flakeDir add flake.nix
|
git -C "$flakeDir" add flake.nix
|
||||||
nix flake check $flakeDir
|
nix flake check "$flakeDir"
|
||||||
nix flake show $flakeDir
|
nix flake show "$flakeDir"
|
||||||
nix flake show $flakeDir --json | jq
|
nix flake show "$flakeDir" --json | jq
|
||||||
git -C $flakeDir commit -a -m 'Initial'
|
git -C "$flakeDir" commit -a -m 'Initial'
|
||||||
|
|
||||||
# Test 'nix flake init' with benign conflicts
|
# Test 'nix flake init' with benign conflicts
|
||||||
createGitRepo "$flakeDir"
|
createGitRepo "$flakeDir"
|
||||||
echo a > $flakeDir/a
|
echo a > "$flakeDir/a"
|
||||||
(cd $flakeDir && nix flake init) # check idempotence
|
(cd "$flakeDir" && nix flake init) # check idempotence
|
||||||
|
|
||||||
# Test 'nix flake init' with conflicts
|
# Test 'nix flake init' with conflicts
|
||||||
createGitRepo "$flakeDir"
|
createGitRepo "$flakeDir"
|
||||||
echo b > $flakeDir/a
|
echo b > "$flakeDir/a"
|
||||||
pushd $flakeDir
|
pushd "$flakeDir"
|
||||||
(! nix flake init) |& grep "refusing to overwrite existing file '$flakeDir/a'"
|
(! nix flake init) |& grep "refusing to overwrite existing file '$flakeDir/a'"
|
||||||
popd
|
popd
|
||||||
git -C $flakeDir commit -a -m 'Changed'
|
git -C "$flakeDir" commit -a -m 'Changed'
|
||||||
|
|
||||||
# Test 'nix flake new'.
|
# Test 'nix flake new'.
|
||||||
rm -rf $flakeDir
|
rm -rf "$flakeDir"
|
||||||
nix flake new -t templates#trivial $flakeDir
|
nix flake new -t templates#trivial "$flakeDir"
|
||||||
nix flake new -t templates#trivial $flakeDir # check idempotence
|
nix flake new -t templates#trivial "$flakeDir" # check idempotence
|
||||||
nix flake check $flakeDir
|
nix flake check "$flakeDir"
|
||||||
|
@ -8,12 +8,12 @@ requireGit
|
|||||||
test_subdir_self_path() {
|
test_subdir_self_path() {
|
||||||
baseDir=$TEST_ROOT/$RANDOM
|
baseDir=$TEST_ROOT/$RANDOM
|
||||||
flakeDir=$baseDir/b-low
|
flakeDir=$baseDir/b-low
|
||||||
mkdir -p $flakeDir
|
mkdir -p "$flakeDir"
|
||||||
writeSimpleFlake $baseDir
|
writeSimpleFlake "$baseDir"
|
||||||
writeSimpleFlake $flakeDir
|
writeSimpleFlake "$flakeDir"
|
||||||
|
|
||||||
echo all good > $flakeDir/message
|
echo all good > "$flakeDir/message"
|
||||||
cat > $flakeDir/flake.nix <<EOF
|
cat > "$flakeDir"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
outputs = inputs: rec {
|
outputs = inputs: rec {
|
||||||
packages.$system = rec {
|
packages.$system = rec {
|
||||||
@ -26,7 +26,7 @@ test_subdir_self_path() {
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
(
|
(
|
||||||
nix build $baseDir?dir=b-low --no-link
|
nix build "$baseDir"?dir=b-low --no-link
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
test_subdir_self_path
|
test_subdir_self_path
|
||||||
@ -34,14 +34,14 @@ test_subdir_self_path
|
|||||||
|
|
||||||
test_git_subdir_self_path() {
|
test_git_subdir_self_path() {
|
||||||
repoDir=$TEST_ROOT/repo-$RANDOM
|
repoDir=$TEST_ROOT/repo-$RANDOM
|
||||||
createGitRepo $repoDir
|
createGitRepo "$repoDir"
|
||||||
flakeDir=$repoDir/b-low
|
flakeDir=$repoDir/b-low
|
||||||
mkdir -p $flakeDir
|
mkdir -p "$flakeDir"
|
||||||
writeSimpleFlake $repoDir
|
writeSimpleFlake "$repoDir"
|
||||||
writeSimpleFlake $flakeDir
|
writeSimpleFlake "$flakeDir"
|
||||||
|
|
||||||
echo all good > $flakeDir/message
|
echo all good > "$flakeDir/message"
|
||||||
cat > $flakeDir/flake.nix <<EOF
|
cat > "$flakeDir"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
outputs = inputs: rec {
|
outputs = inputs: rec {
|
||||||
packages.$system = rec {
|
packages.$system = rec {
|
||||||
@ -55,15 +55,15 @@ test_git_subdir_self_path() {
|
|||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
(
|
(
|
||||||
cd $flakeDir
|
cd "$flakeDir"
|
||||||
git add .
|
git add .
|
||||||
git commit -m init
|
git commit -m init
|
||||||
# nix build
|
# nix build
|
||||||
)
|
)
|
||||||
|
|
||||||
clientDir=$TEST_ROOT/client-$RANDOM
|
clientDir=$TEST_ROOT/client-$RANDOM
|
||||||
mkdir -p $clientDir
|
mkdir -p "$clientDir"
|
||||||
cat > $clientDir/flake.nix <<EOF
|
cat > "$clientDir"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
inputs.inp = {
|
inputs.inp = {
|
||||||
type = "git";
|
type = "git";
|
||||||
@ -76,7 +76,7 @@ EOF
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
nix build $clientDir --no-link
|
nix build "$clientDir" --no-link
|
||||||
|
|
||||||
}
|
}
|
||||||
test_git_subdir_self_path
|
test_git_subdir_self_path
|
||||||
|
@ -5,41 +5,41 @@ source ./common.sh
|
|||||||
[[ $(type -p hg) ]] || skipTest "Mercurial not installed"
|
[[ $(type -p hg) ]] || skipTest "Mercurial not installed"
|
||||||
|
|
||||||
flake1Dir=$TEST_ROOT/flake-hg1
|
flake1Dir=$TEST_ROOT/flake-hg1
|
||||||
mkdir -p $flake1Dir
|
mkdir -p "$flake1Dir"
|
||||||
writeSimpleFlake $flake1Dir
|
writeSimpleFlake "$flake1Dir"
|
||||||
hg init $flake1Dir
|
hg init "$flake1Dir"
|
||||||
|
|
||||||
nix registry add --registry $registry flake1 hg+file://$flake1Dir
|
nix registry add --registry "$registry" flake1 "hg+file://$flake1Dir"
|
||||||
|
|
||||||
flake2Dir=$TEST_ROOT/flake-hg2
|
flake2Dir=$TEST_ROOT/flake-hg2
|
||||||
mkdir -p $flake2Dir
|
mkdir -p "$flake2Dir"
|
||||||
writeDependentFlake $flake2Dir
|
writeDependentFlake "$flake2Dir"
|
||||||
hg init $flake2Dir
|
hg init "$flake2Dir"
|
||||||
|
|
||||||
hg add $flake1Dir/*
|
hg add "$flake1Dir"/*
|
||||||
hg commit --config ui.username=foobar@example.org $flake1Dir -m 'Initial commit'
|
hg commit --config ui.username=foobar@example.org "$flake1Dir" -m 'Initial commit'
|
||||||
|
|
||||||
hg add $flake2Dir/flake.nix
|
hg add "$flake2Dir"/flake.nix
|
||||||
hg commit --config ui.username=foobar@example.org $flake2Dir -m 'Initial commit'
|
hg commit --config ui.username=foobar@example.org "$flake2Dir" -m 'Initial commit'
|
||||||
|
|
||||||
nix build -o $TEST_ROOT/result hg+file://$flake2Dir
|
nix build -o "$TEST_ROOT/result" "hg+file://$flake2Dir"
|
||||||
[[ -e $TEST_ROOT/result/hello ]]
|
[[ -e $TEST_ROOT/result/hello ]]
|
||||||
|
|
||||||
(! nix flake metadata --json hg+file://$flake2Dir | jq -e -r .revision)
|
(! nix flake metadata --json "hg+file://$flake2Dir" | jq -e -r .revision)
|
||||||
|
|
||||||
nix eval hg+file://$flake2Dir#expr
|
nix eval "hg+file://$flake2Dir"#expr
|
||||||
|
|
||||||
nix eval hg+file://$flake2Dir#expr
|
nix eval "hg+file://$flake2Dir"#expr
|
||||||
|
|
||||||
(! nix eval hg+file://$flake2Dir#expr --no-allow-dirty)
|
(! nix eval "hg+file://$flake2Dir"#expr --no-allow-dirty)
|
||||||
|
|
||||||
(! nix flake metadata --json hg+file://$flake2Dir | jq -e -r .revision)
|
(! nix flake metadata --json "hg+file://$flake2Dir" | jq -e -r .revision)
|
||||||
|
|
||||||
hg commit --config ui.username=foobar@example.org $flake2Dir -m 'Add lock file'
|
hg commit --config ui.username=foobar@example.org "$flake2Dir" -m 'Add lock file'
|
||||||
|
|
||||||
nix flake metadata --json hg+file://$flake2Dir --refresh | jq -e -r .revision
|
nix flake metadata --json "hg+file://$flake2Dir" --refresh | jq -e -r .revision
|
||||||
nix flake metadata --json hg+file://$flake2Dir
|
nix flake metadata --json "hg+file://$flake2Dir"
|
||||||
[[ $(nix flake metadata --json hg+file://$flake2Dir | jq -e -r .revCount) = 1 ]]
|
[[ $(nix flake metadata --json "hg+file://$flake2Dir" | jq -e -r .revCount) = 1 ]]
|
||||||
|
|
||||||
nix build -o $TEST_ROOT/result hg+file://$flake2Dir --no-registries --no-allow-dirty
|
nix build -o "$TEST_ROOT/result" "hg+file://$flake2Dir" --no-registries --no-allow-dirty
|
||||||
nix build -o $TEST_ROOT/result hg+file://$flake2Dir --no-use-registries --no-allow-dirty
|
nix build -o "$TEST_ROOT/result" "hg+file://$flake2Dir" --no-use-registries --no-allow-dirty
|
||||||
|
@ -4,8 +4,8 @@ source common.sh
|
|||||||
|
|
||||||
clearStore
|
clearStore
|
||||||
|
|
||||||
writeSimpleFlake $TEST_HOME
|
writeSimpleFlake "$TEST_HOME"
|
||||||
cd $TEST_HOME
|
cd "$TEST_HOME"
|
||||||
mkdir -p foo/subdir
|
mkdir -p foo/subdir
|
||||||
|
|
||||||
echo '{ outputs = _: {}; }' > foo/flake.nix
|
echo '{ outputs = _: {}; }' > foo/flake.nix
|
||||||
@ -27,11 +27,11 @@ success=("" . .# .#test ../subdir ../subdir#test "$PWD")
|
|||||||
failure=("path:$PWD" "../simple.nix")
|
failure=("path:$PWD" "../simple.nix")
|
||||||
|
|
||||||
for i in "${success[@]}"; do
|
for i in "${success[@]}"; do
|
||||||
nix build $i || fail "flake should be found by searching up directories"
|
nix build "$i" || fail "flake should be found by searching up directories"
|
||||||
done
|
done
|
||||||
|
|
||||||
for i in "${failure[@]}"; do
|
for i in "${failure[@]}"; do
|
||||||
! nix build $i || fail "flake should not search up directories when using 'path:'"
|
! nix build "$i" || fail "flake should not search up directories when using 'path:'"
|
||||||
done
|
done
|
||||||
|
|
||||||
popd
|
popd
|
||||||
@ -45,7 +45,7 @@ if [[ -n $(type -p git) ]]; then
|
|||||||
pushd subdir
|
pushd subdir
|
||||||
git init
|
git init
|
||||||
for i in "${success[@]}" "${failure[@]}"; do
|
for i in "${success[@]}" "${failure[@]}"; do
|
||||||
! nix build $i || fail "flake should not search past a git repository"
|
! nix build "$i" || fail "flake should not search past a git repository"
|
||||||
done
|
done
|
||||||
rm -rf .git
|
rm -rf .git
|
||||||
popd
|
popd
|
||||||
|
@ -7,26 +7,26 @@ requireGit
|
|||||||
flake1Dir=$TEST_ROOT/flake1
|
flake1Dir=$TEST_ROOT/flake1
|
||||||
flake2Dir=$TEST_ROOT/flake2
|
flake2Dir=$TEST_ROOT/flake2
|
||||||
|
|
||||||
createGitRepo $flake1Dir
|
createGitRepo "$flake1Dir"
|
||||||
cat > $flake1Dir/flake.nix <<EOF
|
cat > "$flake1Dir"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
outputs = { self }: { x = import ./x.nix; };
|
outputs = { self }: { x = import ./x.nix; };
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
echo 123 > $flake1Dir/x.nix
|
echo 123 > "$flake1Dir"/x.nix
|
||||||
git -C $flake1Dir add flake.nix x.nix
|
git -C "$flake1Dir" add flake.nix x.nix
|
||||||
git -C $flake1Dir commit -m Initial
|
git -C "$flake1Dir" commit -m Initial
|
||||||
|
|
||||||
createGitRepo $flake2Dir
|
createGitRepo "$flake2Dir"
|
||||||
cat > $flake2Dir/flake.nix <<EOF
|
cat > "$flake2Dir"/flake.nix <<EOF
|
||||||
{
|
{
|
||||||
outputs = { self, flake1 }: { x = flake1.x; };
|
outputs = { self, flake1 }: { x = flake1.x; };
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
git -C $flake2Dir add flake.nix
|
git -C "$flake2Dir" add flake.nix
|
||||||
|
|
||||||
[[ $(nix eval --json $flake2Dir#x --override-input flake1 $TEST_ROOT/flake1) = 123 ]]
|
[[ $(nix eval --json "$flake2Dir#x" --override-input flake1 "$TEST_ROOT/flake1") = 123 ]]
|
||||||
|
|
||||||
echo 456 > $flake1Dir/x.nix
|
echo 456 > "$flake1Dir"/x.nix
|
||||||
|
|
||||||
[[ $(nix eval --json $flake2Dir#x --override-input flake1 $TEST_ROOT/flake1) = 456 ]]
|
[[ $(nix eval --json "$flake2Dir#x" --override-input flake1 "$TEST_ROOT/flake1") = 456 ]]
|
||||||
|
@ -21,12 +21,12 @@ expect_trace() {
|
|||||||
<(echo "$expect") \
|
<(echo "$expect") \
|
||||||
<(echo "$actual")
|
<(echo "$actual")
|
||||||
) && result=0 || result=$?
|
) && result=0 || result=$?
|
||||||
if [ $result -eq 0 ]; then
|
if [ "$result" -eq 0 ]; then
|
||||||
echo " ok."
|
echo " ok."
|
||||||
else
|
else
|
||||||
echo " failed. difference:"
|
echo " failed. difference:"
|
||||||
echo "$msg"
|
echo "$msg"
|
||||||
return $result
|
return "$result"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ outPath3=$(nix-store -r $drvPath3)
|
|||||||
touch $outPath3.lock
|
touch $outPath3.lock
|
||||||
|
|
||||||
rm -f "$NIX_STATE_DIR"/gcroots/foo*
|
rm -f "$NIX_STATE_DIR"/gcroots/foo*
|
||||||
ln -s $drvPath2 "$NIX_STATE_DIR"/gcroots/foo
|
ln -s $drvPath2 "$NIX_STATE_DIR/gcroots/foo"
|
||||||
ln -s $outPath3 "$NIX_STATE_DIR"/gcroots/foo2
|
ln -s $outPath3 "$NIX_STATE_DIR/gcroots/foo2"
|
||||||
|
|
||||||
# Start build #1 in the background. It starts immediately.
|
# Start build #1 in the background. It starts immediately.
|
||||||
nix-store -rvv "$drvPath1" &
|
nix-store -rvv "$drvPath1" &
|
||||||
|
@ -12,27 +12,27 @@ esac
|
|||||||
set -m # enable job control, needed for kill
|
set -m # enable job control, needed for kill
|
||||||
|
|
||||||
profiles="$NIX_STATE_DIR"/profiles
|
profiles="$NIX_STATE_DIR"/profiles
|
||||||
rm -rf $profiles
|
rm -rf "$profiles"
|
||||||
|
|
||||||
nix-env -p $profiles/test -f ./gc-runtime.nix -i gc-runtime
|
nix-env -p "$profiles/test" -f ./gc-runtime.nix -i gc-runtime
|
||||||
|
|
||||||
outPath=$(nix-env -p $profiles/test -q --no-name --out-path gc-runtime)
|
outPath=$(nix-env -p "$profiles/test" -q --no-name --out-path gc-runtime)
|
||||||
echo $outPath
|
echo "$outPath"
|
||||||
|
|
||||||
echo "backgrounding program..."
|
echo "backgrounding program..."
|
||||||
$profiles/test/program &
|
"$profiles"/test/program &
|
||||||
sleep 2 # hack - wait for the program to get started
|
sleep 2 # hack - wait for the program to get started
|
||||||
child=$!
|
child=$!
|
||||||
echo PID=$child
|
echo PID=$child
|
||||||
|
|
||||||
nix-env -p $profiles/test -e gc-runtime
|
nix-env -p "$profiles/test" -e gc-runtime
|
||||||
nix-env -p $profiles/test --delete-generations old
|
nix-env -p "$profiles/test" --delete-generations old
|
||||||
|
|
||||||
nix-store --gc
|
nix-store --gc
|
||||||
|
|
||||||
kill -- -$child
|
kill -- -$child
|
||||||
|
|
||||||
if ! test -e $outPath; then
|
if ! test -e "$outPath"; then
|
||||||
echo "running program was garbage collected!"
|
echo "running program was garbage collected!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
@ -8,8 +8,8 @@ drvPath=$(nix-instantiate dependencies.nix)
|
|||||||
outPath=$(nix-store -rvv "$drvPath")
|
outPath=$(nix-store -rvv "$drvPath")
|
||||||
|
|
||||||
# Set a GC root.
|
# Set a GC root.
|
||||||
rm -f "$NIX_STATE_DIR"/gcroots/foo
|
rm -f "$NIX_STATE_DIR/gcroots/foo"
|
||||||
ln -sf $outPath "$NIX_STATE_DIR"/gcroots/foo
|
ln -sf $outPath "$NIX_STATE_DIR/gcroots/foo"
|
||||||
|
|
||||||
[ "$(nix-store -q --roots $outPath)" = "$NIX_STATE_DIR/gcroots/foo -> $outPath" ]
|
[ "$(nix-store -q --roots $outPath)" = "$NIX_STATE_DIR/gcroots/foo -> $outPath" ]
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ cat $outPath/reference-to-input-2/bar
|
|||||||
# Check that the derivation has been GC'd.
|
# Check that the derivation has been GC'd.
|
||||||
if test -e $drvPath; then false; fi
|
if test -e $drvPath; then false; fi
|
||||||
|
|
||||||
rm "$NIX_STATE_DIR"/gcroots/foo
|
rm "$NIX_STATE_DIR/gcroots/foo"
|
||||||
|
|
||||||
nix-collect-garbage
|
nix-collect-garbage
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
source common.sh
|
source common.sh
|
||||||
|
|
||||||
try () {
|
try () {
|
||||||
printf "%s" "$2" > $TEST_ROOT/vector
|
printf "%s" "$2" > "$TEST_ROOT/vector"
|
||||||
hash="$(nix-hash --flat ${FORMAT+--$FORMAT} --type "$1" "$TEST_ROOT/vector")"
|
hash="$(nix-hash --flat ${FORMAT+--$FORMAT} --type "$1" "$TEST_ROOT/vector")"
|
||||||
if ! (( "${NO_TEST_CLASSIC-}" )) && test "$hash" != "$3"; then
|
if ! (( "${NO_TEST_CLASSIC-}" )) && test "$hash" != "$3"; then
|
||||||
echo "try nix-hash: hash $1, expected $3, got $hash"
|
echo "try nix-hash: hash $1, expected $3, got $hash"
|
||||||
@ -61,7 +61,7 @@ NO_TEST_NIX_COMMAND=1 try sha512 "abc" "ddaf35a193617abacc417349ae20413112e6fa4e
|
|||||||
NO_TEST_CLASSIC=1 try sha512 "abc" "sha512-3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw=="
|
NO_TEST_CLASSIC=1 try sha512 "abc" "sha512-3a81oZNherrMQXNJriBBMRLm+k6JqX6iCp7u5ktV05ohkpkqJ0/BqDa6PCOj/uu9RU1EI2Q86A4qmslPpUyknw=="
|
||||||
|
|
||||||
try2 () {
|
try2 () {
|
||||||
hash=$(nix-hash --type "$1" $TEST_ROOT/hash-path)
|
hash=$(nix-hash --type "$1" "$TEST_ROOT/hash-path")
|
||||||
if test "$hash" != "$2"; then
|
if test "$hash" != "$2"; then
|
||||||
echo "try nix-hash; hash $1, expected $2, got $hash"
|
echo "try nix-hash; hash $1, expected $2, got $hash"
|
||||||
exit 1
|
exit 1
|
||||||
@ -73,22 +73,22 @@ try2 () {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
rm -rf $TEST_ROOT/hash-path
|
rm -rf "$TEST_ROOT/hash-path"
|
||||||
mkdir $TEST_ROOT/hash-path
|
mkdir "$TEST_ROOT/hash-path"
|
||||||
echo "Hello World" > $TEST_ROOT/hash-path/hello
|
echo "Hello World" > "$TEST_ROOT/hash-path/hello"
|
||||||
|
|
||||||
try2 md5 "ea9b55537dd4c7e104515b2ccfaf4100"
|
try2 md5 "ea9b55537dd4c7e104515b2ccfaf4100"
|
||||||
|
|
||||||
# Execute bit matters.
|
# Execute bit matters.
|
||||||
chmod +x $TEST_ROOT/hash-path/hello
|
chmod +x "$TEST_ROOT/hash-path/hello"
|
||||||
try2 md5 "20f3ffe011d4cfa7d72bfabef7882836"
|
try2 md5 "20f3ffe011d4cfa7d72bfabef7882836"
|
||||||
|
|
||||||
# Mtime and other bits don't.
|
# Mtime and other bits don't.
|
||||||
touch -r . $TEST_ROOT/hash-path/hello
|
touch -r . "$TEST_ROOT/hash-path/hello"
|
||||||
chmod 744 $TEST_ROOT/hash-path/hello
|
chmod 744 "$TEST_ROOT/hash-path/hello"
|
||||||
try2 md5 "20f3ffe011d4cfa7d72bfabef7882836"
|
try2 md5 "20f3ffe011d4cfa7d72bfabef7882836"
|
||||||
|
|
||||||
# File type (e.g., symlink) does.
|
# File type (e.g., symlink) does.
|
||||||
rm $TEST_ROOT/hash-path/hello
|
rm "$TEST_ROOT/hash-path/hello"
|
||||||
ln -s x $TEST_ROOT/hash-path/hello
|
ln -s x "$TEST_ROOT/hash-path/hello"
|
||||||
try2 md5 "f78b733a68f5edbdf9413899339eaa4a"
|
try2 md5 "f78b733a68f5edbdf9413899339eaa4a"
|
||||||
|
@ -11,4 +11,4 @@ fi
|
|||||||
|
|
||||||
outPath=$(nix-build ./import-derivation.nix --no-out-link)
|
outPath=$(nix-build ./import-derivation.nix --no-out-link)
|
||||||
|
|
||||||
[ "$(cat $outPath)" = FOO579 ]
|
[ "$(cat "$outPath")" = FOO579 ]
|
||||||
|
@ -29,7 +29,7 @@ error:
|
|||||||
| ^
|
| ^
|
||||||
2|
|
2|
|
||||||
|
|
||||||
(19997 duplicate frames omitted)
|
(197 duplicate frames omitted)
|
||||||
|
|
||||||
error: stack overflow; max-call-depth exceeded
|
error: stack overflow; max-call-depth exceeded
|
||||||
at /pwd/lang/eval-fail-infinite-recursion-lambda.nix:1:14:
|
at /pwd/lang/eval-fail-infinite-recursion-lambda.nix:1:14:
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
--max-call-depth 100
|
@ -20,8 +20,8 @@ outPath=$(nix-build ../hermetic.nix --no-out-link --arg busybox "$busybox" --arg
|
|||||||
|
|
||||||
# Set a GC root.
|
# Set a GC root.
|
||||||
mkdir -p "$stateB"
|
mkdir -p "$stateB"
|
||||||
rm -f "$stateB"/gcroots/foo
|
rm -f "$stateB/gcroots/foo"
|
||||||
ln -sf $outPath "$stateB"/gcroots/foo
|
ln -sf $outPath "$stateB/gcroots/foo"
|
||||||
|
|
||||||
[ "$(nix-store -q --roots $outPath)" = "$stateB/gcroots/foo -> $outPath" ]
|
[ "$(nix-store -q --roots $outPath)" = "$stateB/gcroots/foo -> $outPath" ]
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ nix-collect-garbage
|
|||||||
# Check that the root and its dependencies haven't been deleted.
|
# Check that the root and its dependencies haven't been deleted.
|
||||||
cat "$storeBRoot/$outPath"
|
cat "$storeBRoot/$outPath"
|
||||||
|
|
||||||
rm "$stateB"/gcroots/foo
|
rm "$stateB/gcroots/foo"
|
||||||
|
|
||||||
nix-collect-garbage
|
nix-collect-garbage
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ outPath=$(nix-store -q $drvPath)
|
|||||||
echo "building b..."
|
echo "building b..."
|
||||||
outPath=$(nix-build multiple-outputs.nix -A b --no-out-link)
|
outPath=$(nix-build multiple-outputs.nix -A b --no-out-link)
|
||||||
echo "output path is $outPath"
|
echo "output path is $outPath"
|
||||||
[ "$(cat "$outPath"/file)" = "success" ]
|
[ "$(cat "$outPath/file")" = "success" ]
|
||||||
|
|
||||||
# Test nix-build on a derivation with multiple outputs.
|
# Test nix-build on a derivation with multiple outputs.
|
||||||
outPath1=$(nix-build multiple-outputs.nix -A a -o $TEST_ROOT/result)
|
outPath1=$(nix-build multiple-outputs.nix -A a -o $TEST_ROOT/result)
|
||||||
|
@ -7,7 +7,7 @@ clearStore
|
|||||||
outPath=$(nix-build --no-out-link readfile-context.nix)
|
outPath=$(nix-build --no-out-link readfile-context.nix)
|
||||||
|
|
||||||
# Set a GC root.
|
# Set a GC root.
|
||||||
ln -s $outPath "$NIX_STATE_DIR"/gcroots/foo
|
ln -s $outPath "$NIX_STATE_DIR/gcroots/foo"
|
||||||
|
|
||||||
# Check that file exists.
|
# Check that file exists.
|
||||||
[ "$(cat $(cat $outPath))" = "Hello World!" ]
|
[ "$(cat $(cat $outPath))" = "Hello World!" ]
|
||||||
|
@ -31,7 +31,7 @@ echo "registering..."
|
|||||||
nix-store --register-validity < $TEST_ROOT/reg_info
|
nix-store --register-validity < $TEST_ROOT/reg_info
|
||||||
|
|
||||||
echo "collecting garbage..."
|
echo "collecting garbage..."
|
||||||
ln -sfn $reference "$NIX_STATE_DIR"/gcroots/ref
|
ln -sfn $reference "$NIX_STATE_DIR/gcroots/ref"
|
||||||
nix-store --gc
|
nix-store --gc
|
||||||
|
|
||||||
if [ -n "$(type -p sqlite3)" -a "$(sqlite3 $NIX_STATE_DIR/db/db.sqlite 'select count(*) from Refs')" -ne 0 ]; then
|
if [ -n "$(type -p sqlite3)" -a "$(sqlite3 $NIX_STATE_DIR/db/db.sqlite 'select count(*) from Refs')" -ne 0 ]; then
|
||||||
|
@ -14,7 +14,7 @@ echo "output path is $outPath"
|
|||||||
|
|
||||||
(! [ -w $outPath ])
|
(! [ -w $outPath ])
|
||||||
|
|
||||||
text=$(cat "$outPath"/hello)
|
text=$(cat "$outPath/hello")
|
||||||
if test "$text" != "Hello World!"; then exit 1; fi
|
if test "$text" != "Hello World!"; then exit 1; fi
|
||||||
|
|
||||||
# Directed delete: $outPath is not reachable from a root, so it should
|
# Directed delete: $outPath is not reachable from a root, so it should
|
||||||
|
@ -25,7 +25,7 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
EvalState * state;
|
EvalState * state;
|
||||||
Value * value;
|
nix_value * value;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ programs += libexpr-tests
|
|||||||
|
|
||||||
libexpr-tests_NAME := libnixexpr-tests
|
libexpr-tests_NAME := libnixexpr-tests
|
||||||
|
|
||||||
libexpr-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data
|
libexpr-tests_ENV := _NIX_TEST_UNIT_DATA=$(d)/data GTEST_OUTPUT=xml:$$testresults/libexpr-tests.xml
|
||||||
|
|
||||||
libexpr-tests_DIR := $(d)
|
libexpr-tests_DIR := $(d)
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user