Skip to content

Commit

Permalink
Add nix-flake-c, nix_flake_init_global, nix_flake_settings_new
Browse files Browse the repository at this point in the history
  • Loading branch information
roberth committed Nov 23, 2024
1 parent 87347f0 commit c9693c9
Show file tree
Hide file tree
Showing 14 changed files with 301 additions and 0 deletions.
1 change: 1 addition & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ endif
subproject('libutil-c')
subproject('libstore-c')
subproject('libexpr-c')
subproject('libflake-c')
subproject('libmain-c')

# Language Bindings
Expand Down
1 change: 1 addition & 0 deletions packaging/components.nix
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ in
nix-expr-tests = callPackage ../src/libexpr-tests/package.nix { };

nix-flake = callPackage ../src/libflake/package.nix { };
nix-flake-c = callPackage ../src/libflake-c/package.nix { };
nix-flake-tests = callPackage ../src/libflake-tests/package.nix { };

nix-main = callPackage ../src/libmain/package.nix { };
Expand Down
1 change: 1 addition & 0 deletions src/external-api-docs/doxygen.cfg.in
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ GENERATE_LATEX = NO
INPUT = \
@src@/src/libutil-c \
@src@/src/libexpr-c \
@src@/src/libflake-c \
@src@/src/libstore-c \
@src@/src/external-api-docs/README.md

Expand Down
1 change: 1 addition & 0 deletions src/external-api-docs/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mkMesonDerivation (finalAttrs: {
# Source is not compiled, but still must be available for Doxygen
# to gather comments.
(cpp ../libexpr-c)
(cpp ../libflake-c)
(cpp ../libstore-c)
(cpp ../libutil-c)
];
Expand Down
1 change: 1 addition & 0 deletions src/libflake-c/.version
1 change: 1 addition & 0 deletions src/libflake-c/build-utils-meson
93 changes: 93 additions & 0 deletions src/libflake-c/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
project('nix-flake-c', 'cpp',
version : files('.version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'debug=true',
'optimization=2',
'errorlogs=true', # Please print logs for tests that fail
],
meson_version : '>= 1.1',
license : 'LGPL-2.1-or-later',
)

cxx = meson.get_compiler('cpp')

subdir('build-utils-meson/deps-lists')

configdata = configuration_data()

deps_private_maybe_subproject = [
dependency('nix-util'),
dependency('nix-store'),
dependency('nix-expr'),
dependency('nix-flake'),
]
deps_public_maybe_subproject = [
dependency('nix-util-c'),
dependency('nix-store-c'),
dependency('nix-expr-c'),
]
subdir('build-utils-meson/subprojects')

# TODO rename, because it will conflict with downstream projects
configdata.set_quoted('PACKAGE_VERSION', meson.project_version())

config_h = configure_file(
configuration : configdata,
output : 'config-flake.h',
)

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.

# From C++ libraries, only for internals
'-include', 'config-util.hh',
'-include', 'config-store.hh',
'-include', 'config-expr.hh',
# not generated (yet?)
# '-include', 'config-flake.hh',

# From C libraries, for our public, installed headers too
'-include', 'config-util.h',
'-include', 'config-store.h',
'-include', 'config-expr.h',
'-include', 'config-flake.h',
language : 'cpp',
)

subdir('build-utils-meson/common')

sources = files(
'nix_api_flake.cc',
)

include_dirs = [include_directories('.')]

headers = [config_h] + files(
'nix_api_flake.h',
)

# TODO move this header to libexpr, maybe don't use it in tests?
headers += files('nix_api_flake.h')

subdir('build-utils-meson/export-all-symbols')
subdir('build-utils-meson/windows-version')

this_library = library(
'nixflakec',
sources,
dependencies : deps_public + deps_private + deps_other,
include_directories : include_dirs,
link_args: linker_export_flags,
prelink : true, # For C++ static initializers
install : true,
)

install_headers(headers, subdir : 'nix', preserve_path : true)

libraries_private = []

subdir('build-utils-meson/export')
32 changes: 32 additions & 0 deletions src/libflake-c/nix_api_flake.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "nix_api_flake.h"
#include "nix_api_flake_internal.hh"
#include "nix_api_util_internal.h"

#include "flake/flake.hh"

nix_flake_settings * nix_flake_settings_new(nix_c_context * context)
{
try {
auto settings = nix::make_ref<nix::flake::Settings>();
return new nix_flake_settings{settings};
}
NIXC_CATCH_ERRS_NULL
}

void nix_flake_settings_free(nix_flake_settings * settings)
{
delete settings;
}

nix_err nix_flake_init_global(nix_c_context * context, nix_flake_settings * settings)
{
static std::shared_ptr<nix::flake::Settings> registeredSettings;
try {
if (registeredSettings)
throw nix::Error("nix_flake_init_global already initialized");

registeredSettings = settings->settings;
nix::flake::initLib(*registeredSettings);
}
NIXC_CATCH_ERRS
}
44 changes: 44 additions & 0 deletions src/libflake-c/nix_api_flake.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef NIX_API_FLAKE_H
#define NIX_API_FLAKE_H
/** @defgroup libflake libflake
* @brief Bindings to the Nix Flakes library
*
* @{
*/
/** @file
* @brief Main entry for the libflake C bindings
*/

#include "nix_api_store.h"
#include "nix_api_util.h"
#include "nix_api_expr.h"

#ifdef __cplusplus
extern "C" {
#endif
// cffi start

typedef struct nix_flake_settings nix_flake_settings;

// Function prototypes
/**
* Create a nix_flake_settings initialized with default values.
* @param[out] context Optional, stores error information
* @return A new nix_flake_settings or NULL on failure.
* @see nix_flake_settings_free
*/
nix_flake_settings * nix_flake_settings_new(nix_c_context * context);

/**
* @brief Release the resources associated with a nix_flake_settings.
*/
void nix_flake_settings_free(nix_flake_settings * settings);

/**
* @brief Register Flakes support process-wide.
*/
nix_err nix_flake_init_global(nix_c_context * context, nix_flake_settings * settings);

} // extern "C"

#endif
9 changes: 9 additions & 0 deletions src/libflake-c/nix_api_flake_internal.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#include "ref.hh"
#include "flake/settings.hh"

struct nix_flake_settings
{
nix::ref<nix::flake::Settings> settings;
};
60 changes: 60 additions & 0 deletions src/libflake-c/package.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{ lib
, stdenv
, mkMesonLibrary

, nix-store-c
, nix-expr-c
, nix-flake

# Configuration Options

, version
}:

let
inherit (lib) fileset;
in

mkMesonLibrary (finalAttrs: {
pname = "nix-flake-c";
inherit version;

workDir = ./.;
fileset = fileset.unions [
../../build-utils-meson
./build-utils-meson
../../.version
./.version
./meson.build
# ./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
(fileset.fileFilter (file: file.hasExt "h") ./.)
];

propagatedBuildInputs = [
nix-expr-c
nix-store-c
nix-flake
];

preConfigure =
# "Inline" .version so it's not a symlink, and includes the suffix.
# Do the meson utils, without modification.
''
chmod u+w ./.version
echo ${version} > ../../.version
'';

mesonFlags = [
];

env = lib.optionalAttrs (stdenv.isLinux && !(stdenv.hostPlatform.isStatic && stdenv.system == "aarch64-linux")) {
LDFLAGS = "-fuse-ld=gold";
};

meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};

})
3 changes: 3 additions & 0 deletions src/libflake-tests/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ subdir('build-utils-meson/deps-lists')
deps_private_maybe_subproject = [
dependency('nix-expr-test-support'),
dependency('nix-flake'),
dependency('nix-flake-c'),
]
deps_public_maybe_subproject = [
]
Expand Down Expand Up @@ -46,6 +47,7 @@ subdir('build-utils-meson/common')

sources = files(
'flakeref.cc',
'nix_api_flake.cc',
'url-name.cc',
)

Expand All @@ -68,6 +70,7 @@ test(
this_exe,
env : {
'_NIX_TEST_UNIT_DATA': meson.current_source_dir() / 'data',
'NIX_CONFIG': 'extra-experimental-features = flakes',
},
protocol : 'gtest',
)
51 changes: 51 additions & 0 deletions src/libflake-tests/nix_api_flake.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "nix_api_store.h"
#include "nix_api_store_internal.h"
#include "nix_api_util.h"
#include "nix_api_util_internal.h"
#include "nix_api_expr.h"
#include "nix_api_value.h"
#include "nix_api_flake.h"

#include "tests/nix_api_expr.hh"
#include "tests/string_callback.hh"

#include <gmock/gmock.h>
#include <gtest/gtest.h>

namespace nixC {

TEST_F(nix_api_store_test, nix_api_init_global_getFlake_exists)
{
nix_libstore_init(ctx);
assert_ctx_ok();
nix_libexpr_init(ctx);
assert_ctx_ok();

auto settings = nix_flake_settings_new(ctx);
assert_ctx_ok();
ASSERT_NE(nullptr, settings);

nix_flake_init_global(ctx, settings);
assert_ctx_ok();

nix_eval_state_builder * builder = nix_eval_state_builder_new(ctx, store);
ASSERT_NE(nullptr, builder);
assert_ctx_ok();

auto state = nix_eval_state_build(ctx, builder);
assert_ctx_ok();
ASSERT_NE(nullptr, state);

nix_eval_state_builder_free(builder);

auto value = nix_alloc_value(ctx, state);
assert_ctx_ok();
ASSERT_NE(nullptr, value);

nix_err err = nix_expr_eval_from_string(ctx, state, "builtins.getFlake", ".", value);
assert_ctx_ok();
ASSERT_EQ(NIX_OK, err);
ASSERT_EQ(NIX_TYPE_FUNCTION, nix_get_type(ctx, value));
}

} // namespace nixC
3 changes: 3 additions & 0 deletions src/libflake-tests/package.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
, mkMesonExecutable

, nix-flake
, nix-flake-c
, nix-expr-test-support

, rapidcheck
Expand Down Expand Up @@ -38,6 +39,7 @@ mkMesonExecutable (finalAttrs: {

buildInputs = [
nix-flake
nix-flake-c
nix-expr-test-support
rapidcheck
gtest
Expand Down Expand Up @@ -67,6 +69,7 @@ mkMesonExecutable (finalAttrs: {
mkdir -p "$HOME"
'' + ''
export _NIX_TEST_UNIT_DATA=${resolvePath ./data}
export NIX_CONFIG="extra-experimental-features = flakes"
${stdenv.hostPlatform.emulator buildPackages} ${lib.getExe finalAttrs.finalPackage}
touch $out
'');
Expand Down

0 comments on commit c9693c9

Please sign in to comment.