Skip to content

Commit 4efda64

Browse files
committed
libexpr-c: fix changing eval settings having no effect
Using the Rust bindings (which call into the C bindings) to set eval-related settings was not working. Since EvalSettings were defined in libcmd, we need to move them to libexpr if libexpr-c wants to use them. Since libcmd enforces a dependency on libflake, we also need to modify config-global to absorb duplicate registrations and support callbacks for customizing behavior that we only need in libcmd. Note that we add back some of the global setting variables with this, but this does fix the C API.
1 parent 2ba1402 commit 4efda64

File tree

8 files changed

+39
-21
lines changed

8 files changed

+39
-21
lines changed

src/libcmd/common-eval-args.cc

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@
1919

2020
namespace nix {
2121

22-
EvalSettings evalSettings{
23-
settings.readOnlyMode,
24-
{
22+
static GlobalConfig::Register rEvalSettings(&evalSettings, [] {
23+
evalSettings.lookupPathHooks = {
2524
{
2625
"flake",
2726
[](EvalState & state, std::string_view rest) {
@@ -40,10 +39,8 @@ EvalSettings evalSettings{
4039
return state.storePath(storePath);
4140
},
4241
},
43-
},
44-
};
45-
46-
static GlobalConfig::Register rEvalSettings(&evalSettings);
42+
};
43+
});
4744

4845
flake::Settings flakeSettings;
4946

src/libexpr-c/nix_api_expr.cc

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "nix/expr/eval-gc.hh"
77
#include "nix/store/globals.hh"
88
#include "nix/expr/eval-settings.hh"
9+
#include "nix/fetchers/fetch-settings.hh"
910
#include "nix/util/ref.hh"
1011

1112
#include "nix_api_expr.h"
@@ -137,8 +138,8 @@ nix_eval_state_builder * nix_eval_state_builder_new(nix_c_context * context, Sto
137138
return unsafe_new_with_self<nix_eval_state_builder>([&](auto * self) {
138139
return nix_eval_state_builder{
139140
.store = nix::ref<nix::Store>(store->ptr),
140-
.settings = nix::EvalSettings{/* &bool */ self->readOnlyMode},
141-
.fetchSettings = nix::fetchers::Settings{},
141+
.settings = &nix::evalSettings,
142+
.fetchSettings = &nix::fetchSettings,
142143
.readOnlyMode = true,
143144
};
144145
});
@@ -159,9 +160,9 @@ nix_err nix_eval_state_builder_load(nix_c_context * context, nix_eval_state_buil
159160
context->last_err_code = NIX_OK;
160161
try {
161162
// TODO: load in one go?
162-
builder->settings.readOnlyMode = nix::settings.readOnlyMode;
163-
loadConfFile(builder->settings);
164-
loadConfFile(builder->fetchSettings);
163+
builder->settings->readOnlyMode = nix::settings.readOnlyMode;
164+
loadConfFile(*builder->settings);
165+
loadConfFile(*builder->fetchSettings);
165166
}
166167
NIXC_CATCH_ERRS
167168
}
@@ -188,9 +189,9 @@ EvalState * nix_eval_state_build(nix_c_context * context, nix_eval_state_builder
188189
try {
189190
return unsafe_new_with_self<EvalState>([&](auto * self) {
190191
return EvalState{
191-
.fetchSettings = std::move(builder->fetchSettings),
192-
.settings = std::move(builder->settings),
193-
.state = nix::EvalState(builder->lookupPath, builder->store, self->fetchSettings, self->settings),
192+
.fetchSettings = builder->fetchSettings,
193+
.settings = builder->settings,
194+
.state = nix::EvalState(builder->lookupPath, builder->store, *self->fetchSettings, *self->settings),
194195
};
195196
});
196197
}

src/libexpr-c/nix_api_expr_internal.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,17 @@ extern "C" {
1313
struct nix_eval_state_builder
1414
{
1515
nix::ref<nix::Store> store;
16-
nix::EvalSettings settings;
17-
nix::fetchers::Settings fetchSettings;
16+
nix::EvalSettings * settings;
17+
nix::fetchers::Settings * fetchSettings;
1818
nix::LookupPath lookupPath;
1919
// TODO: make an EvalSettings setting own this instead?
2020
bool readOnlyMode;
2121
};
2222

2323
struct EvalState
2424
{
25-
nix::fetchers::Settings fetchSettings;
26-
nix::EvalSettings settings;
25+
nix::fetchers::Settings * fetchSettings;
26+
nix::EvalSettings * settings;
2727
nix::EvalState state;
2828
};
2929

src/libexpr/eval-settings.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "nix/util/users.hh"
2+
#include "nix/util/config-global.hh"
23
#include "nix/store/globals.hh"
34
#include "nix/store/profiles.hh"
45
#include "nix/expr/eval.hh"
@@ -118,4 +119,8 @@ std::filesystem::path getNixDefExpr()
118119
return settings.useXDGBaseDirectories ? getStateDir() / "defexpr" : getHome() / ".nix-defexpr";
119120
}
120121

122+
EvalSettings evalSettings{settings.readOnlyMode};
123+
124+
static GlobalConfig::Register rEvalSettings(&evalSettings);
125+
121126
} // namespace nix

src/libexpr/include/nix/expr/eval-settings.hh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,4 +412,9 @@ std::filesystem::path getNixDefExpr();
412412
*/
413413
constexpr size_t evalStackSize = 60 * 1024 * 1024;
414414

415+
/**
416+
* EvalSettings instance from libexpr.
417+
*/
418+
extern EvalSettings evalSettings;
419+
415420
} // namespace nix

src/libflake-c/nix_api_flake.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ nix_err nix_flake_settings_add_to_eval_state_builder(
3232
{
3333
nix_clear_err(context);
3434
try {
35-
settings->settings->configureEvalSettings(builder->settings);
35+
settings->settings->configureEvalSettings(*builder->settings);
3636
}
3737
NIXC_CATCH_ERRS
3838
}

src/libutil/config-global.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,16 @@ GlobalConfig globalConfig;
6161

6262
GlobalConfig::Register::Register(Config * config)
6363
{
64-
configRegistrations().emplace_back(config);
64+
auto regs = configRegistrations();
65+
if (std::find(regs.begin(), regs.end(), config) == regs.end()) {
66+
configRegistrations().emplace_back(config);
67+
}
68+
}
69+
70+
GlobalConfig::Register::Register(Config * config, std::function<void()> && callback)
71+
: Register(config)
72+
{
73+
callback();
6574
}
6675

6776
ExperimentalFeatureSettings experimentalFeatureSettings;

src/libutil/include/nix/util/config-global.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct GlobalConfig : public AbstractConfig
2626
struct Register
2727
{
2828
Register(Config * config);
29+
Register(Config * config, std::function<void()> && callback);
2930
};
3031
};
3132

0 commit comments

Comments
 (0)