Skip to content

Commit

Permalink
python bindings: Make IFD work by default
Browse files Browse the repository at this point in the history
  • Loading branch information
infinisil committed Feb 1, 2023
1 parent 27e9000 commit 289fc33
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 1 deletion.
14 changes: 14 additions & 0 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,10 @@
final.buildPackages.nix
];

mesonFlags = [
"-Dnix_binary=${final.lib.getBin final.nix}/bin/nix"
];

strictDeps = true;

buildInputs = [
Expand All @@ -419,6 +423,16 @@
installCheckPhase = ''
export TEST_ROOT=$(mktemp -d)
export NIX_STATE_DIR=$TEST_ROOT/var/nix
export NIX_STORE_DIR=$TEST_ROOT/store
export NIX_LOCALSTATE_DIR=$TEST_ROOT/var
export NIX_LOG_DIR=$TEST_ROOT/var/log/nix
export NIX_CONF_DIR=$TEST_ROOT/etc
mkdir "$NIX_CONF_DIR"
cat > "$NIX_CONF_DIR"/nix.conf <<EOF
sandbox = false
substituters =
EOF
export PYTHONPATH=$out/${python.sitePackages}
Expand Down
1 change: 1 addition & 0 deletions python/meson_options.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
option('nix_binary', type : 'string', description : 'An option')
7 changes: 7 additions & 0 deletions python/src/eval.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ PyObject *eval(PyObject *self, PyObject *args, PyObject *keywds) {
PyObject *vars = nullptr;

// TODO: Only do this once
// By default, Nix sets the build-hook to be "$(readlink /proc/self/exe) __build-remote", expecting the current binary to be Nix itself.
// But when we call the Nix library from Python this isn't the case, the current binary is Python then
// So we need to change this default, pointing it to the Nix binary instead
// Because we can't know the path to the Nix binary from here, we use a preprocessor macro,
// which we can then influence from Meson, which we can then influence from the Nix build definition
nix::settings.buildHook = NIX_BUILD_HOOK;
// And by setting buildHook before calling initNix, we can override the defaults without overriding the user-provided options from the config files
nix::initNix();

const char *kwlist[] = {"expression", "vars", nullptr};
Expand Down
6 changes: 5 additions & 1 deletion python/src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ python_mod.extension_module('nix', src,
dependencies : [python_dep, nix_expr_dep, nix_main_dep],
install: true,
install_dir: python_mod.sysconfig_path('platlib'),
cpp_args: ['-std=c++17', '-fvisibility=hidden'])
cpp_args: [
'-std=c++17',
'-fvisibility=hidden',
'-DNIX_BUILD_HOOK="' + get_option('nix_binary') + ' __build-remote"',
])
11 changes: 11 additions & 0 deletions python/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,16 @@ def test_bool(self):
def test_none(self):
self.assertEqual(nix.eval("a", vars=dict(a=None)), None)

def test_ifd(self):
expression = """
builtins.readFile (derivation {
name = "test";
args = [ "-c" "echo -n test > $out" ];
builder = "/bin/sh";
system = builtins.currentSystem;
})
"""
self.assertEqual(nix.eval(expression, vars=dict()), "test")

if __name__ == '__main__':
unittest.main()

0 comments on commit 289fc33

Please sign in to comment.