diff --git a/flake.lock b/flake.lock index 1bf63336..1f4f38f2 100644 --- a/flake.lock +++ b/flake.lock @@ -35,6 +35,39 @@ "type": "github" } }, + "hs-bindgen": { + "flake": false, + "locked": { + "lastModified": 1763740177, + "narHash": "sha256-tyEDNLCBb2jJhBJ478MG+QD2yhOWzbi1Sm3jS5oTmn0=", + "owner": "hercules-ci", + "repo": "hs-bindgen", + "rev": "4eb901ee196b81d39d67755ac62343e263b6519e", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "ref": "avoid-template-haskell", + "repo": "hs-bindgen", + "type": "github" + } + }, + "libclang-bindings": { + "flake": false, + "locked": { + "lastModified": 1763640650, + "narHash": "sha256-ZUWm6FX9Dgt/e/DN9k8NfdZkoZIIvfh4HYfdN/0tdEE=", + "owner": "well-typed", + "repo": "libclang", + "rev": "b62972c5a4227f92ac7af7df60af52f9ead7bd35", + "type": "github" + }, + "original": { + "owner": "well-typed", + "repo": "libclang", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1759036355, @@ -55,6 +88,8 @@ "inputs": { "flake-parts": "flake-parts", "haskell-flake": "haskell-flake", + "hs-bindgen": "hs-bindgen", + "libclang-bindings": "libclang-bindings", "nixpkgs": "nixpkgs" } } diff --git a/flake.nix b/flake.nix index a8d93d7d..07ee7e90 100644 --- a/flake.nix +++ b/flake.nix @@ -5,6 +5,10 @@ inputs.flake-parts.url = "github:hercules-ci/flake-parts"; inputs.flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; inputs.haskell-flake.url = "github:srid/haskell-flake"; + inputs.hs-bindgen.url = "github:hercules-ci/hs-bindgen/avoid-template-haskell"; + inputs.hs-bindgen.flake = false; + inputs.libclang-bindings.url = "github:well-typed/libclang"; + inputs.libclang-bindings.flake = false; # Optional. Omit to use nixpkgs' nix # inputs.nix = { @@ -282,6 +286,16 @@ # Slightly faster and does not create deps: source-drv -> inputs defaults.settings.local.impl.buildFromSdist = [ (project.config.basePackages.buildFromCabalSdist) ]; + # hs-bindgen packages + packages = { + hs-bindgen.source = inputs.hs-bindgen + "/hs-bindgen"; + hs-bindgen-runtime.source = inputs.hs-bindgen + "/hs-bindgen-runtime"; + c-expr-dsl.source = inputs.hs-bindgen + "/c-expr-dsl"; + c-expr-runtime.source = inputs.hs-bindgen + "/c-expr-runtime"; + ansi-diff.source = inputs.hs-bindgen + "/ansi-diff"; + libclang-bindings.source = inputs.libclang-bindings; + }; + devShell.extraLibraries = hp: { inherit (hp) releaser ascii-progress @@ -444,6 +458,12 @@ (x: x.overrideAttrs (o: { passthru = o.passthru // { nixPackage = nix; }; })) + # Add clang/llvm and hs-bindgen for code generation + (h.addBuildTools [ + pkgs.llvmPackages.clang + pkgs.llvmPackages.llvm + self.hs-bindgen + ]) ]; # # Dodge build failures of components we don't need. @@ -468,8 +488,24 @@ # releaser = super.callCabal2nix "releaser" (builtins.getFlake "github:hercules-ci/haskell-releaser?rev=e50360ec896fcb6ad724566aece6625973419e8d") { }; # cabal2nix injects pkg-config dependencies by looking them up in the Haskell package set _or_ `pkgs` - # It does not know about the `nix-flake` pkg-config module yet. + # It does not know about the `nix-flake` and `nix-store-c` pkg-config modules yet. nix-flake = nix; + nix-store-c = nix; + + # hs-bindgen dependencies that are marked broken in nixpkgs + debruijn = h.dontCheck (h.doJailbreak (h.unmarkBroken super.debruijn)); + skew-list = h.dontCheck (h.doJailbreak (h.unmarkBroken super.skew-list)); + + # libclang-bindings needs llvm and libclang - use llvmPackages set + libclang-bindings = h.addExtraLibrary pkgs.llvmPackages.libclang ( + h.addBuildTools [ pkgs.llvmPackages.llvm pkgs.llvmPackages.clang ] super.libclang-bindings + ); + + # c-expr-runtime tests require musl headers (see hs-bindgen's own packaging) + c-expr-runtime = h.dontCheck super.c-expr-runtime; + + # hs-bindgen tests require system headers and have chicken-egg CLI dependency + hs-bindgen = h.dontCheck super.hs-bindgen; }) ]; @@ -505,6 +541,9 @@ pkgs.nixpkgs-fmt pkgs.pre-commit # pkgs.valgrind (broken on x86_64-darwin) + # For hs-bindgen-cli + pkgs.llvmPackages.clang + pkgs.llvmPackages.llvm ] ++ lib.optionals shellWithHaskell [ haskellPackages.haskell-language-server pkgs.haskellPackages.implicit-hie # gen-hie diff --git a/hercules-ci-agent/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Prefetched.hs b/hercules-ci-agent/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Prefetched.hs index b8e492ae..431db456 100644 --- a/hercules-ci-agent/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Prefetched.hs +++ b/hercules-ci-agent/hercules-ci-agent-worker/Hercules/Agent/Worker/Build/Prefetched.hs @@ -45,6 +45,12 @@ C.include "" C.include "" +-- C API internals header to access C++ Store from C API Store +C.include "" + +-- Create a typedef to disambiguate C API Store from nix::Store +C.verbatim "typedef ::Store nix_store;" + C.using "namespace nix" C.using "namespace hercules_ci_cnix" @@ -99,9 +105,9 @@ getDerivation (Store store) derivationPath = nullableMoveToForeignPtrWrapper =<< [C.throwBlock| Derivation *{ ReceiveInterrupts _; - StorePath derivationPath = *$fptr-ptr:(nix::StorePath *derivationPath); + nix::StorePath derivationPath = *$fptr-ptr:(nix::StorePath *derivationPath); std::list> stores = getDefaultSubstituters(); - stores.push_front(*$(refStore* store)); + stores.push_front($(nix_store* store)->ptr); nix::Derivation *derivation = nullptr; @@ -135,13 +141,13 @@ buildDerivation (Store store) derivationPath derivation extraInputs = alloca $ \errorMessagePtr -> do [C.throwBlock| void { ReceiveInterrupts _; - Store &store = **$(refStore* store); + nix::Store &store = *$(nix_store* store)->ptr; bool &success = *$(bool *successPtr); int &status = *$(int *statusPtr); const char *&errorMessage = *$(const char **errorMessagePtr); time_t &startTime = *$(time_t *startTimePtr); time_t &stopTime = *$(time_t *stopTimePtr); - StorePath derivationPath = *$fptr-ptr:(nix::StorePath *derivationPath); + nix::StorePath derivationPath = *$fptr-ptr:(nix::StorePath *derivationPath); if ($(bool materializeDerivation)) { store.addTempRoot(derivationPath); diff --git a/hercules-ci-agent/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore.hs b/hercules-ci-agent/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore.hs index 90139e57..b70e3bf4 100644 --- a/hercules-ci-agent/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore.hs +++ b/hercules-ci-agent/hercules-ci-agent-worker/Hercules/Agent/Worker/HerculesStore.hs @@ -38,6 +38,12 @@ C.include "" C.include "hercules-aliases.h" +-- C API internals header to access C++ Store from C API Store +C.include "" + +-- Create a typedef to disambiguate C API Store from nix::Store +C.verbatim "typedef ::Store nix_store;" + C.using "namespace nix" withHerculesStore :: @@ -48,7 +54,7 @@ withHerculesStore (Store wrappedStore) = bracket ( liftIO [C.block| refHerculesStore* { - refStore &s = *$(refStore *wrappedStore); + refStore &s = $(nix_store *wrappedStore)->ptr; refHerculesStore hs(new HerculesStore(s)); return new refHerculesStore(hs); } |] diff --git a/hercules-ci-cnix-expr/src/Hercules/CNix/Expr.hs b/hercules-ci-cnix-expr/src/Hercules/CNix/Expr.hs index ef2b799e..15541bed 100644 --- a/hercules-ci-cnix-expr/src/Hercules/CNix/Expr.hs +++ b/hercules-ci-cnix-expr/src/Hercules/CNix/Expr.hs @@ -120,6 +120,12 @@ C.include "hercules-ci-cnix/expr.hxx" C.include "hercules-ci-cnix/string.hxx" +-- C API internals header to access C++ Store from C API Store +C.include "" + +-- Create a typedef to disambiguate C API Store from nix::Store +C.verbatim "typedef ::Store nix_store;" + C.include "" C.include "" @@ -261,7 +267,7 @@ newEvalState (Store store) = liftIO [C.throwBlock| EvalState* { nix::LookupPath emptyLookupPath; - return new EvalState(emptyLookupPath, *$(refStore* store), fetchSettings, evalSettings); + return new EvalState(emptyLookupPath, $(nix_store* store)->ptr, fetchSettings, evalSettings); } |] -- | (private) Don't leak it. @@ -417,12 +423,12 @@ getDrvFile evalState (RawValue v) = liftIO do if (!drvInfo) throw EvalError(state, "Not a valid derivation"); - StorePath storePath = drvInfo->requireDrvPath(); + nix::StorePath storePath = drvInfo->requireDrvPath(); // write it (?) auto drv = state.store->derivationFromPath(storePath); - return new StorePath(storePath); + return new nix::StorePath(storePath); }|] getAttrBool :: Ptr EvalState -> Value NixAttrs -> ByteString -> IO (Either SomeException (Maybe Bool)) diff --git a/hercules-ci-cnix-store/.gitignore b/hercules-ci-cnix-store/.gitignore new file mode 100644 index 00000000..879a87fd --- /dev/null +++ b/hercules-ci-cnix-store/.gitignore @@ -0,0 +1 @@ +src-generated/ diff --git a/hercules-ci-cnix-store/Setup.hs b/hercules-ci-cnix-store/Setup.hs index ceb656c5..3157ee9c 100644 --- a/hercules-ci-cnix-store/Setup.hs +++ b/hercules-ci-cnix-store/Setup.hs @@ -1,13 +1,43 @@ import Data.Function ((&)) import Distribution.PkgConfigVersionHook as PV import Distribution.Simple +import Distribution.Simple.LocalBuildInfo +import Distribution.Simple.Setup +import Distribution.Simple.Utils +import Distribution.Verbosity +import System.Directory (createDirectoryIfMissing) +import System.Process (callProcess) main :: IO () main = defaultMainWithHooks $ simpleUserHooks + { preBuild = \args flags -> do + generateBindings (fromFlag $ buildVerbosity flags) + preBuild simpleUserHooks args flags + } & PV.addHook (PV.mkSettings "nix-store") { PV.macroName = "NIX", PV.flagPrefixName = "nix" } + +generateBindings :: Verbosity -> IO () +generateBindings verbosity = do + notice verbosity "Generating Nix C API bindings with hs-bindgen..." + createDirectoryIfMissing True "src-generated" + callProcess + "hs-bindgen-cli" + [ "preprocess", + "-I", + "/nix/store/3bgmbyiinaq8z420gjg8bz2pqf0dpzyp-nix-2.28.5-dev/include", + "--hs-output-dir", + "src-generated", + "--create-output-dirs", + "--module", + "Hercules.CNix.Nix.API.Store", + "--unique-id", + "com.hercules-ci.cnix-store", + "--enable-program-slicing", + "/nix/store/3bgmbyiinaq8z420gjg8bz2pqf0dpzyp-nix-2.28.5-dev/include/nix_api_store.h" + ] diff --git a/hercules-ci-cnix-store/hercules-ci-cnix-store.cabal b/hercules-ci-cnix-store/hercules-ci-cnix-store.cabal index 991b91e2..731392ce 100644 --- a/hercules-ci-cnix-store/hercules-ci-cnix-store.cabal +++ b/hercules-ci-cnix-store/hercules-ci-cnix-store.cabal @@ -56,6 +56,8 @@ custom-setup base < 5 , Cabal >= 2.2.0.0 && < 4 , cabal-pkg-config-version-hook + , directory + , process library import: cxx-opts @@ -75,15 +77,26 @@ library Hercules.CNix.Store.Instances Hercules.CNix.Util Hercules.CNix.Verbosity + other-modules: + Hercules.CNix.Nix.API.Store + Hercules.CNix.Nix.API.Store.Safe + Hercules.CNix.Nix.API.Store.Unsafe + -- Hercules.CNix.Nix.API.Store.FunPtr omitted: uses TH to provide function pointers, which we don't need + autogen-modules: + Hercules.CNix.Nix.API.Store + Hercules.CNix.Nix.API.Store.Safe + Hercules.CNix.Nix.API.Store.Unsafe + -- Hercules.CNix.Nix.API.Store.FunPtr omitted: uses TH to provide function pointers, which we don't need include-dirs: include cbits pkgconfig-depends: nix-store >= 2.28 && < 2.31 + , nix-store-c >= 2.28 && < 2.31 install-includes: hercules-ci-cnix/store.hxx hercules-ci-cnix/string.hxx - hs-source-dirs: src + hs-source-dirs: src src-generated cxx-sources: cbits/string.cxx cbits/signals.cxx @@ -100,6 +113,8 @@ library , unix , unliftio-core , vector + , hs-bindgen-runtime + , c-expr-runtime if ! flag(ide) extra-libraries: boost_context diff --git a/hercules-ci-cnix-store/src/Hercules/CNix/Store.hs b/hercules-ci-cnix-store/src/Hercules/CNix/Store.hs index 005269a6..ea21b5e5 100644 --- a/hercules-ci-cnix-store/src/Hercules/CNix/Store.hs +++ b/hercules-ci-cnix-store/src/Hercules/CNix/Store.hs @@ -151,10 +151,14 @@ import qualified Data.Map as M import Foreign (alloca, free) import Foreign.ForeignPtr import Foreign.ForeignPtr.Unsafe (unsafeForeignPtrToPtr) +import Foreign.Ptr (nullPtr) import Foreign.Storable (peek) import Hercules.CNix.Encapsulation (HasEncapsulation (..), nullableMoveToForeignPtrWrapper) import Hercules.CNix.Memory (Delete (delete), Finalizer (finalizer), toForeignPtr, withDelete) import qualified Hercules.CNix.Memory +-- C API bindings (TH-free!) +import qualified Hercules.CNix.Nix.API.Store as CAPI +import qualified Hercules.CNix.Nix.API.Store.Safe as CAPI import Hercules.CNix.Std.Set (StdSet, stdSetCtx) import qualified Hercules.CNix.Std.Set as Std.Set import Hercules.CNix.Std.String (stdStringCtx) @@ -204,10 +208,16 @@ C.include "hercules-ci-cnix/store.hxx" C.include "hercules-ci-cnix/string.hxx" +-- C API internals header to access C++ Store from C API Store +C.include "" + C.using "namespace nix" C.using "namespace hercules_ci_cnix" +-- Create a typedef to disambiguate C API Store from nix::Store +C.verbatim "typedef ::Store nix_store;" + {-# DEPRECATED forNonNull "Use 'Hercules.CNix.Memory.forNonNull' instead" #-} forNonNull :: Ptr a -> (Ptr a -> IO b) -> IO (Maybe b) forNonNull = Hercules.CNix.Memory.forNonNull @@ -216,18 +226,20 @@ forNonNull = Hercules.CNix.Memory.forNonNull traverseNonNull :: (Ptr a -> IO b) -> Ptr a -> IO (Maybe b) traverseNonNull = Hercules.CNix.Memory.traverseNonNull -newtype Store = Store (Ptr (Ref NixStore)) +-- | Store now wraps a C API Store pointer +newtype Store = Store (Ptr CAPI.Store) -instance Delete (Ref NixStore) where - delete store = [C.exp| void { delete $(refStore* store) } |] +instance Delete CAPI.Store where + delete store = CAPI.nix_store_free store openStore :: IO Store -openStore = - coerce - [C.throwBlock| refStore * { - refStore s = nix::openStore(); - return new refStore(s); - } |] +openStore = do + -- TODO: handle context/errors properly + capiStore <- CAPI.nix_store_open nullPtr nullPtr nullPtr + when (capiStore == nullPtr) $ + Control.Exception.throwIO $ + Prelude.userError "Failed to open store" + pure (Store capiStore) releaseStore :: Store -> IO () releaseStore (Store store) = delete store @@ -251,19 +263,23 @@ withStoreFromURI :: withStoreFromURI storeURIText f = do let storeURI = encodeUtf8 storeURIText (UnliftIO unlift) <- askUnliftIO - liftIO $ - withDelete - [C.throwBlock| refStore* { - refStore s = nix::openStore($bs-cstr:storeURI); - return new refStore(s); - }|] - (unlift . f . Store) + liftIO $ do + -- TODO: handle context/errors properly + BS.unsafeUseAsCString storeURI $ \cstr -> do + capiStore <- CAPI.nix_store_open nullPtr cstr nullPtr + when (capiStore == nullPtr) $ + Control.Exception.throwIO $ + Prelude.userError "Failed to open store" + bracket_ + (pure ()) + (CAPI.nix_store_free capiStore) + (unlift $ f $ Store capiStore) storeUri :: (MonadIO m) => Store -> m ByteString storeUri (Store store) = liftIO do BS.unsafePackMallocCString =<< [C.block| const char* { - std::string uri = (*$(refStore* store))->getUri(); + std::string uri = $(nix_store* store)->ptr->getUri(); return stringdup(uri); }|] @@ -272,7 +288,7 @@ storeDir :: (MonadIO m) => Store -> m ByteString storeDir (Store store) = liftIO do BS.unsafePackMallocCString =<< [C.block| const char* { - std::string uri = (*$(refStore* store))->storeDir; + std::string uri = $(nix_store* store)->ptr->storeDir; return stringdup(uri); }|] @@ -280,7 +296,7 @@ getStoreProtocolVersion :: Store -> IO Int getStoreProtocolVersion (Store store) = fromIntegral <$> [C.throwBlock| int { - Store &store = **$(refStore* store); + nix::Store &store = *$(nix_store* store)->ptr; return store.getProtocol(); }|] @@ -305,7 +321,7 @@ finalizeStorePath = unsafePerformIO [C.exp| void (*)(nix::StorePath *) { - [](StorePath *v) { + [](nix::StorePath *v) { delete v; } } @@ -351,7 +367,7 @@ parseStorePathBaseName :: ByteString -> IO StorePath parseStorePathBaseName bs = moveToForeignPtrWrapper =<< [C.throwBlock| nix::StorePath *{ - return new StorePath(std::string($bs-ptr:bs, $bs-len:bs)); + return new nix::StorePath(std::string($bs-ptr:bs, $bs-len:bs)); }|] -- | Parse a complete store path including storeDir into a 'StorePath'. @@ -361,7 +377,7 @@ parseStorePath :: Store -> ByteString -> IO StorePath parseStorePath (Store store) bs = moveToForeignPtrWrapper =<< [C.throwBlock| nix::StorePath *{ - return new StorePath(std::move((*$(refStore* store))->parseStorePath(std::string($bs-ptr:bs, $bs-len:bs)))); + return new nix::StorePath(std::move($(nix_store* store)->ptr->parseStorePath(std::string($bs-ptr:bs, $bs-len:bs)))); }|] getStorePathBaseName :: StorePath -> IO ByteString @@ -384,8 +400,8 @@ storePathToPath :: Store -> StorePath -> IO ByteString storePathToPath (Store store) (StorePath sp) = BS.unsafePackMallocCString =<< [C.block| const char *{ - Store & store = **$(refStore* store); - StorePath &sp = *$fptr-ptr:(nix::StorePath *sp); + nix::Store & store = *$(nix_store* store)->ptr; + nix::StorePath &sp = *$fptr-ptr:(nix::StorePath *sp); std::string s(store.printStorePath(sp)); return stringdup(s); }|] @@ -394,8 +410,8 @@ ensurePath :: Store -> StorePath -> IO () ensurePath (Store store) (StorePath storePath) = [C.throwBlock| void { ReceiveInterrupts _; - Store &store = **$(refStore* store); - StorePath &storePath = *$fptr-ptr:(nix::StorePath *storePath); + nix::Store &store = *$(nix_store* store)->ptr; + nix::StorePath &storePath = *$fptr-ptr:(nix::StorePath *storePath); store.ensurePath(storePath); } |] @@ -403,15 +419,15 @@ addTemporaryRoot :: Store -> StorePath -> IO () addTemporaryRoot (Store store) storePath = do [C.throwBlock| void { ReceiveInterrupts _; - Store &store = **$(refStore* store); - StorePath &storePath = *$fptr-ptr:(nix::StorePath *storePath); + nix::Store &store = *$(nix_store* store)->ptr; + nix::StorePath &storePath = *$fptr-ptr:(nix::StorePath *storePath); store.addTempRoot(storePath); } |] clearPathInfoCache :: Store -> IO () clearPathInfoCache (Store store) = [C.throwBlock| void { - (*$(refStore* store))->clearPathInfoCache(); + $(nix_store* store)->ptr->clearPathInfoCache(); } |] clearSubstituterCaches :: IO () @@ -457,7 +473,7 @@ getStorePath :: StorePathWithOutputs -> IO StorePath getStorePath swo = mask_ do moveToForeignPtrWrapper =<< [C.exp| nix::StorePath * { - new StorePath($fptr-ptr:(nix::StorePathWithOutputs *swo)->path) + new nix::StorePath($fptr-ptr:(nix::StorePathWithOutputs *swo)->path) }|] getOutputs :: StorePathWithOutputs -> IO [ByteString] @@ -476,7 +492,7 @@ buildPaths :: Store -> StdVector C.NixStorePathWithOutputs -> IO () buildPaths (Store store) (StdVector paths) = do [C.throwBlock| void { ReceiveInterrupts _; - Store &store = **$(refStore* store); + nix::Store &store = *$(nix_store* store)->ptr; std::vector &paths = *$fptr-ptr:(std::vector* paths); store.buildPaths(toDerivedPaths(paths)); }|] @@ -510,7 +526,7 @@ getDerivation (Store store) (StorePath spwo) = do moveToForeignPtrWrapper =<< [C.throwBlock| Derivation *{ ReceiveInterrupts _; - Store &store = **$(refStore* store); + nix::Store &store = *$(nix_store* store)->ptr; return new Derivation( store.derivationFromPath(*$fptr-ptr:(nix::StorePath *spwo)) ); @@ -527,7 +543,7 @@ getDerivationFromString :: getDerivationFromString (Store store) name contents = do moveToForeignPtrWrapper =<< [C.throwBlock| Derivation *{ - Store &store = **$(refStore* store); + nix::Store &store = *$(nix_store* store)->ptr; std::string name($bs-ptr:name, $bs-len:name); return new Derivation(parseDerivation(store, std::string($bs-ptr:contents, $bs-len:contents), name)); }|] @@ -536,7 +552,7 @@ getDerivationNameFromPath :: StorePath -> IO ByteString getDerivationNameFromPath storePath = BS.unsafePackMallocCString =<< [C.throwBlock| const char *{ - StorePath &sp = *$fptr-ptr:(nix::StorePath *storePath); + nix::StorePath &sp = *$fptr-ptr:(nix::StorePath *storePath); std::string s(Derivation::nameFromPath(sp)); return stringdup(s); }|] @@ -587,12 +603,12 @@ getDerivationOutputs (Store store) drvName (Derivation derivationFPtr) = alloca \nameP -> alloca \pathP -> alloca \typP -> alloca \fimP -> alloca \hashTypeP -> alloca \hashValueP -> alloca \hashSizeP -> do [C.throwBlock| void { - Store &store = **$(refStore *store); + nix::Store &store = *$(nix_store *store)->ptr; std::string drvName = std::string($bs-ptr:drvName, $bs-len:drvName); nix::DerivationOutputs::iterator &i = *$(DerivationOutputsIterator *i); const char *&name = *$(const char **nameP); int &typ = *$(int *typP); - StorePath *& path = *$(nix::StorePath **pathP); + nix::StorePath *& path = *$(nix::StorePath **pathP); int &fim = *$(int *fimP); int &hashType = *$(int *hashTypeP); char *&hashValue = *$(char **hashValueP); @@ -604,11 +620,11 @@ getDerivationOutputs (Store store) drvName (Derivation derivationFPtr) = std::visit(overloaded { [&](DerivationOutput::InputAddressed doi) -> void { typ = 0; - path = new StorePath(doi.path); + path = new nix::StorePath(doi.path); }, [&](DerivationOutput::CAFixed dof) -> void { typ = 1; - path = new StorePath(dof.path(store, $(Derivation *derivation)->name, nameString)); + path = new nix::StorePath(dof.path(store, $(Derivation *derivation)->name, nameString)); switch (dof.ca.method.raw) { case ContentAddressMethod::Raw::Text: // FIXME (RFC 92) @@ -784,9 +800,9 @@ getDerivationSources' derivation = mask_ do vec <- moveToForeignPtrWrapper =<< [C.throwBlock| std::vector* { - auto r = new std::vector(); + auto r = new std::vector(); for (auto s : $fptr-ptr:(Derivation *derivation)->inputSrcs) - r->push_back(new StorePath(s)); + r->push_back(new nix::StorePath(s)); return r; }|] traverse moveToForeignPtrWrapper =<< Std.Vector.toList vec @@ -809,7 +825,7 @@ getDerivationInputs' (Derivation derivationFPtr) = else do name <- [C.throwBlock| nix::StorePath *{ - return new StorePath((*$(DerivationInputsIterator *i))->first); + return new nix::StorePath((*$(DerivationInputsIterator *i))->first); }|] >>= moveToForeignPtrWrapper outs <- @@ -955,8 +971,8 @@ copyClosure (Store src) (Store dest) pathList = do withForeignPtr pathsVector' \pathsVector -> [C.throwBlock| void { ReceiveInterrupts _; - ref src = *$(refStore* src); - ref dest = *$(refStore* dest); + ref src = $(nix_store* src)->ptr; + ref dest = $(nix_store* dest)->ptr; std::vector &pathsVector = *$(std::vector* pathsVector); StorePathSet pathSet; @@ -1003,8 +1019,8 @@ signPath (Store store) secretKey (StorePath path) = (== 1) <$> do [C.throwBlock| int { ReceiveInterrupts _; - nix::ref store = *$(refStore *store); - const StorePath &storePath = *$fptr-ptr:(nix::StorePath *path); + nix::ref store = $(nix_store *store)->ptr; + const nix::StorePath &storePath = *$fptr-ptr:(nix::StorePath *path); const SecretKey &secretKey = *$(SecretKey *secretKey); auto currentInfo = store->queryPathInfo(storePath); @@ -1031,9 +1047,9 @@ followLinksToStorePath (Store store) bs = moveToForeignPtrWrapper =<< [C.throwBlock| nix::StorePath *{ ReceiveInterrupts _; - Store &store = **$(refStore* store); + nix::Store &store = *$(nix_store* store)->ptr; std::string s = std::string($bs-ptr:bs, $bs-len:bs); - return new StorePath(store.followLinksToStorePath(s)); + return new nix::StorePath(store.followLinksToStorePath(s)); }|] -- | Whether a path exists and is registered. @@ -1041,8 +1057,8 @@ isValidPath :: Store -> StorePath -> IO Bool isValidPath (Store store) path = [C.throwBlock| bool { ReceiveInterrupts _; - Store &store = **$(refStore* store); - StorePath &path = *$fptr-ptr:(nix::StorePath *path); + nix::Store &store = *$(nix_store* store)->ptr; + nix::StorePath &path = *$fptr-ptr:(nix::StorePath *path); return store.isValidPath(path); }|] <&> (/= 0) @@ -1058,8 +1074,8 @@ queryPathInfo (Store store) (StorePath pathFPtr) = vpi <- [C.throwBlock| refValidPathInfo* { ReceiveInterrupts _; - Store &store = **$(refStore* store); - StorePath &path = *$(nix::StorePath *path); + nix::Store &store = *$(nix_store* store)->ptr; + nix::StorePath &path = *$(nix::StorePath *path); return new refValidPathInfo(store.queryPathInfo(path)); }|] toForeignPtr vpi @@ -1079,8 +1095,8 @@ queryPathInfoFromClientCache (Store store) (StorePath pathFPtr) = mvpi <- [C.throwBlock| refValidPathInfo* { ReceiveInterrupts _; - Store &store = **$(refStore* store); - StorePath &path = *$(nix::StorePath *path); + nix::Store &store = *$(nix_store* store)->ptr; + nix::StorePath &path = *$(nix::StorePath *path); bool &isKnown = *$(bool* isKnownP); std::optional> maybeVPI = store.queryPathInfoFromClientCache(path); @@ -1139,8 +1155,8 @@ validPathInfoDeriver' :: ForeignPtr (Ref ValidPathInfo) -> IO (Maybe StorePath) validPathInfoDeriver' vpi = nullableMoveToForeignPtrWrapper =<< [C.throwBlock| nix::StorePath * { - std::optional deriver = (*$fptr-ptr:(refValidPathInfo* vpi))->deriver; - return deriver ? new StorePath(*deriver) : nullptr; + std::optional deriver = (*$fptr-ptr:(refValidPathInfo* vpi))->deriver; + return deriver ? new nix::StorePath(*deriver) : nullptr; }|] -- | References field of a ValidPathInfo struct. Source: store-api.hh @@ -1154,7 +1170,7 @@ validPathInfoReferences' vpi = do =<< [C.throwBlock| std::vector* { auto sps = new std::vector(); for (auto sp : (*$fptr-ptr:(refValidPathInfo* vpi))->references) - sps->push_back(new StorePath(sp)); + sps->push_back(new nix::StorePath(sp)); return sps; }|] l <- Std.Vector.toList sps @@ -1186,7 +1202,7 @@ computeFSClosure (Store store) params (Std.Set.StdSet startingSet) = do ret@(Std.Set.StdSet retSet) <- Std.Set.new [C.throwBlock| void { ReceiveInterrupts _; - Store &store = **$(refStore* store); + nix::Store &store = *$(nix_store* store)->ptr; StorePathSet &ret = *$fptr-ptr:(std::set* retSet); store.computeFSClosure(*$fptr-ptr:(std::set* startingSet), ret, $(int flipDir), $(int inclOut), $(int inclDrv)); diff --git a/hercules-ci-cnix-store/src/Hercules/CNix/Store/Context.hs b/hercules-ci-cnix-store/src/Hercules/CNix/Store/Context.hs index e024546e..bbfa7639 100644 --- a/hercules-ci-cnix-store/src/Hercules/CNix/Store/Context.hs +++ b/hercules-ci-cnix-store/src/Hercules/CNix/Store/Context.hs @@ -7,6 +7,8 @@ module Hercules.CNix.Store.Context where import Data.ByteString.Unsafe (unsafePackMallocCString) import qualified Data.Map as M import qualified Foreign.C.String +-- Import C API Store type for inline-c context +import qualified Hercules.CNix.Nix.API.Store as CAPI import qualified Language.C.Inline.Context as C import qualified Language.C.Inline.Cpp as C import qualified Language.C.Types as C @@ -52,7 +54,8 @@ context = <> C.bsCtx <> mempty { C.ctxTypesTable = - M.singleton (C.TypeName "refStore") [t|Ref NixStore|] + M.singleton (C.TypeName "nix_store") [t|CAPI.Store|] + <> M.singleton (C.TypeName "refStore") [t|Ref NixStore|] <> M.singleton (C.TypeName "nix::StorePath") [t|NixStorePath|] <> M.singleton (C.TypeName "nix::StorePathWithOutputs") [t|NixStorePathWithOutputs|] <> M.singleton (C.TypeName "refValidPathInfo") [t|Ref ValidPathInfo|]