mirror of
https://github.com/digital-asset/daml.git
synced 2024-11-10 10:46:11 +03:00
1b711d0ac6
* update rules_nixpkgs * Use hermetic nixpkgs cc toolchain CHANGELOG_BEGIN CHANGELOG_END * Work around Bazel's cc toolchain autodetection * Use --crosstool_top for hermetic cc toolchain When using --incompatible_enable_cc_toolchain_resolution instead cc actions still depend on `external/local_config_cc/builtin_include_directory_paths` as well as `external/nixpkgs_cc_toolchain_config/builtin_include_directory_paths`. * override local_config_cc * remove unused attribute * Fix posix toolchain on Windows * nixpkgs cc toolchain not on Windows * Fix nixpkgs cc toolchain on MacOS * nixpkgs cc toolchain uses bin/cc * Use darwin.binutils on MacOS * Remove clang(++) and gcc (g++) symlinks The toolchain only considers `bin/cc` and having the other symlinks around could lead to confusion * Use hermetic toolchain in compatibility workspace * Avoid empty linker flags Co-authored-by: Andreas Herrmann <andreas.herrmann@tweag.io>
1233 lines
42 KiB
Diff
1233 lines
42 KiB
Diff
diff --git a/.bazelrc b/.bazelrc
|
|
index d226e65..687c136 100644
|
|
--- a/.bazelrc
|
|
+++ b/.bazelrc
|
|
@@ -1 +1,7 @@
|
|
build --host_platform=@io_tweag_rules_nixpkgs//nixpkgs/platforms:host
|
|
+build --crosstool_top=@nixpkgs_config_cc//:toolchain
|
|
+# Using toolchain resolution can lead to spurious dependencies on
|
|
+# `@local_config_cc//:builtin_include_directory_paths`. This needs to be
|
|
+# resolved before `--incompatible_enable_cc_toolchain_resolution` can be
|
|
+# recommended for `nixpkgs_cc_configure_hermetic`.
|
|
+# build --incompatible_enable_cc_toolchain_resolution
|
|
diff --git a/BUILD.bazel b/BUILD.bazel
|
|
index e69de29..efcf274 100644
|
|
--- a/BUILD.bazel
|
|
+++ b/BUILD.bazel
|
|
@@ -0,0 +1,4 @@
|
|
+exports_files([
|
|
+ "nixpkgs.json",
|
|
+ "nixpkgs.nix",
|
|
+])
|
|
diff --git a/CHANGELOG.md b/CHANGELOG.md
|
|
index 8596633..234c41b 100644
|
|
--- a/CHANGELOG.md
|
|
+++ b/CHANGELOG.md
|
|
@@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
|
|
|
|
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|
|
|
+## [Unreleased]
|
|
+
|
|
+[Unreleased]: https://github.com/tweag/rules_nixpkgs/compare/v0.7.0...HEAD
|
|
+
|
|
+### Added
|
|
+
|
|
+- Add `expand_location` attribute to `nixpkgs_package`. When enabled instances
|
|
+ of `$(location LABEL)` in the `nixopts` attribute will be expanded to the
|
|
+ file path of the file referenced by `LABEL`.
|
|
+ See [#128][#128].
|
|
+- Define `nixpkgs_cc_configure_hermetic` in `//nixpkgs:repositories.bzl`.
|
|
+ See [#128][#128].
|
|
+
|
|
+### Deprecated
|
|
+
|
|
+- `nixpkgs_cc_configure` has been deprecated in favor of
|
|
+ `nixpkgs_cc_configure_hermetic` and will be replaced by it in future.
|
|
+ See [#128][#128].
|
|
+
|
|
+[#128]: https://github.com/tweag/rules_nixpkgs/pull/128
|
|
+
|
|
## [0.7.0] - 2020-04-20
|
|
|
|
[0.7.0]: https://github.com/tweag/rules_nixpkgs/compare/v0.6.0...v0.7.0
|
|
diff --git a/README.md b/README.md
|
|
index 721f64d..3ee682b 100644
|
|
--- a/README.md
|
|
+++ b/README.md
|
|
@@ -176,7 +176,7 @@ 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,
|
|
+ expand_location, fail_not_supported,
|
|
)
|
|
```
|
|
|
|
@@ -306,6 +306,18 @@ filegroup(
|
|
<p>Extra flags to pass when calling Nix.</p>
|
|
</td>
|
|
</tr>
|
|
+ <tr>
|
|
+ <td><code>nixopts</code></td>
|
|
+ <td>
|
|
+ <p><code>Bool; optional</code></p>
|
|
+ <p>
|
|
+ If set to <code>True</code> any instance of
|
|
+ <code>$(location LABEL)</code> in <code>nixopts</code>
|
|
+ will be replaced by the path to the file referenced by
|
|
+ <code>LABEL</code> relative to the workspace root.
|
|
+ </p>
|
|
+ </td>
|
|
+ </tr>
|
|
<tr>
|
|
<td><code>fail_not_supported</code></td>
|
|
<td>
|
|
@@ -321,6 +333,99 @@ filegroup(
|
|
</tbody>
|
|
</table>
|
|
|
|
+### nixpkgs_cc_configure_hermetic
|
|
+
|
|
+Use a CC toolchain from Nixpkgs. No-op if not a nix-based platform.
|
|
+
|
|
+By default, Bazel auto-configures a CC toolchain from commands (e.g.
|
|
+`gcc`) available in the environment. To make builds more hermetic, use
|
|
+this rule to specify explicitly which commands the toolchain should use.
|
|
+
|
|
+Specifically, it builds a Nix derivation that provides the CC toolchain tools
|
|
+in the `bin/` path and constructs a CC toolchain that uses those tools. The
|
|
+following tools are expected `ar`, `cpp`, `dwp`, `cc`, `gcov`, `ld`, `nm`,
|
|
+`objcopy`, `objdump`, `strip`. Tools that aren't found are replaced by
|
|
+`${coreutils}/bin/false`.
|
|
+
|
|
+Note:
|
|
+
|
|
+You need to configure `--crosstool_top=@<name>//:toolchain` to activate this
|
|
+toolchain.
|
|
+
|
|
+Example:
|
|
+
|
|
+```bzl
|
|
+nixpkgs_cc_configure_hermetic(repository = "@nixpkgs//:default.nix")
|
|
+```
|
|
+
|
|
+<table class="table table-condensed table-bordered table-params">
|
|
+ <colgroup>
|
|
+ <col class="col-param" />
|
|
+ <col class="param-description" />
|
|
+ </colgroup>
|
|
+ <thead>
|
|
+ <tr>
|
|
+ <th colspan="2">Attributes</th>
|
|
+ </tr>
|
|
+ </thead>
|
|
+ <tbody>
|
|
+ <tr>
|
|
+ <td><code>attribute_path</code></td>
|
|
+ <td>
|
|
+ <p><code>String; optional</code></p>
|
|
+ <p>Obtain the toolchain from the Nix expression under this attribute path. Requires `nix_file` or `nix_file_content`.</p>
|
|
+ </td>
|
|
+ <td><code>nix_file</code></td>
|
|
+ <td>
|
|
+ <p><code>String; optional</code></p>
|
|
+ <p>Obtain the toolchain from the Nix expression defined in this file. Specify only one of `nix_file` or `nix_file_content`.</p>
|
|
+ </td>
|
|
+ </tr>
|
|
+ <tr>
|
|
+ <td><code>nix_file_content</code></td>
|
|
+ <td>
|
|
+ <p><code>String; optional</code></p>
|
|
+ <p>Obtain the toolchain from the given Nix expression. Specify only one of `nix_file` or `nix_file_content`.</p>
|
|
+ </td>
|
|
+ </tr>
|
|
+ <tr>
|
|
+ <td><code>nix_file_deps</code></td>
|
|
+ <td>
|
|
+ <p><code>List of labels; optional</code></p>
|
|
+ <p>Additional files that the Nix expression depends on.</p>
|
|
+ </td>
|
|
+ </tr>
|
|
+ <tr>
|
|
+ <td><code>repository</code></td>
|
|
+ <td>
|
|
+ <p><code>Label; optional</code></p>
|
|
+ <p>Provides `<nixpkgs>`. Specify one of `repositories` or `repository`.</p>
|
|
+ </td>
|
|
+ </tr>
|
|
+ <tr>
|
|
+ <td><code>repositories</code></td>
|
|
+ <td>
|
|
+ <p><code>String-keyed label dict; optional</code></p>
|
|
+ <p>Provides `<nixpkgs>` and other repositories. Specify one of `repositories` or `repository`.</p>
|
|
+ </td>
|
|
+ </tr>
|
|
+ <tr>
|
|
+ <td><code>quiet</code></td>
|
|
+ <td>
|
|
+ <p><code>Bool; optional</code></p>
|
|
+ <p>Whether to hide `nix-build` output.</p>
|
|
+ </td>
|
|
+ </tr>
|
|
+ <tr>
|
|
+ <td><code>fail_not_supported</code></td>
|
|
+ <td>
|
|
+ <p><code>Bool; optional</code></p>
|
|
+ <p>Whether to fail if `nix-build` is not available.</p>
|
|
+ </td>
|
|
+ </tr>
|
|
+ </tbody>
|
|
+</table>
|
|
+
|
|
### nixpkgs_cc_configure
|
|
|
|
Tells Bazel to use compilers and linkers from Nixpkgs for the CC
|
|
@@ -328,6 +433,16 @@ toolchain. By default, Bazel autodetects a toolchain on the current
|
|
`PATH`. Overriding this autodetection makes builds more hermetic and
|
|
is considered a best practice.
|
|
|
|
+Deprecated:
|
|
+
|
|
+Use `nixpkgs_cc_configure_hermetic` instead.
|
|
+
|
|
+While this improves upon Bazel's autoconfigure toolchain by picking tools from
|
|
+a Nix derivation rather than the environment, it is still not fully hermetic as
|
|
+it is affected by the environment. In particular, system include directories
|
|
+specified in the environment can leak in and affect the cache keys of targets
|
|
+depending on the cc toolchain leading to cache misses.
|
|
+
|
|
Example:
|
|
|
|
```bzl
|
|
diff --git a/WORKSPACE b/WORKSPACE
|
|
index f37ab6c..f8d40ad 100644
|
|
--- a/WORKSPACE
|
|
+++ b/WORKSPACE
|
|
@@ -6,7 +6,7 @@ rules_nixpkgs_dependencies()
|
|
|
|
load(
|
|
"//nixpkgs:nixpkgs.bzl",
|
|
- "nixpkgs_cc_configure",
|
|
+ "nixpkgs_cc_configure_hermetic",
|
|
"nixpkgs_git_repository",
|
|
"nixpkgs_local_repository",
|
|
"nixpkgs_package",
|
|
@@ -134,7 +134,7 @@ nixpkgs_package(
|
|
repository = "@nixpkgs",
|
|
)
|
|
|
|
-nixpkgs_cc_configure(repository = "@remote_nixpkgs")
|
|
+nixpkgs_cc_configure_hermetic(repository = "@remote_nixpkgs")
|
|
|
|
nixpkgs_python_configure(
|
|
python2_attribute_path = "python2",
|
|
@@ -147,6 +147,27 @@ nixpkgs_package(
|
|
repository = "@remote_nixpkgs",
|
|
)
|
|
|
|
+nixpkgs_package(
|
|
+ name = "nixpkgs_location_expansion_test",
|
|
+ build_file_content = "exports_files(glob(['out/**']))",
|
|
+ expand_location = True,
|
|
+ nix_file = "//tests:location_expansion.nix",
|
|
+ nix_file_deps = [
|
|
+ "//:nixpkgs.json",
|
|
+ "//:nixpkgs.nix",
|
|
+ "@io_tweag_rules_nixpkgs//tests:relative_imports/nixpkgs.nix",
|
|
+ ],
|
|
+ nixopts = [
|
|
+ "--arg",
|
|
+ "attrs",
|
|
+ "{ nixpkgs_json = $(location //:nixpkgs.json); nixpkgs_nix = $(location //:nixpkgs.nix); }",
|
|
+ "--arg",
|
|
+ "relative_imports",
|
|
+ "$(location @io_tweag_rules_nixpkgs//tests:relative_imports/nixpkgs.nix)",
|
|
+ ],
|
|
+ repository = "@remote_nixpkgs",
|
|
+)
|
|
+
|
|
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
|
|
|
http_archive(
|
|
@@ -179,12 +200,11 @@ http_archive(
|
|
|
|
load(
|
|
"//nixpkgs:toolchains/go.bzl",
|
|
- "nixpkgs_go_configure"
|
|
+ "nixpkgs_go_configure",
|
|
)
|
|
|
|
nixpkgs_go_configure(repository = "@nixpkgs")
|
|
|
|
-load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
|
|
+load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
|
|
|
|
go_rules_dependencies()
|
|
-
|
|
diff --git a/nixpkgs/constraints/BUILD.bazel b/nixpkgs/constraints/BUILD.bazel
|
|
index 6662530..94678bd 100644
|
|
--- a/nixpkgs/constraints/BUILD.bazel
|
|
+++ b/nixpkgs/constraints/BUILD.bazel
|
|
@@ -3,7 +3,7 @@ package(default_visibility = ["//visibility:public"])
|
|
constraint_setting(name = "nix")
|
|
|
|
constraint_value(
|
|
- name = "support_nix",
|
|
+ name = "support_nix",
|
|
constraint_setting = ":nix",
|
|
)
|
|
|
|
diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl
|
|
index fb87da4..9a9ad75 100644
|
|
--- a/nixpkgs/nixpkgs.bzl
|
|
+++ b/nixpkgs/nixpkgs.bzl
|
|
@@ -1,7 +1,15 @@
|
|
"""Rules for importing Nixpkgs packages."""
|
|
|
|
+load("@bazel_skylib//lib:paths.bzl", "paths")
|
|
+load("@bazel_skylib//lib:sets.bzl", "sets")
|
|
load("@bazel_tools//tools/cpp:cc_configure.bzl", "cc_autoconf_impl")
|
|
-load("@bazel_tools//tools/cpp:lib_cc_configure.bzl", "get_cpu_value")
|
|
+load(
|
|
+ "@bazel_tools//tools/cpp:lib_cc_configure.bzl",
|
|
+ "get_cpu_value",
|
|
+ "get_starlark_list",
|
|
+ "write_builtin_include_directory_paths",
|
|
+)
|
|
+load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
|
|
|
|
def _nixpkgs_git_repository_impl(repository_ctx):
|
|
repository_ctx.file("BUILD")
|
|
@@ -70,6 +78,54 @@ nixpkgs_local_repository = repository_rule(
|
|
def _is_supported_platform(repository_ctx):
|
|
return repository_ctx.which("nix-build") != None
|
|
|
|
+def _expand_location(repository_ctx, string, labels, attr = None):
|
|
+ """Expand `$(location label)` to a path.
|
|
+
|
|
+ Attrs:
|
|
+ repository_ctx: The repository rule context.
|
|
+ string: string, Replace instances of `$(location )` in this string.
|
|
+ labels: dict from label to path: Known label to path mappings.
|
|
+ attr: string, The rule attribute to use for error reporting.
|
|
+
|
|
+ Returns:
|
|
+ The string with all instances of `$(location )` replaced by paths.
|
|
+ """
|
|
+ num = string.count("$(location ")
|
|
+ result = ""
|
|
+ offset = 0
|
|
+ for i in range(num):
|
|
+ start = string.find("$(location ", offset)
|
|
+ label_start = start + len("$(location ")
|
|
+ label_end = string.find(")", label_start)
|
|
+ if label_end == -1:
|
|
+ fail("Unbalanced parentheses in location expansion for '{}'.".format(string[start:]), attr)
|
|
+ end = label_end + 1
|
|
+ label_str = string[label_start:label_end]
|
|
+ label_candidates = [
|
|
+ (lbl, path)
|
|
+ for (lbl, path) in labels.items()
|
|
+ if lbl.relative(label_str) == lbl
|
|
+ ]
|
|
+ if len(label_candidates) == 0:
|
|
+ fail("Unknown label '{}' in location expansion for '{}'.".format(label_str, string), attr)
|
|
+ elif len(label_candidates) > 1:
|
|
+ fail(
|
|
+ "Ambiguous label '{}' in location expansion for '{}'. Candidates: {}".format(
|
|
+ label_str,
|
|
+ string,
|
|
+ ", ".join([str(lbl) for lbl in label_candidates]),
|
|
+ ),
|
|
+ attr,
|
|
+ )
|
|
+ location = paths.join(".", paths.relativize(
|
|
+ str(repository_ctx.path(label_candidates[0][1])),
|
|
+ str(repository_ctx.path(".")),
|
|
+ ))
|
|
+ result += string[offset:start] + location
|
|
+ offset = end
|
|
+ result += string[offset:]
|
|
+ return result
|
|
+
|
|
def _nixpkgs_package_impl(repository_ctx):
|
|
repository = repository_ctx.attr.repository
|
|
repositories = repository_ctx.attr.repositories
|
|
@@ -117,8 +173,9 @@ def _nixpkgs_package_impl(repository_ctx):
|
|
else:
|
|
expr_args = ["-E", "import <nixpkgs> { config = {}; overlays = []; }"]
|
|
|
|
+ nix_file_deps = {}
|
|
for dep in repository_ctx.attr.nix_file_deps:
|
|
- _cp(repository_ctx, dep)
|
|
+ nix_file_deps[dep] = _cp(repository_ctx, dep)
|
|
|
|
expr_args.extend([
|
|
"-A",
|
|
@@ -133,7 +190,13 @@ def _nixpkgs_package_impl(repository_ctx):
|
|
"bazel-support/nix-out-link",
|
|
])
|
|
|
|
- expr_args.extend(repository_ctx.attr.nixopts)
|
|
+ if repository_ctx.attr.expand_location:
|
|
+ expr_args.extend([
|
|
+ _expand_location(repository_ctx, opt, nix_file_deps, "nixopts")
|
|
+ for opt in repository_ctx.attr.nixopts
|
|
+ ])
|
|
+ else:
|
|
+ expr_args.extend(repository_ctx.attr.nixopts)
|
|
|
|
for repo in repositories.keys():
|
|
path = str(repository_ctx.path(repo).dirname) + "/nix-file-deps"
|
|
@@ -206,7 +269,7 @@ def _nixpkgs_package_impl(repository_ctx):
|
|
if create_build_file_if_needed:
|
|
p = repository_ctx.path("BUILD")
|
|
if not p.exists:
|
|
- repository_ctx.template("BUILD", Label("@io_tweag_rules_nixpkgs//nixpkgs:BUILD.pkg"))
|
|
+ repository_ctx.template("BUILD", Label("@io_tweag_rules_nixpkgs//nixpkgs:BUILD.pkg"))
|
|
|
|
_nixpkgs_package = repository_rule(
|
|
implementation = _nixpkgs_package_impl,
|
|
@@ -220,6 +283,7 @@ _nixpkgs_package = repository_rule(
|
|
"build_file": attr.label(),
|
|
"build_file_content": attr.string(),
|
|
"nixopts": attr.string_list(),
|
|
+ "expand_location": attr.bool(default = False),
|
|
"quiet": attr.bool(),
|
|
"fail_not_supported": attr.bool(default = True, doc = """
|
|
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.
|
|
@@ -244,6 +308,329 @@ def nixpkgs_package(*args, **kwargs):
|
|
else:
|
|
_nixpkgs_package(*args, **kwargs)
|
|
|
|
+def _parse_cc_toolchain_info(content, filename):
|
|
+ """Parses the `CC_TOOLCHAIN_INFO` file generated by Nix.
|
|
+
|
|
+ Attrs:
|
|
+ content: string, The content of the `CC_TOOLCHAIN_INFO` file.
|
|
+ filename: string, The path to the `CC_TOOLCHAIN_INFO` file, used for error reporting.
|
|
+
|
|
+ Returns:
|
|
+ struct, The substitutions for `@bazel_tools//tools/cpp:BUILD.tpl`.
|
|
+ """
|
|
+
|
|
+ # Parse the content of CC_TOOLCHAIN_INFO.
|
|
+ #
|
|
+ # Each line has the form
|
|
+ #
|
|
+ # <key>:<value1>:<value2>:...
|
|
+ info = {}
|
|
+ for line in content.splitlines():
|
|
+ fields = line.split(":")
|
|
+ if len(fields) == 0:
|
|
+ fail(
|
|
+ "Malformed CC_TOOLCHAIN_INFO '{}': Empty line encountered.".format(filename),
|
|
+ "cc_toolchain_info",
|
|
+ )
|
|
+ info[fields[0]] = fields[1:]
|
|
+
|
|
+ # Validate the keys in CC_TOOLCHAIN_INFO.
|
|
+ expected_keys = sets.make([
|
|
+ "TOOL_NAMES",
|
|
+ "TOOL_PATHS",
|
|
+ "CXX_BUILTIN_INCLUDE_DIRECTORIES",
|
|
+ "COMPILER_FLAGS",
|
|
+ "CXX_FLAGS",
|
|
+ "LINK_FLAGS",
|
|
+ "LINK_LIBS",
|
|
+ "OPT_COMPILE_FLAGS",
|
|
+ "OPT_LINK_FLAGS",
|
|
+ "UNFILTERED_COMPILE_FLAGS",
|
|
+ "DBG_COMPILE_FLAGS",
|
|
+ "COVERAGE_COMPILE_FLAGS",
|
|
+ "COVERAGE_LINK_FLAGS",
|
|
+ "SUPPORTS_START_END_LIB",
|
|
+ ])
|
|
+ actual_keys = sets.make(info.keys())
|
|
+ missing_keys = sets.difference(expected_keys, actual_keys)
|
|
+ unexpected_keys = sets.difference(actual_keys, expected_keys)
|
|
+ if sets.length(missing_keys) > 0:
|
|
+ fail(
|
|
+ "Malformed CC_TOOLCHAIN_INFO '{}': Missing entries '{}'.".format(
|
|
+ filename,
|
|
+ "', '".join(sets.to_list(missing_keys)),
|
|
+ ),
|
|
+ "cc_toolchain_info",
|
|
+ )
|
|
+ if sets.length(unexpected_keys) > 0:
|
|
+ fail(
|
|
+ "Malformed CC_TOOLCHAIN_INFO '{}': Unexpected entries '{}'.".format(
|
|
+ filename,
|
|
+ "', '".join(sets.to_list(unexpected_keys)),
|
|
+ ),
|
|
+ "cc_toolchain_info",
|
|
+ )
|
|
+
|
|
+ return struct(
|
|
+ tool_paths = {
|
|
+ tool: path
|
|
+ for (tool, path) in zip(info["TOOL_NAMES"], info["TOOL_PATHS"])
|
|
+ },
|
|
+ cxx_builtin_include_directories = info["CXX_BUILTIN_INCLUDE_DIRECTORIES"],
|
|
+ compiler_flags = info["COMPILER_FLAGS"],
|
|
+ cxx_flags = info["CXX_FLAGS"],
|
|
+ link_flags = info["LINK_FLAGS"],
|
|
+ link_libs = info["LINK_LIBS"],
|
|
+ opt_compile_flags = info["OPT_COMPILE_FLAGS"],
|
|
+ opt_link_flags = info["OPT_LINK_FLAGS"],
|
|
+ unfiltered_compile_flags = info["UNFILTERED_COMPILE_FLAGS"],
|
|
+ dbg_compile_flags = info["DBG_COMPILE_FLAGS"],
|
|
+ coverage_compile_flags = info["COVERAGE_COMPILE_FLAGS"],
|
|
+ coverage_link_flags = info["COVERAGE_LINK_FLAGS"],
|
|
+ supports_start_end_lib = info["SUPPORTS_START_END_LIB"] == "True",
|
|
+ )
|
|
+
|
|
+def _nixpkgs_cc_toolchain_config_impl(repository_ctx):
|
|
+ cpu_value = get_cpu_value(repository_ctx)
|
|
+ darwin = cpu_value == "darwin"
|
|
+
|
|
+ cc_toolchain_info_file = repository_ctx.path(repository_ctx.attr.cc_toolchain_info)
|
|
+ if not cc_toolchain_info_file.exists and not repository_ctx.attr.fail_not_supported:
|
|
+ return
|
|
+ info = _parse_cc_toolchain_info(
|
|
+ repository_ctx.read(cc_toolchain_info_file),
|
|
+ cc_toolchain_info_file,
|
|
+ )
|
|
+
|
|
+ # Generate the cc_toolchain workspace following the example from
|
|
+ # `@bazel_tools//tools/cpp:unix_cc_configure.bzl`.
|
|
+ repository_ctx.symlink(
|
|
+ repository_ctx.path(repository_ctx.attr._unix_cc_toolchain_config),
|
|
+ "cc_toolchain_config.bzl",
|
|
+ )
|
|
+ repository_ctx.symlink(
|
|
+ repository_ctx.path(repository_ctx.attr._armeabi_cc_toolchain_config),
|
|
+ "armeabi_cc_toolchain_config.bzl",
|
|
+ )
|
|
+ cc_wrapper_src = (
|
|
+ repository_ctx.attr._osx_cc_wrapper if darwin else repository_ctx.attr._linux_cc_wrapper
|
|
+ )
|
|
+ repository_ctx.template(
|
|
+ "cc_wrapper.sh",
|
|
+ repository_ctx.path(cc_wrapper_src),
|
|
+ {
|
|
+ "%{cc}": info.tool_paths["gcc"],
|
|
+ "%{env}": "",
|
|
+ },
|
|
+ )
|
|
+ if darwin:
|
|
+ info.tool_paths["gcc"] = "cc_wrapper.sh"
|
|
+ info.tool_paths["ar"] = "/usr/bin/libtool"
|
|
+ write_builtin_include_directory_paths(
|
|
+ repository_ctx,
|
|
+ info.tool_paths["gcc"],
|
|
+ info.cxx_builtin_include_directories,
|
|
+ )
|
|
+ repository_ctx.template(
|
|
+ "BUILD.bazel",
|
|
+ repository_ctx.path(repository_ctx.attr._build),
|
|
+ {
|
|
+ "%{cc_toolchain_identifier}": "local",
|
|
+ "%{name}": cpu_value,
|
|
+ "%{supports_param_files}": "0" if darwin else "1",
|
|
+ "%{cc_compiler_deps}": get_starlark_list(
|
|
+ [":builtin_include_directory_paths"] + (
|
|
+ [":cc_wrapper"] if darwin else []
|
|
+ ),
|
|
+ ),
|
|
+ "%{compiler}": "compiler",
|
|
+ "%{abi_version}": "local",
|
|
+ "%{abi_libc_version}": "local",
|
|
+ "%{host_system_name}": "local",
|
|
+ "%{target_libc}": "macosx" if darwin else "local",
|
|
+ "%{target_cpu}": cpu_value,
|
|
+ "%{target_system_name}": "local",
|
|
+ "%{tool_paths}": ",\n ".join(
|
|
+ ['"%s": "%s"' % (k, v) for (k, v) in info.tool_paths.items()],
|
|
+ ),
|
|
+ "%{cxx_builtin_include_directories}": get_starlark_list(info.cxx_builtin_include_directories),
|
|
+ "%{compile_flags}": get_starlark_list(info.compiler_flags),
|
|
+ "%{cxx_flags}": get_starlark_list(info.cxx_flags),
|
|
+ "%{link_flags}": get_starlark_list(info.link_flags),
|
|
+ "%{link_libs}": get_starlark_list(info.link_libs),
|
|
+ "%{opt_compile_flags}": get_starlark_list(info.opt_compile_flags),
|
|
+ "%{opt_link_flags}": get_starlark_list(info.opt_link_flags),
|
|
+ "%{unfiltered_compile_flags}": get_starlark_list(info.unfiltered_compile_flags),
|
|
+ "%{dbg_compile_flags}": get_starlark_list(info.dbg_compile_flags),
|
|
+ "%{coverage_compile_flags}": get_starlark_list(info.coverage_compile_flags),
|
|
+ "%{coverage_link_flags}": get_starlark_list(info.coverage_link_flags),
|
|
+ "%{supports_start_end_lib}": repr(info.supports_start_end_lib),
|
|
+ },
|
|
+ )
|
|
+
|
|
+_nixpkgs_cc_toolchain_config = repository_rule(
|
|
+ _nixpkgs_cc_toolchain_config_impl,
|
|
+ attrs = {
|
|
+ "cc_toolchain_info": attr.label(),
|
|
+ "fail_not_supported": attr.bool(),
|
|
+ "_unix_cc_toolchain_config": attr.label(
|
|
+ default = Label("@bazel_tools//tools/cpp:unix_cc_toolchain_config.bzl"),
|
|
+ ),
|
|
+ "_armeabi_cc_toolchain_config": attr.label(
|
|
+ default = Label("@bazel_tools//tools/cpp:armeabi_cc_toolchain_config.bzl"),
|
|
+ ),
|
|
+ "_osx_cc_wrapper": attr.label(
|
|
+ default = Label("@bazel_tools//tools/cpp:osx_cc_wrapper.sh.tpl"),
|
|
+ ),
|
|
+ "_linux_cc_wrapper": attr.label(
|
|
+ default = Label("@bazel_tools//tools/cpp:linux_cc_wrapper.sh.tpl"),
|
|
+ ),
|
|
+ "_build": attr.label(
|
|
+ default = Label("@bazel_tools//tools/cpp:BUILD.tpl"),
|
|
+ ),
|
|
+ },
|
|
+)
|
|
+
|
|
+def _nixpkgs_cc_toolchain_impl(repository_ctx):
|
|
+ cpu = get_cpu_value(repository_ctx)
|
|
+ repository_ctx.file(
|
|
+ "BUILD.bazel",
|
|
+ executable = False,
|
|
+ content = """\
|
|
+package(default_visibility = ["//visibility:public"])
|
|
+
|
|
+toolchain(
|
|
+ name = "cc-toolchain-{cpu}",
|
|
+ toolchain = "@{cc_toolchain_config}//:cc-compiler-{cpu}",
|
|
+ toolchain_type = "@rules_cc//cc:toolchain_type",
|
|
+ exec_compatible_with = [
|
|
+ "@platforms//cpu:x86_64",
|
|
+ "@platforms//os:{os}",
|
|
+ "@io_tweag_rules_nixpkgs//nixpkgs/constraints:support_nix",
|
|
+ ],
|
|
+ target_compatible_with = [
|
|
+ "@platforms//cpu:x86_64",
|
|
+ "@platforms//os:{os}",
|
|
+ ],
|
|
+)
|
|
+
|
|
+toolchain(
|
|
+ name = "cc-toolchain-armeabi-v7a",
|
|
+ toolchain = "@{cc_toolchain_config}//:cc-compiler-armeabi-v7a",
|
|
+ toolchain_type = "@rules_cc//cc:toolchain_type",
|
|
+ exec_compatible_with = [
|
|
+ "@platforms//cpu:x86_64",
|
|
+ "@platforms//os:{os}",
|
|
+ "@io_tweag_rules_nixpkgs//nixpkgs/constraints:support_nix",
|
|
+ ],
|
|
+ target_compatible_with = [
|
|
+ "@platforms//cpu:arm",
|
|
+ "@platforms//os:android",
|
|
+ ],
|
|
+)
|
|
+""".format(
|
|
+ cc_toolchain_config = repository_ctx.attr.cc_toolchain_config,
|
|
+ cpu = cpu,
|
|
+ os = {"darwin": "osx"}.get(cpu, "linux"),
|
|
+ ),
|
|
+ )
|
|
+
|
|
+_nixpkgs_cc_toolchain = repository_rule(
|
|
+ _nixpkgs_cc_toolchain_impl,
|
|
+ attrs = {
|
|
+ "cc_toolchain_config": attr.string(),
|
|
+ },
|
|
+)
|
|
+
|
|
+def nixpkgs_cc_configure_hermetic(
|
|
+ name = "nixpkgs_config_cc",
|
|
+ attribute_path = "",
|
|
+ nix_file = None,
|
|
+ nix_file_content = "",
|
|
+ nix_file_deps = [],
|
|
+ repositories = {},
|
|
+ repository = None,
|
|
+ nixopts = [],
|
|
+ quiet = False,
|
|
+ fail_not_supported = True):
|
|
+ """Use a CC toolchain from Nixpkgs. No-op if not a nix-based platform.
|
|
+
|
|
+ By default, Bazel auto-configures a CC toolchain from commands (e.g.
|
|
+ `gcc`) available in the environment. To make builds more hermetic, use
|
|
+ this rule to specify explicitly which commands the toolchain should use.
|
|
+
|
|
+ Specifically, it builds a Nix derivation that provides the CC toolchain
|
|
+ tools in the `bin/` path and constructs a CC toolchain that uses those
|
|
+ tools. The following tools are expected `ar`, `cpp`, `dwp`, `cc`, `gcov`,
|
|
+ `ld`, `nm`, `objcopy`, `objdump`, `strip`. Tools that aren't found are
|
|
+ replaced by `${coreutils}/bin/false`.
|
|
+
|
|
+ Note:
|
|
+ You need to configure `--crosstool_top=@<name>//:toolchain` to activate this
|
|
+ toolchain.
|
|
+
|
|
+ Attrs:
|
|
+ attribute_path: optional, string, Obtain the toolchain from the Nix expression under this attribute path. Requires `nix_file` or `nix_file_content`.
|
|
+ nix_file: optional, Label, Obtain the toolchain from the Nix expression defined in this file. Specify only one of `nix_file` or `nix_file_content`.
|
|
+ nix_file_content: optional, string, Obtain the toolchain from the given Nix expression. Specify only one of `nix_file` or `nix_file_content`.
|
|
+ nix_file_deps: optional, list of Label, Additional files that the Nix expression depends on.
|
|
+ repositories: dict of Label to string, Provides `<nixpkgs>` and other repositories. Specify one of `repositories` or `repository`.
|
|
+ repository: Label, Provides `<nixpkgs>`. Specify one of `repositories` or `repository`.
|
|
+ quiet: bool, Whether to hide `nix-build` output.
|
|
+ fail_not_supported: bool, Whether to fail if `nix-build` is not available.
|
|
+ """
|
|
+
|
|
+ if attribute_path and not (nix_file or nix_file_content):
|
|
+ fail("'attribute_path' requires one of 'nix_file' or 'nix_file_content'", "attribute_path")
|
|
+ if nix_file and nix_file_content:
|
|
+ fail("Cannot specify both 'nix_file' and 'nix_file_content'.")
|
|
+
|
|
+ nixopts = list(nixopts)
|
|
+ nix_file_deps = list(nix_file_deps)
|
|
+ if attribute_path:
|
|
+ # The `attribute_path` is forwarded to `cc.nix` as an argument.
|
|
+ nixopts.extend(["--argstr", "attribute_path", attribute_path])
|
|
+ if nix_file:
|
|
+ nixopts.extend(["--arg", "nix_expr", "import $(location {})".format(nix_file)])
|
|
+ nix_file_deps.append(nix_file)
|
|
+ if nix_file_content:
|
|
+ # The `nix_file_content` is forwarded to `cc.nix` as an argument.
|
|
+ nixopts.extend(["--arg", "nix_expr", nix_file_content])
|
|
+
|
|
+ # Invoke `toolchains/cc.nix` which generates `CC_TOOLCHAIN_INFO`.
|
|
+ nixpkgs_package(
|
|
+ name = "{}_info".format(name),
|
|
+ nix_file = "@io_tweag_rules_nixpkgs//nixpkgs:toolchains/cc.nix",
|
|
+ nix_file_deps = nix_file_deps,
|
|
+ build_file_content = "exports_files(['CC_TOOLCHAIN_INFO'])",
|
|
+ repositories = repositories,
|
|
+ repository = repository,
|
|
+ nixopts = nixopts,
|
|
+ expand_location = True,
|
|
+ quiet = quiet,
|
|
+ fail_not_supported = fail_not_supported,
|
|
+ )
|
|
+
|
|
+ # Generate the `cc_toolchain_config` workspace.
|
|
+ _nixpkgs_cc_toolchain_config(
|
|
+ name = "{}".format(name),
|
|
+ cc_toolchain_info = "@{}_info//:CC_TOOLCHAIN_INFO".format(name),
|
|
+ fail_not_supported = fail_not_supported,
|
|
+ )
|
|
+
|
|
+ # Generate the `cc_toolchain` workspace.
|
|
+ _nixpkgs_cc_toolchain(
|
|
+ name = "{}_toolchains".format(name),
|
|
+ cc_toolchain_config = name,
|
|
+ )
|
|
+
|
|
+ maybe(
|
|
+ native.bind,
|
|
+ name = "cc_toolchain",
|
|
+ actual = "@{}//:toolchain".format(name),
|
|
+ )
|
|
+ native.register_toolchains("@{}_toolchains//:all".format(name))
|
|
+
|
|
def _readlink(repository_ctx, path):
|
|
return repository_ctx.path(path).realpath
|
|
|
|
@@ -323,6 +710,16 @@ def nixpkgs_cc_configure(
|
|
nixopts = []):
|
|
"""Use a CC toolchain from Nixpkgs. No-op if not a nix-based platform.
|
|
|
|
+ Deprecated:
|
|
+ Use `nixpkgs_cc_configure_hermetic` instead.
|
|
+
|
|
+ While this improves upon Bazel's autoconfigure toolchain by picking tools
|
|
+ from a Nix derivation rather than the environment, it is still not fully
|
|
+ hermetic as it is affected by the environment. In particular, system
|
|
+ include directories specified in the environment can leak in and affect
|
|
+ the cache keys of targets depending on the cc toolchain leading to cache
|
|
+ misses.
|
|
+
|
|
By default, Bazel auto-configures a CC toolchain from commands (e.g.
|
|
`gcc`) available in the environment. To make builds more hermetic, use
|
|
this rule to specific explicitly which commands the toolchain should
|
|
diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix
|
|
new file mode 100644
|
|
index 0000000..6b1bff4
|
|
--- /dev/null
|
|
+++ b/nixpkgs/toolchains/cc.nix
|
|
@@ -0,0 +1,278 @@
|
|
+with import <nixpkgs> { config = {}; overlays = []; };
|
|
+
|
|
+{ attribute_path ? null
|
|
+, nix_expr ? null
|
|
+}:
|
|
+
|
|
+let
|
|
+ darwinCC =
|
|
+ # Work around https://github.com/NixOS/nixpkgs/issues/42059.
|
|
+ # See also https://github.com/NixOS/nixpkgs/pull/41589.
|
|
+ with darwin.apple_sdk.frameworks;
|
|
+ runCommand "bazel-nixpkgs-cc-wrapper"
|
|
+ {
|
|
+ buildInputs = [ stdenv.cc makeWrapper ];
|
|
+ }
|
|
+ ''
|
|
+ mkdir -p $out/bin
|
|
+
|
|
+ for i in ${stdenv.cc}/bin/*; do
|
|
+ ln -sf $i $out/bin
|
|
+ done
|
|
+
|
|
+ # Override cc
|
|
+ rm -f $out/bin/cc $out/bin/clang $out/bin/clang++
|
|
+ makeWrapper ${stdenv.cc}/bin/cc $out/bin/cc --add-flags \
|
|
+ "-isystem ${llvmPackages.libcxx}/include/c++/v1 \
|
|
+ -F${CoreFoundation}/Library/Frameworks \
|
|
+ -F${CoreServices}/Library/Frameworks \
|
|
+ -F${Security}/Library/Frameworks \
|
|
+ -F${Foundation}/Library/Frameworks \
|
|
+ -L${libcxx}/lib \
|
|
+ -L${darwin.libobjc}/lib"
|
|
+ '';
|
|
+ cc =
|
|
+ if isNull nix_expr then
|
|
+ buildEnv {
|
|
+ name = "bazel-nixpkgs-cc";
|
|
+ # XXX: `gcov` is missing in `/bin`.
|
|
+ # It exists in `stdenv.cc.cc` but that collides with `stdenv.cc`.
|
|
+ paths =
|
|
+ if stdenv.isDarwin then
|
|
+ [ (overrideCC stdenv darwinCC).cc darwin.binutils ]
|
|
+ else
|
|
+ [ stdenv.cc binutils ];
|
|
+ pathsToLink = [ "/bin" ];
|
|
+ }
|
|
+ else if isNull attribute_path then
|
|
+ nix_expr
|
|
+ else
|
|
+ lib.attrByPath (lib.splitString "." attribute_path) null nix_expr
|
|
+ ;
|
|
+in
|
|
+ runCommand "bazel-nixpkgs-cc-toolchain"
|
|
+ { executable = false;
|
|
+ # Pointless to do this on a remote machine.
|
|
+ preferLocalBuild = true;
|
|
+ allowSubstitutes = false;
|
|
+ }
|
|
+ ''
|
|
+ # This constructs the substitutions for
|
|
+ # `@bazel_tools//tools/cpp:BUILD.tpl` following the example of
|
|
+ # `@bazel_tools//tools/cpp:unix_cc_configure.bzl` as of Bazel v2.1.0 git
|
|
+ # revision 0f4c498a270f05b3896d57055b6489e824821eda.
|
|
+
|
|
+ # Determine toolchain tool paths.
|
|
+ #
|
|
+ # If a tool is not available then we use `bin/false` as a stand-in.
|
|
+ declare -A TOOLS=( [ar]=ar [cpp]=cpp [dwp]=dwp [gcc]=cc [gcov]=gcov [ld]=ld [nm]=nm [objcopy]=objcopy [objdump]=objdump [strip]=strip )
|
|
+ TOOL_NAMES=(''${!TOOLS[@]})
|
|
+ declare -A TOOL_PATHS=()
|
|
+ for tool_name in ''${!TOOLS[@]}; do
|
|
+ tool_path=${cc}/bin/''${TOOLS[$tool_name]}
|
|
+ if [[ -x $tool_path ]]; then
|
|
+ TOOL_PATHS[$tool_name]=$tool_path
|
|
+ else
|
|
+ TOOL_PATHS[$tool_name]=${coreutils}/bin/false
|
|
+ fi
|
|
+ done
|
|
+ cc=''${TOOL_PATHS[gcc]}
|
|
+
|
|
+ # Check whether a flag is supported by the compiler.
|
|
+ #
|
|
+ # The logic checks whether the flag causes an error message that contains
|
|
+ # the flag (or a pattern) verbatim. The assumption is that this will be a
|
|
+ # message of the kind `unknown argument: XYZ`. This logic is copied and
|
|
+ # adapted to bash from `@bazel_tools//tools/cpp:unix_cc_configure.bzl`.
|
|
+ is_compiler_option_supported() {
|
|
+ local option="$1"
|
|
+ local pattern="''${2-$1}"
|
|
+ { $cc "$option" -o /dev/null -c -x c++ - <<<"int main() {}" 2>&1 1>/dev/null || true; } \
|
|
+ | grep -qe "$pattern" && return 1 || return 0
|
|
+ }
|
|
+ is_linker_option_supported() {
|
|
+ local option="$1"
|
|
+ local pattern="''${2-$1}"
|
|
+ { $cc "$option" -o /dev/null -x c++ - <<<"int main() {}" 2>&1 1>/dev/null || true; } \
|
|
+ | grep -qe "$pattern" && return 1 || return 0
|
|
+ }
|
|
+ add_compiler_option_if_supported() {
|
|
+ if is_compiler_option_supported "$@"; then
|
|
+ echo "$1"
|
|
+ fi
|
|
+ }
|
|
+ add_linker_option_if_supported() {
|
|
+ if is_linker_option_supported "$@"; then
|
|
+ echo "$1"
|
|
+ fi
|
|
+ }
|
|
+
|
|
+ # Determine default include directories.
|
|
+ #
|
|
+ # This is copied and adapted to bash from
|
|
+ # `@bazel_tools//tools/cpp:unix_cc_configure.bzl`.
|
|
+ IFS=$'\n'
|
|
+ include_dirs_for() {
|
|
+ $cc -E -x "$1" - -v "''${@:2}" 2>&1 \
|
|
+ | sed '1,/^#include <...>/d;/^[^ ]/,$d;s/^ *//' \
|
|
+ | tr '\n' '\0' \
|
|
+ | xargs -0 realpath -ms
|
|
+ }
|
|
+ CXX_BUILTIN_INCLUDE_DIRECTORIES=($({
|
|
+ include_dirs_for c
|
|
+ include_dirs_for c++
|
|
+ if is_compiler_option_supported -fno-canonical-system-headers; then
|
|
+ include_dirs_for c -fno-canonical-system-headers
|
|
+ include_dirs_for c++ -std=c++0x -fno-canonical-system-headers
|
|
+ elif is_compiler_option_supported -no-canonical-prefixes; then
|
|
+ include_dirs_for c -no-canonical-prefixes
|
|
+ include_dirs_for c++ -std=c++0x -no-canonical-prefixes
|
|
+ fi
|
|
+ } 2>&1 | sort -u))
|
|
+ unset IFS
|
|
+
|
|
+ # Determine list of supported compiler and linker flags.
|
|
+ #
|
|
+ # This is copied and adapted to bash from
|
|
+ # `@bazel_tools//tools/cpp:unix_cc_configure.bzl`.
|
|
+ COMPILER_FLAGS=(
|
|
+ # Security hardening requires optimization.
|
|
+ # We need to undef it as some distributions now have it enabled by default.
|
|
+ -U_FORTIFY_SOURCE
|
|
+ -fstack-protector
|
|
+ # All warnings are enabled. Maybe enable -Werror as well?
|
|
+ -Wall
|
|
+ $(
|
|
+ # Enable a few more warnings that aren't part of -Wall.
|
|
+ add_compiler_option_if_supported -Wthread-safety
|
|
+ add_compiler_option_if_supported -Wself-assign
|
|
+ # Disable problematic warnings.
|
|
+ add_compiler_option_if_supported -Wunused-but-set-parameter
|
|
+ # has false positives
|
|
+ add_compiler_option_if_supported -Wno-free-nonheap-object
|
|
+ # Enable coloring even if there's no attached terminal. Bazel removes the
|
|
+ # escape sequences if --nocolor is specified.
|
|
+ add_compiler_option_if_supported -fcolor-diagnostics
|
|
+ )
|
|
+ # Keep stack frames for debugging, even in opt mode.
|
|
+ -fno-omit-frame-pointer
|
|
+ )
|
|
+ CXX_FLAGS=(-std=c++0x)
|
|
+ LINK_FLAGS=(
|
|
+ $(
|
|
+ if [[ -x ${cc}/bin/ld.gold ]]; then echo -fuse-ld=gold; fi
|
|
+ add_linker_option_if_supported -Wl,-no-as-needed -no-as-needed
|
|
+ add_linker_option_if_supported -Wl,-z,relro,-z,now -z
|
|
+ )
|
|
+ ${
|
|
+ if stdenv.isDarwin
|
|
+ then "-undefined dynamic_lookup -headerpad_max_install_names"
|
|
+ else "-B${cc}/bin"
|
|
+ }
|
|
+ $(
|
|
+ # Have gcc return the exit code from ld.
|
|
+ add_compiler_option_if_supported -pass-exit-codes
|
|
+ )
|
|
+ -lstdc++
|
|
+ -lm
|
|
+ )
|
|
+ LINK_LIBS=()
|
|
+ OPT_COMPILE_FLAGS=(
|
|
+ # No debug symbols.
|
|
+ # Maybe we should enable https://gcc.gnu.org/wiki/DebugFission for opt or
|
|
+ # even generally? However, that can't happen here, as it requires special
|
|
+ # handling in Bazel.
|
|
+ -g0
|
|
+
|
|
+ # Conservative choice for -O
|
|
+ # -O3 can increase binary size and even slow down the resulting binaries.
|
|
+ # Profile first and / or use FDO if you need better performance than this.
|
|
+ -O2
|
|
+
|
|
+ # Security hardening on by default.
|
|
+ # Conservative choice; -D_FORTIFY_SOURCE=2 may be unsafe in some cases.
|
|
+ -D_FORTIFY_SOURCE=1
|
|
+
|
|
+ # Disable assertions
|
|
+ -DNDEBUG
|
|
+
|
|
+ # Removal of unused code and data at link time (can this increase binary
|
|
+ # size in some cases?).
|
|
+ -ffunction-sections
|
|
+ -fdata-sections
|
|
+ )
|
|
+ OPT_LINK_FLAGS=(
|
|
+ ${
|
|
+ if stdenv.isDarwin
|
|
+ then ""
|
|
+ else "$(add_linker_option_if_supported -Wl,--gc-sections -gc-sections)"
|
|
+ }
|
|
+ )
|
|
+ UNFILTERED_COMPILE_FLAGS=(
|
|
+ $(
|
|
+ if is_compiler_option_supported -fno-canonical-system-headers; then
|
|
+ echo -fno-canonical-system-headers
|
|
+ elif is_compiler_option_supported -no-canonical-prefixes; then
|
|
+ echo -no-canonical-prefixes
|
|
+ fi
|
|
+ )
|
|
+ # Make C++ compilation deterministic. Use linkstamping instead of these
|
|
+ # compiler symbols.
|
|
+ -Wno-builtin-macro-redefined
|
|
+ -D__DATE__=\\\"redacted\\\"
|
|
+ -D__TIMESTAMP__=\\\"redacted\\\"
|
|
+ -D__TIME__=\\\"redacted\\\"
|
|
+ )
|
|
+ DBG_COMPILE_FLAGS=(-g)
|
|
+ COVERAGE_COMPILE_FLAGS=(
|
|
+ ${
|
|
+ if stdenv.isDarwin then
|
|
+ "-fprofile-instr-generate -fcoverage-mapping"
|
|
+ else
|
|
+ "--coverage"
|
|
+ }
|
|
+ )
|
|
+ COVERAGE_LINK_FLAGS=(
|
|
+ ${
|
|
+ if stdenv.isDarwin then
|
|
+ "-fprofile-instr-generate"
|
|
+ else
|
|
+ "--coverage"
|
|
+ }
|
|
+ )
|
|
+ SUPPORTS_START_END_LIB=(
|
|
+ $(
|
|
+ if [[ -x ${cc}/bin/ld.gold ]]; then echo True; else echo False; fi
|
|
+ )
|
|
+ )
|
|
+
|
|
+ # Write CC_TOOLCHAIN_INFO
|
|
+ #
|
|
+ # Each line has the following shape:
|
|
+ # <key>:<value1>:<value2>:...
|
|
+ # or
|
|
+ # <key>
|
|
+ # I.e. each line is a colon-separated list of the key and the values.
|
|
+ mkdir -p $out
|
|
+ write_info() {
|
|
+ local -n flags=$1
|
|
+ local output=( "$1" "''${flags[@]}" )
|
|
+ IFS=:
|
|
+ echo "''${output[*]}" >>$out/CC_TOOLCHAIN_INFO
|
|
+ unset IFS
|
|
+ }
|
|
+ write_info TOOL_NAMES
|
|
+ write_info TOOL_PATHS
|
|
+ write_info CXX_BUILTIN_INCLUDE_DIRECTORIES
|
|
+ write_info COMPILER_FLAGS
|
|
+ write_info CXX_FLAGS
|
|
+ write_info LINK_FLAGS
|
|
+ write_info LINK_LIBS
|
|
+ write_info OPT_COMPILE_FLAGS
|
|
+ write_info OPT_LINK_FLAGS
|
|
+ write_info UNFILTERED_COMPILE_FLAGS
|
|
+ write_info DBG_COMPILE_FLAGS
|
|
+ write_info COVERAGE_COMPILE_FLAGS
|
|
+ write_info COVERAGE_LINK_FLAGS
|
|
+ write_info SUPPORTS_START_END_LIB
|
|
+ ''
|
|
diff --git a/nixpkgs/toolchains/go.bzl b/nixpkgs/toolchains/go.bzl
|
|
index 79cbb99..d8c6366 100644
|
|
--- a/nixpkgs/toolchains/go.bzl
|
|
+++ b/nixpkgs/toolchains/go.bzl
|
|
@@ -2,20 +2,19 @@ load(
|
|
"@io_bazel_rules_go//go:deps.bzl",
|
|
"go_wrap_sdk",
|
|
)
|
|
-
|
|
load(
|
|
"//nixpkgs:nixpkgs.bzl",
|
|
- "nixpkgs_package"
|
|
+ "nixpkgs_package",
|
|
)
|
|
|
|
def nixpkgs_go_configure(
|
|
- sdk_name = "go_sdk",
|
|
- repository = None,
|
|
- repositories = {},
|
|
- nix_file = None,
|
|
- nix_file_deps = None,
|
|
- nix_file_content = None,
|
|
- nixopts = []):
|
|
+ sdk_name = "go_sdk",
|
|
+ repository = None,
|
|
+ repositories = {},
|
|
+ nix_file = None,
|
|
+ nix_file_deps = None,
|
|
+ nix_file_content = None,
|
|
+ nixopts = []):
|
|
"""
|
|
Use go toolchain from Nixpkgs. Will fail if not a nix-based platform.
|
|
|
|
@@ -41,7 +40,6 @@ def nixpkgs_go_configure(
|
|
}
|
|
"""
|
|
|
|
-
|
|
nixpkgs_package(
|
|
name = "nixpkgs_go_toolchain",
|
|
repository = repository,
|
|
diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel
|
|
index 450810b..d86d6a5 100644
|
|
--- a/tests/BUILD.bazel
|
|
+++ b/tests/BUILD.bazel
|
|
@@ -1,6 +1,7 @@
|
|
package(default_testonly = 1)
|
|
|
|
load("@io_bazel_rules_go//go:def.bzl", "go_binary")
|
|
+load("cc-test.bzl", "cc_toolchain_test")
|
|
|
|
[
|
|
# All of these tests use the "hello" binary to see
|
|
@@ -54,12 +55,41 @@ load("@io_bazel_rules_go//go:def.bzl", "go_binary")
|
|
),
|
|
]
|
|
|
|
-# Test nixpkgs_cc_configure() by building some CC code.
|
|
+# Test nixopts location expansion
|
|
+sh_test(
|
|
+ name = "location-expansion-test",
|
|
+ srcs = ["location_expansion.sh"],
|
|
+ args = [
|
|
+ "$(POSIX_DIFF)",
|
|
+ "$(rootpath //:nixpkgs.json)",
|
|
+ "$(rootpath //:nixpkgs.nix)",
|
|
+ "$(rootpath //tests:relative_imports/nixpkgs.nix)",
|
|
+ "$(rootpath @nixpkgs_location_expansion_test//:out/nixpkgs.json)",
|
|
+ "$(rootpath @nixpkgs_location_expansion_test//:out/nixpkgs.nix)",
|
|
+ "$(rootpath @nixpkgs_location_expansion_test//:out/relative_imports.nix)",
|
|
+ ],
|
|
+ data = [
|
|
+ "//:nixpkgs.json",
|
|
+ "//:nixpkgs.nix",
|
|
+ "//tests:relative_imports/nixpkgs.nix",
|
|
+ "@nixpkgs_location_expansion_test//:out/nixpkgs.json",
|
|
+ "@nixpkgs_location_expansion_test//:out/nixpkgs.nix",
|
|
+ "@nixpkgs_location_expansion_test//:out/relative_imports.nix",
|
|
+ ],
|
|
+ toolchains = ["@rules_sh//sh/posix:make_variables"],
|
|
+)
|
|
+
|
|
+# Test nixpkgs_cc_configure_hermetic() by building some CC code.
|
|
cc_binary(
|
|
name = "cc-test",
|
|
srcs = ["cc-test.cc"],
|
|
)
|
|
|
|
+# Test that nixpkgs_cc_configure_hermetic is selected.
|
|
+cc_toolchain_test(
|
|
+ name = "cc-toolchain",
|
|
+)
|
|
+
|
|
# Test nixpkgs_python_configure() by running some Python code.
|
|
test_suite(
|
|
name = "python-test",
|
|
@@ -86,5 +116,5 @@ sh_test(
|
|
# Test nixpkgs_go_configure()
|
|
go_binary(
|
|
name = "go-test",
|
|
- srcs = ["go-test.go"]
|
|
+ srcs = ["go-test.go"],
|
|
)
|
|
diff --git a/tests/cc-test.bzl b/tests/cc-test.bzl
|
|
new file mode 100644
|
|
index 0000000..8494cc8
|
|
--- /dev/null
|
|
+++ b/tests/cc-test.bzl
|
|
@@ -0,0 +1,59 @@
|
|
+load("@bazel_skylib//lib:paths.bzl", "paths")
|
|
+load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
|
|
+
|
|
+def _cc_toolchain_test_impl(ctx):
|
|
+ cc = find_cpp_toolchain(ctx)
|
|
+ executable = ctx.actions.declare_file(ctx.attr.name + ".sh")
|
|
+ cc_toolchain_info = ctx.file._cc_toolchain_info
|
|
+ cc_toolchain_info_path = ctx.expand_location(
|
|
+ "$(rootpath {})".format(str(ctx.attr._cc_toolchain_info.label)),
|
|
+ [ctx.attr._cc_toolchain_info],
|
|
+ )
|
|
+ ctx.actions.write(executable, content = """\
|
|
+# Find cc in CC_TOOLCHAIN_INFO
|
|
+while IFS=: read -a line; do
|
|
+ if [[ ${{line[0]}} = TOOL_PATHS ]]; then
|
|
+ for item in ${{line[@]:1}}; do
|
|
+ if [[ $item = */bin/cc ]]; then
|
|
+ CC=$item
|
|
+ fi
|
|
+ done
|
|
+ fi
|
|
+done <{cc_toolchain_info_path}
|
|
+if [[ {cc} = */cc_wrapper.sh ]]; then
|
|
+ grep -q "$CC" "{cc}" || {{
|
|
+ echo "Expected C compiler '$CC' in wrapper script '{cc}'." >&2
|
|
+ exit 1
|
|
+ }}
|
|
+else
|
|
+ if [[ {cc} != $CC ]]; then
|
|
+ echo "Expected C compiler '$CC', but found '{cc}'." >&2
|
|
+ exit 1
|
|
+ fi
|
|
+fi
|
|
+""".format(
|
|
+ cc = cc.compiler_executable,
|
|
+ cc_toolchain_info_path = cc_toolchain_info_path,
|
|
+ ))
|
|
+ return [DefaultInfo(
|
|
+ executable = executable,
|
|
+ runfiles = ctx.runfiles(
|
|
+ files = [ctx.file._cc_toolchain_info],
|
|
+ transitive_files = cc.all_files,
|
|
+ ),
|
|
+ )]
|
|
+
|
|
+cc_toolchain_test = rule(
|
|
+ _cc_toolchain_test_impl,
|
|
+ attrs = {
|
|
+ "_cc_toolchain": attr.label(
|
|
+ default = Label("@rules_cc//cc:current_cc_toolchain"),
|
|
+ ),
|
|
+ "_cc_toolchain_info": attr.label(
|
|
+ allow_single_file = True,
|
|
+ default = Label("@nixpkgs_config_cc_info//:CC_TOOLCHAIN_INFO"),
|
|
+ ),
|
|
+ },
|
|
+ test = True,
|
|
+ toolchains = ["@rules_cc//cc:toolchain_type"],
|
|
+)
|
|
diff --git a/tests/location_expansion.nix b/tests/location_expansion.nix
|
|
new file mode 100644
|
|
index 0000000..8023925
|
|
--- /dev/null
|
|
+++ b/tests/location_expansion.nix
|
|
@@ -0,0 +1,17 @@
|
|
+with import <nixpkgs> { config = {}; overlays = []; };
|
|
+
|
|
+{ attrs, relative_imports }:
|
|
+let
|
|
+ inherit (attrs) nixpkgs_json nixpkgs_nix;
|
|
+in
|
|
+ runCommand "location-expansion"
|
|
+ {
|
|
+ preferLocalBuild = true;
|
|
+ allowSubstitutes = false;
|
|
+ }
|
|
+ ''
|
|
+ mkdir -p $out/out
|
|
+ cp ${nixpkgs_json} $out/out/nixpkgs.json
|
|
+ cp ${nixpkgs_nix} $out/out/nixpkgs.nix
|
|
+ cp ${relative_imports} $out/out/relative_imports.nix
|
|
+ ''
|
|
diff --git a/tests/location_expansion.sh b/tests/location_expansion.sh
|
|
new file mode 100755
|
|
index 0000000..9f4df14
|
|
--- /dev/null
|
|
+++ b/tests/location_expansion.sh
|
|
@@ -0,0 +1,5 @@
|
|
+DIFF="$1"
|
|
+
|
|
+diff "$2" "$5"
|
|
+diff "$3" "$6"
|
|
+diff "$4" "$7"
|