-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(Towards) stable C bindings for libutil, libexpr #8699
Merged
Merged
Changes from all commits
Commits
Show all changes
70 commits
Select commit
Hold shift + click to select a range
4702317
libutil: add C bindings
yorickvP 1d41600
libstore: add C bindings
yorickvP e76652a
libexpr: add C bindings
yorickvP 748b322
nix_api_value: fix primop arity
puckipedia 4a49361
nix_api_value: fix documentation for get_attr_byname
yorickvP c3b5b8e
nix_api_expr, store: fix minor documentation issues
yorickvP efcddcd
nix_api_external: fix missing void* self param
yorickvP 1e583c4
nix_api_value: nix_{get,set}_double -> nix_{get,set}_float
yorickvP 1777e4a
nix_api_store: add userdata param to nix_store_build
yorickvP aa85f7d
nix_api_expr: merge nix_parse_expr and nix_expr_eval, remove Expr
yorickvP 022b918
nix_api_expr: remove bindingsbuilder refcounting
yorickvP bebee70
nix_api_external: own return strings on the nix side
yorickvP ded0ef6
nix_api_expr: switch to refcounting
yorickvP ada2af4
nix_api_expr: add nix_gc_now()
yorickvP 866558a
nix_api_expr: add error handling to incref, decref
yorickvP b0741f7
external-api-doc: introduce and improve documentation
yorickvP f41a7e3
nix_err_code: do not fail
yorickvP e58a938
nix_api_expr, nix_api_util: slightly improve documentation
yorickvP e74d6c1
nix_api_expr: document nix_value_force
yorickvP f0afe7f
nix_api_util: throw nix::error instead of new nix::Error for null ctx's
yorickvP c48b9b8
nix_api_util: tests
yorickvP 9cccb8b
nix_api_expr: always force values before giving them to the user
yorickvP e891aac
nix_api_value: add nix_get_attr_name_byidx get attr names without for…
yorickvP 713f10a
nix_api_value: Add nix_register_primop to add builtins
yorickvP dc0f7d8
initPlugins: run nix_plugin_entry() on dlopen'd plugins
yorickvP df9401e
nix_api_store: add nix_init_plugins
yorickvP e642bbc
C API: move to src/lib*/c/
yorickvP 3b41830
docs/external-api: write main page
yorickvP 40f5d48
Apply documentation suggestions from code review
yorickvP 5d82d6e
nix_api: fix missing includes in headers
yorickvP 9d380c0
C API: clarify some documentation
yorickvP 91e53de
C API: update README example
yorickvP e1bb799
C API: reformat according to proposed clang-format file
yorickvP 9e423de
C API: update after rebase
yorickvP 48aa575
primops: change to std::function, allowing the passing of user data
yorickvP 3d79f38
C API: add user_data argument to nix_alloc_primop
yorickvP ab92502
C API: add a way to throw errors from primops
yorickvP c6e28d8
C API: fix: macos doesn't have std::bind_front
yorickvP 550af11
String value refactor
jlesquembre 46f5d0e
Apply suggestions from code review
jlesquembre 41f1669
C API: add tests for libutil and libstore
jlesquembre 5560196
C API: fix documentation build
jlesquembre ac3a9c6
C API: add nix_api_expr tests
jlesquembre 92dacec
C API: Apply documentation suggestions
jlesquembre 24604d0
C API: fix docs build after rebase
jlesquembre 5356941
C API: rename State to EvalState
jlesquembre d5ec1d0
C API: nix_store_open, check for empty strings
jlesquembre 415583a
C API: use bool argument consistently
jlesquembre 51ff547
C API: add more tests to nix_api_expr
jlesquembre dfdb90d
C API: Consolidate initializers
jlesquembre 24c8f68
C API: if store doesn't have a version, return an empty string
jlesquembre b9cd24a
C API: fix api_expr tests
jlesquembre 6c231dc
C API: disable test
jlesquembre 2349185
C API: fix after rebase
jlesquembre 7c602d9
C API: add tests for external values
jlesquembre c49b88b
C API: update docs based on PR feedback
jlesquembre 693e8ec
C API: unify makefile after rebase
jlesquembre 2e1dbbe
C API: refactor test support
jlesquembre 1093ab6
C API: add more tests
jlesquembre 34d15e8
C API: rename nix_store_build -> nix_store_realise
jlesquembre 1a574c6
C API: refactor ListBuilder
jlesquembre 31fbb24
C API: refactor nix_store_realise
jlesquembre 940ff65
C API: update libstore tests
jlesquembre d96b52b
C api: nix_export_std_string -> nix_observe_string
jlesquembre c57de60
C API: Keep the structure flat
jlesquembre 925a8fd
C API: Use new ListBuilder helper
jlesquembre 061140f
C API: remove unused argument
jlesquembre 2bb609b
C API: rename nix_observe_string -> nix_get_string_callback
jlesquembre 2d84433
C API: update documentation
jlesquembre 926fbad
C API: add more tests
jlesquembre File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
/doxygen.cfg | ||
/html | ||
/latex |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
# Getting started | ||
|
||
> **Warning** These bindings are **experimental**, which means they can change | ||
> at any time or be removed outright; nevertheless the plan is to provide a | ||
> stable external C API to the Nix language and the Nix store. | ||
|
||
The language library allows evaluating Nix expressions and interacting with Nix | ||
language values. The Nix store API is still rudimentary, and only allows | ||
initialising and connecting to a store for the Nix language evaluator to | ||
interact with. | ||
|
||
Currently there are two ways to interface with the Nix language evaluator | ||
programmatically: | ||
|
||
1. Embedding the evaluator | ||
2. Writing language plug-ins | ||
|
||
Embedding means you link the Nix C libraries in your program and use them from | ||
there. Adding a plug-in means you make a library that gets loaded by the Nix | ||
language evaluator, specified through a configuration option. | ||
|
||
Many of the components and mechanisms involved are not yet documented, therefore | ||
please refer to the [Nix source code](https://github.com/NixOS/nix/) for | ||
details. Additions to in-code documentation and the reference manual are highly | ||
appreciated. | ||
|
||
The following examples, for simplicity, don't include error handling. See the | ||
[Handling errors](@ref errors) section for more information. | ||
|
||
# Embedding the Nix Evaluator | ||
|
||
In this example we programmatically start the Nix language evaluator with a | ||
dummy store (that has no store paths and cannot be written to), and evaluate the | ||
Nix expression `builtins.nixVersion`. | ||
|
||
**main.c:** | ||
|
||
```C | ||
#include <nix_api_util.h> | ||
#include <nix_api_expr.h> | ||
#include <nix_api_value.h> | ||
#include <stdio.h> | ||
|
||
// NOTE: This example lacks all error handling. Production code must check for | ||
// errors, as some return values will be undefined. | ||
int main() { | ||
nix_libexpr_init(NULL); | ||
|
||
Store* store = nix_store_open(NULL, "dummy://", NULL); | ||
EvalState* state = nix_state_create(NULL, NULL, store); // empty search path (NIX_PATH) | ||
Value *value = nix_alloc_value(NULL, state); | ||
|
||
nix_expr_eval_from_string(NULL, state, "builtins.nixVersion", ".", value); | ||
nix_value_force(NULL, state, value); | ||
printf("Nix version: %s\n", nix_get_string(NULL, value)); | ||
|
||
nix_gc_decref(NULL, value); | ||
nix_state_free(state); | ||
nix_store_free(store); | ||
return 0; | ||
} | ||
``` | ||
|
||
**Usage:** | ||
|
||
```ShellSession | ||
$ gcc main.c $(pkg-config nix-expr-c --libs --cflags) -o main | ||
$ ./main | ||
Nix version: 2.17 | ||
``` | ||
|
||
# Writing a Nix language plug-in | ||
|
||
In this example we add a custom primitive operation (_primop_) to `builtins`. It | ||
will increment the argument if it is an integer and throw an error otherwise. | ||
|
||
yorickvP marked this conversation as resolved.
Show resolved
Hide resolved
|
||
**plugin.c:** | ||
|
||
```C | ||
#include <nix_api_util.h> | ||
#include <nix_api_expr.h> | ||
#include <nix_api_value.h> | ||
|
||
void increment(void* user_data, nix_c_context* ctx, EvalState* state, Value** args, Value* v) { | ||
nix_value_force(NULL, state, args[0]); | ||
if (nix_get_type(NULL, args[0]) == NIX_TYPE_INT) { | ||
nix_init_int(NULL, v, nix_get_int(NULL, args[0]) + 1); | ||
} else { | ||
nix_set_err_msg(ctx, NIX_ERR_UNKNOWN, "First argument should be an integer."); | ||
} | ||
} | ||
|
||
void nix_plugin_entry() { | ||
const char* args[] = {"n", NULL}; | ||
PrimOp *p = nix_alloc_primop(NULL, increment, 1, "increment", args, "Example custom built-in function: increments an integer", NULL); | ||
nix_register_primop(NULL, p); | ||
nix_gc_decref(NULL, p); | ||
} | ||
``` | ||
|
||
**Usage:** | ||
|
||
```ShellSession | ||
$ gcc plugin.c $(pkg-config nix-expr-c --libs --cflags) -shared -o plugin.so | ||
$ nix --plugin-files ./plugin.so repl | ||
nix-repl> builtins.increment 1 | ||
2 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# Doxyfile 1.9.5 | ||
|
||
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by | ||
# double-quotes, unless you are using Doxywizard) that should identify the | ||
# project for which the documentation is generated. This name is used in the | ||
# title of most generated pages and in a few other places. | ||
# The default value is: My Project. | ||
|
||
PROJECT_NAME = "Nix" | ||
|
||
# The PROJECT_NUMBER tag can be used to enter a project or revision number. This | ||
# could be handy for archiving the generated documentation or if some version | ||
# control system is used. | ||
|
||
PROJECT_NUMBER = @PACKAGE_VERSION@ | ||
|
||
# Using the PROJECT_BRIEF tag one can provide an optional one line description | ||
# for a project that appears at the top of each page and should give viewer a | ||
# quick idea about the purpose of the project. Keep the description short. | ||
|
||
PROJECT_BRIEF = "Nix, the purely functional package manager: C API (experimental)" | ||
|
||
# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. | ||
# The default value is: YES. | ||
|
||
GENERATE_LATEX = NO | ||
|
||
# The INPUT tag is used to specify the files and/or directories that contain | ||
# documented source files. You may enter file names like myfile.cpp or | ||
# directories like /usr/src/myproject. Separate the files or directories with | ||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING | ||
# Note: If this tag is empty the current directory is searched. | ||
|
||
# FIXME Make this list more maintainable somehow. We could maybe generate this | ||
# in the Makefile, but we would need to change how `.in` files are preprocessed | ||
# so they can expand variables despite configure variables. | ||
|
||
INPUT = \ | ||
src/libutil-c \ | ||
src/libexpr-c \ | ||
src/libstore-c \ | ||
doc/external-api/README.md | ||
|
||
FILE_PATTERNS = nix_api_*.h *.md | ||
|
||
# The INCLUDE_PATH tag can be used to specify one or more directories that | ||
# contain include files that are not input files but should be processed by the | ||
# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of | ||
# RECURSIVE has no effect here. | ||
# This tag requires that the tag SEARCH_INCLUDES is set to YES. | ||
|
||
INCLUDE_PATH = @RAPIDCHECK_HEADERS@ | ||
EXCLUDE_PATTERNS = *_internal.h | ||
GENERATE_TREEVIEW = YES | ||
OPTIMIZE_OUTPUT_FOR_C = YES | ||
|
||
USE_MDFILE_AS_MAINPAGE = doc/external-api/README.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
$(docdir)/external-api/html/index.html $(docdir)/external-api/latex: $(d)/doxygen.cfg | ||
mkdir -p $(docdir)/external-api | ||
{ cat $< ; echo "OUTPUT_DIRECTORY=$(docdir)/external-api" ; } | doxygen - | ||
|
||
# Generate the HTML API docs for Nix's unstable C bindings | ||
.PHONY: external-api-html | ||
external-api-html: $(docdir)/external-api/html/index.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
libraries += libexprc | ||
|
||
libexprc_NAME = libnixexprc | ||
|
||
libexprc_DIR := $(d) | ||
|
||
libexprc_SOURCES := \ | ||
$(wildcard $(d)/*.cc) \ | ||
|
||
# Not just for this library itself, but also for downstream libraries using this library | ||
|
||
INCLUDE_libexprc := -I $(d) | ||
libexprc_CXXFLAGS += $(INCLUDE_libutil) $(INCLUDE_libutilc) \ | ||
$(INCLUDE_libfetchers) \ | ||
$(INCLUDE_libstore) $(INCLUDE_libstorec) \ | ||
$(INCLUDE_libexpr) $(INCLUDE_libexprc) | ||
|
||
libexprc_LIBS = libutil libutilc libstore libstorec libexpr | ||
|
||
libexprc_LDFLAGS += -pthread | ||
|
||
$(eval $(call install-file-in, $(d)/nix-expr-c.pc, $(libdir)/pkgconfig, 0644)) | ||
|
||
libexprc_FORCE_INSTALL := 1 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
prefix=@prefix@ | ||
libdir=@libdir@ | ||
includedir=@includedir@ | ||
|
||
Name: Nix | ||
Description: Nix Language Evaluator - C API | ||
Version: @PACKAGE_VERSION@ | ||
Requires: nix-store-c | ||
Libs: -L${libdir} -lnixexprc | ||
Cflags: -I${includedir}/nix |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.