From 9f7430d57983481b81f83c760506505ea27f965f Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Sat, 9 May 2020 02:21:56 +0200 Subject: [PATCH 01/21] nixpkgs_cc_configure_hermetic This introduces a new repository rule `nixpkgs_cc_configure_hermetic` which is meant to replace `nixpkgs_cc_configure`. The latter is implemented by calling Bazel's builtin CC toolchain autodetection with the binary paths overriden to point to Nix provided tools. This is more hermetic than Bazel's default behavior in that the tools are not just picked from `$PATH`. However, it is not hermetic. Bazel's CC toolchain autodetection is influenced by environment variables, and it shells out to the provided `cc` binary in the context of a repository rule to determine system include paths which is also affected by environment variables. Concretely, this caused cache misses due to include paths provided by a `nix-shell` changing the cache keys of build actions depending on the CC toolchain. `nixpkgs_cc_configure_hermetic` on the other hand uses binaries determined by a Nix derivation and performs additional configuration such as determining system include paths within a Nix build, i.e. within Nix's own sandbox. The results are stored in a text file `CC_TOOLCHAIN_INFO` which is then parsed in a Bazel repository rule. From there on the toolchain configuration follows the example of Bazel's builtin CC toolchain for Unix: https://github.com/bazelbuild/bazel/blob/0f4c498a270f05b3896d57055b6489e824821eda/tools/cpp/unix_cc_configure.bzl#L310. Users can override the Nix provided compiler using the `nix_file` or `nix_file_content` and `attribute_path` arguments. The corresponding Nix derivation should produce the required tools, e.g. `bin/cc`. --- .bazelrc | 6 + CHANGELOG.md | 12 ++ README.md | 103 ++++++++++++ WORKSPACE | 4 +- nixpkgs/nixpkgs.bzl | 341 +++++++++++++++++++++++++++++++++++++- nixpkgs/toolchains/cc.nix | 276 ++++++++++++++++++++++++++++++ tests/BUILD.bazel | 8 +- tests/cc-test.bzl | 59 +++++++ 8 files changed, 805 insertions(+), 4 deletions(-) create mode 100644 nixpkgs/toolchains/cc.nix create mode 100644 tests/cc-test.bzl diff --git a/.bazelrc b/.bazelrc index d226e65e2..687c13626 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/CHANGELOG.md b/CHANGELOG.md index a1c6ddab2..b53ffd870 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). [Unreleased]: https://github.com/tweag/rules_nixpkgs/compare/v0.7.0...HEAD +### Added + +- Define `nixpkgs_cc_configure_hermetic` in `//nixpkgs:repositories.bzl`. + See [#128][#128]. + ### Changed - The values in the `nixopts` attribute to `nixpkgs_package` are now subject to @@ -16,6 +21,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). `LABEL`. To pass a plain `$` to Nix it must be escaped as `$$`. See [#132][#132]. +### 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 [#132]: https://github.com/tweag/rules_nixpkgs/pull/132 ## [0.7.0] - 2020-04-20 diff --git a/README.md b/README.md index de7f269e1..2883d2171 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,99 @@ filegroup( +### 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=@//:toolchain` to activate this +toolchain. + +Example: + +```bzl +nixpkgs_cc_configure_hermetic(repository = "@nixpkgs//:default.nix") +``` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Attributes
attribute_path +

String; optional

+

Obtain the toolchain from the Nix expression under this attribute path. Requires `nix_file` or `nix_file_content`.

+
nix_file +

String; optional

+

Obtain the toolchain from the Nix expression defined in this file. Specify only one of `nix_file` or `nix_file_content`.

+
nix_file_content +

String; optional

+

Obtain the toolchain from the given Nix expression. Specify only one of `nix_file` or `nix_file_content`.

+
nix_file_deps +

List of labels; optional

+

Additional files that the Nix expression depends on.

+
repository +

Label; optional

+

Provides ``. Specify one of `repositories` or `repository`.

+
repositories +

String-keyed label dict; optional

+

Provides `` and other repositories. Specify one of `repositories` or `repository`.

+
quiet +

Bool; optional

+

Whether to hide `nix-build` output.

+
fail_not_supported +

Bool; optional

+

Whether to fail if `nix-build` is not available.

+
+ ### nixpkgs_cc_configure Tells Bazel to use compilers and linkers from Nixpkgs for the CC @@ -333,6 +426,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 85143ecc4..bfd04e11a 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", @@ -161,7 +161,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", diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 40308ed98..b2244446b 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -1,7 +1,14 @@ """Rules for importing Nixpkgs packages.""" +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") load(":private/location_expansion.bzl", "expand_location") def _nixpkgs_git_repository_impl(repository_ctx): @@ -257,6 +264,328 @@ 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 + # + # :::... + 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=@//: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 `` and other repositories. Specify one of `repositories` or `repository`. + repository: Label, Provides ``. 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, + 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 @@ -336,6 +665,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 000000000..13ec92bad --- /dev/null +++ b/nixpkgs/toolchains/cc.nix @@ -0,0 +1,276 @@ +with import { 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: + # :::... + # I.e. each line contains one colon-separated key-value pair, where the + # value is a colon-separated list. + mkdir -p $out + write_info() { + local -n flags=$1 + IFS=: + echo "$1:''${flags[*]}" >>$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/tests/BUILD.bazel b/tests/BUILD.bazel index e782f747e..84a9742d8 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") load(":location_expansion_unit_test.bzl", "expand_location_unit_test_suite") expand_location_unit_test_suite() @@ -75,12 +76,17 @@ sh_test( toolchains = ["@rules_sh//sh/posix:make_variables"], ) -# Test nixpkgs_cc_configure() by building some CC code. +# 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", diff --git a/tests/cc-test.bzl b/tests/cc-test.bzl new file mode 100644 index 000000000..8494cc851 --- /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"], +) From b9560afc7baec716a40ba316b01bbcc3d84d574d Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 18 May 2020 16:59:12 +0200 Subject: [PATCH 02/21] cc.nix: Handle empty sequences correctly --- nixpkgs/toolchains/cc.nix | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix index 13ec92bad..6b1bff463 100644 --- a/nixpkgs/toolchains/cc.nix +++ b/nixpkgs/toolchains/cc.nix @@ -250,13 +250,15 @@ in # # Each line has the following shape: # :::... - # I.e. each line contains one colon-separated key-value pair, where the - # value is a colon-separated list. + # or + # + # 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 "$1:''${flags[*]}" >>$out/CC_TOOLCHAIN_INFO + echo "''${output[*]}" >>$out/CC_TOOLCHAIN_INFO unset IFS } write_info TOOL_NAMES From b6c5b7dcca926f3659fb13866b7701c457a32a80 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 17 Jul 2020 10:33:26 +0200 Subject: [PATCH 03/21] Track whether cc is clang --- nixpkgs/nixpkgs.bzl | 2 ++ nixpkgs/toolchains/cc.nix | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index b2244446b..8c794ce60 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -306,6 +306,7 @@ def _parse_cc_toolchain_info(content, filename): "COVERAGE_COMPILE_FLAGS", "COVERAGE_LINK_FLAGS", "SUPPORTS_START_END_LIB", + "IS_CLANG", ]) actual_keys = sets.make(info.keys()) missing_keys = sets.difference(expected_keys, actual_keys) @@ -344,6 +345,7 @@ def _parse_cc_toolchain_info(content, filename): coverage_compile_flags = info["COVERAGE_COMPILE_FLAGS"], coverage_link_flags = info["COVERAGE_LINK_FLAGS"], supports_start_end_lib = info["SUPPORTS_START_END_LIB"] == ["True"], + is_clang = info["IS_CLANG"] == ["True"], ) def _nixpkgs_cc_toolchain_config_impl(repository_ctx): diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix index 6b1bff463..1e9e089ef 100644 --- a/nixpkgs/toolchains/cc.nix +++ b/nixpkgs/toolchains/cc.nix @@ -245,6 +245,11 @@ in if [[ -x ${cc}/bin/ld.gold ]]; then echo True; else echo False; fi ) ) + IS_CLANG=( + $( + ${cc}/bin/cc -v 2>&1 | grep -q clang && echo True || echo False + ) + ) # Write CC_TOOLCHAIN_INFO # @@ -275,4 +280,5 @@ in write_info COVERAGE_COMPILE_FLAGS write_info COVERAGE_LINK_FLAGS write_info SUPPORTS_START_END_LIB + write_info IS_CLANG '' From f2a5ecdd3618ced3a18297cd1183516730f0e5c7 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 17 Jul 2020 11:22:53 +0200 Subject: [PATCH 04/21] Write system module map if required. --- nixpkgs/nixpkgs.bzl | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 8c794ce60..8188b5811 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -1,6 +1,7 @@ """Rules for importing Nixpkgs packages.""" load("@bazel_skylib//lib:sets.bzl", "sets") +load("@bazel_skylib//lib:versions.bzl", "versions") load("@bazel_tools//tools/cpp:cc_configure.bzl", "cc_autoconf_impl") load( "@bazel_tools//tools/cpp:lib_cc_configure.bzl", @@ -370,6 +371,23 @@ def _nixpkgs_cc_toolchain_config_impl(repository_ctx): repository_ctx.path(repository_ctx.attr._armeabi_cc_toolchain_config), "armeabi_cc_toolchain_config.bzl", ) + + # A module map is required for clang starting from Bazel version 3.3.0. + # https://github.com/bazelbuild/bazel/commit/8b9f74649512ee17ac52815468bf3d7e5e71c9fa + needs_module_map = info.is_clang and versions.is_at_least("3.3.0", versions.get()) + if needs_module_map: + generate_system_module_map = [ + repository_ctx.path(repository_ctx.attr._generate_system_module_map), + ] + repository_ctx.file( + "module.modulemap", + _execute_or_fail( + repository_ctx, + generate_system_module_map + info.cxx_builtin_include_directories, + "Failed to generate system module map.", + ).stdout.strip(), + executable = False, + ) cc_wrapper_src = ( repository_ctx.attr._osx_cc_wrapper if darwin else repository_ctx.attr._linux_cc_wrapper ) @@ -395,6 +413,7 @@ def _nixpkgs_cc_toolchain_config_impl(repository_ctx): { "%{cc_toolchain_identifier}": "local", "%{name}": cpu_value, + "%{modulemap}": ("\":module.modulemap\"" if needs_module_map else "None"), "%{supports_param_files}": "0" if darwin else "1", "%{cc_compiler_deps}": get_starlark_list( [":builtin_include_directory_paths"] + ( @@ -437,6 +456,9 @@ _nixpkgs_cc_toolchain_config = repository_rule( "_armeabi_cc_toolchain_config": attr.label( default = Label("@bazel_tools//tools/cpp:armeabi_cc_toolchain_config.bzl"), ), + "_generate_system_module_map": attr.label( + default = Label("@bazel_tools//tools/cpp:generate_system_module_map.sh"), + ), "_osx_cc_wrapper": attr.label( default = Label("@bazel_tools//tools/cpp:osx_cc_wrapper.sh.tpl"), ), From 80da9370bf142979d0d6e84f5e7826fee3a0719d Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Wed, 29 Jul 2020 12:13:34 +0200 Subject: [PATCH 05/21] bzl_library dependencies Required for stardoc documentation generation downstream, e.g. rules_haskell. --- nixpkgs/BUILD.bazel | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nixpkgs/BUILD.bazel b/nixpkgs/BUILD.bazel index 18f32ded3..680b55398 100644 --- a/nixpkgs/BUILD.bazel +++ b/nixpkgs/BUILD.bazel @@ -42,6 +42,8 @@ bzl_library( visibility = ["//visibility:public"], deps = [ ":bazel_tools", + "@bazel_skylib//lib:new_sets", "@bazel_skylib//lib:paths", + "@bazel_skylib//lib:sets", ], ) From 55e1615ba28bb8d4dd785fcdd00399b752a08066 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 6 Nov 2020 18:29:49 +0100 Subject: [PATCH 06/21] Update nixpkgs/toolchains/cc.nix Co-authored-by: Wael Nasreddine --- nixpkgs/toolchains/cc.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix index 1e9e089ef..4ccb13ce8 100644 --- a/nixpkgs/toolchains/cc.nix +++ b/nixpkgs/toolchains/cc.nix @@ -114,7 +114,7 @@ in IFS=$'\n' include_dirs_for() { $cc -E -x "$1" - -v "''${@:2}" 2>&1 \ - | sed '1,/^#include <...>/d;/^[^ ]/,$d;s/^ *//' \ + | sed -e '1,/^#include <...>/d;/^[^ ]/,$d;s/^ *//' -e 's: (framework directory)::g' \ | tr '\n' '\0' \ | xargs -0 realpath -ms } From 9299eed69929f2ae8dd7e11be63c6692ba3eae5c Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 6 Nov 2020 18:31:35 +0100 Subject: [PATCH 07/21] Document the dependency on rules_cc --- README.md | 2 ++ nixpkgs/nixpkgs.bzl | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.md b/README.md index 2883d2171..c787edb6f 100644 --- a/README.md +++ b/README.md @@ -340,6 +340,8 @@ 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`. +This rule depends on [`rules_cc`](https://github.com/bazelbuild/rules_cc). + Note: You need to configure `--crosstool_top=@//:toolchain` to activate this diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 8188b5811..4839e5dbf 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -545,6 +545,8 @@ def nixpkgs_cc_configure_hermetic( `ld`, `nm`, `objcopy`, `objdump`, `strip`. Tools that aren't found are replaced by `${coreutils}/bin/false`. + This rule depends on [`rules_cc`](https://github.com/bazelbuild/rules_cc). + Note: You need to configure `--crosstool_top=@//:toolchain` to activate this toolchain. From 60e0819a1261acb799dda35eed12cac1df1f5d1a Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Fri, 6 Nov 2020 18:38:10 +0100 Subject: [PATCH 08/21] Avoid clang errors due to unused command line flags https://github.com/tweag/rules_nixpkgs/pull/128#issuecomment-720658838 --- nixpkgs/toolchains/cc.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix index 4ccb13ce8..fdf68a1b5 100644 --- a/nixpkgs/toolchains/cc.nix +++ b/nixpkgs/toolchains/cc.nix @@ -148,6 +148,7 @@ in add_compiler_option_if_supported -Wself-assign # Disable problematic warnings. add_compiler_option_if_supported -Wunused-but-set-parameter + add_compiler_option_if_supported -Wno-unused-command-line-argument # has false positives add_compiler_option_if_supported -Wno-free-nonheap-object # Enable coloring even if there's no attached terminal. Bazel removes the From b3cce104ac66f357cb60c4ad14171e54fc3af648 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 9 Nov 2020 10:24:13 +0100 Subject: [PATCH 09/21] Configure warnings on Nix derivation This way the presence of the flag remains user configurable through the nix_file or nix_file_content attribute. --- nixpkgs/toolchains/cc.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix index fdf68a1b5..f9a441fc9 100644 --- a/nixpkgs/toolchains/cc.nix +++ b/nixpkgs/toolchains/cc.nix @@ -23,7 +23,8 @@ let # 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 \ + "-Wno-unused-command-line-argument \ + -isystem ${llvmPackages.libcxx}/include/c++/v1 \ -F${CoreFoundation}/Library/Frameworks \ -F${CoreServices}/Library/Frameworks \ -F${Security}/Library/Frameworks \ @@ -148,7 +149,6 @@ in add_compiler_option_if_supported -Wself-assign # Disable problematic warnings. add_compiler_option_if_supported -Wunused-but-set-parameter - add_compiler_option_if_supported -Wno-unused-command-line-argument # has false positives add_compiler_option_if_supported -Wno-free-nonheap-object # Enable coloring even if there's no attached terminal. Bazel removes the From ca71928d99e2a5980ea1afbf9c849050641bd56d Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 12 Nov 2020 16:12:00 +0100 Subject: [PATCH 10/21] Drop the `_hermetic` suffix on new cc toolchain Addressing review comment https://github.com/tweag/rules_nixpkgs/pull/128#issuecomment-724841478 --- CHANGELOG.md | 15 ++++++++------- README.md | 11 ++++++----- WORKSPACE | 4 ++-- nixpkgs/nixpkgs.bzl | 6 +++--- tests/BUILD.bazel | 4 ++-- 5 files changed, 21 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b53ffd870..d3d6ec9c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,13 +8,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). [Unreleased]: https://github.com/tweag/rules_nixpkgs/compare/v0.7.0...HEAD -### Added - -- Define `nixpkgs_cc_configure_hermetic` in `//nixpkgs:repositories.bzl`. - See [#128][#128]. - ### Changed +- The implementation of `nixpkgs_cc_configure` has been replaced by a more + hermetic version that no longer uses Bazel's builtin autodection toolchain + under the hood. The previous behavior is now available under the name + `nixpkgs_cc_configure_deprecated`, if required. + See [#128][#128]. - The values in the `nixopts` attribute to `nixpkgs_package` are now subject to location expansion. Any instance of `$(location LABEL)` in the `nixopts` attribute will be expanded to the file path of the file referenced by @@ -23,8 +23,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/). ### Deprecated -- `nixpkgs_cc_configure` has been deprecated in favor of - `nixpkgs_cc_configure_hermetic` and will be replaced by it in future. +- The old implementation of `nixpkgs_cc_configure`, now available under the + name `nixpkgs_cc_configure_deprecated`, has been marked as deprecated in + favor of `nixpkgs_cc_configure` and will be replaced by it in future. See [#128][#128]. [#128]: https://github.com/tweag/rules_nixpkgs/pull/128 diff --git a/README.md b/README.md index c787edb6f..59adc4daf 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Links: * [nixpkgs_git_repository](#nixpkgs_git_repository) * [nixpkgs_package](#nixpkgs_package) * [nixpkgs_cc_configure](#nixpkgs_cc_configure) +* [nixpkgs_cc_configure_deprecated](#nixpkgs_cc_configure_deprecated) * [nixpkgs_go_configure](#nixpkgs_go_configure) ## Setup @@ -326,7 +327,7 @@ filegroup( -### nixpkgs_cc_configure_hermetic +### nixpkgs_cc_configure Use a CC toolchain from Nixpkgs. No-op if not a nix-based platform. @@ -350,7 +351,7 @@ toolchain. Example: ```bzl -nixpkgs_cc_configure_hermetic(repository = "@nixpkgs//:default.nix") +nixpkgs_cc_configure(repository = "@nixpkgs//:default.nix") ``` @@ -421,7 +422,7 @@ nixpkgs_cc_configure_hermetic(repository = "@nixpkgs//:default.nix")
-### nixpkgs_cc_configure +### nixpkgs_cc_configure_deprecated Tells Bazel to use compilers and linkers from Nixpkgs for the CC toolchain. By default, Bazel autodetects a toolchain on the current @@ -430,7 +431,7 @@ is considered a best practice. Deprecated: -Use `nixpkgs_cc_configure_hermetic` instead. +Use `nixpkgs_cc_configure` 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 @@ -441,7 +442,7 @@ depending on the cc toolchain leading to cache misses. Example: ```bzl -nixpkgs_cc_configure(repository = "@nixpkgs//:default.nix") +nixpkgs_cc_configure_deprecated(repository = "@nixpkgs//:default.nix") ``` diff --git a/WORKSPACE b/WORKSPACE index bfd04e11a..85143ecc4 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -6,7 +6,7 @@ rules_nixpkgs_dependencies() load( "//nixpkgs:nixpkgs.bzl", - "nixpkgs_cc_configure_hermetic", + "nixpkgs_cc_configure", "nixpkgs_git_repository", "nixpkgs_local_repository", "nixpkgs_package", @@ -161,7 +161,7 @@ nixpkgs_package( repository = "@nixpkgs", ) -nixpkgs_cc_configure_hermetic(repository = "@remote_nixpkgs") +nixpkgs_cc_configure(repository = "@remote_nixpkgs") nixpkgs_python_configure( python2_attribute_path = "python2", diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 4839e5dbf..f1636955f 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -522,7 +522,7 @@ _nixpkgs_cc_toolchain = repository_rule( }, ) -def nixpkgs_cc_configure_hermetic( +def nixpkgs_cc_configure( name = "nixpkgs_config_cc", attribute_path = "", nix_file = None, @@ -682,7 +682,7 @@ nixpkgs_cc_autoconf = repository_rule( ], ) -def nixpkgs_cc_configure( +def nixpkgs_cc_configure_deprecated( repository = None, repositories = {}, nix_file = None, @@ -692,7 +692,7 @@ def nixpkgs_cc_configure( """Use a CC toolchain from Nixpkgs. No-op if not a nix-based platform. Deprecated: - Use `nixpkgs_cc_configure_hermetic` instead. + Use `nixpkgs_cc_configure` 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 diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel index 84a9742d8..077c0c845 100644 --- a/tests/BUILD.bazel +++ b/tests/BUILD.bazel @@ -76,13 +76,13 @@ sh_test( toolchains = ["@rules_sh//sh/posix:make_variables"], ) -# Test nixpkgs_cc_configure_hermetic() by building some CC code. +# Test nixpkgs_cc_configure() by building some CC code. cc_binary( name = "cc-test", srcs = ["cc-test.cc"], ) -# Test that nixpkgs_cc_configure_hermetic is selected. +# Test that nixpkgs_cc_configure is selected. cc_toolchain_test( name = "cc-toolchain", ) From a62b793dc472862060b46df21e392f048a2e7da6 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Thu, 12 Nov 2020 16:21:36 +0100 Subject: [PATCH 11/21] Use local_config_cc as default cc toolchain name --- WORKSPACE | 7 ++++++- nixpkgs/nixpkgs.bzl | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 85143ecc4..33cc5b44f 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -161,7 +161,12 @@ nixpkgs_package( repository = "@nixpkgs", ) -nixpkgs_cc_configure(repository = "@remote_nixpkgs") +nixpkgs_cc_configure( + # Use a different name to be able to distinguish this toolchain from the + # builtin one in the tests. + name = "nixpkgs_config_cc", + repository = "@remote_nixpkgs", +) nixpkgs_python_configure( python2_attribute_path = "python2", diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index f1636955f..69ac3a8c1 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -523,7 +523,7 @@ _nixpkgs_cc_toolchain = repository_rule( ) def nixpkgs_cc_configure( - name = "nixpkgs_config_cc", + name = "local_config_cc", attribute_path = "", nix_file = None, nix_file_content = "", From f34bd28327bdfc9f0f6f197760c2e810897adaf6 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 23 Nov 2020 16:34:30 +0100 Subject: [PATCH 12/21] Don't hardcode tool list in docs https://github.com/tweag/rules_nixpkgs/pull/128/files/c5e464ff1eb7096d55cdb482c4c76070757f3a2e..a8a4db35092d5580bcc6cd27353cc6f1d0e07d35#r525424846 --- README.md | 10 +++++----- nixpkgs/nixpkgs.bzl | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 59adc4daf..3de31e4b5 100644 --- a/README.md +++ b/README.md @@ -335,11 +335,11 @@ 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`. +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. Tools that aren't found are replaced by `${coreutils}/bin/false`. +You can inspect the resulting `@_info//:CC_TOOLCHAIN_INFO` to see +which tools were discovered. This rule depends on [`rules_cc`](https://github.com/bazelbuild/rules_cc). diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 69ac3a8c1..6a9623784 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -541,9 +541,9 @@ def nixpkgs_cc_configure( 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`. + tools. Tools that aren't found are replaced by `${coreutils}/bin/false`. + You can inspect the resulting `@_info//:CC_TOOLCHAIN_INFO` to see + which tools were discovered. This rule depends on [`rules_cc`](https://github.com/bazelbuild/rules_cc). From c229107afb5de70259155c928eb8582071b915bc Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 23 Nov 2020 16:46:18 +0100 Subject: [PATCH 13/21] Reference bazel_tools templates https://github.com/tweag/rules_nixpkgs/pull/128/files/c5e464ff1eb7096d55cdb482c4c76070757f3a2e..a8a4db35092d5580bcc6cd27353cc6f1d0e07d35#r525443743 --- nixpkgs/nixpkgs.bzl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 6a9623784..17e47c2fe 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -363,6 +363,8 @@ def _nixpkgs_cc_toolchain_config_impl(repository_ctx): # Generate the cc_toolchain workspace following the example from # `@bazel_tools//tools/cpp:unix_cc_configure.bzl`. + # Uses the corresponding templates from `@bazel_tools` as well, see the + # private attributes of the `_nixpkgs_cc_toolchain_config` rule. repository_ctx.symlink( repository_ctx.path(repository_ctx.attr._unix_cc_toolchain_config), "cc_toolchain_config.bzl", From 169875ef52446a060fc2b74f0fecda5249d89e12 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 23 Nov 2020 16:49:02 +0100 Subject: [PATCH 14/21] compiler_flags --> compile_flags https://github.com/tweag/rules_nixpkgs/pull/128/files/c5e464ff1eb7096d55cdb482c4c76070757f3a2e..a8a4db35092d5580bcc6cd27353cc6f1d0e07d35#r525432170 --- nixpkgs/nixpkgs.bzl | 6 +++--- nixpkgs/toolchains/cc.nix | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 17e47c2fe..9ba74843c 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -296,7 +296,7 @@ def _parse_cc_toolchain_info(content, filename): "TOOL_NAMES", "TOOL_PATHS", "CXX_BUILTIN_INCLUDE_DIRECTORIES", - "COMPILER_FLAGS", + "COMPILE_FLAGS", "CXX_FLAGS", "LINK_FLAGS", "LINK_LIBS", @@ -335,7 +335,7 @@ def _parse_cc_toolchain_info(content, filename): 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"], + compile_flags = info["COMPILE_FLAGS"], cxx_flags = info["CXX_FLAGS"], link_flags = info["LINK_FLAGS"], link_libs = info["LINK_LIBS"], @@ -433,7 +433,7 @@ def _nixpkgs_cc_toolchain_config_impl(repository_ctx): ['"%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), + "%{compile_flags}": get_starlark_list(info.compile_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), diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix index f9a441fc9..43e78d627 100644 --- a/nixpkgs/toolchains/cc.nix +++ b/nixpkgs/toolchains/cc.nix @@ -136,7 +136,7 @@ in # # This is copied and adapted to bash from # `@bazel_tools//tools/cpp:unix_cc_configure.bzl`. - COMPILER_FLAGS=( + COMPILE_FLAGS=( # Security hardening requires optimization. # We need to undef it as some distributions now have it enabled by default. -U_FORTIFY_SOURCE @@ -270,7 +270,7 @@ in write_info TOOL_NAMES write_info TOOL_PATHS write_info CXX_BUILTIN_INCLUDE_DIRECTORIES - write_info COMPILER_FLAGS + write_info COMPILE_FLAGS write_info CXX_FLAGS write_info LINK_FLAGS write_info LINK_LIBS From efe429373cf6d6c6ebb50c836f374342b623c427 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 23 Nov 2020 16:50:44 +0100 Subject: [PATCH 15/21] ternary vs. dict.get https://github.com/tweag/rules_nixpkgs/pull/128#discussion_r525552457 --- nixpkgs/nixpkgs.bzl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 9ba74843c..296f62aa9 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -513,7 +513,7 @@ toolchain( """.format( cc_toolchain_config = repository_ctx.attr.cc_toolchain_config, cpu = cpu, - os = {"darwin": "osx"}.get(cpu, "linux"), + os = "osx" if cpu == "darwin" else "linux", ), ) From 173ba0862434ac86393fd68c13d991c43545ee74 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 23 Nov 2020 17:13:12 +0100 Subject: [PATCH 16/21] Docstring for nixopts https://github.com/tweag/rules_nixpkgs/pull/128/files/c5e464ff1eb7096d55cdb482c4c76070757f3a2e..a8a4db35092d5580bcc6cd27353cc6f1d0e07d35#r525556207 --- README.md | 12 ++++++++++++ nixpkgs/nixpkgs.bzl | 1 + 2 files changed, 13 insertions(+) diff --git a/README.md b/README.md index 3de31e4b5..7e1023abf 100644 --- a/README.md +++ b/README.md @@ -405,6 +405,18 @@ nixpkgs_cc_configure(repository = "@nixpkgs//:default.nix")

Provides `` and other repositories. Specify one of `repositories` or `repository`.

+
+ + +
nixopts +

String list; optional

+

+ Extra flags to pass when calling Nix. Subject to location + expansion, any instance of $(location LABEL) will be + replaced by the path to the file ferenced by LABEL + relative to the workspace root. +

+
quiet diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 296f62aa9..9c06239ae 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -560,6 +560,7 @@ def nixpkgs_cc_configure( nix_file_deps: optional, list of Label, Additional files that the Nix expression depends on. repositories: dict of Label to string, Provides `` and other repositories. Specify one of `repositories` or `repository`. repository: Label, Provides ``. Specify one of `repositories` or `repository`. + nixopts: optional, list of string, Extra flags to pass when calling Nix. Subject to location expansion, any instance of `$(location LABEL)` will be replaced by the path to the file ferenced by `LABEL` relative to the workspace root. quiet: bool, Whether to hide `nix-build` output. fail_not_supported: bool, Whether to fail if `nix-build` is not available. """ From 9b2114d70c12e8a47a5e4a667f5fe35b911487f8 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 23 Nov 2020 17:21:49 +0100 Subject: [PATCH 17/21] avoid with https://github.com/tweag/rules_nixpkgs/pull/128/files/c5e464ff1eb7096d55cdb482c4c76070757f3a2e..a8a4db35092d5580bcc6cd27353cc6f1d0e07d35#r525998121 --- nixpkgs/toolchains/cc.nix | 49 ++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix index 43e78d627..0573be9dd 100644 --- a/nixpkgs/toolchains/cc.nix +++ b/nixpkgs/toolchains/cc.nix @@ -1,4 +1,6 @@ -with import { config = {}; overlays = []; }; +let + pkgs = import { config = {}; overlays = []; }; +in { attribute_path ? null , nix_expr ? null @@ -8,50 +10,49 @@ 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" + pkgs.runCommand "bazel-nixpkgs-cc-wrapper" { - buildInputs = [ stdenv.cc makeWrapper ]; + buildInputs = [ pkgs.stdenv.cc pkgs.makeWrapper ]; } '' mkdir -p $out/bin - for i in ${stdenv.cc}/bin/*; do + for i in ${pkgs.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 \ + makeWrapper ${pkgs.stdenv.cc}/bin/cc $out/bin/cc --add-flags \ "-Wno-unused-command-line-argument \ - -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" + -isystem ${pkgs.darwin.apple_sdk.frameworks.llvmPackages.libcxx}/include/c++/v1 \ + -F${pkgs.darwin.apple_sdk.frameworks.CoreFoundation}/Library/Frameworks \ + -F${pkgs.darwin.apple_sdk.frameworks.CoreServices}/Library/Frameworks \ + -F${pkgs.darwin.apple_sdk.frameworks.Security}/Library/Frameworks \ + -F${pkgs.darwin.apple_sdk.frameworks.Foundation}/Library/Frameworks \ + -L${pkgs.darwin.apple_sdk.frameworks.libcxx}/lib \ + -L${pkgs.darwin.apple_sdk.frameworks.darwin.libobjc}/lib" ''; cc = if isNull nix_expr then - buildEnv { + pkgs.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 ] + if pkgs.stdenv.isDarwin then + [ (pkgs.overrideCC pkgs.stdenv darwinCC).cc pkgs.darwin.binutils ] else - [ stdenv.cc binutils ]; + [ pkgs.stdenv.cc pkgs.binutils ]; pathsToLink = [ "/bin" ]; } else if isNull attribute_path then nix_expr else - lib.attrByPath (lib.splitString "." attribute_path) null nix_expr + pkgs.lib.attrByPath (pkgs.lib.splitString "." attribute_path) null nix_expr ; in - runCommand "bazel-nixpkgs-cc-toolchain" + pkgs.runCommand "bazel-nixpkgs-cc-toolchain" { executable = false; # Pointless to do this on a remote machine. preferLocalBuild = true; @@ -74,7 +75,7 @@ in if [[ -x $tool_path ]]; then TOOL_PATHS[$tool_name]=$tool_path else - TOOL_PATHS[$tool_name]=${coreutils}/bin/false + TOOL_PATHS[$tool_name]=${pkgs.coreutils}/bin/false fi done cc=''${TOOL_PATHS[gcc]} @@ -166,7 +167,7 @@ in add_linker_option_if_supported -Wl,-z,relro,-z,now -z ) ${ - if stdenv.isDarwin + if pkgs.stdenv.isDarwin then "-undefined dynamic_lookup -headerpad_max_install_names" else "-B${cc}/bin" } @@ -204,7 +205,7 @@ in ) OPT_LINK_FLAGS=( ${ - if stdenv.isDarwin + if pkgs.stdenv.isDarwin then "" else "$(add_linker_option_if_supported -Wl,--gc-sections -gc-sections)" } @@ -227,7 +228,7 @@ in DBG_COMPILE_FLAGS=(-g) COVERAGE_COMPILE_FLAGS=( ${ - if stdenv.isDarwin then + if pkgs.stdenv.isDarwin then "-fprofile-instr-generate -fcoverage-mapping" else "--coverage" @@ -235,7 +236,7 @@ in ) COVERAGE_LINK_FLAGS=( ${ - if stdenv.isDarwin then + if pkgs.stdenv.isDarwin then "-fprofile-instr-generate" else "--coverage" From a579b93db0cb21872ea74d617c3095f23f3273e0 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 23 Nov 2020 17:32:02 +0100 Subject: [PATCH 18/21] Remove unused build input https://github.com/tweag/rules_nixpkgs/pull/128/files/c5e464ff1eb7096d55cdb482c4c76070757f3a2e..a8a4db35092d5580bcc6cd27353cc6f1d0e07d35#r525999726 --- nixpkgs/toolchains/cc.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix index 0573be9dd..0fe1667a0 100644 --- a/nixpkgs/toolchains/cc.nix +++ b/nixpkgs/toolchains/cc.nix @@ -12,7 +12,7 @@ let # See also https://github.com/NixOS/nixpkgs/pull/41589. pkgs.runCommand "bazel-nixpkgs-cc-wrapper" { - buildInputs = [ pkgs.stdenv.cc pkgs.makeWrapper ]; + buildInputs = [ pkgs.makeWrapper ]; } '' mkdir -p $out/bin From be84215b5150e82dd7182c5cf970dc34f430d995 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 23 Nov 2020 18:01:20 +0100 Subject: [PATCH 19/21] More explicit switch between attrset/expression/default https://github.com/tweag/rules_nixpkgs/pull/128/files/c5e464ff1eb7096d55cdb482c4c76070757f3a2e..a8a4db35092d5580bcc6cd27353cc6f1d0e07d35#r526011393 --- nixpkgs/nixpkgs.bzl | 40 ++++++++++++++++++++++++++------------- nixpkgs/toolchains/cc.nix | 15 ++++++++------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index 9c06239ae..fed4597f8 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -565,22 +565,36 @@ def nixpkgs_cc_configure( 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_expr = None + if nix_file and nix_file_content: + fail("Cannot specify both 'nix_file' and 'nix_file_content'.") + elif nix_file: + 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]) + elif nix_file_content: + nix_expr = nix_file_content + + if attribute_path and nix_expr == None: + fail("'attribute_path' requires one of 'nix_file' or 'nix_file_content'", "attribute_path") + elif attribute_path: + nixopts.extend([ + "--argstr", "ccType", "ccTypeAttribute", + "--argstr", "ccAttrPath", attribute_path, + "--arg", "ccAttrSet", nix_expr, + ]) + elif nix_expr: + nixopts.extend([ + "--argstr", "ccType", "ccTypeExpression", + "--arg", "ccExpr", nix_expr, + ]) + else: + nixopts.extend([ + "--argstr", "ccType", "ccTypeDefault", + ]) + # Invoke `toolchains/cc.nix` which generates `CC_TOOLCHAIN_INFO`. nixpkgs_package( diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix index 0fe1667a0..5780cfd8f 100644 --- a/nixpkgs/toolchains/cc.nix +++ b/nixpkgs/toolchains/cc.nix @@ -2,8 +2,9 @@ let pkgs = import { config = {}; overlays = []; }; in -{ attribute_path ? null -, nix_expr ? null +{ ccType +, ccAttrPath ? null, ccAttrSet ? null +, ccExpr ? null }: let @@ -34,7 +35,11 @@ let -L${pkgs.darwin.apple_sdk.frameworks.darwin.libobjc}/lib" ''; cc = - if isNull nix_expr then + if ccType == "ccTypeAttribute" then + pkgs.lib.attrByPath (pkgs.lib.splitString "." ccAttrPath) null ccAttrSet + else if ccType == "ccTypeExpression" then + ccExpr + else pkgs.buildEnv { name = "bazel-nixpkgs-cc"; # XXX: `gcov` is missing in `/bin`. @@ -46,10 +51,6 @@ let [ pkgs.stdenv.cc pkgs.binutils ]; pathsToLink = [ "/bin" ]; } - else if isNull attribute_path then - nix_expr - else - pkgs.lib.attrByPath (pkgs.lib.splitString "." attribute_path) null nix_expr ; in pkgs.runCommand "bazel-nixpkgs-cc-toolchain" From dba7836716d30675d233cc5e4d43e1931b2c40fb Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Mon, 23 Nov 2020 18:47:59 +0100 Subject: [PATCH 20/21] fmt --- nixpkgs/nixpkgs.bzl | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/nixpkgs/nixpkgs.bzl b/nixpkgs/nixpkgs.bzl index fed4597f8..666948e3c 100644 --- a/nixpkgs/nixpkgs.bzl +++ b/nixpkgs/nixpkgs.bzl @@ -581,21 +581,32 @@ def nixpkgs_cc_configure( fail("'attribute_path' requires one of 'nix_file' or 'nix_file_content'", "attribute_path") elif attribute_path: nixopts.extend([ - "--argstr", "ccType", "ccTypeAttribute", - "--argstr", "ccAttrPath", attribute_path, - "--arg", "ccAttrSet", nix_expr, + "--argstr", + "ccType", + "ccTypeAttribute", + "--argstr", + "ccAttrPath", + attribute_path, + "--arg", + "ccAttrSet", + nix_expr, ]) elif nix_expr: nixopts.extend([ - "--argstr", "ccType", "ccTypeExpression", - "--arg", "ccExpr", nix_expr, + "--argstr", + "ccType", + "ccTypeExpression", + "--arg", + "ccExpr", + nix_expr, ]) else: nixopts.extend([ - "--argstr", "ccType", "ccTypeDefault", + "--argstr", + "ccType", + "ccTypeDefault", ]) - # Invoke `toolchains/cc.nix` which generates `CC_TOOLCHAIN_INFO`. nixpkgs_package( name = "{}_info".format(name), From ae1a25505c3ab9f39b7665cd809f80aa29233c75 Mon Sep 17 00:00:00 2001 From: Andreas Herrmann Date: Tue, 24 Nov 2020 13:42:56 +0100 Subject: [PATCH 21/21] Fix Darwin attributes --- nixpkgs/toolchains/cc.nix | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nixpkgs/toolchains/cc.nix b/nixpkgs/toolchains/cc.nix index 5780cfd8f..a234e3276 100644 --- a/nixpkgs/toolchains/cc.nix +++ b/nixpkgs/toolchains/cc.nix @@ -26,13 +26,13 @@ let rm -f $out/bin/cc $out/bin/clang $out/bin/clang++ makeWrapper ${pkgs.stdenv.cc}/bin/cc $out/bin/cc --add-flags \ "-Wno-unused-command-line-argument \ - -isystem ${pkgs.darwin.apple_sdk.frameworks.llvmPackages.libcxx}/include/c++/v1 \ + -isystem ${pkgs.llvmPackages.libcxx}/include/c++/v1 \ -F${pkgs.darwin.apple_sdk.frameworks.CoreFoundation}/Library/Frameworks \ -F${pkgs.darwin.apple_sdk.frameworks.CoreServices}/Library/Frameworks \ -F${pkgs.darwin.apple_sdk.frameworks.Security}/Library/Frameworks \ -F${pkgs.darwin.apple_sdk.frameworks.Foundation}/Library/Frameworks \ - -L${pkgs.darwin.apple_sdk.frameworks.libcxx}/lib \ - -L${pkgs.darwin.apple_sdk.frameworks.darwin.libobjc}/lib" + -L${pkgs.libcxx}/lib \ + -L${pkgs.darwin.libobjc}/lib" ''; cc = if ccType == "ccTypeAttribute" then