sayrer / rules_nixpkgs

Rules for importing Nixpkgs packages into Bazel.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Nixpkgs rules for Bazel

Build status

Use Nix and the Nixpkgs package set to import external dependencies (like system packages) into Bazel hermetically. If the version of any dependency changes, Bazel will correctly rebuild targets, and only those targets that use the external dependencies that changed.

Links:

Rules

Setup

Add the following to your WORKSPACE file, and select a $COMMIT accordingly.

http_archive(
    name = "io_tweag_rules_nixpkgs",
    strip_prefix = "rules_nixpkgs-$COMMIT",
    urls = ["https://github.com/tweag/rules_nixpkgs/archive/$COMMIT.tar.gz"],
)

load("@io_tweag_rules_nixpkgs//nixpkgs:repositories.bzl", "rules_nixpkgs_dependencies")
rules_nixpkgs_dependencies()

load("@io_tweag_rules_nixpkgs//nixpkgs:nixpkgs.bzl", "nixpkgs_git_repository", "nixpkgs_package", "nixpkgs_cc_toolchain")

load("@io_tweag_rules_nixpkgs//nixpkgs:toolchains/go.bzl", "nixpkgs_go_toolchain") # optional

Example

nixpkgs_git_repository(
    name = "nixpkgs",
    revision = "17.09", # Any tag or commit hash
    sha256 = "" # optional sha to verify package integrity!
)

nixpkgs_package(
    name = "hello",
    repositories = { "nixpkgs": "@nixpkgs//:default.nix" }
)

Rules

nixpkgs_git_repository

Name a specific revision of Nixpkgs on GitHub or a local checkout.

nixpkgs_git_repository(name, revision, sha256)
Attributes
name

Name; required

A unique name for this repository.

revision

String; required

Git commit hash or tag identifying the version of Nixpkgs to use.

remote

String; optional

The URI of the remote Git repository. This must be a HTTP URL. There is currently no support for authentication. Defaults to upstream nixpkgs.

sha256

String; optional

The SHA256 used to verify the integrity of the repository.

nixpkgs_local_repository

Create an external repository representing the content of Nixpkgs, based on a Nix expression stored locally or provided inline. One of nix_file or nix_file_content must be provided.

nixpkgs_local_repository(name, nix_file, nix_file_deps, nix_file_content)
Attributes
name

Name; required

A unique name for this repository.

nix_file

String; optional

A file containing an expression for a Nix derivation.

nix_file_deps

List of labels; optional

Dependencies of `nix_file` if any.

nix_file_content

String; optional

An expression for a Nix derivation.

nixpkgs_package

Make the content of a Nixpkgs package available in the Bazel workspace.

nixpkgs_package(
    name, attribute_path, nix_file, nix_file_deps, nix_file_content,
    repository, repositories, build_file, build_file_content, nixopts,
    fail_not_supported,
)

If repositories is not specified, you must provide a nixpkgs clone in nix_file or nix_file_content.

Attributes
name

Name; required

A unique name for this target

attribute_path

String; optional

Select an attribute from the top-level Nix expression being evaluated. The attribute path is a sequence of attribute names separated by dots.

nix_file

String; optional

A file containing an expression for a Nix derivation.

nix_file_deps

List of labels; optional

Dependencies of `nix_file` if any.

nix_file_content

String; optional

An expression for a Nix derivation.

repository

Label; optional

A repository label identifying which Nixpkgs to use. Equivalent to `repositories = { "nixpkgs": ...}`

repositories

String-keyed label dict; optional

A dictionary mapping `NIX_PATH` entries to repository labels.

Setting it to

repositories = { "myrepo" : "//:myrepo" }
for example would replace all instances of <myrepo> in the called nix code by the path to the target "//:myrepo". See the relevant section in the nix manual for more information.

Specify one of `path` or `repositories`.

build_file

Label; optional

The file to use as the BUILD file for this repository. Its contents are copied copied into the file BUILD in root of the nix output folder. The Label does not need to be named BUILD, but can be.

For common use cases we provide filegroups that expose certain files as targets:

:bin
Everything in the bin/ directory.
:lib
All .so and .a files that can be found in subdirectories of lib/.
:include
All .h files that can be found in subdirectories of bin/.

If you need different files from the nix package, you can reference them like this:

package(default_visibility = [ "//visibility:public" ])
filegroup(
  name = "our-docs",
  srcs = glob(["share/doc/ourpackage/**/*"]),
)
See the bazel documentation of filegroup and glob.

build_file_content

String; optional

Like build_file, but a string of the contents instead of a file name.

nixopts

String list; optional

Extra flags to pass when calling Nix.

fail_not_supported

Boolean; optional; default = True

If set to True (default) this rule will fail on platforms which do not support Nix (e.g. Windows). If set to False calling this rule will succeed but no output will be generated.

nixpkgs_cc_configure

Tells Bazel to use compilers and linkers from Nixpkgs for the CC toolchain. By default, Bazel autodetects a toolchain on the current PATH. Overriding this autodetection makes builds more hermetic and is considered a best practice.

Example:

nixpkgs_cc_configure(repository = "@nixpkgs//:default.nix")
Attributes
nix_file

String; optional

An expression for a Nix environment derivation. The environment should expose all the commands that make up a CC toolchain (`cc`, `ld` etc). Exposes all commands in `stdenv.cc` and `binutils` by default.

nix_file_deps

List of labels; optional

Dependencies of `nix_file` if any.

nix_file_content

String; optional

An expression for a Nix environment derivation.

repository

Label; optional

A repository label identifying which Nixpkgs to use. Equivalent to `repositories = { "nixpkgs": ...}`

repositories

String-keyed label dict; optional

A dictionary mapping `NIX_PATH` entries to repository labels.

Setting it to

repositories = { "myrepo" : "//:myrepo" }
for example would replace all instances of <myrepo> in the called nix code by the path to the target "//:myrepo". See the relevant section in the nix manual for more information.

Specify one of `path` or `repositories`.

nixpkgs_go_configure

NOTE: this rule resides in @io_tweag_rules_nixpkgs//nixpkgs:toolchains/go.bzl to avoid unnecessary dependencies on rules_go for those who don't need go toolchain

For this rule to work rules_go must be available for loading before loading of @io_tweag_rules_nixpkgs//nixpkgs:toolchains/go.bzl.

Tells bazel to use go sdk from nixpkgs. This rule will fail if nix is not present - you can always wrap it in rule if you need to optionally provide nix support.

By default rules_go configures go toolchain to be downloaded as binaries (which doesn't work on NixOS), there is a way to tell rules_go to look into environment and find local go binary which is not hermetic. This command allows to setup hermetic go sdk from Nixpkgs, which should be considerate as best practice.

Note that nix package must provide full go sdk at the root of the package instead of in $out/share/go And also provide an empty normal file named PACKAGE_ROOT at the root of package

Example:

nixpkgs_go_configure(repository = "@nixpkgs//:default.nix")

Example (optional nix support when go is transitive dependency):

# .bazel-lib/nixos-support.bzl
def _has_nix(ctx):
    return ctx.which("nix-build") != None

def _gen_imports_impl(ctx):
    ctx.file("BUILD", "")

    imports_for_nix = """
        load("@io_tweag_rules_nixpkgs//nixpkgs:toolchains/go.bzl", "nixpkgs_go_toolchain")

        def fix_go():
            nixpkgs_go_toolchain(repository = "@nixpkgs")
    """
    imports_for_non_nix = """
        def fix_go():
            # if go isn't transitive you'll need to add call to go_register_toolchains here
            pass
    """

    if _has_nix(ctx):
        ctx.file("imports.bzl", imports_for_nix)
    else:
        ctx.file("imports.bzl", imports_for_non_nix)

_gen_imports = repository_rule(
    implementation = _gen_imports_impl,
    attrs = dict(),
)

def gen_imports():
    _gen_imports(
        name = "nixos_support",
    )



# WORKSPACE

// ...
http_archive(name = "io_tweag_rules_nixpkgs", ...)
// ...
local_repository(
    name = "bazel_lib",
    path = ".bazel-lib",
)
load("@bazel_lib//:nixos-support.bzl", "gen_imports")
gen_imports()
load("@nixos_support//:imports.bzl", "fix_go")
fix_go()
Attributes
sdk_name

String; optional

Go sdk name to pass in rules_go

nix_file

String; optional

An expression for a Nix environment derivation. The environment should expose whole go SDK (bin, src, ...) at the root of package. It also must contain PACKAGE_ROOT file in the root of pacakge.

nix_file_deps

List of labels; optional

Dependencies of `nix_file` if any.

nix_file_content

String; optional

An expression for a Nix environment derivation.

repository

Label; optional

A repository label identifying which Nixpkgs to use. Equivalent to `repositories = { "nixpkgs": ...}`

repositories

String-keyed label dict; optional

A dictionary mapping `NIX_PATH` entries to repository labels.

Setting it to

repositories = { "myrepo" : "//:myrepo" }
for example would replace all instances of <myrepo> in the called nix code by the path to the target "//:myrepo". See the relevant section in the nix manual for more information.

Specify one of `path` or `repositories`.

Migration

path Attribute

path was an attribute from the early days of rules_nixpkgs, and its ability to reference arbitrary paths a danger to build hermeticity.

Replace it with either nixpkgs_git_repository if you need a specific version of nixpkgs. If you absolutely must depend on a local folder, use bazel’s local_repository workspace rule. Both approaches work well with the repositories attribute of nixpkgs_package.

local_repository(
  name = "local-nixpkgs",
  path = "/path/to/nixpkgs",
)

nixpkgs_package(
  name = "somepackage",
  repositories = {
    "nixpkgs": "@local-nixpkgs//:default.nix",
  },
  …
)

About

Rules for importing Nixpkgs packages into Bazel.

License:Apache License 2.0


Languages

Language:Starlark 87.3%Language:Nix 6.7%Language:Shell 5.8%Language:Go 0.1%Language:C++ 0.1%