Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 40 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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;

})
];
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ 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 "<nix_api_store_internal.h>"

-- 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"
Expand Down Expand Up @@ -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<nix::ref<nix::Store>> stores = getDefaultSubstituters();
stores.push_front(*$(refStore* store));
stores.push_front($(nix_store* store)->ptr);

nix::Derivation *derivation = nullptr;

Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ C.include "<cstring>"

C.include "hercules-aliases.h"

-- C API internals header to access C++ Store from C API Store
C.include "<nix_api_store_internal.h>"

-- Create a typedef to disambiguate C API Store from nix::Store
C.verbatim "typedef ::Store nix_store;"

C.using "namespace nix"

withHerculesStore ::
Expand All @@ -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);
} |]
Expand Down
12 changes: 9 additions & 3 deletions hercules-ci-cnix-expr/src/Hercules/CNix/Expr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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 "<nix_api_store_internal.h>"

-- Create a typedef to disambiguate C API Store from nix::Store
C.verbatim "typedef ::Store nix_store;"

C.include "<gc/gc.h>"

C.include "<gc/gc_cpp.h>"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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))
Expand Down
1 change: 1 addition & 0 deletions hercules-ci-cnix-store/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
src-generated/
30 changes: 30 additions & 0 deletions hercules-ci-cnix-store/Setup.hs
Original file line number Diff line number Diff line change
@@ -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"
]
17 changes: 16 additions & 1 deletion hercules-ci-cnix-store/hercules-ci-cnix-store.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -100,6 +113,8 @@ library
, unix
, unliftio-core
, vector
, hs-bindgen-runtime
, c-expr-runtime
if ! flag(ide)
extra-libraries:
boost_context
Expand Down
Loading