Skip to content

Instantly share code, notes, and snippets.

@jtacoma
Last active January 27, 2025 00:59
Show Gist options
  • Save jtacoma/a8d6e54cf560930b85f8b1395c0b3ae8 to your computer and use it in GitHub Desktop.
Save jtacoma/a8d6e54cf560930b85f8b1395c0b3ae8 to your computer and use it in GitHub Desktop.
Polyglot builds with Bazel and Nix
common --enable_bzlmod
build --host_platform=@rules_nixpkgs_core//platforms:host
  1. Learn Nix if you haven't yet.
  2. Until I learn how to use Bazel modules defined within other modules, I need a local copy of rules_nixpkgs. I use something like git submodules add https://github.com/tweag/rules_nixpkgs.
  3. Run nix develop to launch a shell with Nix-provided Bazel.
  4. Run the demo: bazel run :main_cc
Hello, from Go!
Hello, from Rust!
Hello, from C++!

Copyright 2021 Google LLC
SPDX-License-Identifier: Apache-2.0

load("@rules_cc//cc:defs.bzl", "cc_library", "cc_binary")
load("@rules_go//go:def.bzl", "go_binary", "go_library")
load("@rules_rust//rust:defs.bzl", "rust_static_library")
cc_binary(
name = "main_cc",
srcs = ["main_cc.cc"],
deps = [
":hello_go.cc",
":hello_rs",
],
)
go_binary(
name = "hello_go",
srcs = ["hello_go.go"],
cgo = True,
linkmode = "c-archive",
)
rust_static_library(
name = "hello_rs",
srcs = ["hello_rs.rs"],
)
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1737885589,
"narHash": "sha256-Zf0hSrtzaM1DEz8//+Xs51k/wdSajticVrATqDrfQjg=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "852ff1d9e153d8875a83602e03fdef8a63f0ecf8",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixos-unstable",
"type": "indirect"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}
{
description = "A polyglot binary that says hello from multiple languages.";
inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
outputs = all @ {self, nixpkgs, ...}:
let
supportedSystems = ["x86_64-linux"];
forAllSystems = nixpkgs.lib.genAttrs supportedSystems;
nixpkgsFor = forAllSystems (system:
import nixpkgs {
inherit system;
overlays = [self.overlays.default];
});
in {
overlays.default = final: prev: {};
devShells = forAllSystems (system:
with nixpkgsFor.${system}; {
default = mkShell {
nativeBuildInputs = [bazel_7 bazel-buildtools];
};
});
};
}
package main
import "C"
//export DemoHelloGo
func DemoHelloGo() {
println("Hello, from Go!")
}
// CGo works more easily with an executable build target.
func main() {}
#[no_mangle]
pub extern "C" fn demo_hello_rust() -> () {
println!("{}", "Hello, from Rust!");
}
#include <cstdint>
#include <iostream>
#include "hello_go.h"
extern "C" { extern void demo_hello_rust(); }
int main() {
DemoHelloGo();
demo_hello_rust();
std::cout << "Hello, from C++!" << std::endl;
return 0;
}
module(name = "polyglot_hello", version = "0.1")
# Core
bazel_dep(name = "bazel_skylib", version = "1.7.1")
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "rules_cc", version = "0.1.0")
bazel_dep(name = "rules_rust", version = "0.56.0")
bazel_dep(name = "rules_go", version = "0.52.0")
# Nixpkgs
bazel_dep(name = "rules_nixpkgs_core")
bazel_dep(name = "rules_nixpkgs_cc")
bazel_dep(name = "rules_nixpkgs_rust")
local_path_override(module_name = "rules_nixpkgs_core", path = "rules_nixpkgs/core")
local_path_override(module_name = "rules_nixpkgs_cc", path = "rules_nixpkgs/toolchains/cc")
local_path_override(module_name = "rules_nixpkgs_rust", path = "rules_nixpkgs/toolchains/rust")
non_module_deps = use_extension("//:non_module_deps.bzl", "non_module_deps")
use_repo(non_module_deps, "nixpkgs")
use_repo(non_module_deps, "nixpkgs_config_cc")
use_repo(non_module_deps, "nixpkgs_config_cc_info")
use_repo(non_module_deps, "nixpkgs_config_cc_toolchains")
register_toolchains("@nixpkgs_config_cc_toolchains//:all")
use_repo(non_module_deps, "nixpkgs_config_rust_toolchain")
register_toolchains("@nixpkgs_config_rust_toolchain//:all")
# Help rules_nixpkgs synchronize with the flake's locked version of Nixpkgs.
let
lock = builtins.fromJSON (builtins.readFile ./flake.lock);
spec = lock.nodes.nixpkgs.locked;
nixpkgs = fetchTarball "https://github.com/${spec.owner}/${spec.repo}/archive/${spec.rev}.tar.gz";
in
import nixpkgs
load("@rules_nixpkgs_core//:nixpkgs.bzl", "nixpkgs_local_repository", "nixpkgs_package")
load("@rules_nixpkgs_cc//:cc.bzl", "nixpkgs_cc_configure")
load("@rules_nixpkgs_rust//:rust.bzl", "nixpkgs_rust_configure")
def _non_module_deps_impl(_ctx):
nixpkgs_local_repository(name = "nixpkgs", nix_file = "//:nixpkgs.nix", nix_file_deps = ["//:flake.lock"])
nixpkgs_cc_configure(name = "nixpkgs_config_cc", repository = "@nixpkgs", register = False, cc_std = "c++23")
nixpkgs_rust_configure(repository = "@nixpkgs", name = "nixpkgs_config_rust", register = False)
non_module_deps = module_extension(
implementation = _non_module_deps_impl,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment