From 5ee0d5669e783438ede3ba5b2a66d4f474426c0f Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 5 Aug 2025 02:15:21 +0300 Subject: [PATCH 1/3] libstore: Move State to an anonymous namespace Having a State class in the nix namespace is asking for ODR trouble. This class is already private to the translation unit, let's move it into an anonymous namespace. --- src/libstore/builtins/buildenv.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libstore/builtins/buildenv.cc b/src/libstore/builtins/buildenv.cc index 0ff0be3aa..22ed8d807 100644 --- a/src/libstore/builtins/buildenv.cc +++ b/src/libstore/builtins/buildenv.cc @@ -10,12 +10,16 @@ namespace nix { +namespace { + struct State { std::map priorities; unsigned long symlinks = 0; }; +} // namespace + /* For each activated package, create symlinks */ static void createLinks(State & state, const Path & srcDir, const Path & dstDir, int priority) { From 0118e5ea5d4f08553f3876976296e2547ed69571 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 5 Aug 2025 02:20:28 +0300 Subject: [PATCH 2/3] libutil: Move Ctx type from the nix namespace to Hash class Same as previous commit. This really should not be a part of the `nix` namespace. Otherwise the doxygen documentation is really confusing. --- src/libutil/hash.cc | 14 +++++++------- src/libutil/include/nix/util/hash.hh | 7 ++++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/libutil/hash.cc b/src/libutil/hash.cc index 38ef5dd90..941224d58 100644 --- a/src/libutil/hash.cc +++ b/src/libutil/hash.cc @@ -273,7 +273,7 @@ Hash newHashAllowEmpty(std::string_view hashStr, std::optional ha return Hash::parseAny(hashStr, ha); } -union Ctx +union Hash::Ctx { blake3_hasher blake3; MD5_CTX md5; @@ -282,7 +282,7 @@ union Ctx SHA512_CTX sha512; }; -static void start(HashAlgorithm ha, Ctx & ctx) +static void start(HashAlgorithm ha, Hash::Ctx & ctx) { if (ha == HashAlgorithm::BLAKE3) blake3_hasher_init(&ctx.blake3); @@ -317,7 +317,7 @@ void blake3_hasher_update_with_heuristics(blake3_hasher * blake3, std::string_vi } } -static void update(HashAlgorithm ha, Ctx & ctx, std::string_view data) +static void update(HashAlgorithm ha, Hash::Ctx & ctx, std::string_view data) { if (ha == HashAlgorithm::BLAKE3) blake3_hasher_update_with_heuristics(&ctx.blake3, data); @@ -331,7 +331,7 @@ static void update(HashAlgorithm ha, Ctx & ctx, std::string_view data) SHA512_Update(&ctx.sha512, data.data(), data.size()); } -static void finish(HashAlgorithm ha, Ctx & ctx, unsigned char * hash) +static void finish(HashAlgorithm ha, Hash::Ctx & ctx, unsigned char * hash) { if (ha == HashAlgorithm::BLAKE3) blake3_hasher_finalize(&ctx.blake3, hash, BLAKE3_OUT_LEN); @@ -347,7 +347,7 @@ static void finish(HashAlgorithm ha, Ctx & ctx, unsigned char * hash) Hash hashString(HashAlgorithm ha, std::string_view s, const ExperimentalFeatureSettings & xpSettings) { - Ctx ctx; + Hash::Ctx ctx; Hash hash(ha, xpSettings); start(ha, ctx); update(ha, ctx, s); @@ -365,7 +365,7 @@ Hash hashFile(HashAlgorithm ha, const Path & path) HashSink::HashSink(HashAlgorithm ha) : ha(ha) { - ctx = new Ctx; + ctx = new Hash::Ctx; bytes = 0; start(ha, *ctx); } @@ -393,7 +393,7 @@ HashResult HashSink::finish() HashResult HashSink::currentHash() { flush(); - Ctx ctx2 = *ctx; + Hash::Ctx ctx2 = *ctx; Hash hash(ha); nix::finish(ha, ctx2, hash.hash); return HashResult(hash, bytes); diff --git a/src/libutil/include/nix/util/hash.hh b/src/libutil/include/nix/util/hash.hh index daacd7adf..584ab6899 100644 --- a/src/libutil/include/nix/util/hash.hh +++ b/src/libutil/include/nix/util/hash.hh @@ -57,6 +57,9 @@ extern const StringSet hashFormats; struct Hash { + /** Opaque handle type for the hash calculation state. */ + union Ctx; + constexpr static size_t maxHashSize = 64; size_t hashSize = 0; uint8_t hash[maxHashSize] = {}; @@ -224,8 +227,6 @@ std::optional parseHashAlgoOpt(std::string_view s); */ std::string_view printHashAlgo(HashAlgorithm ha); -union Ctx; - struct AbstractHashSink : virtual Sink { virtual HashResult finish() = 0; @@ -235,7 +236,7 @@ class HashSink : public BufferedSink, public AbstractHashSink { private: HashAlgorithm ha; - Ctx * ctx; + Hash::Ctx * ctx; uint64_t bytes; public: From 866d5e6cf4f7dc213ff56941afe9621a866b2cb1 Mon Sep 17 00:00:00 2001 From: Sergei Zimmerman Date: Tue, 5 Aug 2025 02:25:40 +0300 Subject: [PATCH 3/3] treewide: Sprinkle more anonymous namespace for classes private to TUs This code should be private to the corresponding translation units. --- src/libutil/args.cc | 4 ++++ src/nix/diff-closures.cc | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/libutil/args.cc b/src/libutil/args.cc index 2e6d85afd..f4309473b 100644 --- a/src/libutil/args.cc +++ b/src/libutil/args.cc @@ -81,6 +81,8 @@ std::optional RootArgs::needsCompletion(std::string_view s) return {}; } +namespace { + /** * Basically this is `typedef std::optional Parser(std::string_view s, Strings & r);` * @@ -246,6 +248,8 @@ void ParseQuoted::operator()(std::shared_ptr & state, Strings & r) assert(false); } +} // namespace + Strings parseShebangContent(std::string_view s) { Strings result; diff --git a/src/nix/diff-closures.cc b/src/nix/diff-closures.cc index 020c3e13b..cbf842e5c 100644 --- a/src/nix/diff-closures.cc +++ b/src/nix/diff-closures.cc @@ -10,11 +10,15 @@ namespace nix { +namespace { + struct Info { std::string outputName; }; +} // namespace + // name -> version -> store paths typedef std::map>> GroupedPaths;