Fundamentals
Main.nix format
Each main.nix
file under the makes/
directory
should be a function that receives one or more arguments
and returns a derivation:
Derivations
A Nix derivation is the process of:
- taking zero or more inputs
- transforming them as we see fit
- placing the results in the output path
Derivation outputs live in the /nix/store
.
Their locations in the filesystem are always in the form:
/nix/store/hash123-name
where
hash123
is computed by hashing the derivation's inputs.
Derivation outputs are:
- A regular file
- A regular directory that contains arbitrary contents
For instance the derivation output for Bash is:
/nix/store/kxj6cblcsd1qcbbxlmbswwrn89zcmgd6-bash-4.4-p23
which contains, among other files:
makeSearchPaths
On Linux software dependencies can be located anywhere in the file system.
We can control where programs find other programs, dependencies, libraries, etc, through special environment variables.
Below we describe shortly the purpose of the environment variables we currently support.
- CLASSPATH: Location of user-defined classes and packages.
- CRYSTAL_LIBRARY_PATH: Location of Crystal libraries.
- GEM_PATH: Location of libraries for Ruby.
- LD_LIBRARY_PATH: Location of libraries for Dynamic Linking Loaders.
- MYPYPATH: Location of library stubs and static types for MyPy.
- NODE_PATH: Location of Node.js modules.
- OCAMLPATH: Location of OCaml libraries.
- CAML_LD_LIBRARY_PATH: Location of OCaml stublibs.
- PATH: Location of directories where executable programs are located.
- PKG_CONFIG_PATH: Location of pkg-config packages.
- PYTHONPATH: Location of Python modules and site-packages.
makeSearchPaths
helps you write code like this:
Instead of this:
Types:
- makeSearchPaths (
function { ... } -> package
):bin
(listOf coercibleToStr
): Optional. Append/bin
of each element in the list to PATH. Defaults to[ ]
.rpath
(listOf coercibleToStr
): Optional. Append/lib
and/lib64
of each element in the list to LD_LIBRARY_PATH. Defaults to[ ]
.source
(listOf coercibleToStr
): Optional. Source (as in Bash'ssource
command) each element in the list. Defaults to[ ]
.
Types specific to Crystal:
- makeSearchPaths (
function { ... } -> package
):crystalLib
(listOf coercibleToStr
): Optional. Append/lib
of each element in the list to CRYSTAL_LIBRARY_PATH. Defaults to[ ]
.
Types specific to Java:
- makeSearchPaths (
function { ... } -> package
):javaClass
(listOf coercibleToStr
): Optional. Append each element in the list to CLASSPATH. Defaults to[ ]
.
Types specific to Kubernetes:
- makeSearchPaths (
function { ... } -> package
):kubeConfig
(listOf coercibleToStr
): Optional. Append each element in the list to KUBECONFIG. Defaults to[ ]
.
Types specific to pkg-config:
- makeSearchPaths (
function { ... } -> package
):pkgConfig
(listOf coercibleToStr
): Optional. Append/lib/pkgconfig
of each element in the list to PKG_CONFIG_PATH. Defaults to[ ]
.
Types specific to OCaml:
- makeSearchPaths (
function { ... } -> package
):ocamlBin
(listOf coercibleToStr
): Optional. Append/bin
of each element in the list to PATH. Defaults to[ ]
.ocamlLib
(listOf coercibleToStr
): Optional. Append/
of each element in the list to OCAMLPATH. Defaults to[ ]
.ocamlStublib
(listOf coercibleToStr
): Optional. Append/stublib
of each element in the list to CAML_LD_LIBRARY_PATH. Defaults to[ ]
Types specific to Python:
- makeSearchPaths (
function { ... } -> package
):pythonMypy
(listOf coercibleToStr
): Optional. Append/
of each element in the list to MYPYPATH. Defaults to[ ]
.pythonMypy39
(listOf coercibleToStr
): Optional. Append/lib/python3.9/site-packages
of each element in the list to MYPYPATH. Defaults to[ ]
.pythonMypy310
(listOf coercibleToStr
): Optional. Append/lib/python3.10/site-packages
of each element in the list to MYPYPATH. Defaults to[ ]
.pythonMypy311
(listOf coercibleToStr
): Optional. Append/lib/python3.11/site-packages
of each element in the list to MYPYPATH. Defaults to[ ]
.pythonPackage
(listOf coercibleToStr
): Optional. Append/
of each element in the list to PYTHONPATH. Defaults to[ ]
.pythonPackage39
(listOf coercibleToStr
): Optional. Append/lib/python3.9/site-packages
of each element in the list to PYTHONPATH. Defaults to[ ]
.pythonPackage310
(listOf coercibleToStr
): Optional. Append/lib/python3.10/site-packages
of each element in the list to PYTHONPATH. Defaults to[ ]
.pythonPackage311
(listOf coercibleToStr
): Optional. Append/lib/python3.11/site-packages
of each element in the list to PYTHONPATH. Defaults to[ ]
.
Types specific to Node.js:
- makeSearchPaths (
function { ... } -> package
):nodeBin
(listOf coercibleToStr
): Optional. Append/.bin
of each element in the list to PATH. Defaults to[ ]
.nodeModule
(listOf coercibleToStr
): Optional. Append/
of each element in the list to NODE_PATH. Defaults to[ ]
.
Types specific to Ruby:
- makeSearchPaths (
function { ... } -> package
):rubyBin
(listOf coercibleToStr
): Optional. Append/bin
of each element in the list to PATH. Defaults to[ ]
.rubyGemPath
(listOf coercibleToStr
): Optional. Append/
of each element in the list to GEM_PATH. Defaults to[ ]
.
Types for non covered cases:
- makeSearchPaths (
function { ... } -> package
):-
export
(listOf (tuple [ str coercibleToStr str ])
): Optional. Export (as in Bash'sexport
command) each tuple in the list.Defaults to
[ ]
.Tuples elements are:
- Name of the environment variable to export.
- Base package to export from.
- Relative path with respect to the package that should be appended.
-
Example:
makeDerivation
Perform a build step in an isolated environment:
- External environment variables are not visible by the builder script. This means you can't use secrets here.
- Search Paths as in
makeSearchPaths
are completely empty. - The
HOME
environment variable is set to/homeless-shelter
. - Only GNU coreutils commands (cat, echo, ls, ...) are present by default.
- An environment variable called
out
is present and represents the derivation's output. The derivation must produce an output, may be a file, or a directory. -
Convenience bash functions are exported:
echo_stderr
: Likeecho
but to standard error.debug
: Likeecho_stderr
but with a[DEBUG]
prefix.info
: Likeecho_stderr
but with a[INFO]
prefix.warn
: Likeecho_stderr
but with a[WARNING]
prefix.error
: Likeecho_stderr
but with a[ERROR]
prefix. Returns exit code 1 to signal failure.critical
: Likeecho_stderr
but with a[CRITICAL]
prefix. Exits immediately with exit code 1, aborting the entire execution.copy
: Likecp
but making paths writeable after copying them.-
require_env_var
:error
s when the specified env var is not set, or set to an empty value.
-
After the build, for all paths in
$out
:- User and group ownership are removed
- Last-modified timestamps are reset to
1970-01-01T00:00:00+00:00
.
Types:
- makeDerivation (
function { ... } -> package
):- builder (
either str package
): A Bash script that performs the build step. - env (
attrsOf str
): Optional. Environment variables that will be propagated to thebuilder
. Variable names must start withenv
. Defaults to{ }
. - local (
bool
): Optional. Should we always build locally this step? Thus effectively ignoring any configured binary caches. Defaults tofalse
. - name (
str
): Custom name to assign to the build step, be creative, it helps in debugging. - searchPaths (
asIn makeSearchPaths
): Optional. Arguments here will be passed as-is tomakeSearchPaths
. Defaults tomakeSearchPaths
's defaults.
- builder (
Example:
makeTemplate
Replace placeholders with the specified values in a file of any format.
Types:
- makeTemplate (
function { ... } -> package
):- local (
bool
): Optional. Should we always build locally this step? Thus effectively ignoring any configured binary caches. Defaults totrue
. - name (
str
): Custom name to assign to the build step, be creative, it helps in debugging. - replace (
attrsOf strLike
): Optional. Placeholders will be replaced in the script with their respective value. Variable names must start with__arg
, end with__
and have at least 6 characters long. Defaults to{ }
. - template (
either str package
): A string, file, output or package in which placeholders will be replaced.
- local (
Example:
makeScript
Wrap a Bash script that runs in a almost-isolated environment.
- The file system is not isolated, the script runs in user-space.
- External environment variables are visible by the script. You can use this to propagate secrets.
- Search Paths as in
makeSearchPaths
are completely empty. - The
HOME_IMPURE
environment variable is set to the user's home directory. - The
HOME
environment variable is set to a temporary directory. - Only GNU coreutils commands (cat, echo, ls, ...) are present by default.
- An environment variable called
STATE
points to a directory that can be used to store the script's state (if any). That state can be optionally persisted. That state can be optionally shared across repositories. -
Convenience bash functions are exported:
-
running_in_ci_cd_provider
: Detects if we are running on the CI/CD provider (gitlab/github/etc). -
prompt_user_for_confirmation
: Warns the user about a possibly destructive action that will be executed soon and aborts if the user does not confirm aproppriately.This function assumes a positive answer when running on the CI/CD provider because there is no human interaction. -
prompt_user_for_input
: Ask the user to type information or optionally use a default value by pressing ENTER.This function assumes the default value when running on the CI/CD provider because there is no human interaction.
-
-
After the build, the script is executed.
Types:
- makeScript (
function { ... } -> package
):- entrypoint (
either str package
): A Bash script that performs the build step. - name (
str
): Custom name to assign to the build step, be creative, it helps in debugging. - replace (
attrsOf strLike
): Optional. Placeholders will be replaced in the script with their respective value. Variable names must start with__arg
, end with__
and have at least 6 characters long. Defaults to{ }
. - searchPaths (
asIn makeSearchPaths
): Optional. Arguments here will be passed as-is tomakeSearchPaths
. Defaults tomakeSearchPaths
's defaults. - persistState (
bool
): Optional. If true, state will not be cleared before each script run. Defaults tofalse
. -
globalState (
bool
): Optional. If true, script state will be written toglobalStateDir
and toprojectStateDir
otherwise. Defaults tofalse
, ifprojectStateDir
is specified or derived.Note
- It is implicitly
true
, ifprojectStateDir == globalStateDir
. projectStateDir == globalStateDir
is the default ifprojectIdentifier
is not configured.- Hence, generally enable project local state by
- either setting
projectIdentifier
- or
projectStateDir
different fromglobalStateDir
.
- either setting
- It is implicitly
- entrypoint (
Example:
projectPath
Copy a path from the current Makes project being evaluated to the Nix store in the most pure and reproducible way possible.
Types:
- projectPath (
function str -> package
):- (
str
): Absolute path, assumming the repository is located at"/"
.
- (
Example: