1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-27 12:41:15 +02:00

Cleanup config headers

There are two big changes:

1. Public and private config is now separated. Configuration variables
   that are only used internally do not go in a header which is
   installed.

   (Additionally, libutil has a unix-specific private config header,
   which should only be used in unix-specific code. This keeps things a
   bit more organized, in a purely private implementation-internal way.)

2. Secondly, there is no more `-include`. There are very few config
   items that need to be publically exposed, so now it is feasible to
   just make the headers that need them just including the (public)
   configuration header.

And there are also a few more small cleanups on top of those:

- The configuration files have better names.

- The few CPP variables that remain exposed in the public headers are
  now also renamed to always start with `NIX_`. This ensures they should
  not conflict with variables defined elsewhere.

- We now always use `#if` and not `#ifdef`/`#ifndef` for our
  configuration variables, which helps avoid bugs by requiring that
  variables must be defined in all cases.
This commit is contained in:
John Ericson 2025-03-28 13:24:50 -04:00
parent 5a8dedc45c
commit c204e307ac
59 changed files with 333 additions and 385 deletions

View file

@ -5,7 +5,9 @@
#include "nix/serialise.hh"
#include "nix/eval-gc.hh"
#if HAVE_BOEHMGC
#include "expr-config-private.hh"
#if NIX_USE_BOEHMGC
# include <pthread.h>
# if __FreeBSD__
@ -24,7 +26,7 @@
namespace nix {
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
/* Called when the Boehm GC runs out of memory. */
static void * oomHandler(size_t requested)
{
@ -94,7 +96,7 @@ void initGC()
if (gcInitialised)
return;
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
initGCReal();
gcCyclesAfterInit = GC_get_gc_no();

View file

@ -295,7 +295,7 @@ EvalState::EvalState(
, debugStop(false)
, trylevel(0)
, regexCache(makeRegexCache())
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
, valueAllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr))
, env1AllocCache(std::allocate_shared<void *>(traceable_allocator<void *>(), nullptr))
, baseEnvP(std::allocate_shared<Env *>(traceable_allocator<Env *>(), &allocEnv(BASE_ENV_SIZE)))
@ -2812,7 +2812,7 @@ bool EvalState::eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_v
}
bool EvalState::fullGC() {
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
GC_gcollect();
// Check that it ran. We might replace this with a version that uses more
// of the boehm API to get this reliably, at a maintenance cost.
@ -2831,7 +2831,7 @@ void EvalState::maybePrintStats()
if (showStats) {
// Make the final heap size more deterministic.
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
if (!fullGC()) {
warn("failed to perform a full GC before reporting stats");
}
@ -2853,7 +2853,7 @@ void EvalState::printStatistics()
uint64_t bValues = nrValues * sizeof(Value);
uint64_t bAttrsets = nrAttrsets * sizeof(Bindings) + nrAttrsInAttrsets * sizeof(Attr);
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
GC_word heapSize, totalBytes;
GC_get_heap_usage_safe(&heapSize, 0, 0, 0, &totalBytes);
double gcFullOnlyTime = ({
@ -2875,7 +2875,7 @@ void EvalState::printStatistics()
#ifndef _WIN32 // TODO implement
{"cpu", cpuTime},
#endif
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
{GC_is_incremental_mode() ? "gcNonIncremental" : "gc", gcFullOnlyTime},
#ifndef _WIN32 // TODO implement
{GC_is_incremental_mode() ? "gcNonIncrementalFraction" : "gcFraction", gcFullOnlyTime / cpuTime},
@ -2919,7 +2919,7 @@ void EvalState::printStatistics()
topObj["nrLookups"] = nrLookups;
topObj["nrPrimOpCalls"] = nrPrimOpCalls;
topObj["nrFunctionCalls"] = nrFunctionCalls;
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
topObj["gc"] = {
{"heapSize", heapSize},
{"totalBytes", totalBytes},

View file

@ -3,7 +3,10 @@
#include <cstddef>
#if HAVE_BOEHMGC
// For `NIX_USE_BOEHMGC`, and if that's set, `GC_THREADS`
#include "nix/expr-config.hh"
#if NIX_USE_BOEHMGC
# define GC_INCLUDE_NEW
@ -43,7 +46,7 @@ void initGC();
*/
void assertGCInitialized();
#ifdef HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
/**
* The number of GC cycles since initGC().
*/

View file

@ -6,6 +6,9 @@
#include "nix/eval-error.hh"
#include "nix/eval-settings.hh"
// For `NIX_USE_BOEHMGC`, and if that's set, `GC_THREADS`
#include "nix/expr-config.hh"
namespace nix {
/**
@ -15,7 +18,7 @@ namespace nix {
inline void * allocBytes(size_t n)
{
void * p;
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
p = GC_MALLOC(n);
#else
p = calloc(n, 1);
@ -28,7 +31,7 @@ inline void * allocBytes(size_t n)
[[gnu::always_inline]]
Value * EvalState::allocValue()
{
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
/* We use the boehm batch allocator to speed up allocations of Values (of which there are many).
GC_malloc_many returns a linked list of objects of the given size, where the first word
of each object is also the pointer to the next object in the list. This also means that we
@ -60,7 +63,7 @@ Env & EvalState::allocEnv(size_t size)
Env * env;
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
if (size == 1) {
/* see allocValue for explanations. */
if (!*env1AllocCache) {

View file

@ -16,6 +16,9 @@
#include "nix/repl-exit-status.hh"
#include "nix/ref.hh"
// For `NIX_USE_BOEHMGC`, and if that's set, `GC_THREADS`
#include "nix/expr-config.hh"
#include <map>
#include <optional>
#include <functional>
@ -369,7 +372,7 @@ private:
*/
std::shared_ptr<RegexCache> regexCache;
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
/**
* Allocation cache for GC'd Value objects.
*/
@ -596,7 +599,7 @@ public:
*/
SingleDerivedPath coerceToSingleDerivedPath(const PosIdx pos, Value & v, std::string_view errorCtx);
#if HAVE_BOEHMGC
#if NIX_USE_BOEHMGC
/** A GC root for the baseEnv reference. */
std::shared_ptr<Env *> baseEnvP;
#endif

View file

@ -2,12 +2,12 @@
include_dirs = [include_directories('..')]
config_h = configure_file(
configuration : configdata,
output : 'config-expr.hh',
config_pub_h = configure_file(
configuration : configdata_pub,
output : 'expr-config.hh',
)
headers = [config_h] + files(
headers = [config_pub_h] + files(
'attr-path.hh',
'attr-set.hh',
'eval-cache.hh',

View file

@ -14,7 +14,8 @@ cxx = meson.get_compiler('cpp')
subdir('nix-meson-build-support/deps-lists')
configdata = configuration_data()
configdata_pub = configuration_data()
configdata_priv = configuration_data()
deps_private_maybe_subproject = [
]
@ -26,6 +27,16 @@ deps_public_maybe_subproject = [
subdir('nix-meson-build-support/subprojects')
subdir('nix-meson-build-support/big-objs')
# Check for each of these functions, and create a define like `#define HAVE_LCHOWN 1`.
check_funcs = [
'sysconf',
]
foreach funcspec : check_funcs
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
define_value = cxx.has_function(funcspec).to_int()
configdata_priv.set(define_name, define_value)
endforeach
boost = dependency(
'boost',
modules : ['container', 'context'],
@ -47,11 +58,13 @@ if bdw_gc.found()
]
define_name = 'HAVE_' + funcspec.underscorify().to_upper()
define_value = cxx.has_function(funcspec).to_int()
configdata.set(define_name, define_value)
configdata_priv.set(define_name, define_value)
endforeach
configdata.set('GC_THREADS', 1)
# Affects ABI, because it changes what bdw_gc itself does!
configdata_pub.set('GC_THREADS', 1)
endif
configdata.set('HAVE_BOEHMGC', bdw_gc.found().to_int())
# Used in public header. Affects ABI!
configdata_pub.set('NIX_USE_BOEHMGC', bdw_gc.found().to_int())
toml11 = dependency(
'toml11',
@ -61,14 +74,9 @@ toml11 = dependency(
)
deps_other += toml11
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', 'nix/config-util.hh',
'-include', 'nix/config-store.hh',
# '-include', 'nix_api_fetchers_config.h',
'-include', 'nix/config-expr.hh',
language : 'cpp',
config_priv_h = configure_file(
configuration : configdata_priv,
output : 'expr-config-private.hh',
)
subdir('nix-meson-build-support/common')
@ -158,6 +166,7 @@ subdir('nix-meson-build-support/windows-version')
this_library = library(
'nixexpr',
sources,
config_priv_h,
parser_tab,
lexer_tab,
generated_headers,