rules_go: Cannot compile on NixOS

Environment

$ bazel version
Build label: 0.10.1- (@non-git)
Build target: bazel-out/k8-opt/bin/src/main/java/com/google/devtools/build/lib/bazel/BazelServer_deploy.jar
Build time: Sat Nov 2 00:00:00 +11968 (315532800000)
Build timestamp: 315532800000
Build timestamp as int: 315532800000
$ nixos-version
17.09.3129.1dcd022f01b (Hummingbird)

Failure

$ bazel build tarball
DEBUG: /home/alex/.cache/bazel/_bazel_alex/9a62ea23e6672e5bdeba02f2fd03b905/external/io_bazel_rules_go/go/private/sdk.bzl:103:5: env: ‘bin/go’: No such file or directory
ERROR: /home/alex/.cache/bazel/_bazel_alex/9a62ea23e6672e5bdeba02f2fd03b905/external/io_bazel_rules_go/BUILD.bazel:7:1: every rule of type go_context_data implicitly depends upon the target '
@go_sdk//:packages.txt', but this target could not be found because of: no such package '@go_sdk//': Traceback (most recent call last):                                                        
        File "/home/alex/.cache/bazel/_bazel_alex/9a62ea23e6672e5bdeba02f2fd03b905/external/io_bazel_rules_go/go/private/sdk.bzl", line 50
                _prepare(ctx)                                                                                                             
        File "/home/alex/.cache/bazel/_bazel_alex/9a62ea23e6672e5bdeba02f2fd03b905/external/io_bazel_rules_go/go/private/sdk.bzl", line 104, in _prepare
                fail("failed to list standard package...")                                                                                              
failed to list standard packages                          
ERROR: Analysis of target '//:tarball' failed; build aborted: no such package '@go_sdk//': Traceback (most recent call last):
        File "/home/alex/.cache/bazel/_bazel_alex/9a62ea23e6672e5bdeba02f2fd03b905/external/io_bazel_rules_go/go/private/sdk.bzl", line 50
                _prepare(ctx)                                                                                                             
        File "/home/alex/.cache/bazel/_bazel_alex/9a62ea23e6672e5bdeba02f2fd03b905/external/io_bazel_rules_go/go/private/sdk.bzl", line 104, in _prepare
                fail("failed to list standard package...")                                                                                              
failed to list standard packages                          
INFO: Elapsed time: 20.224s     
FAILED: Build did NOT complete successfully (110 packages loaded)

The reason this fails is because the rules are downloading a dynamically-linked copy of the Go toolchain:

$ file /home/alex/.cache/bazel/_bazel_alex/9a62ea23e6672e5bdeba02f2fd03b905/external/go_sdk/bin/go
/home/alex/.cache/bazel/_bazel_alex/9a62ea23e6672e5bdeba02f2fd03b905/external/go_sdk/bin/go: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, with debug_info, not stripped

My system (and no NixOS system) has /lib64/ld-linux-x86-64.so.2, so I get a “no such file or directory” error when I try to execute this binary.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 17 (9 by maintainers)

Commits related to this issue

Most upvoted comments

I got it working like this:

$ cat shell.nix                            
{ nixpkgs ? import <nixpkgs> {} }:
nixpkgs.stdenv.mkDerivation {
    name = "monorepo";
    buildInputs = [
        nixpkgs.bazel
        nixpkgs.go
    ];
    shellHook = ''
        export GOROOT="$(go env GOROOT)"
    '';
}
$ cat WORKSPACE | tail -n3
load("@io_bazel_rules_go//go:def.bzl", "go_register_toolchains", "go_rules_dependencies")
go_rules_dependencies()
go_register_toolchains(go_version = "host")
$ nix-shell --run 'bazel build //...'

The shell hook is vital! rules_go will not attempt go env GOROOT; it will only consider the GOROOT environment variable.

strong-arm bazel into becoming a reproducible build system

Bazel is also intended to be a reproducible build system; it verifies sha256 checksums of downloaded files (assuming the workspace rules actually specify them) just like Nix does, so in theory it ought to be acceptable to allow Bazel to download things.

That said, there are still plenty of reasons why Nix builds may not want to operate that way, and the way to do it may be to use bazel build --override_repository="repository_name=/local/path/to/repository" and have Nix pre-fetch them.