diff --git a/doc/external-api/README.md b/doc/external-api/README.md new file mode 100644 index 000000000..20015e7a9 --- /dev/null +++ b/doc/external-api/README.md @@ -0,0 +1,74 @@ +# Getting started + +There are two ways to interface with nix: embedding it, or as a plugin. Embedding means you link one of the nix libraries in your program and use it from there, while being a plugin means you make a library that gets loaded by the nix evaluator, specified through a configuration option. + +# Embedding the Nix Evaluator + +These examples don't include error handling. +See the [Handling errors](@ref errors) section for more information. + +**main.c:** +```C +#include +#include +#include +#include + +int main() { + nix_libexpr_init(NULL); + + Store* store = nix_store_open(NULL, "dummy://", NULL); + State* state = nix_state_create(NULL, NULL, store); // empty 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_unref(store); + return 0; +} +``` + +**Usage:** +``` +$ gcc main.c $(pkg-config nix-expr-c --libs --cflags) -o main +$ ./main +nix version 1.2.3 +``` + + +# Writing a Nix Plugin + +**plugin.c:** +```C +#include +#include +#include + +void increment(State* state, int pos, Value** args, Value* v) { + nix_value_force(NULL, state, args[0]); + if (nix_get_type(NULL, args[0]) == NIX_TYPE_INT) { + nix_set_int(NULL, v, nix_get_int(NULL, args[0]) + 1); + } else { + nix_set_null(NULL, v); + } +} + +void nix_plugin_entry() { + const char* args[] = {"n", NULL}; + PrimOp *p = nix_alloc_primop(NULL, increment, 1, "increment", args, "Example nix plugin function: increments an int"); + nix_register_primop(NULL, p); + nix_gc_decref(NULL, p); +} +``` + +**Usage:** +``` +$ 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 +``` diff --git a/doc/external-api/doxygen.cfg.in b/doc/external-api/doxygen.cfg.in index d78188900..c9f2e4b7b 100644 --- a/doc/external-api/doxygen.cfg.in +++ b/doc/external-api/doxygen.cfg.in @@ -38,9 +38,10 @@ GENERATE_LATEX = NO INPUT = \ src/libutil/c \ src/libexpr/c \ - src/libstore/c + src/libstore/c \ + doc/external-api/README.md -FILE_PATTERNS = nix_api_*.h +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 @@ -52,3 +53,5 @@ 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