Skip to content

Commit 45386ad

Browse files
committed
Implement nixpkgs_cc_configure.
This macro calls cc_autoconf_impl like before, but ahead of then also defines a nixpkgs_package with all the tools we want for the CC toolchain.
1 parent a456a2e commit 45386ad

File tree

4 files changed

+74
-65
lines changed

4 files changed

+74
-65
lines changed

WORKSPACE

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
workspace(name = "io_tweag_rules_nixpkgs")
22

3-
load("//nixpkgs:nixpkgs.bzl", "nixpkgs_git_repository", "nixpkgs_package")
3+
load(
4+
"//nixpkgs:nixpkgs.bzl",
5+
"nixpkgs_cc_configure",
6+
"nixpkgs_git_repository",
7+
"nixpkgs_package"
8+
)
49

510
# For tests
611

@@ -74,3 +79,5 @@ filegroup(
7479
)
7580
""",
7681
)
82+
83+
nixpkgs_cc_configure(repository = "@remote_nixpkgs//:default.nix")

nixpkgs/BUILD.pkg

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package(default_visibility = [ "//visibility:public" ])
1+
package(default_visibility = ["//visibility:public"])
22

33
filegroup(
44
name = "bin",

nixpkgs/nixpkgs.bzl

+59-63
Original file line numberDiff line numberDiff line change
@@ -187,67 +187,63 @@ stderr:
187187
stdout=exec_result.stdout,
188188
stderr=exec_result.stderr))
189189

190-
def _cc_configure_custom(ctx):
191-
overriden_tools = {
192-
"gcc": ctx.path(ctx.attr.gcc),
193-
"ld": ctx.path(ctx.attr.ld),
194-
}
195-
return cc_autoconf_impl(ctx, overriden_tools)
196-
197-
cc_configure_custom = repository_rule(
198-
implementation = _cc_configure_custom,
199-
attrs = {
200-
"gcc": attr.label(
201-
executable=True,
202-
cfg="host",
203-
allow_single_file=True,
204-
doc="`gcc` to use in cc toolchain",
205-
),
206-
"ld": attr.label(
207-
executable=True,
208-
cfg="host",
209-
allow_single_file=True,
210-
doc="`ld` to use in cc toolchain",
211-
),
212-
},
213-
local = True,
214-
environ = [
215-
"ABI_LIBC_VERSION",
216-
"ABI_VERSION",
217-
"BAZEL_COMPILER",
218-
"BAZEL_HOST_SYSTEM",
219-
"BAZEL_LINKOPTS",
220-
"BAZEL_PYTHON",
221-
"BAZEL_SH",
222-
"BAZEL_TARGET_CPU",
223-
"BAZEL_TARGET_LIBC",
224-
"BAZEL_TARGET_SYSTEM",
225-
"BAZEL_USE_CPP_ONLY_TOOLCHAIN",
226-
"BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN",
227-
"BAZEL_USE_LLVM_NATIVE_COVERAGE",
228-
"BAZEL_VC",
229-
"BAZEL_VS",
230-
"CC",
231-
"CC_CONFIGURE_DEBUG",
232-
"CC_TOOLCHAIN_NAME",
233-
"CPLUS_INCLUDE_PATH",
234-
"CUDA_COMPUTE_CAPABILITIES",
235-
"CUDA_PATH",
236-
"GCOV",
237-
"HOMEBREW_RUBY_PATH",
238-
"NO_WHOLE_ARCHIVE_OPTION",
239-
"SYSTEMROOT",
240-
"USE_DYNAMIC_CRT",
241-
"USE_MSVC_WRAPPER",
242-
"VS90COMNTOOLS",
243-
"VS100COMNTOOLS",
244-
"VS110COMNTOOLS",
245-
"VS120COMNTOOLS",
246-
"VS140COMNTOOLS",
247-
],
190+
def _nixpkgs_cc_autoconf_impl(repository_ctx):
191+
# Calling repository_ctx.path() on anything but a regular file
192+
# fails. So the roundabout way to do the same thing is to find
193+
# a regular file we know is in the workspace (i.e. the WORKSPACE
194+
# file itself) and then use dirname to get the path of the workspace
195+
# root.
196+
workspace_file_path = repository_ctx.path(
197+
Label("@nixpkgs_cc_toolchain//:WORKSPACE")
198+
)
199+
workspace_root = repository_ctx.execute(
200+
["dirname", workspace_file_path]
201+
).stdout.rstrip()
202+
203+
# Make a list of all available tools in the Nix derivation. Override
204+
# the Bazel autoconfiguration with the tools we found.
205+
res = repository_ctx.execute(["ls", workspace_root + "/bin"])
206+
if res.return_code == 0:
207+
overriden_tools = {
208+
tool: repository_ctx.path(Label("@nixpkgs_cc_toolchain//:bin/" + tool))
209+
for tool in res.stdout.splitlines()
210+
}
211+
cc_autoconf_impl(repository_ctx, overriden_tools = overriden_tools)
212+
else:
213+
fail("Cannot list content of @nixpkgs_cc_toolchain:" + res.stderr)
214+
215+
_nixpkgs_cc_autoconf = repository_rule(
216+
implementation = _nixpkgs_cc_autoconf_impl
248217
)
249-
"""Overwrite cc toolchain by supplying custom `gcc` and `ld` (e.g. from
250-
Nix). This allows to fix mismatch of `gcc` versions between what is used by
251-
packages that come from Nix (e.g. `ghc`) and what Bazel detects
252-
automatically (i.e. system-level `gcc`).
253-
"""
218+
219+
def nixpkgs_cc_configure(
220+
repository = None,
221+
repositories = None,
222+
nix_file_content = """
223+
with import <nixpkgs> {}; buildEnv {
224+
name = "bazel-cc-toolchain";
225+
paths = [ gcc binutils ];
226+
}
227+
""",
228+
build_file_content = """exports_files(glob(["bin/*"]))"""):
229+
"""Use a CC toolchain from Nixpkgs.
230+
231+
By default, Bazel auto-configures a CC toolchain from commands (e.g.
232+
`gcc`) available in the environment. To make builds more hermetic, use
233+
this rule to specific explicitly which commands the toolchain should
234+
use.
235+
"""
236+
if repository and repositories or not repository and not repositories:
237+
fail("Specify one of repository or repositories (but not both).")
238+
elif repository:
239+
repositories = {"nixpkgs": repository}
240+
241+
nixpkgs_package(
242+
name = "nixpkgs_cc_toolchain",
243+
repositories = repositories,
244+
nix_file_content = nix_file_content,
245+
build_file_content = build_file_content,
246+
)
247+
_nixpkgs_cc_autoconf(name = "local_config_cc")
248+
native.bind(name = "cc_toolchain", actual = "@local_config_cc//:toolchain")
249+
native.register_toolchains("@local_config_cc//:all")

tests/BUILD

+6
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,9 @@ package(default_testonly = 1)
4747
timeout = "short",
4848
)
4949
]
50+
51+
# Test nixpkgs_cc_configure() by building some CC code.
52+
cc_binary(
53+
name = "cc-test",
54+
srcs = ["cc-test.cc"],
55+
)

0 commit comments

Comments
 (0)