Remove crostool migration tools
The migration to .bzl configured toolchains happened a long time ago and the conversion tools from proto files are not needed anymore.
This also cleans up rules_cc dependencies to build those tools. And unblock me around the import of py_proto_library, which is not needed anymore.
PiperOrigin-RevId: 683582749
Change-Id: I9a56d9e3f9089f7434708a2cfefdd4f12d186658
diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml
index 8d7899d..9fbb3ed 100644
--- a/.bazelci/presubmit.yml
+++ b/.bazelci/presubmit.yml
@@ -16,7 +16,6 @@
- "//examples/my_c_archive:all"
- "//examples/my_c_compile:all"
- "//examples/write_cc_toolchain_cpu:all"
- - "//tools/migration:all"
- "//tests/..."
test_flags:
- "--test_timeout=120"
@@ -29,7 +28,6 @@
- "//examples/my_c_archive:all"
- "//examples/my_c_compile:all"
- "//examples/write_cc_toolchain_cpu:all"
- - "//tools/migration:all"
- "//tests/..."
buildifier:
diff --git a/WORKSPACE b/WORKSPACE
index a4587d5..9501829 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -12,34 +12,6 @@
)
http_archive(
- name = "com_google_googletest",
- sha256 = "81964fe578e9bd7c94dfdb09c8e4d6e6759e19967e397dbea48d1c10e45d0df2",
- strip_prefix = "googletest-release-1.12.1",
- urls = [
- "https://mirror.bazel.build/github.com/google/googletest/archive/refs/tags/release-1.12.1.tar.gz",
- "https://github.com/google/googletest/archive/refs/tags/release-1.12.1.tar.gz",
- ],
-)
-
-http_archive(
- name = "io_abseil_py",
- sha256 = "0fb3a4916a157eb48124ef309231cecdfdd96ff54adf1660b39c0d4a9790a2c0",
- strip_prefix = "abseil-py-1.4.0",
- urls = [
- "https://github.com/abseil/abseil-py/archive/refs/tags/v1.4.0.tar.gz",
- ],
-)
-
-http_archive(
- name = "io_bazel_rules_go",
- sha256 = "91585017debb61982f7054c9688857a2ad1fd823fc3f9cb05048b0025c47d023",
- urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.42.0/rules_go-v0.42.0.zip",
- "https://github.com/bazelbuild/rules_go/releases/download/v0.42.0/rules_go-v0.42.0.zip",
- ],
-)
-
-http_archive(
name = "platforms",
sha256 = "218efe8ee736d26a3572663b374a253c012b716d8af0c07e842e82f238a0a7ee",
urls = [
@@ -48,49 +20,10 @@
],
)
-http_archive(
- name = "py_mock",
- patch_cmds = [
- "mkdir -p py/mock",
- "mv mock.py py/mock/__init__.py",
- """echo 'licenses(["notice"])' > BUILD""",
- "touch py/BUILD",
- """echo 'py_library(name = "mock", srcs = ["__init__.py"], visibility = ["//visibility:public"],)' > py/mock/BUILD""",
- ],
- sha256 = "b839dd2d9c117c701430c149956918a423a9863b48b09c90e30a6013e7d2f44f",
- strip_prefix = "mock-1.0.1",
- urls = [
- "https://mirror.bazel.build/pypi.python.org/packages/source/m/mock/mock-1.0.1.tar.gz",
- "https://pypi.python.org/packages/source/m/mock/mock-1.0.1.tar.gz",
- ],
-)
-
-http_archive(
- name = "rules_proto",
- sha256 = "9a0503631679e9ab4e27d891ea60fee3e86a85654ea2048cae25516171dd260e",
- strip_prefix = "rules_proto-e51f588e5932966ab9e63e0b0f6de6f740cf04c4",
- urls = [
- "https://mirror.bazel.build/github.com/bazelbuild/rules_proto/archive/e51f588e5932966ab9e63e0b0f6de6f740cf04c4.tar.gz",
- "https://github.com/bazelbuild/rules_proto/archive/e51f588e5932966ab9e63e0b0f6de6f740cf04c4.tar.gz",
- ],
-)
-
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
bazel_skylib_workspace()
-load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
-
-go_rules_dependencies()
-
-go_register_toolchains(version = "1.20.5")
-
-load("@rules_proto//proto:repositories.bzl", "rules_proto_dependencies", "rules_proto_toolchains")
-
-rules_proto_dependencies()
-
-rules_proto_toolchains()
-
http_archive(
name = "rules_testing",
sha256 = "02c62574631876a4e3b02a1820cb51167bb9cdcdea2381b2fa9d9b8b11c407c4",
diff --git a/third_party/BUILD b/third_party/BUILD
deleted file mode 100644
index 0c41157..0000000
--- a/third_party/BUILD
+++ /dev/null
@@ -1 +0,0 @@
-# Intentionally empty, only there to make //third_party a package.
diff --git a/third_party/com/github/bazelbuild/bazel/src/main/protobuf/BUILD b/third_party/com/github/bazelbuild/bazel/src/main/protobuf/BUILD
deleted file mode 100644
index c08e13b..0000000
--- a/third_party/com/github/bazelbuild/bazel/src/main/protobuf/BUILD
+++ /dev/null
@@ -1,30 +0,0 @@
-load("@com_google_protobuf//:protobuf.bzl", "py_proto_library")
-load("@io_bazel_rules_go//proto:def.bzl", "go_proto_library")
-load("@rules_proto//proto:defs.bzl", "proto_library")
-
-licenses(["notice"]) # Apache 2.0
-
-py_proto_library(
- name = "crosstool_config_py_pb2",
- srcs = ["crosstool_config.proto"],
- visibility = [
- "//tools/migration:__pkg__",
- ],
-)
-
-proto_library(
- name = "crosstool_config_pb2",
- srcs = ["crosstool_config.proto"],
- visibility = [
- "//tools/migration:__pkg__",
- ],
-)
-
-go_proto_library(
- name = "crosstool_config_go_proto",
- importpath = "third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config_go_proto",
- proto = ":crosstool_config_pb2",
- visibility = [
- "//tools/migration:__pkg__",
- ],
-)
diff --git a/third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config.proto b/third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config.proto
deleted file mode 100644
index 45ad1e5..0000000
--- a/third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config.proto
+++ /dev/null
@@ -1,548 +0,0 @@
-// Copyright 2014 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-// File format for Blaze to configure Crosstool releases.
-
-syntax = "proto2";
-
-package com.google.devtools.build.lib.view.config.crosstool;
-
-// option java_api_version = 2; // copybara-comment-this-out-please
-option java_package = "com.google.devtools.build.lib.view.config.crosstool";
-
-// A description of a toolchain, which includes all the tools generally expected
-// to be available for building C/C++ targets, based on the GNU C compiler.
-//
-// System and cpu names are two overlapping concepts, which need to be both
-// supported at this time. The cpu name is the blaze command-line name for the
-// target system. The most common values are 'k8' and 'piii'. The system name is
-// a more generic identification of the executable system, based on the names
-// used by the GNU C compiler.
-//
-// Typically, the system name contains an identifier for the cpu (e.g. x86_64 or
-// alpha), an identifier for the machine (e.g. pc, or unknown), and an
-// identifier for the operating system (e.g. cygwin or linux-gnu). Typical
-// examples are 'x86_64-unknown-linux-gnu' and 'i686-unknown-cygwin'.
-//
-// The system name is used to determine if a given machine can execute a given
-// executable. In particular, it is used to check if the compilation products of
-// a toolchain can run on the host machine.
-message CToolchain {
- // A group of correlated flags. Supports parametrization via variable
- // expansion.
- //
- // To expand a variable of list type, flag_group has to be annotated with
- // `iterate_over` message. Then all nested flags or flag_groups will be
- // expanded repeatedly for each element of the list.
- //
- // For example:
- // flag_group {
- // iterate_over: 'include_path'
- // flag: '-I'
- // flag: '%{include_path}'
- // }
- // ... will get expanded to -I /to/path1 -I /to/path2 ... for each
- // include_path /to/pathN.
- //
- // To expand a variable of structure type, use dot-notation, e.g.:
- // flag_group {
- // iterate_over: "libraries_to_link"
- // flag_group {
- // iterate_over: "libraries_to_link.libraries"
- // flag: "-L%{libraries_to_link.libraries.directory}"
- // }
- // }
- //
- // Flag groups can be nested; if they are, the flag group must only contain
- // other flag groups (no flags) so the order is unambiguously specified.
- // In order to expand a variable of nested lists, 'iterate_over' can be used.
- //
- // For example:
- // flag_group {
- // iterate_over: 'object_files'
- // flag_group { flag: '--start-lib' }
- // flag_group {
- // iterate_over: 'object_files'
- // flag: '%{object_files}'
- // }
- // flag_group { flag: '--end-lib' }
- // }
- // ... will get expanded to
- // --start-lib a1.o a2.o ... --end-lib --start-lib b1.o b2.o .. --end-lib
- // with %{object_files} being a variable of nested list type
- // [['a1.o', 'a2.o', ...], ['b1.o', 'b2.o', ...], ...].
- //
- // TODO(bazel-team): Write more elaborate documentation and add a link to it.
- message FlagGroup {
- repeated string flag = 1;
-
- repeated FlagGroup flag_group = 2;
-
- optional string iterate_over = 3;
-
- repeated string expand_if_all_available = 4;
-
- repeated string expand_if_none_available = 5;
-
- optional string expand_if_true = 6;
-
- optional string expand_if_false = 7;
-
- optional VariableWithValue expand_if_equal = 8;
- }
-
- message VariableWithValue {
- required string variable = 1;
-
- required string value = 2;
- }
-
- // A key/value pair to be added as an environment variable. The value of
- // this pair is expanded in the same way as is described in FlagGroup.
- // The key remains an unexpanded string literal.
- message EnvEntry {
- required string key = 1;
- required string value = 2;
- repeated string expand_if_all_available = 3;
- }
-
- // A set of features; used to support logical 'and' when specifying feature
- // requirements in Feature.
- message FeatureSet {
- repeated string feature = 1;
- }
-
- // A set of positive and negative features. This stanza will
- // evaluate to true when every 'feature' is enabled, and every
- // 'not_feature' is not enabled.
- message WithFeatureSet {
- repeated string feature = 1;
- repeated string not_feature = 2;
- }
-
- // A set of flags that are expanded in the command line for specific actions.
- message FlagSet {
- // The actions this flag set applies to; each flag set must specify at
- // least one action.
- repeated string action = 1;
-
- // The flags applied via this flag set.
- repeated FlagGroup flag_group = 2;
-
- // A list of feature sets defining when this flag set gets applied. The
- // flag set will be applied when any one of the feature sets evaluate to
- // true. (That is, when when every 'feature' is enabled, and every
- // 'not_feature' is not enabled.)
- //
- // If 'with_feature' is omitted, the flag set will be applied
- // unconditionally for every action specified.
- repeated WithFeatureSet with_feature = 3;
-
- // Deprecated (https://github.com/bazelbuild/bazel/issues/7008) - use
- // expand_if_all_available in flag_group
- //
- // A list of build variables that this feature set needs, but which are
- // allowed to not be set. If any of the build variables listed is not
- // set, the feature set will not be expanded.
- //
- // NOTE: Consider alternatives before using this; usually tools should
- // consistently create the same set of files, even if empty; use this
- // only for backwards compatibility with already existing behavior in tools
- // that are currently not worth changing.
- repeated string expand_if_all_available = 4;
- }
-
- // A set of environment variables that are expanded in the command line for
- // specific actions.
- message EnvSet {
- // The actions this env set applies to; each env set must specify at
- // least one action.
- repeated string action = 1;
-
- // The environment variables applied via this env set.
- repeated EnvEntry env_entry = 2;
-
- // A list of feature sets defining when this env set gets applied. The
- // env set will be applied when any one of the feature sets evaluate to
- // true. (That is, when when every 'feature' is enabled, and every
- // 'not_feature' is not enabled.)
- //
- // If 'with_feature' is omitted, the env set will be applied
- // unconditionally for every action specified.
- repeated WithFeatureSet with_feature = 3;
- }
-
- // Contains all flag specifications for one feature.
- // Next ID: 8
- message Feature {
- // The feature's name. Feature names are generally defined by Bazel; it is
- // possible to introduce a feature without a change to Bazel by adding a
- // 'feature' section to the toolchain and adding the corresponding string as
- // feature in the BUILD file.
- optional string name = 1;
-
- // If 'true', this feature is enabled unless a rule type explicitly marks it
- // as unsupported. Such features cannot be turned off from within a BUILD
- // file or the command line.
- optional bool enabled = 7;
-
- // If the given feature is enabled, the flag sets will be applied for the
- // actions in the modes that they are specified for.
- repeated FlagSet flag_set = 2;
-
- // If the given feature is enabled, the env sets will be applied for the
- // actions in the modes that they are specified for.
- repeated EnvSet env_set = 6;
-
- // A list of feature sets defining when this feature is supported by the
- // toolchain. The feature is supported if any of the feature sets fully
- // apply, that is, when all features of a feature set are enabled.
- //
- // If 'requires' is omitted, the feature is supported independently of which
- // other features are enabled.
- //
- // Use this for example to filter flags depending on the build mode
- // enabled (opt / fastbuild / dbg).
- repeated FeatureSet requires = 3;
-
- // A list of features or action configs that are automatically enabled when
- // this feature is enabled. If any of the implied features or action configs
- // cannot be enabled, this feature will (silently) not be enabled either.
- repeated string implies = 4;
-
- // A list of names this feature conflicts with.
- // A feature cannot be enabled if:
- // - 'provides' contains the name of a different feature or action config
- // that we want to enable.
- // - 'provides' contains the same value as a 'provides' in a different
- // feature or action config that we want to enable.
- //
- // Use this in order to ensure that incompatible features cannot be
- // accidentally activated at the same time, leading to hard to diagnose
- // compiler errors.
- repeated string provides = 5;
- }
-
- // Describes a tool associated with a crosstool action config.
- message Tool {
- // Describes the origin of a path.
- enum PathOrigin {
- // Indicates that `tool_path` is relative to the location of the
- // crosstool. For legacy reasons, absolute paths are als0 allowed here.
- CROSSTOOL_PACKAGE = 0;
-
- // Indicates that `tool_path` is an absolute path.
- // This is enforced by Bazel.
- FILESYSTEM_ROOT = 1;
-
- // Indicates that `tool_path` is relative to the current workspace's
- // exec root.
- WORKSPACE_ROOT = 2;
- }
-
- // Path to the tool, relative to the location of the crosstool.
- required string tool_path = 1;
-
- // Origin of `tool_path`.
- // Optional only for legacy reasons. New crosstools should set this value!
- optional PathOrigin tool_path_origin = 4 [default = CROSSTOOL_PACKAGE];
-
- // A list of feature sets defining when this tool is applicable. The tool
- // will used when any one of the feature sets evaluate to true. (That is,
- // when when every 'feature' is enabled, and every 'not_feature' is not
- // enabled.)
- //
- // If 'with_feature' is omitted, the tool will apply for any feature
- // configuration.
- repeated WithFeatureSet with_feature = 2;
-
- // Requirements on the execution environment for the execution of this tool,
- // to be passed as out-of-band "hints" to the execution backend.
- // Ex. "requires-darwin"
- repeated string execution_requirement = 3;
- }
-
- // The name for an artifact of a given category of input or output artifacts
- // to an action.
- message ArtifactNamePattern {
- // The category of artifacts that this selection applies to. This field
- // is compared against a list of categories defined in bazel. Example
- // categories include "linked_output" or "debug_symbols". An error is thrown
- // if no category is matched.
- required string category_name = 1;
- // The prefix and extension for creating the artifact for this selection.
- // They are used to create an artifact name based on the target name.
- required string prefix = 2;
- required string extension = 3;
- }
-
- // An action config corresponds to a blaze action, and allows selection of
- // a tool based on activated features. Action configs come in two varieties:
- // automatic (the blaze action will exist whether or not the action config
- // is activated) and attachable (the blaze action will be added to the
- // action graph only if the action config is activated).
- //
- // Action config activation occurs by the same semantics as features: a
- // feature can 'require' or 'imply' an action config in the same way that it
- // would another feature.
- // Next ID: 9
- message ActionConfig {
- // The name other features will use to activate this action config. Can
- // be the same as action_name.
- required string config_name = 1;
-
- // The name of the blaze action that this config applies to, ex. 'c-compile'
- // or 'c-module-compile'.
- required string action_name = 2;
-
- // If 'true', this feature is enabled unless a rule type explicitly marks it
- // as unsupported. Such action_configs cannot be turned off from within a
- // BUILD file or the command line.
- optional bool enabled = 8;
-
- // The tool applied to the action will be the first Tool with a feature
- // set that matches the feature configuration. An error will be thrown
- // if no tool matches a provided feature configuration - for that reason,
- // it's a good idea to provide a default tool with an empty feature set.
- repeated Tool tool = 3;
-
- // If the given action config is enabled, the flag sets will be applied
- // to the corresponding action.
- repeated FlagSet flag_set = 4;
-
- // If the given action config is enabled, the env sets will be applied
- // to the corresponding action.
- repeated EnvSet env_set = 5;
-
- // A list of feature sets defining when this action config
- // is supported by the toolchain. The action config is supported if any of
- // the feature sets fully apply, that is, when all features of a
- // feature set are enabled.
- //
- // If 'requires' is omitted, the action config is supported independently
- // of which other features are enabled.
- //
- // Use this for example to filter actions depending on the build
- // mode enabled (opt / fastbuild / dbg).
- repeated FeatureSet requires = 6;
-
- // A list of features or action configs that are automatically enabled when
- // this action config is enabled. If any of the implied features or action
- // configs cannot be enabled, this action config will (silently)
- // not be enabled either.
- repeated string implies = 7;
- }
-
- repeated Feature feature = 50;
- repeated ActionConfig action_config = 53;
- repeated ArtifactNamePattern artifact_name_pattern = 54;
-
- // The unique identifier of the toolchain within the crosstool release. It
- // must be possible to use this as a directory name in a path.
- // It has to match the following regex: [a-zA-Z_][\.\- \w]*
- required string toolchain_identifier = 1;
-
- // A basic toolchain description.
- required string host_system_name = 2;
- required string target_system_name = 3;
- required string target_cpu = 4;
- required string target_libc = 5;
- required string compiler = 6;
-
- required string abi_version = 7;
- required string abi_libc_version = 8;
-
- // Tool locations. Relative paths are resolved relative to the configuration
- // file directory.
- // NOTE: DEPRECATED. Prefer specifying an ActionConfig for the action that
- // needs the tool.
- // TODO(b/27903698) migrate to ActionConfig.
- repeated ToolPath tool_path = 9;
-
- // Feature flags.
- // TODO(bazel-team): Sink those into 'Feature' instances.
- // Legacy field, ignored by Bazel.
- optional bool supports_gold_linker = 10 [default = false];
- // Legacy field, ignored by Bazel.
- optional bool supports_thin_archives = 11 [default = false];
- // Legacy field, use 'supports_start_end_lib' feature instead.
- optional bool supports_start_end_lib = 28 [default = false];
- // Legacy field, use 'supports_interface_shared_libraries' instead.
- optional bool supports_interface_shared_objects = 32 [default = false];
- // Legacy field, use 'static_link_cpp_runtimes' feature instead.
- optional bool supports_embedded_runtimes = 40 [default = false];
- // If specified, Blaze finds statically linked / dynamically linked runtime
- // libraries in the declared crosstool filegroup. Otherwise, Blaze
- // looks in "[static|dynamic]-runtime-libs-$TARGET_CPU".
- // Deprecated, see https://github.com/bazelbuild/bazel/issues/6942
- optional string static_runtimes_filegroup = 45;
- // Deprecated, see https://github.com/bazelbuild/bazel/issues/6942
- optional string dynamic_runtimes_filegroup = 46;
- // Legacy field, ignored by Bazel.
- optional bool supports_incremental_linker = 41 [default = false];
- // Legacy field, ignored by Bazel.
- optional bool supports_normalizing_ar = 26 [default = false];
- // Legacy field, use 'per_object_debug_info' feature instead.
- optional bool supports_fission = 43 [default = false];
- // Legacy field, ignored by Bazel.
- optional bool supports_dsym = 51 [default = false];
- // Legacy field, use 'supports_pic' feature instead
- optional bool needsPic = 12 [default = false];
-
- // Compiler flags for C/C++/Asm compilation.
- repeated string compiler_flag = 13;
- // Additional compiler flags for C++ compilation.
- repeated string cxx_flag = 14;
- // Additional unfiltered compiler flags for C/C++/Asm compilation.
- // These are not subject to nocopt filtering in cc_* rules.
- // Note: These flags are *not* applied to objc/objc++ compiles.
- repeated string unfiltered_cxx_flag = 25;
- // Linker flags.
- repeated string linker_flag = 15;
- // Additional linker flags when linking dynamic libraries.
- repeated string dynamic_library_linker_flag = 27;
- // Additional test-only linker flags.
- repeated string test_only_linker_flag = 49;
- // Objcopy flags for embedding files into binaries.
- repeated string objcopy_embed_flag = 16;
- // Ld flags for embedding files into binaries. This is used by filewrapper
- // since it calls ld directly and needs to know what -m flag to pass.
- repeated string ld_embed_flag = 23;
- // Ar flags for combining object files into archives. If this is not set, it
- // defaults to "rcsD".
- // TODO(b/37271982): Remove after blaze with ar action_config release
- repeated string ar_flag = 47;
- // Legacy field, ignored by Bazel.
- repeated string ar_thin_archives_flag = 48;
- // Legacy field, ignored by Bazel.
- repeated string gcc_plugin_compiler_flag = 34;
-
- // Additional compiler and linker flags depending on the compilation mode.
- repeated CompilationModeFlags compilation_mode_flags = 17;
-
- // Additional linker flags depending on the linking mode.
- repeated LinkingModeFlags linking_mode_flags = 18;
-
- // Legacy field, ignored by Bazel.
- repeated string gcc_plugin_header_directory = 19;
- // Legacy field, ignored by Bazel.
- repeated string mao_plugin_header_directory = 20;
-
- // Make variables that are made accessible to rules.
- repeated MakeVariable make_variable = 21;
-
- // Built-in include directories for C++ compilation. These should be the exact
- // paths used by the compiler, and are generally relative to the exec root.
- // The paths used by the compiler can be determined by 'gcc -Wp,-v some.c'.
- // We currently use the C++ paths also for C compilation, which is safe as
- // long as there are no name clashes between C++ and C header files.
- //
- // Relative paths are resolved relative to the configuration file directory.
- //
- // If the compiler has --sysroot support, then these paths should use
- // %sysroot% rather than the include path, and specify the sysroot attribute
- // in order to give blaze the information necessary to make the correct
- // replacements.
- repeated string cxx_builtin_include_directory = 22;
-
- // The built-in sysroot. If this attribute is not present, blaze does not
- // allow using a different sysroot, i.e. through the --grte_top option. Also
- // see the documentation above.
- optional string builtin_sysroot = 24;
-
- // Legacy field, ignored by Bazel.
- optional string default_python_top = 29;
- // Legacy field, ignored by Bazel.
- optional string default_python_version = 30;
- // Legacy field, ignored by Bazel.
- optional bool python_preload_swigdeps = 42;
-
- // The default GRTE to use. This should be a label, and gets the same
- // treatment from Blaze as the --grte_top option. This setting is only used in
- // the absence of an explicit --grte_top option. If unset, Blaze will not pass
- // -sysroot by default. The local part must be 'everything', i.e.,
- // '//some/label:everything'. There can only be one GRTE library per package,
- // because the compiler expects the directory as a parameter of the -sysroot
- // option.
- // This may only be set to a non-empty value if builtin_sysroot is also set!
- optional string default_grte_top = 31;
-
- // Legacy field, ignored by Bazel.
- repeated string debian_extra_requires = 33;
-
- // Legacy field, ignored by Bazel. Only there for compatibility with
- // things internal to Google.
- optional string cc_target_os = 55;
-
- // Next free id: 56
-}
-
-message ToolPath {
- required string name = 1;
- required string path = 2;
-}
-
-enum CompilationMode {
- FASTBUILD = 1;
- DBG = 2;
- OPT = 3;
- // This value is ignored and should not be used in new files.
- COVERAGE = 4;
-}
-
-message CompilationModeFlags {
- required CompilationMode mode = 1;
- repeated string compiler_flag = 2;
- repeated string cxx_flag = 3;
- // Linker flags that are added when compiling in a certain mode.
- repeated string linker_flag = 4;
-}
-
-enum LinkingMode {
- FULLY_STATIC = 1;
- MOSTLY_STATIC = 2;
- DYNAMIC = 3;
- MOSTLY_STATIC_LIBRARIES = 4;
-}
-
-message LinkingModeFlags {
- required LinkingMode mode = 1;
- repeated string linker_flag = 2;
-}
-
-message MakeVariable {
- required string name = 1;
- required string value = 2;
-}
-
-message DefaultCpuToolchain {
- required string cpu = 1;
- required string toolchain_identifier = 2;
-}
-
-// An entire crosstool release, containing the version number, and a set of
-// toolchains.
-message CrosstoolRelease {
- // The major and minor version of the crosstool release.
- required string major_version = 1;
- required string minor_version = 2;
-
- // Legacy field, ignored by Bazel.
- optional string default_target_cpu = 3;
- // Legacy field, ignored by Bazel.
- repeated DefaultCpuToolchain default_toolchain = 4;
-
- // All the toolchains in this release.
- repeated CToolchain toolchain = 5;
-}
diff --git a/third_party/six.BUILD b/third_party/six.BUILD
deleted file mode 100644
index 19433c2..0000000
--- a/third_party/six.BUILD
+++ /dev/null
@@ -1,16 +0,0 @@
-# Description:
-# Six provides simple utilities for wrapping over differences between Python 2
-# and Python 3.
-
-load("@rules_python//python:defs.bzl", "py_library")
-
-licenses(["notice"]) # MIT
-
-exports_files(["LICENSE"])
-
-py_library(
- name = "six",
- srcs = ["six.py"],
- srcs_version = "PY2AND3",
- visibility = ["//visibility:public"],
-)
diff --git a/tools/migration/BUILD b/tools/migration/BUILD
deleted file mode 100644
index 1550c15..0000000
--- a/tools/migration/BUILD
+++ /dev/null
@@ -1,144 +0,0 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
-load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
-load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test")
-
-package(default_visibility = ["//visibility:public"])
-
-licenses(["notice"])
-
-py_binary(
- name = "legacy_fields_migrator",
- srcs = ["legacy_fields_migrator.py"],
- python_version = "PY3",
- deps = [
- ":legacy_fields_migration_lib",
- "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
- "@io_abseil_py//absl:app",
- "@io_abseil_py//absl/flags",
- #internal proto upb dep,
- ],
-)
-
-py_library(
- name = "legacy_fields_migration_lib",
- srcs = ["legacy_fields_migration_lib.py"],
- deps = [
- "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
- ],
-)
-
-py_test(
- name = "legacy_fields_migration_lib_test",
- srcs = ["legacy_fields_migration_lib_test.py"],
- python_version = "PY3",
- deps = [
- ":legacy_fields_migration_lib",
- "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
- ],
-)
-
-py_binary(
- name = "crosstool_query",
- srcs = ["crosstool_query.py"],
- python_version = "PY3",
- deps = [
- "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
- "@io_abseil_py//absl:app",
- "@io_abseil_py//absl/flags",
- #internal proto upb dep,
- ],
-)
-
-py_binary(
- name = "ctoolchain_comparator",
- srcs = ["ctoolchain_comparator.py"],
- python_version = "PY3",
- deps = [
- ":ctoolchain_comparator_lib",
- "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
- "@io_abseil_py//absl:app",
- "@io_abseil_py//absl/flags",
- #internal proto upb dep,
- ],
-)
-
-py_library(
- name = "ctoolchain_comparator_lib",
- srcs = ["ctoolchain_comparator_lib.py"],
- deps = [
- "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
- ],
-)
-
-py_test(
- name = "ctoolchain_comparator_lib_test",
- srcs = ["ctoolchain_comparator_lib_test.py"],
- python_version = "PY3",
- deps = [
- ":ctoolchain_comparator_lib",
- "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_py_pb2",
- "@py_mock//py/mock",
- ],
-)
-
-go_binary(
- name = "convert_crosstool_to_starlark",
- srcs = ["convert_crosstool_to_starlark.go"],
- deps = [
- ":crosstooltostarlarklib",
- "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_go_proto",
- "@com_github_golang_protobuf//proto:go_default_library",
- ],
-)
-
-go_library(
- name = "crosstooltostarlarklib",
- srcs = ["crosstool_to_starlark_lib.go"],
- importpath = "tools/migration/crosstooltostarlarklib",
- deps = ["//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_go_proto"],
-)
-
-go_test(
- name = "crosstooltostarlarklib_test",
- size = "small",
- srcs = ["crosstool_to_starlark_lib_test.go"],
- embed = [":crosstooltostarlarklib"],
- deps = [
- "//third_party/com/github/bazelbuild/bazel/src/main/protobuf:crosstool_config_go_proto",
- "@com_github_golang_protobuf//proto:go_default_library",
- ],
-)
-
-filegroup(
- name = "bazel_osx_p4deps",
- srcs = [
- "BUILD",
- "ctoolchain_compare.bzl",
- ],
-)
-
-bzl_library(
- name = "ctoolchain_compare_bzl",
- srcs = ["ctoolchain_compare.bzl"],
- visibility = ["//visibility:private"],
-)
-
-bzl_library(
- name = "cc_toolchain_config_comparator_bzl",
- srcs = ["cc_toolchain_config_comparator.bzl"],
- visibility = ["//visibility:private"],
-)
diff --git a/tools/migration/cc_toolchain_config_comparator.bzl b/tools/migration/cc_toolchain_config_comparator.bzl
deleted file mode 100644
index 66746b3..0000000
--- a/tools/migration/cc_toolchain_config_comparator.bzl
+++ /dev/null
@@ -1,53 +0,0 @@
-"""A test rule that compares two C++ toolchain configuration rules in proto format."""
-
-def _impl(ctx):
- first_toolchain_config_proto = ctx.actions.declare_file(
- ctx.label.name + "_first_toolchain_config.proto",
- )
- ctx.actions.write(
- first_toolchain_config_proto,
- ctx.attr.first[CcToolchainConfigInfo].proto,
- )
-
- second_toolchain_config_proto = ctx.actions.declare_file(
- ctx.label.name + "_second_toolchain_config.proto",
- )
- ctx.actions.write(
- second_toolchain_config_proto,
- ctx.attr.second[CcToolchainConfigInfo].proto,
- )
-
- script = ("%s --before='%s' --after='%s'" % (
- ctx.executable._comparator.short_path,
- first_toolchain_config_proto.short_path,
- second_toolchain_config_proto.short_path,
- ))
- test_executable = ctx.actions.declare_file(ctx.label.name)
- ctx.actions.write(test_executable, script, is_executable = True)
-
- runfiles = ctx.runfiles(files = [first_toolchain_config_proto, second_toolchain_config_proto])
- runfiles = runfiles.merge(ctx.attr._comparator[DefaultInfo].default_runfiles)
-
- return DefaultInfo(runfiles = runfiles, executable = test_executable)
-
-cc_toolchain_config_compare_test = rule(
- implementation = _impl,
- attrs = {
- "first": attr.label(
- mandatory = True,
- providers = [CcToolchainConfigInfo],
- doc = "A C++ toolchain config rule",
- ),
- "second": attr.label(
- mandatory = True,
- providers = [CcToolchainConfigInfo],
- doc = "A C++ toolchain config rule",
- ),
- "_comparator": attr.label(
- default = ":ctoolchain_comparator",
- executable = True,
- cfg = "exec",
- ),
- },
- test = True,
-)
diff --git a/tools/migration/convert_crosstool_to_starlark.go b/tools/migration/convert_crosstool_to_starlark.go
deleted file mode 100644
index 2c31456..0000000
--- a/tools/migration/convert_crosstool_to_starlark.go
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-The convert_crosstool_to_starlark script takes in a CROSSTOOL file and
-generates a Starlark rule.
-
-See https://github.com/bazelbuild/bazel/issues/5380
-
-Example usage:
-bazel run \
-@rules_cc//tools/migration:convert_crosstool_to_starlark -- \
---crosstool=/path/to/CROSSTOOL \
---output_location=/path/to/cc_config.bzl
-*/
-package main
-
-import (
- "flag"
- "fmt"
- "io/ioutil"
- "os"
- "os/user"
- "path"
- "strings"
-
- // Google internal base/go package, commented out by copybara
- "log"
- crosstoolpb "third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config_go_proto"
- "github.com/golang/protobuf/proto"
-
- "tools/migration/crosstooltostarlarklib"
-)
-
-var (
- crosstoolLocation = flag.String(
- "crosstool", "", "Location of the CROSSTOOL file")
- outputLocation = flag.String(
- "output_location", "", "Location of the output .bzl file")
-)
-
-func toAbsolutePath(pathString string) (string, error) {
- usr, err := user.Current()
- if err != nil {
- return "", err
- }
- homeDir := usr.HomeDir
-
- if strings.HasPrefix(pathString, "~") {
- return path.Join(homeDir, pathString[1:]), nil
- }
-
- if path.IsAbs(pathString) {
- return pathString, nil
- }
-
- workingDirectory := os.Getenv("BUILD_WORKING_DIRECTORY")
- return path.Join(workingDirectory, pathString), nil
-}
-
-func main() {
- flag.Parse()
-
- if *crosstoolLocation == "" {
- log.Fatalf("Missing mandatory argument 'crosstool'")
- }
- crosstoolPath, err := toAbsolutePath(*crosstoolLocation)
- if err != nil {
- log.Fatalf("Error while resolving CROSSTOOL location:", err)
- }
-
- if *outputLocation == "" {
- log.Fatalf("Missing mandatory argument 'output_location'")
- }
- outputPath, err := toAbsolutePath(*outputLocation)
- if err != nil {
- log.Fatalf("Error resolving output location:", err)
- }
-
- in, err := ioutil.ReadFile(crosstoolPath)
- if err != nil {
- log.Fatalf("Error reading CROSSTOOL file:", err)
- }
- crosstool := &crosstoolpb.CrosstoolRelease{}
- if err := proto.UnmarshalText(string(in), crosstool); err != nil {
- log.Fatalf("Failed to parse CROSSTOOL:", err)
- }
-
- file, err := os.Create(outputPath)
- if err != nil {
- log.Fatalf("Error creating output file:", err)
- }
- defer file.Close()
-
- rule, err := crosstooltostarlarklib.Transform(crosstool)
- if err != nil {
- log.Fatalf("Error converting CROSSTOOL to a Starlark rule:", err)
- }
-
- if _, err := file.WriteString(rule); err != nil {
- log.Fatalf("Error converting CROSSTOOL to a Starlark rule:", err)
- }
- fmt.Println("Success!")
-}
diff --git a/tools/migration/crosstool_query.py b/tools/migration/crosstool_query.py
deleted file mode 100644
index af3f7fa..0000000
--- a/tools/migration/crosstool_query.py
+++ /dev/null
@@ -1,53 +0,0 @@
-"""Script to make automated CROSSTOOL refactorings easier.
-
-This script reads the CROSSTOOL file and allows for querying of its fields.
-"""
-
-from absl import app
-from absl import flags
-from google.protobuf import text_format
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-
-flags.DEFINE_string("crosstool", None, "CROSSTOOL file path to be queried")
-flags.DEFINE_string("identifier", None,
- "Toolchain identifier to specify toolchain.")
-flags.DEFINE_string("print_field", None, "Field to be printed to stdout.")
-
-
-def main(unused_argv):
- crosstool = crosstool_config_pb2.CrosstoolRelease()
-
- crosstool_filename = flags.FLAGS.crosstool
- identifier = flags.FLAGS.identifier
- print_field = flags.FLAGS.print_field
-
- if not crosstool_filename:
- raise app.UsageError("ERROR crosstool unspecified")
- if not identifier:
- raise app.UsageError("ERROR identifier unspecified")
-
- if not print_field:
- raise app.UsageError("ERROR print_field unspecified")
-
- with open(crosstool_filename, "r") as f:
- text = f.read()
- text_format.Merge(text, crosstool)
-
- toolchain_found = False
- for toolchain in crosstool.toolchain:
- if toolchain.toolchain_identifier == identifier:
- toolchain_found = True
- if not print_field:
- continue
- for field, value in toolchain.ListFields():
- if print_field == field.name:
- print value
-
- if not toolchain_found:
- print "toolchain_identifier %s not found, valid values are:" % identifier
- for toolchain in crosstool.toolchain:
- print " " + toolchain.toolchain_identifier
-
-
-if __name__ == "__main__":
- app.run(main)
diff --git a/tools/migration/crosstool_to_starlark_lib.go b/tools/migration/crosstool_to_starlark_lib.go
deleted file mode 100644
index 15f5c12..0000000
--- a/tools/migration/crosstool_to_starlark_lib.go
+++ /dev/null
@@ -1,1419 +0,0 @@
-/*
-Package crosstooltostarlarklib provides the Transform method
-for conversion of a CROSSTOOL file to a Starlark rule.
-
-https://github.com/bazelbuild/bazel/issues/5380
-*/
-package crosstooltostarlarklib
-
-import (
- "bytes"
- "errors"
- "fmt"
- "sort"
- "strings"
-
- crosstoolpb "third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config_go_proto"
-)
-
-// CToolchainIdentifier is what we'll use to differ between CToolchains
-// If a CToolchain can be distinguished from the other CToolchains
-// by only one of the fields (eg if cpu is different for each CToolchain
-// then only that field will be set.
-type CToolchainIdentifier struct {
- cpu string
- compiler string
-}
-
-// Writes the load statement for the cc_toolchain_config_lib
-func getCcToolchainConfigHeader() string {
- return `load("@rules_cc//cc:cc_toolchain_config_lib.bzl",
- "action_config",
- "artifact_name_pattern",
- "env_entry",
- "env_set",
- "feature",
- "feature_set",
- "flag_group",
- "flag_set",
- "make_variable",
- "tool",
- "tool_path",
- "variable_with_value",
- "with_feature_set",
-)
-`
-}
-
-var allCompileActions = []string{
- "c-compile",
- "c++-compile",
- "linkstamp-compile",
- "assemble",
- "preprocess-assemble",
- "c++-header-parsing",
- "c++-module-compile",
- "c++-module-codegen",
- "clif-match",
- "lto-backend",
-}
-
-var allCppCompileActions = []string{
- "c++-compile",
- "linkstamp-compile",
- "c++-header-parsing",
- "c++-module-compile",
- "c++-module-codegen",
- "clif-match",
-}
-
-var preprocessorCompileActions = []string{
- "c-compile",
- "c++-compile",
- "linkstamp-compile",
- "preprocess-assemble",
- "c++-header-parsing",
- "c++-module-compile",
- "clif-match",
-}
-
-var codegenCompileActions = []string{
- "c-compile",
- "c++-compile",
- "linkstamp-compile",
- "assemble",
- "preprocess-assemble",
- "c++-module-codegen",
- "lto-backend",
-}
-
-var allLinkActions = []string{
- "c++-link-executable",
- "c++-link-dynamic-library",
- "c++-link-nodeps-dynamic-library",
-}
-
-var actionNames = map[string]string{
- "c-compile": "ACTION_NAMES.c_compile",
- "c++-compile": "ACTION_NAMES.cpp_compile",
- "linkstamp-compile": "ACTION_NAMES.linkstamp_compile",
- "cc-flags-make-variable": "ACTION_NAMES.cc_flags_make_variable",
- "c++-module-codegen": "ACTION_NAMES.cpp_module_codegen",
- "c++-header-parsing": "ACTION_NAMES.cpp_header_parsing",
- "c++-module-compile": "ACTION_NAMES.cpp_module_compile",
- "assemble": "ACTION_NAMES.assemble",
- "preprocess-assemble": "ACTION_NAMES.preprocess_assemble",
- "lto-indexing": "ACTION_NAMES.lto_indexing",
- "lto-backend": "ACTION_NAMES.lto_backend",
- "c++-link-executable": "ACTION_NAMES.cpp_link_executable",
- "c++-link-dynamic-library": "ACTION_NAMES.cpp_link_dynamic_library",
- "c++-link-nodeps-dynamic-library": "ACTION_NAMES.cpp_link_nodeps_dynamic_library",
- "c++-link-static-library": "ACTION_NAMES.cpp_link_static_library",
- "strip": "ACTION_NAMES.strip",
- "objc-compile": "ACTION_NAMES.objc_compile",
- "objc++-compile": "ACTION_NAMES.objcpp_compile",
- "clif-match": "ACTION_NAMES.clif_match",
-// "objcopy_embed_data": "ACTION_NAMES.objcopy_embed_data", // copybara-comment-this-out-please
-// "ld_embed_data": "ACTION_NAMES.ld_embed_data", // copybara-comment-this-out-please
-}
-
-func getLoadActionsStmt() string {
- return "load(\"@rules_cc//cc:action_names.bzl\", \"ACTION_NAMES\")\n\n"
-}
-
-// Returns a map {toolchain_identifier : CToolchainIdentifier}
-func toolchainToCToolchainIdentifier(
- crosstool *crosstoolpb.CrosstoolRelease) map[string]CToolchainIdentifier {
- cpuToCompiler := make(map[string][]string)
- compilerToCPU := make(map[string][]string)
- var cpus []string
- var compilers []string
- var identifiers []string
- res := make(map[string]CToolchainIdentifier)
- for _, cToolchain := range crosstool.GetToolchain() {
- cpu := cToolchain.GetTargetCpu()
- compiler := cToolchain.GetCompiler()
-
- cpuToCompiler[cpu] = append(cpuToCompiler[cpu], compiler)
- compilerToCPU[compiler] = append(compilerToCPU[compiler], cpu)
-
- cpus = append(cpus, cToolchain.GetTargetCpu())
- compilers = append(compilers, cToolchain.GetCompiler())
- identifiers = append(identifiers, cToolchain.GetToolchainIdentifier())
- }
-
- for i := range cpus {
- if len(cpuToCompiler[cpus[i]]) == 1 {
- // if cpu is unique among CToolchains, we don't need the compiler field
- res[identifiers[i]] = CToolchainIdentifier{cpu: cpus[i], compiler: ""}
- } else {
- res[identifiers[i]] = CToolchainIdentifier{
- cpu: cpus[i],
- compiler: compilers[i],
- }
- }
- }
- return res
-}
-
-func getConditionStatementForCToolchainIdentifier(identifier CToolchainIdentifier) string {
- if identifier.compiler != "" {
- return fmt.Sprintf(
- "ctx.attr.cpu == \"%s\" and ctx.attr.compiler == \"%s\"",
- identifier.cpu,
- identifier.compiler)
- }
- return fmt.Sprintf("ctx.attr.cpu == \"%s\"", identifier.cpu)
-}
-
-func isArrayPrefix(prefix []string, arr []string) bool {
- if len(prefix) > len(arr) {
- return false
- }
- for i := 0; i < len(prefix); i++ {
- if arr[i] != prefix[i] {
- return false
- }
- }
- return true
-}
-
-func isAllCompileActions(actions []string) (bool, []string) {
- if isArrayPrefix(allCompileActions, actions) {
- return true, actions[len(allCompileActions):]
- }
- return false, actions
-}
-
-func isAllCppCompileActions(actions []string) (bool, []string) {
- if isArrayPrefix(allCppCompileActions, actions) {
- return true, actions[len(allCppCompileActions):]
- }
- return false, actions
-}
-
-func isPreprocessorCompileActions(actions []string) (bool, []string) {
- if isArrayPrefix(preprocessorCompileActions, actions) {
- return true, actions[len(preprocessorCompileActions):]
- }
- return false, actions
-}
-
-func isCodegenCompileActions(actions []string) (bool, []string) {
- if isArrayPrefix(codegenCompileActions, actions) {
- return true, actions[len(codegenCompileActions):]
- }
- return false, actions
-}
-
-func isAllLinkActions(actions []string) (bool, []string) {
- if isArrayPrefix(allLinkActions, actions) {
- return true, actions[len(allLinkActions):]
- }
- return false, actions
-}
-
-func getActionNames(actions []string) []string {
- var res []string
- for _, el := range actions {
- if name, ok := actionNames[el]; ok {
- res = append(res, name)
- } else {
- res = append(res, "\""+el+"\"")
- }
- }
- return res
-}
-
-func getListOfActions(name string, depth int) string {
- var res []string
- if name == "all_compile_actions" {
- res = getActionNames(allCompileActions)
- } else if name == "all_cpp_compile_actions" {
- res = getActionNames(allCppCompileActions)
- } else if name == "preprocessor_compile_actions" {
- res = getActionNames(preprocessorCompileActions)
- } else if name == "codegen_compile_actions" {
- res = getActionNames(codegenCompileActions)
- } else if name == "all_link_actions" {
- res = getActionNames(allLinkActions)
- }
- stmt := fmt.Sprintf("%s%s = %s\n\n", getTabs(depth),
- name, makeStringArr(res, depth /* isPlainString= */, false))
- return stmt
-}
-
-func processActions(actions []string, depth int) []string {
- var res []string
- var ok bool
- initLen := len(actions)
- if ok, actions = isAllCompileActions(actions); ok {
- res = append(res, "all_compile_actions")
- }
- if ok, actions = isAllCppCompileActions(actions); ok {
- res = append(res, "all_cpp_compile_actions")
- }
- if ok, actions = isPreprocessorCompileActions(actions); ok {
- res = append(res, "preprocessor_compile_actions")
- }
- if ok, actions = isCodegenCompileActions(actions); ok {
- res = append(res, "codegen_actions")
- }
- if ok, actions = isAllLinkActions(actions); ok {
- res = append(res, "all_link_actions")
- }
- if len(actions) != 0 {
- actions = getActionNames(actions)
- newDepth := depth + 1
- if len(actions) != initLen {
- newDepth++
- }
- res = append(res, makeStringArr(actions, newDepth /* isPlainString= */, false))
- }
- return res
-}
-
-func getUniqueValues(arr []string) []string {
- valuesSet := make(map[string]bool)
- for _, val := range arr {
- valuesSet[val] = true
- }
- var uniques []string
- for val, _ := range valuesSet {
- uniques = append(uniques, val)
- }
- sort.Strings(uniques)
- return uniques
-}
-
-func getRule(cToolchainIdentifiers map[string]CToolchainIdentifier,
- allowedCompilers []string) string {
- cpus := make(map[string]bool)
- shouldUseCompilerAttribute := false
- for _, val := range cToolchainIdentifiers {
- cpus[val.cpu] = true
- if val.compiler != "" {
- shouldUseCompilerAttribute = true
- }
- }
-
- var cpuValues []string
- for cpu := range cpus {
- cpuValues = append(cpuValues, cpu)
- }
-
- var args []string
- sort.Strings(cpuValues)
- args = append(args,
- fmt.Sprintf(
- `"cpu": attr.string(mandatory=True, values=["%s"]),`,
- strings.Join(cpuValues, "\", \"")))
- if shouldUseCompilerAttribute {
- // If there are two CToolchains that share the cpu we need the compiler attribute
- // for our cc_toolchain_config rule.
- allowedCompilers = getUniqueValues(allowedCompilers)
- args = append(args,
- fmt.Sprintf(`"compiler": attr.string(mandatory=True, values=["%s"]),`,
- strings.Join(allowedCompilers, "\", \"")))
- }
- return fmt.Sprintf(`cc_toolchain_config = rule(
- implementation = _impl,
- attrs = {
- %s
- },
- provides = [CcToolchainConfigInfo],
- executable = True,
-)
-`, strings.Join(args, "\n "))
-}
-
-func getImplHeader() string {
- return "def _impl(ctx):\n"
-}
-
-func getStringStatement(crosstool *crosstoolpb.CrosstoolRelease,
- cToolchainIdentifiers map[string]CToolchainIdentifier, field string,
- depth int) string {
-
- identifiers := getToolchainIdentifiers(crosstool)
- var fieldValues []string
- if field == "toolchain_identifier" {
- fieldValues = getToolchainIdentifiers(crosstool)
- } else if field == "host_system_name" {
- fieldValues = getHostSystemNames(crosstool)
- } else if field == "target_system_name" {
- fieldValues = getTargetSystemNames(crosstool)
- } else if field == "target_cpu" {
- fieldValues = getTargetCpus(crosstool)
- } else if field == "target_libc" {
- fieldValues = getTargetLibcs(crosstool)
- } else if field == "compiler" {
- fieldValues = getCompilers(crosstool)
- } else if field == "abi_version" {
- fieldValues = getAbiVersions(crosstool)
- } else if field == "abi_libc_version" {
- fieldValues = getAbiLibcVersions(crosstool)
- } else if field == "cc_target_os" {
- fieldValues = getCcTargetOss(crosstool)
- } else if field == "builtin_sysroot" {
- fieldValues = getBuiltinSysroots(crosstool)
- }
-
- mappedValuesToIds := getMappedStringValuesToIdentifiers(identifiers, fieldValues)
- return getAssignmentStatement(field, mappedValuesToIds, crosstool,
- cToolchainIdentifiers, depth /* isPlainString= */, true /* shouldFail= */, true)
-}
-
-func getFeatures(crosstool *crosstoolpb.CrosstoolRelease) (
- map[string][]string, map[string]map[string][]string, error) {
- featureNameToFeature := make(map[string]map[string][]string)
- toolchainToFeatures := make(map[string][]string)
- for _, toolchain := range crosstool.GetToolchain() {
- id := toolchain.GetToolchainIdentifier()
- if len(toolchain.GetFeature()) == 0 {
- toolchainToFeatures[id] = []string{}
- }
- for _, feature := range toolchain.GetFeature() {
- featureName := strings.ToLower(feature.GetName()) + "_feature"
- featureName = strings.Replace(featureName, "+", "p", -1)
- featureName = strings.Replace(featureName, ".", "_", -1)
- featureName = strings.Replace(featureName, "-", "_", -1)
- stringFeature, err := parseFeature(feature, 1)
- if err != nil {
- return nil, nil, fmt.Errorf(
- "Error in feature '%s': %v", feature.GetName(), err)
- }
- if _, ok := featureNameToFeature[featureName]; !ok {
- featureNameToFeature[featureName] = make(map[string][]string)
- }
- featureNameToFeature[featureName][stringFeature] = append(
- featureNameToFeature[featureName][stringFeature], id)
- toolchainToFeatures[id] = append(toolchainToFeatures[id], featureName)
- }
- }
- return toolchainToFeatures, featureNameToFeature, nil
-}
-
-func getFeaturesDeclaration(crosstool *crosstoolpb.CrosstoolRelease,
- cToolchainIdentifiers map[string]CToolchainIdentifier,
- featureNameToFeature map[string]map[string][]string, depth int) string {
- var res []string
- for featureName, featureStringToID := range featureNameToFeature {
- res = append(res,
- getAssignmentStatement(
- featureName,
- featureStringToID,
- crosstool,
- cToolchainIdentifiers,
- depth,
- /* isPlainString= */ false,
- /* shouldFail= */ false))
- }
- return strings.Join(res, "")
-}
-
-func getFeaturesStmt(cToolchainIdentifiers map[string]CToolchainIdentifier,
- toolchainToFeatures map[string][]string, depth int) string {
- var res []string
- arrToIdentifier := make(map[string][]string)
- for id, features := range toolchainToFeatures {
- arrayString := strings.Join(features, "{arrayFieldDelimiter}")
- arrToIdentifier[arrayString] = append(arrToIdentifier[arrayString], id)
- }
- res = append(res,
- getStringArrStatement(
- "features",
- arrToIdentifier,
- cToolchainIdentifiers,
- depth,
- /* isPlainString= */ false))
- return strings.Join(res, "\n")
-}
-
-func getActions(crosstool *crosstoolpb.CrosstoolRelease) (
- map[string][]string, map[string]map[string][]string, error) {
- actionNameToAction := make(map[string]map[string][]string)
- toolchainToActions := make(map[string][]string)
- for _, toolchain := range crosstool.GetToolchain() {
- id := toolchain.GetToolchainIdentifier()
- var actionName string
- if len(toolchain.GetActionConfig()) == 0 {
- toolchainToActions[id] = []string{}
- }
- for _, action := range toolchain.GetActionConfig() {
- if aName, ok := actionNames[action.GetActionName()]; ok {
- actionName = aName
- } else {
- actionName = strings.ToLower(action.GetActionName())
- actionName = strings.Replace(actionName, "+", "p", -1)
- actionName = strings.Replace(actionName, ".", "_", -1)
- actionName = strings.Replace(actionName, "-", "_", -1)
- }
- stringAction, err := parseAction(action, 1)
- if err != nil {
- return nil, nil, fmt.Errorf(
- "Error in action_config '%s': %v", action.GetActionName(), err)
- }
- if _, ok := actionNameToAction[actionName]; !ok {
- actionNameToAction[actionName] = make(map[string][]string)
- }
- actionNameToAction[actionName][stringAction] = append(
- actionNameToAction[actionName][stringAction], id)
- toolchainToActions[id] = append(
- toolchainToActions[id],
- strings.TrimPrefix(strings.ToLower(actionName), "action_names.")+"_action")
- }
- }
- return toolchainToActions, actionNameToAction, nil
-}
-
-func getActionConfigsDeclaration(
- crosstool *crosstoolpb.CrosstoolRelease,
- cToolchainIdentifiers map[string]CToolchainIdentifier,
- actionNameToAction map[string]map[string][]string, depth int) string {
- var res []string
- for actionName, actionStringToID := range actionNameToAction {
- variableName := strings.TrimPrefix(strings.ToLower(actionName), "action_names.") + "_action"
- res = append(res,
- getAssignmentStatement(
- variableName,
- actionStringToID,
- crosstool,
- cToolchainIdentifiers,
- depth,
- /* isPlainString= */ false,
- /* shouldFail= */ false))
- }
- return strings.Join(res, "")
-}
-
-func getActionConfigsStmt(
- cToolchainIdentifiers map[string]CToolchainIdentifier,
- toolchainToActions map[string][]string, depth int) string {
- var res []string
- arrToIdentifier := make(map[string][]string)
- for id, actions := range toolchainToActions {
- var arrayString string
- arrayString = strings.Join(actions, "{arrayFieldDelimiter}")
- arrToIdentifier[arrayString] = append(arrToIdentifier[arrayString], id)
- }
- res = append(res,
- getStringArrStatement(
- "action_configs",
- arrToIdentifier,
- cToolchainIdentifiers,
- depth,
- /* isPlainString= */ false))
- return strings.Join(res, "\n")
-}
-
-func parseAction(action *crosstoolpb.CToolchain_ActionConfig, depth int) (string, error) {
- actionName := action.GetActionName()
- aName := ""
- if val, ok := actionNames[actionName]; ok {
- aName = val
- } else {
- aName = "\"" + action.GetActionName() + "\""
- }
- name := fmt.Sprintf("action_name = %s", aName)
- fields := []string{name}
- if action.GetEnabled() {
- fields = append(fields, "enabled = True")
- }
- if len(action.GetFlagSet()) != 0 {
- flagSets, err := parseFlagSets(action.GetFlagSet(), depth+1)
- if err != nil {
- return "", err
- }
- fields = append(fields, "flag_sets = "+flagSets)
- }
- if len(action.GetImplies()) != 0 {
- implies := "implies = " +
- makeStringArr(action.GetImplies(), depth+1 /* isPlainString= */, true)
- fields = append(fields, implies)
- }
- if len(action.GetTool()) != 0 {
- tools := "tools = " + parseTools(action.GetTool(), depth+1)
- fields = append(fields, tools)
- }
- return createObject("action_config", fields, depth), nil
-}
-
-func getStringArrStatement(attr string, arrValToIds map[string][]string,
- cToolchainIdentifiers map[string]CToolchainIdentifier, depth int, plainString bool) string {
- var b bytes.Buffer
- if len(arrValToIds) == 0 {
- b.WriteString(fmt.Sprintf("%s%s = []\n", getTabs(depth), attr))
- } else if len(arrValToIds) == 1 {
- for value := range arrValToIds {
- var arr []string
- if value == "" {
- arr = []string{}
- } else if value == "None" {
- b.WriteString(fmt.Sprintf("%s%s = None\n", getTabs(depth), attr))
- break
- } else {
- arr = strings.Split(value, "{arrayFieldDelimiter}")
- }
- b.WriteString(
- fmt.Sprintf(
- "%s%s = %s\n",
- getTabs(depth),
- attr,
- makeStringArr(arr, depth+1, plainString)))
- break
- }
- } else {
- first := true
- var keys []string
- for k := range arrValToIds {
- keys = append(keys, k)
- }
- sort.Strings(keys)
- for _, value := range keys {
- ids := arrValToIds[value]
- branch := "elif"
- if first {
- branch = "if"
- }
- first = false
- var arr []string
- if value == "" {
- arr = []string{}
- } else if value == "None" {
- b.WriteString(
- getIfStatement(
- branch, ids, attr, "None", cToolchainIdentifiers,
- depth /* isPlainString= */, true))
- continue
- } else {
- arr = strings.Split(value, "{arrayFieldDelimiter}")
- }
- b.WriteString(
- getIfStatement(branch, ids, attr,
- makeStringArr(arr, depth+1, plainString),
- cToolchainIdentifiers, depth /* isPlainString= */, false))
- }
- b.WriteString(fmt.Sprintf("%selse:\n%sfail(\"Unreachable\")\n", getTabs(depth), getTabs(depth+1)))
- }
- b.WriteString("\n")
- return b.String()
-}
-
-func getStringArr(crosstool *crosstoolpb.CrosstoolRelease,
- cToolchainIdentifiers map[string]CToolchainIdentifier, attr string, depth int) string {
- var res []string
- arrToIdentifier := make(map[string][]string)
- for _, toolchain := range crosstool.GetToolchain() {
- id := toolchain.GetToolchainIdentifier()
- arrayString := strings.Join(getArrField(attr, toolchain), "{arrayFieldDelimiter}")
- arrToIdentifier[arrayString] = append(arrToIdentifier[arrayString], id)
- }
- statement := getStringArrStatement(attr, arrToIdentifier, cToolchainIdentifiers, depth /* isPlainString= */, true)
- res = append(res, statement)
- return strings.Join(res, "\n")
-}
-
-func getArrField(attr string, toolchain *crosstoolpb.CToolchain) []string {
- var arr []string
- if attr == "cxx_builtin_include_directories" {
- arr = toolchain.GetCxxBuiltinIncludeDirectory()
- }
- return arr
-}
-
-func getTabs(depth int) string {
- var res string
- for i := 0; i < depth; i++ {
- res = res + " "
- }
- return res
-}
-
-func createObject(objtype string, fields []string, depth int) string {
- if len(fields) == 0 {
- return objtype + "()"
- }
- singleLine := objtype + "(" + strings.Join(fields, ", ") + ")"
- if len(singleLine) < 60 {
- return singleLine
- }
- return objtype +
- "(\n" +
- getTabs(depth+1) +
- strings.Join(fields, ",\n"+getTabs(depth+1)) +
- ",\n" + getTabs(depth) +
- ")"
-}
-
-func getArtifactNamePatterns(crosstool *crosstoolpb.CrosstoolRelease,
- cToolchainIdentifiers map[string]CToolchainIdentifier, depth int) string {
- var res []string
- artifactToIds := make(map[string][]string)
- for _, toolchain := range crosstool.GetToolchain() {
- artifactNamePatterns := parseArtifactNamePatterns(
- toolchain.GetArtifactNamePattern(),
- depth)
- artifactToIds[artifactNamePatterns] = append(
- artifactToIds[artifactNamePatterns],
- toolchain.GetToolchainIdentifier())
- }
- res = append(res,
- getAssignmentStatement(
- "artifact_name_patterns",
- artifactToIds,
- crosstool,
- cToolchainIdentifiers,
- depth,
- /* isPlainString= */ false,
- /* shouldFail= */ true))
- return strings.Join(res, "\n")
-}
-
-func parseArtifactNamePatterns(
- artifactNamePatterns []*crosstoolpb.CToolchain_ArtifactNamePattern, depth int) string {
- var res []string
- for _, pattern := range artifactNamePatterns {
- res = append(res, parseArtifactNamePattern(pattern, depth+1))
- }
- return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseArtifactNamePattern(
- artifactNamePattern *crosstoolpb.CToolchain_ArtifactNamePattern, depth int) string {
- categoryName := fmt.Sprintf("category_name = \"%s\"", artifactNamePattern.GetCategoryName())
- prefix := fmt.Sprintf("prefix = \"%s\"", artifactNamePattern.GetPrefix())
- extension := fmt.Sprintf("extension = \"%s\"", artifactNamePattern.GetExtension())
- fields := []string{categoryName, prefix, extension}
- return createObject("artifact_name_pattern", fields, depth)
-}
-
-func parseFeature(feature *crosstoolpb.CToolchain_Feature, depth int) (string, error) {
- name := fmt.Sprintf("name = \"%s\"", feature.GetName())
-
- fields := []string{name}
- if feature.GetEnabled() {
- fields = append(fields, "enabled = True")
- }
-
- if len(feature.GetFlagSet()) > 0 {
- flagSets, err := parseFlagSets(feature.GetFlagSet(), depth+1)
- if err != nil {
- return "", err
- }
- fields = append(fields, "flag_sets = "+flagSets)
- }
- if len(feature.GetEnvSet()) > 0 {
- envSets := "env_sets = " + parseEnvSets(feature.GetEnvSet(), depth+1)
- fields = append(fields, envSets)
- }
- if len(feature.GetRequires()) > 0 {
- requires := "requires = " + parseFeatureSets(feature.GetRequires(), depth+1)
- fields = append(fields, requires)
- }
- if len(feature.GetImplies()) > 0 {
- implies := "implies = " +
- makeStringArr(feature.GetImplies(), depth+1 /* isPlainString= */, true)
- fields = append(fields, implies)
- }
- if len(feature.GetProvides()) > 0 {
- provides := "provides = " +
- makeStringArr(feature.GetProvides(), depth+1 /* isPlainString= */, true)
- fields = append(fields, provides)
- }
- return createObject("feature", fields, depth), nil
-}
-
-func parseFlagSets(flagSets []*crosstoolpb.CToolchain_FlagSet, depth int) (string, error) {
- var res []string
- for _, flagSet := range flagSets {
- parsedFlagset, err := parseFlagSet(flagSet, depth+1)
- if err != nil {
- return "", err
- }
- res = append(res, parsedFlagset)
- }
- return makeStringArr(res, depth /* isPlainString= */, false), nil
-}
-
-func parseFlagSet(flagSet *crosstoolpb.CToolchain_FlagSet, depth int) (string, error) {
- var fields []string
- if len(flagSet.GetAction()) > 0 {
- actionArr := processActions(flagSet.GetAction(), depth)
- actions := "actions = " + strings.Join(actionArr, " +\n"+getTabs(depth+2))
- fields = append(fields, actions)
- }
- if len(flagSet.GetFlagGroup()) > 0 {
- flagGroups, err := parseFlagGroups(flagSet.GetFlagGroup(), depth+1)
- if err != nil {
- return "", err
- }
- fields = append(fields, "flag_groups = "+flagGroups)
- }
- if len(flagSet.GetWithFeature()) > 0 {
- withFeatures := "with_features = " +
- parseWithFeatureSets(flagSet.GetWithFeature(), depth+1)
- fields = append(fields, withFeatures)
- }
- return createObject("flag_set", fields, depth), nil
-}
-
-func parseFlagGroups(flagGroups []*crosstoolpb.CToolchain_FlagGroup, depth int) (string, error) {
- var res []string
- for _, flagGroup := range flagGroups {
- flagGroupString, err := parseFlagGroup(flagGroup, depth+1)
- if err != nil {
- return "", err
- }
- res = append(res, flagGroupString)
- }
- return makeStringArr(res, depth /* isPlainString= */, false), nil
-}
-
-func parseFlagGroup(flagGroup *crosstoolpb.CToolchain_FlagGroup, depth int) (string, error) {
- var res []string
- if len(flagGroup.GetFlag()) != 0 {
- res = append(res, "flags = "+makeStringArr(flagGroup.GetFlag(), depth+1, true))
- }
- if flagGroup.GetIterateOver() != "" {
- res = append(res, fmt.Sprintf("iterate_over = \"%s\"", flagGroup.GetIterateOver()))
- }
- if len(flagGroup.GetFlagGroup()) != 0 {
- flagGroupString, err := parseFlagGroups(flagGroup.GetFlagGroup(), depth+1)
- if err != nil {
- return "", err
- }
- res = append(res, "flag_groups = "+flagGroupString)
- }
- if len(flagGroup.GetExpandIfAllAvailable()) > 1 {
- return "", errors.New("Flag group must not have more than one 'expand_if_all_available' field")
- }
- if len(flagGroup.GetExpandIfAllAvailable()) != 0 {
- res = append(res,
- fmt.Sprintf(
- "expand_if_available = \"%s\"",
- flagGroup.GetExpandIfAllAvailable()[0]))
- }
- if len(flagGroup.GetExpandIfNoneAvailable()) > 1 {
- return "", errors.New("Flag group must not have more than one 'expand_if_none_available' field")
- }
- if len(flagGroup.GetExpandIfNoneAvailable()) != 0 {
- res = append(res,
- fmt.Sprintf(
- "expand_if_not_available = \"%s\"",
- flagGroup.GetExpandIfNoneAvailable()[0]))
- }
- if flagGroup.GetExpandIfTrue() != "" {
- res = append(res, fmt.Sprintf("expand_if_true = \"%s\"",
- flagGroup.GetExpandIfTrue()))
- }
- if flagGroup.GetExpandIfFalse() != "" {
- res = append(res, fmt.Sprintf("expand_if_false = \"%s\"",
- flagGroup.GetExpandIfFalse()))
- }
- if flagGroup.GetExpandIfEqual() != nil {
- res = append(res,
- "expand_if_equal = "+parseVariableWithValue(
- flagGroup.GetExpandIfEqual(), depth+1))
- }
- return createObject("flag_group", res, depth), nil
-}
-
-func parseVariableWithValue(variable *crosstoolpb.CToolchain_VariableWithValue, depth int) string {
- variableName := fmt.Sprintf("name = \"%s\"", variable.GetVariable())
- value := fmt.Sprintf("value = \"%s\"", variable.GetValue())
- return createObject("variable_with_value", []string{variableName, value}, depth)
-}
-
-func getToolPaths(crosstool *crosstoolpb.CrosstoolRelease,
- cToolchainIdentifiers map[string]CToolchainIdentifier, depth int) string {
- var res []string
- toolPathsToIds := make(map[string][]string)
- for _, toolchain := range crosstool.GetToolchain() {
- toolPaths := parseToolPaths(toolchain.GetToolPath(), depth)
- toolPathsToIds[toolPaths] = append(
- toolPathsToIds[toolPaths],
- toolchain.GetToolchainIdentifier())
- }
- res = append(res,
- getAssignmentStatement(
- "tool_paths",
- toolPathsToIds,
- crosstool,
- cToolchainIdentifiers,
- depth,
- /* isPlainString= */ false,
- /* shouldFail= */ true))
- return strings.Join(res, "\n")
-}
-
-func parseToolPaths(toolPaths []*crosstoolpb.ToolPath, depth int) string {
- var res []string
- for _, toolPath := range toolPaths {
- res = append(res, parseToolPath(toolPath, depth+1))
- }
- return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseToolPath(toolPath *crosstoolpb.ToolPath, depth int) string {
- name := fmt.Sprintf("name = \"%s\"", toolPath.GetName())
- path := toolPath.GetPath()
- if path == "" {
- path = "NOT_USED"
- }
- path = fmt.Sprintf("path = \"%s\"", path)
- return createObject("tool_path", []string{name, path}, depth)
-}
-
-func getMakeVariables(crosstool *crosstoolpb.CrosstoolRelease,
- cToolchainIdentifiers map[string]CToolchainIdentifier, depth int) string {
- var res []string
- makeVariablesToIds := make(map[string][]string)
- for _, toolchain := range crosstool.GetToolchain() {
- makeVariables := parseMakeVariables(toolchain.GetMakeVariable(), depth)
- makeVariablesToIds[makeVariables] = append(
- makeVariablesToIds[makeVariables],
- toolchain.GetToolchainIdentifier())
- }
- res = append(res,
- getAssignmentStatement(
- "make_variables",
- makeVariablesToIds,
- crosstool,
- cToolchainIdentifiers,
- depth,
- /* isPlainString= */ false,
- /* shouldFail= */ true))
- return strings.Join(res, "\n")
-}
-
-func parseMakeVariables(makeVariables []*crosstoolpb.MakeVariable, depth int) string {
- var res []string
- for _, makeVariable := range makeVariables {
- res = append(res, parseMakeVariable(makeVariable, depth+1))
- }
- return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseMakeVariable(makeVariable *crosstoolpb.MakeVariable, depth int) string {
- name := fmt.Sprintf("name = \"%s\"", makeVariable.GetName())
- value := fmt.Sprintf("value = \"%s\"", makeVariable.GetValue())
- return createObject("make_variable", []string{name, value}, depth)
-}
-
-func parseTools(tools []*crosstoolpb.CToolchain_Tool, depth int) string {
- var res []string
- for _, tool := range tools {
- res = append(res, parseTool(tool, depth+1))
- }
- return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseTool(tool *crosstoolpb.CToolchain_Tool, depth int) string {
- toolPath := "path = \"NOT_USED\""
- if tool.GetToolPath() != "" {
- toolPath = fmt.Sprintf("path = \"%s\"", tool.GetToolPath())
- }
- fields := []string{toolPath}
- if len(tool.GetWithFeature()) != 0 {
- withFeatures := "with_features = " + parseWithFeatureSets(tool.GetWithFeature(), depth+1)
- fields = append(fields, withFeatures)
- }
- if len(tool.GetExecutionRequirement()) != 0 {
- executionRequirements := "execution_requirements = " +
- makeStringArr(tool.GetExecutionRequirement(), depth+1 /* isPlainString= */, true)
- fields = append(fields, executionRequirements)
- }
- return createObject("tool", fields, depth)
-}
-
-func parseEnvEntries(envEntries []*crosstoolpb.CToolchain_EnvEntry, depth int) string {
- var res []string
- for _, envEntry := range envEntries {
- res = append(res, parseEnvEntry(envEntry, depth+1))
- }
- return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseEnvEntry(envEntry *crosstoolpb.CToolchain_EnvEntry, depth int) string {
- key := fmt.Sprintf("key = \"%s\"", envEntry.GetKey())
- value := fmt.Sprintf("value = \"%s\"", envEntry.GetValue())
- return createObject("env_entry", []string{key, value}, depth)
-}
-
-func parseWithFeatureSets(withFeatureSets []*crosstoolpb.CToolchain_WithFeatureSet,
- depth int) string {
- var res []string
- for _, withFeature := range withFeatureSets {
- res = append(res, parseWithFeatureSet(withFeature, depth+1))
- }
- return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseWithFeatureSet(withFeature *crosstoolpb.CToolchain_WithFeatureSet,
- depth int) string {
- var fields []string
- if len(withFeature.GetFeature()) != 0 {
- features := "features = " +
- makeStringArr(withFeature.GetFeature(), depth+1 /* isPlainString= */, true)
- fields = append(fields, features)
- }
- if len(withFeature.GetNotFeature()) != 0 {
- notFeatures := "not_features = " +
- makeStringArr(withFeature.GetNotFeature(), depth+1 /* isPlainString= */, true)
- fields = append(fields, notFeatures)
- }
- return createObject("with_feature_set", fields, depth)
-}
-
-func parseEnvSets(envSets []*crosstoolpb.CToolchain_EnvSet, depth int) string {
- var res []string
- for _, envSet := range envSets {
- envSetString := parseEnvSet(envSet, depth+1)
- res = append(res, envSetString)
- }
- return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseEnvSet(envSet *crosstoolpb.CToolchain_EnvSet, depth int) string {
- actionsStatement := processActions(envSet.GetAction(), depth)
- actions := "actions = " + strings.Join(actionsStatement, " +\n"+getTabs(depth+2))
- fields := []string{actions}
- if len(envSet.GetEnvEntry()) != 0 {
- envEntries := "env_entries = " + parseEnvEntries(envSet.GetEnvEntry(), depth+1)
- fields = append(fields, envEntries)
- }
- if len(envSet.GetWithFeature()) != 0 {
- withFeatures := "with_features = " + parseWithFeatureSets(envSet.GetWithFeature(), depth+1)
- fields = append(fields, withFeatures)
- }
- return createObject("env_set", fields, depth)
-}
-
-func parseFeatureSets(featureSets []*crosstoolpb.CToolchain_FeatureSet, depth int) string {
- var res []string
- for _, featureSet := range featureSets {
- res = append(res, parseFeatureSet(featureSet, depth+1))
- }
- return makeStringArr(res, depth /* isPlainString= */, false)
-}
-
-func parseFeatureSet(featureSet *crosstoolpb.CToolchain_FeatureSet, depth int) string {
- features := "features = " +
- makeStringArr(featureSet.GetFeature(), depth+1 /* isPlainString= */, true)
- return createObject("feature_set", []string{features}, depth)
-}
-
-// Takes in a list of string elements and returns a string that represents
-// an array :
-// [
-// "element1",
-// "element2",
-// ]
-// The isPlainString argument tells us whether the input elements should be
-// treated as string (eg, flags), or not (eg, variable names)
-func makeStringArr(arr []string, depth int, isPlainString bool) string {
- if len(arr) == 0 {
- return "[]"
- }
- var escapedArr []string
- for _, el := range arr {
- if isPlainString {
- escapedArr = append(escapedArr, strings.Replace(el, "\"", "\\\"", -1))
- } else {
- escapedArr = append(escapedArr, el)
- }
- }
- addQuote := ""
- if isPlainString {
- addQuote = "\""
- }
- singleLine := "[" + addQuote + strings.Join(escapedArr, addQuote+", "+addQuote) + addQuote + "]"
- if len(singleLine) < 60 {
- return singleLine
- }
- return "[\n" +
- getTabs(depth+1) +
- addQuote +
- strings.Join(escapedArr, addQuote+",\n"+getTabs(depth+1)+addQuote) +
- addQuote +
- ",\n" +
- getTabs(depth) +
- "]"
-}
-
-// Returns a string that represents a value assignment
-// (eg if ctx.attr.cpu == "linux":
-// compiler = "llvm"
-// elif ctx.attr.cpu == "windows":
-// compiler = "mingw"
-// else:
-// fail("Unreachable")
-func getAssignmentStatement(field string, valToIds map[string][]string,
- crosstool *crosstoolpb.CrosstoolRelease,
- toCToolchainIdentifier map[string]CToolchainIdentifier,
- depth int, isPlainString, shouldFail bool) string {
- var b bytes.Buffer
- if len(valToIds) <= 1 {
- // if there is only one possible value for this field, we don't need if statements
- for val := range valToIds {
- if val != "None" && isPlainString {
- val = "\"" + val + "\""
- }
- b.WriteString(fmt.Sprintf("%s%s = %s\n", getTabs(depth), field, val))
- break
- }
- } else {
- first := true
- var keys []string
- for k := range valToIds {
- keys = append(keys, k)
- }
- sort.Strings(keys)
- for _, value := range keys {
- ids := valToIds[value]
- branch := "elif"
- if first {
- branch = "if"
- }
- b.WriteString(
- getIfStatement(branch, ids, field, value,
- toCToolchainIdentifier, depth, isPlainString))
- first = false
- }
- if shouldFail {
- b.WriteString(
- fmt.Sprintf(
- "%selse:\n%sfail(\"Unreachable\")\n",
- getTabs(depth), getTabs(depth+1)))
- } else {
- b.WriteString(
- fmt.Sprintf(
- "%selse:\n%s%s = None\n",
- getTabs(depth), getTabs(depth+1), field))
- }
- }
- b.WriteString("\n")
- return b.String()
-}
-
-func getCPUToCompilers(identifiers []CToolchainIdentifier) map[string][]string {
- res := make(map[string][]string)
- for _, identifier := range identifiers {
- if identifier.compiler != "" {
- res[identifier.cpu] = append(res[identifier.cpu], identifier.compiler)
- }
- }
- return res
-}
-
-func getIfStatement(ifOrElseIf string, identifiers []string, field, val string,
- toCToolchainIdentifier map[string]CToolchainIdentifier, depth int,
- isPlainString bool) string {
- usedStmts := make(map[string]bool)
- if val != "None" && isPlainString {
- val = "\"" + val + "\""
- }
- var cToolchainIdentifiers []CToolchainIdentifier
- for _, value := range toCToolchainIdentifier {
- cToolchainIdentifiers = append(cToolchainIdentifiers, value)
- }
- cpuToCompilers := getCPUToCompilers(cToolchainIdentifiers)
- countCpus := make(map[string]int)
- var conditions []string
- for _, id := range identifiers {
- identifier := toCToolchainIdentifier[id]
- stmt := getConditionStatementForCToolchainIdentifier(identifier)
- if _, ok := usedStmts[stmt]; !ok {
- conditions = append(conditions, stmt)
- usedStmts[stmt] = true
- if identifier.compiler != "" {
- countCpus[identifier.cpu]++
- }
- }
- }
-
- var compressedConditions []string
- usedStmtsOptimized := make(map[string]bool)
- for _, id := range identifiers {
- identifier := toCToolchainIdentifier[id]
- var stmt string
- if _, ok := countCpus[identifier.cpu]; ok {
- if countCpus[identifier.cpu] == len(cpuToCompilers[identifier.cpu]) {
- stmt = getConditionStatementForCToolchainIdentifier(
- CToolchainIdentifier{cpu: identifier.cpu, compiler: ""})
- } else {
- stmt = getConditionStatementForCToolchainIdentifier(identifier)
- }
- } else {
- stmt = getConditionStatementForCToolchainIdentifier(identifier)
- }
- if _, ok := usedStmtsOptimized[stmt]; !ok {
- compressedConditions = append(compressedConditions, stmt)
- usedStmtsOptimized[stmt] = true
- }
- }
-
- sort.Strings(compressedConditions)
- val = strings.Join(strings.Split(val, "\n"+getTabs(depth)), "\n"+getTabs(depth+1))
- return fmt.Sprintf(`%s%s %s:
-%s%s = %s
-`, getTabs(depth),
- ifOrElseIf,
- "("+strings.Join(compressedConditions, "\n"+getTabs(depth+1)+"or ")+")",
- getTabs(depth+1),
- field,
- val)
-}
-
-func getToolchainIdentifiers(crosstool *crosstoolpb.CrosstoolRelease) []string {
- var res []string
- for _, toolchain := range crosstool.GetToolchain() {
- res = append(res, toolchain.GetToolchainIdentifier())
- }
- return res
-}
-
-func getHostSystemNames(crosstool *crosstoolpb.CrosstoolRelease) []string {
- var res []string
- for _, toolchain := range crosstool.GetToolchain() {
- res = append(res, toolchain.GetHostSystemName())
- }
- return res
-}
-
-func getTargetSystemNames(crosstool *crosstoolpb.CrosstoolRelease) []string {
- var res []string
- for _, toolchain := range crosstool.GetToolchain() {
- res = append(res, toolchain.GetTargetSystemName())
- }
- return res
-}
-
-func getTargetCpus(crosstool *crosstoolpb.CrosstoolRelease) []string {
- var res []string
- for _, toolchain := range crosstool.GetToolchain() {
- res = append(res, toolchain.GetTargetCpu())
- }
- return res
-}
-
-func getTargetLibcs(crosstool *crosstoolpb.CrosstoolRelease) []string {
- var res []string
- for _, toolchain := range crosstool.GetToolchain() {
- res = append(res, toolchain.GetTargetLibc())
- }
- return res
-}
-
-func getCompilers(crosstool *crosstoolpb.CrosstoolRelease) []string {
- var res []string
- for _, toolchain := range crosstool.GetToolchain() {
- res = append(res, toolchain.GetCompiler())
- }
- return res
-}
-
-func getAbiVersions(crosstool *crosstoolpb.CrosstoolRelease) []string {
- var res []string
- for _, toolchain := range crosstool.GetToolchain() {
- res = append(res, toolchain.GetAbiVersion())
- }
- return res
-}
-
-func getAbiLibcVersions(crosstool *crosstoolpb.CrosstoolRelease) []string {
- var res []string
- for _, toolchain := range crosstool.GetToolchain() {
- res = append(res, toolchain.GetAbiLibcVersion())
- }
- return res
-}
-
-func getCcTargetOss(crosstool *crosstoolpb.CrosstoolRelease) []string {
- var res []string
- for _, toolchain := range crosstool.GetToolchain() {
- targetOS := "None"
- if toolchain.GetCcTargetOs() != "" {
- targetOS = toolchain.GetCcTargetOs()
- }
- res = append(res, targetOS)
- }
- return res
-}
-
-func getBuiltinSysroots(crosstool *crosstoolpb.CrosstoolRelease) []string {
- var res []string
- for _, toolchain := range crosstool.GetToolchain() {
- sysroot := "None"
- if toolchain.GetBuiltinSysroot() != "" {
- sysroot = toolchain.GetBuiltinSysroot()
- }
- res = append(res, sysroot)
- }
- return res
-}
-
-func getMappedStringValuesToIdentifiers(identifiers, fields []string) map[string][]string {
- res := make(map[string][]string)
- for i := range identifiers {
- res[fields[i]] = append(res[fields[i]], identifiers[i])
- }
- return res
-}
-
-func getReturnStatement() string {
- return `
- out = ctx.actions.declare_file(ctx.label.name)
- ctx.actions.write(out, "Fake executable")
- return [
- cc_common.create_cc_toolchain_config_info(
- ctx = ctx,
- features = features,
- action_configs = action_configs,
- artifact_name_patterns = artifact_name_patterns,
- cxx_builtin_include_directories = cxx_builtin_include_directories,
- toolchain_identifier = toolchain_identifier,
- host_system_name = host_system_name,
- target_system_name = target_system_name,
- target_cpu = target_cpu,
- target_libc = target_libc,
- compiler = compiler,
- abi_version = abi_version,
- abi_libc_version = abi_libc_version,
- tool_paths = tool_paths,
- make_variables = make_variables,
- builtin_sysroot = builtin_sysroot,
- cc_target_os = cc_target_os
- ),
- DefaultInfo(
- executable = out,
- ),
- ]
-`
-}
-
-// Transform writes a cc_toolchain_config rule functionally equivalent to the
-// CROSSTOOL file.
-func Transform(crosstool *crosstoolpb.CrosstoolRelease) (string, error) {
- var b bytes.Buffer
-
- cToolchainIdentifiers := toolchainToCToolchainIdentifier(crosstool)
-
- toolchainToFeatures, featureNameToFeature, err := getFeatures(crosstool)
- if err != nil {
- return "", err
- }
-
- toolchainToActions, actionNameToAction, err := getActions(crosstool)
- if err != nil {
- return "", err
- }
-
- header := getCcToolchainConfigHeader()
- if _, err := b.WriteString(header); err != nil {
- return "", err
- }
-
- loadActionsStmt := getLoadActionsStmt()
- if _, err := b.WriteString(loadActionsStmt); err != nil {
- return "", err
- }
-
- implHeader := getImplHeader()
- if _, err := b.WriteString(implHeader); err != nil {
- return "", err
- }
-
- stringFields := []string{
- "toolchain_identifier",
- "host_system_name",
- "target_system_name",
- "target_cpu",
- "target_libc",
- "compiler",
- "abi_version",
- "abi_libc_version",
- "cc_target_os",
- "builtin_sysroot",
- }
-
- for _, stringField := range stringFields {
- stmt := getStringStatement(crosstool, cToolchainIdentifiers, stringField, 1)
- if _, err := b.WriteString(stmt); err != nil {
- return "", err
- }
- }
-
- listsOfActions := []string{
- "all_compile_actions",
- "all_cpp_compile_actions",
- "preprocessor_compile_actions",
- "codegen_compile_actions",
- "all_link_actions",
- }
-
- for _, listOfActions := range listsOfActions {
- actions := getListOfActions(listOfActions, 1)
- if _, err := b.WriteString(actions); err != nil {
- return "", err
- }
- }
-
- actionConfigDeclaration := getActionConfigsDeclaration(
- crosstool, cToolchainIdentifiers, actionNameToAction, 1)
- if _, err := b.WriteString(actionConfigDeclaration); err != nil {
- return "", err
- }
-
- actionConfigStatement := getActionConfigsStmt(
- cToolchainIdentifiers, toolchainToActions, 1)
- if _, err := b.WriteString(actionConfigStatement); err != nil {
- return "", err
- }
-
- featureDeclaration := getFeaturesDeclaration(
- crosstool, cToolchainIdentifiers, featureNameToFeature, 1)
- if _, err := b.WriteString(featureDeclaration); err != nil {
- return "", err
- }
-
- featuresStatement := getFeaturesStmt(
- cToolchainIdentifiers, toolchainToFeatures, 1)
- if _, err := b.WriteString(featuresStatement); err != nil {
- return "", err
- }
-
- includeDirectories := getStringArr(
- crosstool, cToolchainIdentifiers, "cxx_builtin_include_directories", 1)
- if _, err := b.WriteString(includeDirectories); err != nil {
- return "", err
- }
-
- artifactNamePatterns := getArtifactNamePatterns(
- crosstool, cToolchainIdentifiers, 1)
- if _, err := b.WriteString(artifactNamePatterns); err != nil {
- return "", err
- }
-
- makeVariables := getMakeVariables(crosstool, cToolchainIdentifiers, 1)
- if _, err := b.WriteString(makeVariables); err != nil {
- return "", err
- }
-
- toolPaths := getToolPaths(crosstool, cToolchainIdentifiers, 1)
- if _, err := b.WriteString(toolPaths); err != nil {
- return "", err
- }
-
- if _, err := b.WriteString(getReturnStatement()); err != nil {
- return "", err
- }
-
- rule := getRule(cToolchainIdentifiers, getCompilers(crosstool))
- if _, err := b.WriteString(rule); err != nil {
- return "", err
- }
-
- return b.String(), nil
-}
diff --git a/tools/migration/crosstool_to_starlark_lib_test.go b/tools/migration/crosstool_to_starlark_lib_test.go
deleted file mode 100644
index 63d9736..0000000
--- a/tools/migration/crosstool_to_starlark_lib_test.go
+++ /dev/null
@@ -1,1756 +0,0 @@
-package crosstooltostarlarklib
-
-import (
- "fmt"
- "strings"
- "testing"
-
- "log"
- crosstoolpb "third_party/com/github/bazelbuild/bazel/src/main/protobuf/crosstool_config_go_proto"
- "github.com/golang/protobuf/proto"
-)
-
-func makeCToolchainString(lines []string) string {
- return fmt.Sprintf(`toolchain {
- %s
-}`, strings.Join(lines, "\n "))
-}
-
-func makeCrosstool(CToolchains []string) *crosstoolpb.CrosstoolRelease {
- crosstool := &crosstoolpb.CrosstoolRelease{}
- requiredFields := []string{
- "major_version: '0'",
- "minor_version: '0'",
- "default_target_cpu: 'cpu'",
- }
- CToolchains = append(CToolchains, requiredFields...)
- if err := proto.UnmarshalText(strings.Join(CToolchains, "\n"), crosstool); err != nil {
- log.Fatalf("Failed to parse CROSSTOOL:", err)
- }
- return crosstool
-}
-
-func getSimpleCToolchain(id string) string {
- lines := []string{
- "toolchain_identifier: 'id-" + id + "'",
- "host_system_name: 'host-" + id + "'",
- "target_system_name: 'target-" + id + "'",
- "target_cpu: 'cpu-" + id + "'",
- "compiler: 'compiler-" + id + "'",
- "target_libc: 'libc-" + id + "'",
- "abi_version: 'version-" + id + "'",
- "abi_libc_version: 'libc_version-" + id + "'",
- }
- return makeCToolchainString(lines)
-}
-
-func getCToolchain(id, cpu, compiler string, extraLines []string) string {
- lines := []string{
- "toolchain_identifier: '" + id + "'",
- "host_system_name: 'host'",
- "target_system_name: 'target'",
- "target_cpu: '" + cpu + "'",
- "compiler: '" + compiler + "'",
- "target_libc: 'libc'",
- "abi_version: 'version'",
- "abi_libc_version: 'libc_version'",
- }
- lines = append(lines, extraLines...)
- return makeCToolchainString(lines)
-}
-
-func TestStringFieldsConditionStatement(t *testing.T) {
- toolchain1 := getSimpleCToolchain("1")
- toolchain2 := getSimpleCToolchain("2")
- toolchains := []string{toolchain1, toolchain2}
- crosstool := makeCrosstool(toolchains)
-
- testCases := []struct {
- field string
- expectedText string
- }{
- {field: "toolchain_identifier",
- expectedText: `
- if (ctx.attr.cpu == "cpu-1"):
- toolchain_identifier = "id-1"
- elif (ctx.attr.cpu == "cpu-2"):
- toolchain_identifier = "id-2"
- else:
- fail("Unreachable")`},
- {field: "host_system_name",
- expectedText: `
- if (ctx.attr.cpu == "cpu-1"):
- host_system_name = "host-1"
- elif (ctx.attr.cpu == "cpu-2"):
- host_system_name = "host-2"
- else:
- fail("Unreachable")`},
- {field: "target_system_name",
- expectedText: `
- if (ctx.attr.cpu == "cpu-1"):
- target_system_name = "target-1"
- elif (ctx.attr.cpu == "cpu-2"):
- target_system_name = "target-2"
- else:
- fail("Unreachable")`},
- {field: "target_cpu",
- expectedText: `
- if (ctx.attr.cpu == "cpu-1"):
- target_cpu = "cpu-1"
- elif (ctx.attr.cpu == "cpu-2"):
- target_cpu = "cpu-2"
- else:
- fail("Unreachable")`},
- {field: "target_libc",
- expectedText: `
- if (ctx.attr.cpu == "cpu-1"):
- target_libc = "libc-1"
- elif (ctx.attr.cpu == "cpu-2"):
- target_libc = "libc-2"
- else:
- fail("Unreachable")`},
- {field: "compiler",
- expectedText: `
- if (ctx.attr.cpu == "cpu-1"):
- compiler = "compiler-1"
- elif (ctx.attr.cpu == "cpu-2"):
- compiler = "compiler-2"
- else:
- fail("Unreachable")`},
- {field: "abi_version",
- expectedText: `
- if (ctx.attr.cpu == "cpu-1"):
- abi_version = "version-1"
- elif (ctx.attr.cpu == "cpu-2"):
- abi_version = "version-2"
- else:
- fail("Unreachable")`},
- {field: "abi_libc_version",
- expectedText: `
- if (ctx.attr.cpu == "cpu-1"):
- abi_libc_version = "libc_version-1"
- elif (ctx.attr.cpu == "cpu-2"):
- abi_libc_version = "libc_version-2"
- else:
- fail("Unreachable")`}}
-
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
-
- failed := false
- for _, tc := range testCases {
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- failed = true
- }
- }
- if failed {
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(toolchains, "\n"), got)
- }
-}
-
-func TestConditionsSameCpu(t *testing.T) {
- toolchainAA := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainAB := getCToolchain("2", "cpuA", "compilerB", []string{})
- toolchains := []string{toolchainAA, toolchainAB}
- crosstool := makeCrosstool(toolchains)
-
- testCases := []struct {
- field string
- expectedText string
- }{
- {field: "toolchain_identifier",
- expectedText: `
- if (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerA"):
- toolchain_identifier = "1"
- elif (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerB"):
- toolchain_identifier = "2"
- else:
- fail("Unreachable")`},
- {field: "host_system_name",
- expectedText: `
- host_system_name = "host"`},
- {field: "target_system_name",
- expectedText: `
- target_system_name = "target"`},
- {field: "target_cpu",
- expectedText: `
- target_cpu = "cpuA"`},
- {field: "target_libc",
- expectedText: `
- target_libc = "libc"`},
- {field: "compiler",
- expectedText: `
- if (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerA"):
- compiler = "compilerA"
- elif (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerB"):
- compiler = "compilerB"
- else:
- fail("Unreachable")`},
- {field: "abi_version",
- expectedText: `
- abi_version = "version"`},
- {field: "abi_libc_version",
- expectedText: `
- abi_libc_version = "libc_version"`}}
-
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
-
- failed := false
- for _, tc := range testCases {
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- failed = true
- }
- }
- if failed {
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(toolchains, "\n"), got)
- }
-}
-
-func TestConditionsSameCompiler(t *testing.T) {
- toolchainAA := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainBA := getCToolchain("2", "cpuB", "compilerA", []string{})
- toolchains := []string{toolchainAA, toolchainBA}
- crosstool := makeCrosstool(toolchains)
-
- testCases := []struct {
- field string
- expectedText string
- }{
- {field: "toolchain_identifier",
- expectedText: `
- if (ctx.attr.cpu == "cpuA"):
- toolchain_identifier = "1"
- elif (ctx.attr.cpu == "cpuB"):
- toolchain_identifier = "2"
- else:
- fail("Unreachable")`},
- {field: "target_cpu",
- expectedText: `
- if (ctx.attr.cpu == "cpuA"):
- target_cpu = "cpuA"
- elif (ctx.attr.cpu == "cpuB"):
- target_cpu = "cpuB"
- else:
- fail("Unreachable")`},
- {field: "compiler",
- expectedText: `
- compiler = "compilerA"`}}
-
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
-
- failed := false
- for _, tc := range testCases {
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- failed = true
- }
- }
- if failed {
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(toolchains, "\n"), got)
- }
-}
-
-func TestNonMandatoryStrings(t *testing.T) {
- toolchainAA := getCToolchain("1", "cpuA", "compilerA", []string{"cc_target_os: 'osA'"})
- toolchainBB := getCToolchain("2", "cpuB", "compilerB", []string{})
- toolchains := []string{toolchainAA, toolchainBB}
- crosstool := makeCrosstool(toolchains)
-
- testCases := []struct {
- field string
- expectedText string
- }{
- {field: "cc_target_os",
- expectedText: `
- if (ctx.attr.cpu == "cpuB"):
- cc_target_os = None
- elif (ctx.attr.cpu == "cpuA"):
- cc_target_os = "osA"
- else:
- fail("Unreachable")`},
- {field: "builtin_sysroot",
- expectedText: `
- builtin_sysroot = None`}}
-
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
-
- failed := false
- for _, tc := range testCases {
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- failed = true
- }
- }
- if failed {
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(toolchains, "\n"), got)
- }
-}
-
-func TestBuiltinIncludeDirectories(t *testing.T) {
- toolchainAA := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainBA := getCToolchain("2", "cpuB", "compilerA", []string{})
- toolchainCA := getCToolchain("3", "cpuC", "compilerA",
- []string{"cxx_builtin_include_directory: 'dirC'"})
- toolchainCB := getCToolchain("4", "cpuC", "compilerB",
- []string{"cxx_builtin_include_directory: 'dirC'",
- "cxx_builtin_include_directory: 'dirB'"})
- toolchainDA := getCToolchain("5", "cpuD", "compilerA",
- []string{"cxx_builtin_include_directory: 'dirC'"})
-
- toolchainsEmpty := []string{toolchainAA, toolchainBA}
-
- toolchainsOneNonempty := []string{toolchainAA, toolchainBA, toolchainCA}
-
- toolchainsSameNonempty := []string{toolchainCA, toolchainDA}
-
- allToolchains := []string{toolchainAA, toolchainBA, toolchainCA, toolchainCB, toolchainDA}
-
- testCases := []struct {
- field string
- toolchains []string
- expectedText string
- }{
- {field: "cxx_builtin_include_directories",
- toolchains: toolchainsEmpty,
- expectedText: `
- cxx_builtin_include_directories = []`},
- {field: "cxx_builtin_include_directories",
- toolchains: toolchainsOneNonempty,
- expectedText: `
- if (ctx.attr.cpu == "cpuA"
- or ctx.attr.cpu == "cpuB"):
- cxx_builtin_include_directories = []
- elif (ctx.attr.cpu == "cpuC"):
- cxx_builtin_include_directories = ["dirC"]
- else:
- fail("Unreachable")`},
- {field: "cxx_builtin_include_directories",
- toolchains: toolchainsSameNonempty,
- expectedText: `
- cxx_builtin_include_directories = ["dirC"]`},
- {field: "cxx_builtin_include_directories",
- toolchains: allToolchains,
- expectedText: `
- if (ctx.attr.cpu == "cpuA"
- or ctx.attr.cpu == "cpuB"):
- cxx_builtin_include_directories = []
- elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
- or ctx.attr.cpu == "cpuD"):
- cxx_builtin_include_directories = ["dirC"]
- elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
- cxx_builtin_include_directories = ["dirC", "dirB"]`}}
-
- for _, tc := range testCases {
- crosstool := makeCrosstool(tc.toolchains)
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(tc.toolchains, "\n"), got)
- }
- }
-}
-
-func TestMakeVariables(t *testing.T) {
- toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
- toolchainA1 := getCToolchain("3", "cpuC", "compilerA",
- []string{"make_variable {name: 'A', value: 'a/b/c'}"})
- toolchainA2 := getCToolchain("4", "cpuC", "compilerB",
- []string{"make_variable {name: 'A', value: 'a/b/c'}"})
- toolchainAB := getCToolchain("5", "cpuC", "compilerC",
- []string{"make_variable {name: 'A', value: 'a/b/c'}",
- "make_variable {name: 'B', value: 'a/b/c'}"})
- toolchainBA := getCToolchain("6", "cpuD", "compilerA",
- []string{"make_variable {name: 'B', value: 'a/b/c'}",
- "make_variable {name: 'A', value: 'a b c'}"})
-
- toolchainsEmpty := []string{toolchainEmpty1, toolchainEmpty2}
-
- toolchainsOneNonempty := []string{toolchainEmpty1, toolchainA1}
-
- toolchainsSameNonempty := []string{toolchainA1, toolchainA2}
-
- toolchainsDifferentOrder := []string{toolchainAB, toolchainBA}
-
- allToolchains := []string{
- toolchainEmpty1,
- toolchainEmpty2,
- toolchainA1,
- toolchainA2,
- toolchainAB,
- toolchainBA,
- }
-
- testCases := []struct {
- field string
- toolchains []string
- expectedText string
- }{
- {field: "make_variables",
- toolchains: toolchainsEmpty,
- expectedText: `
- make_variables = []`},
- {field: "make_variables",
- toolchains: toolchainsOneNonempty,
- expectedText: `
- if (ctx.attr.cpu == "cpuA"):
- make_variables = []
- elif (ctx.attr.cpu == "cpuC"):
- make_variables = [make_variable(name = "A", value = "a/b/c")]
- else:
- fail("Unreachable")`},
- {field: "make_variables",
- toolchains: toolchainsSameNonempty,
- expectedText: `
- make_variables = [make_variable(name = "A", value = "a/b/c")]`},
- {field: "make_variables",
- toolchains: toolchainsDifferentOrder,
- expectedText: `
- if (ctx.attr.cpu == "cpuC"):
- make_variables = [
- make_variable(name = "A", value = "a/b/c"),
- make_variable(name = "B", value = "a/b/c"),
- ]
- elif (ctx.attr.cpu == "cpuD"):
- make_variables = [
- make_variable(name = "B", value = "a/b/c"),
- make_variable(name = "A", value = "a b c"),
- ]
- else:
- fail("Unreachable")`},
- {field: "make_variables",
- toolchains: allToolchains,
- expectedText: `
- if (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerC"):
- make_variables = [
- make_variable(name = "A", value = "a/b/c"),
- make_variable(name = "B", value = "a/b/c"),
- ]
- elif (ctx.attr.cpu == "cpuD"):
- make_variables = [
- make_variable(name = "B", value = "a/b/c"),
- make_variable(name = "A", value = "a b c"),
- ]
- elif (ctx.attr.cpu == "cpuA"
- or ctx.attr.cpu == "cpuB"):
- make_variables = []
- elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
- or ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
- make_variables = [make_variable(name = "A", value = "a/b/c")]
- else:
- fail("Unreachable")`}}
-
- for _, tc := range testCases {
- crosstool := makeCrosstool(tc.toolchains)
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(tc.toolchains, "\n"), got)
- }
- }
-}
-
-func TestToolPaths(t *testing.T) {
- toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
- toolchainA1 := getCToolchain("3", "cpuC", "compilerA",
- []string{"tool_path {name: 'A', path: 'a/b/c'}"})
- toolchainA2 := getCToolchain("4", "cpuC", "compilerB",
- []string{"tool_path {name: 'A', path: 'a/b/c'}"})
- toolchainAB := getCToolchain("5", "cpuC", "compilerC",
- []string{"tool_path {name: 'A', path: 'a/b/c'}",
- "tool_path {name: 'B', path: 'a/b/c'}"})
- toolchainBA := getCToolchain("6", "cpuD", "compilerA",
- []string{"tool_path {name: 'B', path: 'a/b/c'}",
- "tool_path {name: 'A', path: 'a/b/c'}"})
-
- toolchainsEmpty := []string{toolchainEmpty1, toolchainEmpty2}
-
- toolchainsOneNonempty := []string{toolchainEmpty1, toolchainA1}
-
- toolchainsSameNonempty := []string{toolchainA1, toolchainA2}
-
- toolchainsDifferentOrder := []string{toolchainAB, toolchainBA}
-
- allToolchains := []string{
- toolchainEmpty1,
- toolchainEmpty2,
- toolchainA1,
- toolchainA2,
- toolchainAB,
- toolchainBA,
- }
-
- testCases := []struct {
- field string
- toolchains []string
- expectedText string
- }{
- {field: "tool_paths",
- toolchains: toolchainsEmpty,
- expectedText: `
- tool_paths = []`},
- {field: "tool_paths",
- toolchains: toolchainsOneNonempty,
- expectedText: `
- if (ctx.attr.cpu == "cpuA"):
- tool_paths = []
- elif (ctx.attr.cpu == "cpuC"):
- tool_paths = [tool_path(name = "A", path = "a/b/c")]
- else:
- fail("Unreachable")`},
- {field: "tool_paths",
- toolchains: toolchainsSameNonempty,
- expectedText: `
- tool_paths = [tool_path(name = "A", path = "a/b/c")]`},
- {field: "tool_paths",
- toolchains: toolchainsDifferentOrder,
- expectedText: `
- if (ctx.attr.cpu == "cpuC"):
- tool_paths = [
- tool_path(name = "A", path = "a/b/c"),
- tool_path(name = "B", path = "a/b/c"),
- ]
- elif (ctx.attr.cpu == "cpuD"):
- tool_paths = [
- tool_path(name = "B", path = "a/b/c"),
- tool_path(name = "A", path = "a/b/c"),
- ]
- else:
- fail("Unreachable")`},
- {field: "tool_paths",
- toolchains: allToolchains,
- expectedText: `
- if (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerC"):
- tool_paths = [
- tool_path(name = "A", path = "a/b/c"),
- tool_path(name = "B", path = "a/b/c"),
- ]
- elif (ctx.attr.cpu == "cpuD"):
- tool_paths = [
- tool_path(name = "B", path = "a/b/c"),
- tool_path(name = "A", path = "a/b/c"),
- ]
- elif (ctx.attr.cpu == "cpuA"
- or ctx.attr.cpu == "cpuB"):
- tool_paths = []
- elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
- or ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
- tool_paths = [tool_path(name = "A", path = "a/b/c")]
- else:
- fail("Unreachable")`}}
-
- for _, tc := range testCases {
- crosstool := makeCrosstool(tc.toolchains)
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(tc.toolchains, "\n"), got)
- }
- }
-}
-
-func getArtifactNamePattern(lines []string) string {
- return fmt.Sprintf(`artifact_name_pattern {
- %s
-}`, strings.Join(lines, "\n "))
-}
-
-func TestArtifactNamePatterns(t *testing.T) {
- toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
- toolchainA1 := getCToolchain("3", "cpuC", "compilerA",
- []string{
- getArtifactNamePattern([]string{
- "category_name: 'A'",
- "prefix: 'p'",
- "extension: '.exe'"}),
- },
- )
- toolchainA2 := getCToolchain("4", "cpuC", "compilerB",
- []string{
- getArtifactNamePattern([]string{
- "category_name: 'A'",
- "prefix: 'p'",
- "extension: '.exe'"}),
- },
- )
- toolchainAB := getCToolchain("5", "cpuC", "compilerC",
- []string{
- getArtifactNamePattern([]string{
- "category_name: 'A'",
- "prefix: 'p'",
- "extension: '.exe'"}),
- getArtifactNamePattern([]string{
- "category_name: 'B'",
- "prefix: 'p'",
- "extension: '.exe'"}),
- },
- )
- toolchainBA := getCToolchain("6", "cpuD", "compilerA",
- []string{
- getArtifactNamePattern([]string{
- "category_name: 'B'",
- "prefix: 'p'",
- "extension: '.exe'"}),
- getArtifactNamePattern([]string{
- "category_name: 'A'",
- "prefix: 'p'",
- "extension: '.exe'"}),
- },
- )
- toolchainsEmpty := []string{toolchainEmpty1, toolchainEmpty2}
-
- toolchainsOneNonempty := []string{toolchainEmpty1, toolchainA1}
-
- toolchainsSameNonempty := []string{toolchainA1, toolchainA2}
-
- toolchainsDifferentOrder := []string{toolchainAB, toolchainBA}
-
- allToolchains := []string{
- toolchainEmpty1,
- toolchainEmpty2,
- toolchainA1,
- toolchainA2,
- toolchainAB,
- toolchainBA,
- }
-
- testCases := []struct {
- field string
- toolchains []string
- expectedText string
- }{
- {field: "artifact_name_patterns",
- toolchains: toolchainsEmpty,
- expectedText: `
- artifact_name_patterns = []`},
- {field: "artifact_name_patterns",
- toolchains: toolchainsOneNonempty,
- expectedText: `
- if (ctx.attr.cpu == "cpuC"):
- artifact_name_patterns = [
- artifact_name_pattern(
- category_name = "A",
- prefix = "p",
- extension = ".exe",
- ),
- ]
- elif (ctx.attr.cpu == "cpuA"):
- artifact_name_patterns = []
- else:
- fail("Unreachable")`},
- {field: "artifact_name_patterns",
- toolchains: toolchainsSameNonempty,
- expectedText: `
- artifact_name_patterns = [
- artifact_name_pattern(
- category_name = "A",
- prefix = "p",
- extension = ".exe",
- ),
- ]`},
- {field: "artifact_name_patterns",
- toolchains: toolchainsDifferentOrder,
- expectedText: `
- if (ctx.attr.cpu == "cpuC"):
- artifact_name_patterns = [
- artifact_name_pattern(
- category_name = "A",
- prefix = "p",
- extension = ".exe",
- ),
- artifact_name_pattern(
- category_name = "B",
- prefix = "p",
- extension = ".exe",
- ),
- ]
- elif (ctx.attr.cpu == "cpuD"):
- artifact_name_patterns = [
- artifact_name_pattern(
- category_name = "B",
- prefix = "p",
- extension = ".exe",
- ),
- artifact_name_pattern(
- category_name = "A",
- prefix = "p",
- extension = ".exe",
- ),
- ]
- else:
- fail("Unreachable")`},
- {field: "artifact_name_patterns",
- toolchains: allToolchains,
- expectedText: `
- if (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerC"):
- artifact_name_patterns = [
- artifact_name_pattern(
- category_name = "A",
- prefix = "p",
- extension = ".exe",
- ),
- artifact_name_pattern(
- category_name = "B",
- prefix = "p",
- extension = ".exe",
- ),
- ]
- elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
- or ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
- artifact_name_patterns = [
- artifact_name_pattern(
- category_name = "A",
- prefix = "p",
- extension = ".exe",
- ),
- ]
- elif (ctx.attr.cpu == "cpuD"):
- artifact_name_patterns = [
- artifact_name_pattern(
- category_name = "B",
- prefix = "p",
- extension = ".exe",
- ),
- artifact_name_pattern(
- category_name = "A",
- prefix = "p",
- extension = ".exe",
- ),
- ]
- elif (ctx.attr.cpu == "cpuA"
- or ctx.attr.cpu == "cpuB"):
- artifact_name_patterns = []
- else:
- fail("Unreachable")`}}
-
- for _, tc := range testCases {
- crosstool := makeCrosstool(tc.toolchains)
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(tc.toolchains, "\n"), got)
- }
- }
-}
-
-func getFeature(lines []string) string {
- return fmt.Sprintf(`feature {
- %s
-}`, strings.Join(lines, "\n "))
-}
-
-func TestFeatureListAssignment(t *testing.T) {
- toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
- toolchainA1 := getCToolchain("3", "cpuC", "compilerA",
- []string{getFeature([]string{"name: 'A'"})},
- )
- toolchainA2 := getCToolchain("4", "cpuC", "compilerB",
- []string{getFeature([]string{"name: 'A'"})},
- )
- toolchainAB := getCToolchain("5", "cpuC", "compilerC",
- []string{
- getFeature([]string{"name: 'A'"}),
- getFeature([]string{"name: 'B'"}),
- },
- )
- toolchainBA := getCToolchain("6", "cpuD", "compilerA",
- []string{
- getFeature([]string{"name: 'B'"}),
- getFeature([]string{"name: 'A'"}),
- },
- )
- toolchainsEmpty := []string{toolchainEmpty1, toolchainEmpty2}
-
- toolchainsOneNonempty := []string{toolchainEmpty1, toolchainA1}
-
- toolchainsSameNonempty := []string{toolchainA1, toolchainA2}
-
- toolchainsDifferentOrder := []string{toolchainAB, toolchainBA}
-
- allToolchains := []string{
- toolchainEmpty1,
- toolchainEmpty2,
- toolchainA1,
- toolchainA2,
- toolchainAB,
- toolchainBA,
- }
-
- testCases := []struct {
- field string
- toolchains []string
- expectedText string
- }{
- {field: "features",
- toolchains: toolchainsEmpty,
- expectedText: `
- features = []`},
- {field: "features",
- toolchains: toolchainsOneNonempty,
- expectedText: `
- if (ctx.attr.cpu == "cpuA"):
- features = []
- elif (ctx.attr.cpu == "cpuC"):
- features = [a_feature]
- else:
- fail("Unreachable")`},
- {field: "features",
- toolchains: toolchainsSameNonempty,
- expectedText: `
- features = [a_feature]`},
- {field: "features",
- toolchains: toolchainsDifferentOrder,
- expectedText: `
- if (ctx.attr.cpu == "cpuC"):
- features = [a_feature, b_feature]
- elif (ctx.attr.cpu == "cpuD"):
- features = [b_feature, a_feature]
- else:
- fail("Unreachable")`},
- {field: "features",
- toolchains: allToolchains,
- expectedText: `
- if (ctx.attr.cpu == "cpuA"
- or ctx.attr.cpu == "cpuB"):
- features = []
- elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
- or ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
- features = [a_feature]
- elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerC"):
- features = [a_feature, b_feature]
- elif (ctx.attr.cpu == "cpuD"):
- features = [b_feature, a_feature]
- else:
- fail("Unreachable")`}}
-
- for _, tc := range testCases {
- crosstool := makeCrosstool(tc.toolchains)
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(tc.toolchains, "\n"), got)
- }
- }
-}
-
-func getActionConfig(lines []string) string {
- return fmt.Sprintf(`action_config {
- %s
-}`, strings.Join(lines, "\n "))
-}
-
-func TestActionConfigListAssignment(t *testing.T) {
- toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
- toolchainA1 := getCToolchain("3", "cpuC", "compilerA",
- []string{
- getActionConfig([]string{"action_name: 'A'", "config_name: 'A'"}),
- },
- )
- toolchainA2 := getCToolchain("4", "cpuC", "compilerB",
- []string{
- getActionConfig([]string{"action_name: 'A'", "config_name: 'A'"}),
- },
- )
- toolchainAB := getCToolchain("5", "cpuC", "compilerC",
- []string{
- getActionConfig([]string{"action_name: 'A'", "config_name: 'A'"}),
- getActionConfig([]string{"action_name: 'B'", "config_name: 'B'"}),
- },
- )
- toolchainBA := getCToolchain("6", "cpuD", "compilerA",
- []string{
- getActionConfig([]string{"action_name: 'B'", "config_name: 'B'"}),
- getActionConfig([]string{"action_name: 'A'", "config_name: 'A'"}),
- },
- )
- toolchainsEmpty := []string{toolchainEmpty1, toolchainEmpty2}
-
- toolchainsOneNonempty := []string{toolchainEmpty1, toolchainA1}
-
- toolchainsSameNonempty := []string{toolchainA1, toolchainA2}
-
- toolchainsDifferentOrder := []string{toolchainAB, toolchainBA}
-
- allToolchains := []string{
- toolchainEmpty1,
- toolchainEmpty2,
- toolchainA1,
- toolchainA2,
- toolchainAB,
- toolchainBA,
- }
-
- testCases := []struct {
- field string
- toolchains []string
- expectedText string
- }{
- {field: "action_configs",
- toolchains: toolchainsEmpty,
- expectedText: `
- action_configs = []`},
- {field: "action_configs",
- toolchains: toolchainsOneNonempty,
- expectedText: `
- if (ctx.attr.cpu == "cpuA"):
- action_configs = []
- elif (ctx.attr.cpu == "cpuC"):
- action_configs = [a_action]
- else:
- fail("Unreachable")`},
- {field: "action_configs",
- toolchains: toolchainsSameNonempty,
- expectedText: `
- action_configs = [a_action]`},
- {field: "action_configs",
- toolchains: toolchainsDifferentOrder,
- expectedText: `
- if (ctx.attr.cpu == "cpuC"):
- action_configs = [a_action, b_action]
- elif (ctx.attr.cpu == "cpuD"):
- action_configs = [b_action, a_action]
- else:
- fail("Unreachable")`},
- {field: "action_configs",
- toolchains: allToolchains,
- expectedText: `
- if (ctx.attr.cpu == "cpuA"
- or ctx.attr.cpu == "cpuB"):
- action_configs = []
- elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"
- or ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
- action_configs = [a_action]
- elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerC"):
- action_configs = [a_action, b_action]
- elif (ctx.attr.cpu == "cpuD"):
- action_configs = [b_action, a_action]
- else:
- fail("Unreachable")`}}
-
- for _, tc := range testCases {
- crosstool := makeCrosstool(tc.toolchains)
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(tc.toolchains, "\n"), got)
- }
- }
-}
-
-func TestAllAndNoneAvailableErrorsWhenMoreThanOneElement(t *testing.T) {
- toolchainFeatureAllAvailable := getCToolchain("1", "cpu", "compiler",
- []string{getFeature([]string{
- "name: 'A'",
- "flag_set {",
- " action: 'A'",
- " flag_group {",
- " flag: 'f'",
- " expand_if_all_available: 'e1'",
- " expand_if_all_available: 'e2'",
- " }",
- "}",
- })},
- )
- toolchainFeatureNoneAvailable := getCToolchain("1", "cpu", "compiler",
- []string{getFeature([]string{
- "name: 'A'",
- "flag_set {",
- " action: 'A'",
- " flag_group {",
- " flag: 'f'",
- " expand_if_none_available: 'e1'",
- " expand_if_none_available: 'e2'",
- " }",
- "}",
- })},
- )
- toolchainActionConfigAllAvailable := getCToolchain("1", "cpu", "compiler",
- []string{getActionConfig([]string{
- "config_name: 'A'",
- "action_name: 'A'",
- "flag_set {",
- " action: 'A'",
- " flag_group {",
- " flag: 'f'",
- " expand_if_all_available: 'e1'",
- " expand_if_all_available: 'e2'",
- " }",
- "}",
- })},
- )
- toolchainActionConfigNoneAvailable := getCToolchain("1", "cpu", "compiler",
- []string{getActionConfig([]string{
- "config_name: 'A'",
- "action_name: 'A'",
- "flag_set {",
- " action: 'A'",
- " flag_group {",
- " flag: 'f'",
- " expand_if_none_available: 'e1'",
- " expand_if_none_available: 'e2'",
- " }",
- "}",
- })},
- )
-
- testCases := []struct {
- field string
- toolchain string
- expectedText string
- }{
- {field: "features",
- toolchain: toolchainFeatureAllAvailable,
- expectedText: "Error in feature 'A': Flag group must not have more " +
- "than one 'expand_if_all_available' field"},
- {field: "features",
- toolchain: toolchainFeatureNoneAvailable,
- expectedText: "Error in feature 'A': Flag group must not have more " +
- "than one 'expand_if_none_available' field"},
- {field: "action_configs",
- toolchain: toolchainActionConfigAllAvailable,
- expectedText: "Error in action_config 'A': Flag group must not have more " +
- "than one 'expand_if_all_available' field"},
- {field: "action_configs",
- toolchain: toolchainActionConfigNoneAvailable,
- expectedText: "Error in action_config 'A': Flag group must not have more " +
- "than one 'expand_if_none_available' field"},
- }
-
- for _, tc := range testCases {
- crosstool := makeCrosstool([]string{tc.toolchain})
- _, err := Transform(crosstool)
- if err == nil || !strings.Contains(err.Error(), tc.expectedText) {
- t.Errorf("Expected error: %s, got: %v", tc.expectedText, err)
- }
- }
-}
-
-func TestFeaturesAndActionConfigsSetToNoneWhenAllOptionsAreExausted(t *testing.T) {
- toolchainFeatureAEnabled := getCToolchain("1", "cpuA", "compilerA",
- []string{getFeature([]string{"name: 'A'", "enabled: true"})},
- )
- toolchainFeatureADisabled := getCToolchain("2", "cpuA", "compilerB",
- []string{getFeature([]string{"name: 'A'", "enabled: false"})},
- )
-
- toolchainWithoutFeatureA := getCToolchain("3", "cpuA", "compilerC", []string{})
-
- toolchainActionConfigAEnabled := getCToolchain("4", "cpuA", "compilerD",
- []string{getActionConfig([]string{
- "config_name: 'A'",
- "action_name: 'A'",
- "enabled: true",
- })})
-
- toolchainActionConfigADisabled := getCToolchain("5", "cpuA", "compilerE",
- []string{getActionConfig([]string{
- "config_name: 'A'",
- "action_name: 'A'",
- })})
-
- toolchainWithoutActionConfigA := getCToolchain("6", "cpuA", "compilerF", []string{})
-
- testCases := []struct {
- field string
- toolchains []string
- expectedText string
- }{
- {field: "features",
- toolchains: []string{
- toolchainFeatureAEnabled, toolchainFeatureADisabled, toolchainWithoutFeatureA},
- expectedText: `
- if (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerB"):
- a_feature = feature(name = "A")
- elif (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerA"):
- a_feature = feature(name = "A", enabled = True)
- else:
- a_feature = None
-`},
- {field: "action_config",
- toolchains: []string{
- toolchainActionConfigAEnabled, toolchainActionConfigADisabled, toolchainWithoutActionConfigA},
- expectedText: `
- if (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerE"):
- a_action = action_config(action_name = "A")
- elif (ctx.attr.cpu == "cpuA" and ctx.attr.compiler == "compilerD"):
- a_action = action_config(action_name = "A", enabled = True)
- else:
- a_action = None
-`},
- }
-
- for _, tc := range testCases {
- crosstool := makeCrosstool(tc.toolchains)
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly convert '%s' field, expected to contain:\n%v\n",
- tc.field, tc.expectedText)
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(tc.toolchains, "\n"), got)
- }
- }
-}
-
-func TestActionConfigDeclaration(t *testing.T) {
- toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
-
- toolchainNameNotInDict := getCToolchain("3", "cpBC", "compilerB",
- []string{
- getActionConfig([]string{"action_name: 'A-B.C'", "config_name: 'A-B.C'"}),
- },
- )
- toolchainNameInDictA := getCToolchain("4", "cpuC", "compilerA",
- []string{
- getActionConfig([]string{"action_name: 'c++-compile'", "config_name: 'c++-compile'"}),
- },
- )
- toolchainNameInDictB := getCToolchain("5", "cpuC", "compilerB",
- []string{
- getActionConfig([]string{
- "action_name: 'c++-compile'",
- "config_name: 'c++-compile'",
- "tool {",
- " tool_path: '/a/b/c'",
- "}",
- }),
- },
- )
- toolchainComplexActionConfig := getCToolchain("6", "cpuC", "compilerC",
- []string{
- getActionConfig([]string{
- "action_name: 'action-complex'",
- "config_name: 'action-complex'",
- "enabled: true",
- "tool {",
- " tool_path: '/a/b/c'",
- " with_feature {",
- " feature: 'a'",
- " feature: 'b'",
- " not_feature: 'c'",
- " not_feature: 'd'",
- " }",
- " with_feature{",
- " feature: 'e'",
- " }",
- " execution_requirement: 'a'",
- "}",
- "tool {",
- " tool_path: ''",
- "}",
- "flag_set {",
- " flag_group {",
- " flag: 'a'",
- " flag: '%b'",
- " iterate_over: 'c'",
- " expand_if_all_available: 'd'",
- " expand_if_none_available: 'e'",
- " expand_if_true: 'f'",
- " expand_if_false: 'g'",
- " expand_if_equal {",
- " variable: 'var'",
- " value: 'val'",
- " }",
- " }",
- " flag_group {",
- " flag_group {",
- " flag: 'a'",
- " }",
- " }",
- "}",
- "flag_set {",
- " with_feature {",
- " feature: 'a'",
- " feature: 'b'",
- " not_feature: 'c'",
- " not_feature: 'd'",
- " }",
- "}",
- "env_set {",
- " action: 'a'",
- " env_entry {",
- " key: 'k'",
- " value: 'v'",
- " }",
- " with_feature {",
- " feature: 'a'",
- " }",
- "}",
- "requires {",
- " feature: 'a'",
- " feature: 'b'",
- "}",
- "implies: 'a'",
- "implies: 'b'",
- }),
- },
- )
-
- testCases := []struct {
- toolchains []string
- expectedText string
- }{
- {
- toolchains: []string{toolchainEmpty1, toolchainEmpty2},
- expectedText: `
- action_configs = []`},
- {
- toolchains: []string{toolchainEmpty1, toolchainNameNotInDict},
- expectedText: `
- a_b_c_action = action_config(action_name = "A-B.C")`},
- {
- toolchains: []string{toolchainNameInDictA, toolchainNameInDictB},
- expectedText: `
- if (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerB"):
- cpp_compile_action = action_config(
- action_name = ACTION_NAMES.cpp_compile,
- tools = [tool(path = "/a/b/c")],
- )
- elif (ctx.attr.cpu == "cpuC" and ctx.attr.compiler == "compilerA"):
- cpp_compile_action = action_config(action_name = ACTION_NAMES.cpp_compile)`},
- {
- toolchains: []string{toolchainComplexActionConfig},
- expectedText: `
- action_complex_action = action_config(
- action_name = "action-complex",
- enabled = True,
- flag_sets = [
- flag_set(
- flag_groups = [
- flag_group(
- flags = ["a", "%b"],
- iterate_over = "c",
- expand_if_available = "d",
- expand_if_not_available = "e",
- expand_if_true = "f",
- expand_if_false = "g",
- expand_if_equal = variable_with_value(name = "var", value = "val"),
- ),
- flag_group(flag_groups = [flag_group(flags = ["a"])]),
- ],
- ),
- flag_set(
- with_features = [
- with_feature_set(
- features = ["a", "b"],
- not_features = ["c", "d"],
- ),
- ],
- ),
- ],
- implies = ["a", "b"],
- tools = [
- tool(
- path = "/a/b/c",
- with_features = [
- with_feature_set(
- features = ["a", "b"],
- not_features = ["c", "d"],
- ),
- with_feature_set(features = ["e"]),
- ],
- execution_requirements = ["a"],
- ),
- tool(path = "NOT_USED"),
- ],
- )`}}
-
- for _, tc := range testCases {
- crosstool := makeCrosstool(tc.toolchains)
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly declare an action_config, expected to contain:\n%v\n",
- tc.expectedText)
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(tc.toolchains, "\n"), got)
- }
- }
-}
-
-func TestFeatureDeclaration(t *testing.T) {
- toolchainEmpty1 := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainEmpty2 := getCToolchain("2", "cpuB", "compilerA", []string{})
-
- toolchainSimpleFeatureA1 := getCToolchain("3", "cpuB", "compilerB",
- []string{
- getFeature([]string{"name: 'Feature-c++.a'", "enabled: true"}),
- },
- )
- toolchainSimpleFeatureA2 := getCToolchain("4", "cpuC", "compilerA",
- []string{
- getFeature([]string{"name: 'Feature-c++.a'"}),
- },
- )
- toolchainComplexFeature := getCToolchain("5", "cpuC", "compilerC",
- []string{
- getFeature([]string{
- "name: 'complex-feature'",
- "enabled: true",
- "flag_set {",
- " action: 'c++-compile'", // in ACTION_NAMES
- " action: 'something-else'", // not in ACTION_NAMES
- " flag_group {",
- " flag: 'a'",
- " flag: '%b'",
- " iterate_over: 'c'",
- " expand_if_all_available: 'd'",
- " expand_if_none_available: 'e'",
- " expand_if_true: 'f'",
- " expand_if_false: 'g'",
- " expand_if_equal {",
- " variable: 'var'",
- " value: 'val'",
- " }",
- " }",
- " flag_group {",
- " flag_group {",
- " flag: 'a'",
- " }",
- " }",
- "}",
- "flag_set {", // all_compile_actions
- " action: 'c-compile'",
- " action: 'c++-compile'",
- " action: 'linkstamp-compile'",
- " action: 'assemble'",
- " action: 'preprocess-assemble'",
- " action: 'c++-header-parsing'",
- " action: 'c++-module-compile'",
- " action: 'c++-module-codegen'",
- " action: 'clif-match'",
- " action: 'lto-backend'",
- "}",
- "flag_set {", // all_cpp_compile_actions
- " action: 'c++-compile'",
- " action: 'linkstamp-compile'",
- " action: 'c++-header-parsing'",
- " action: 'c++-module-compile'",
- " action: 'c++-module-codegen'",
- " action: 'clif-match'",
- "}",
- "flag_set {", // all_link_actions
- " action: 'c++-link-executable'",
- " action: 'c++-link-dynamic-library'",
- " action: 'c++-link-nodeps-dynamic-library'",
- "}",
- "flag_set {", // all_cpp_compile_actions + all_link_actions
- " action: 'c++-compile'",
- " action: 'linkstamp-compile'",
- " action: 'c++-header-parsing'",
- " action: 'c++-module-compile'",
- " action: 'c++-module-codegen'",
- " action: 'clif-match'",
- " action: 'c++-link-executable'",
- " action: 'c++-link-dynamic-library'",
- " action: 'c++-link-nodeps-dynamic-library'",
- "}",
- "flag_set {", // all_link_actions + something else
- " action: 'c++-link-executable'",
- " action: 'c++-link-dynamic-library'",
- " action: 'c++-link-nodeps-dynamic-library'",
- " action: 'some.unknown-c++.action'",
- "}",
- "env_set {",
- " action: 'a'",
- " env_entry {",
- " key: 'k'",
- " value: 'v'",
- " }",
- " with_feature {",
- " feature: 'a'",
- " }",
- "}",
- "env_set {",
- " action: 'c-compile'",
- "}",
- "env_set {", // all_compile_actions
- " action: 'c-compile'",
- " action: 'c++-compile'",
- " action: 'linkstamp-compile'",
- " action: 'assemble'",
- " action: 'preprocess-assemble'",
- " action: 'c++-header-parsing'",
- " action: 'c++-module-compile'",
- " action: 'c++-module-codegen'",
- " action: 'clif-match'",
- " action: 'lto-backend'",
- "}",
- "requires {",
- " feature: 'a'",
- " feature: 'b'",
- "}",
- "implies: 'a'",
- "implies: 'b'",
- "provides: 'c'",
- "provides: 'd'",
- }),
- },
- )
-
- testCases := []struct {
- toolchains []string
- expectedText string
- }{
- {
- toolchains: []string{toolchainEmpty1, toolchainEmpty2},
- expectedText: `
- features = []
-`},
- {
- toolchains: []string{toolchainEmpty1, toolchainSimpleFeatureA1},
- expectedText: `
- feature_cpp_a_feature = feature(name = "Feature-c++.a", enabled = True)`},
- {
- toolchains: []string{toolchainSimpleFeatureA1, toolchainSimpleFeatureA2},
- expectedText: `
- if (ctx.attr.cpu == "cpuC"):
- feature_cpp_a_feature = feature(name = "Feature-c++.a")
- elif (ctx.attr.cpu == "cpuB"):
- feature_cpp_a_feature = feature(name = "Feature-c++.a", enabled = True)`},
- {
- toolchains: []string{toolchainComplexFeature},
- expectedText: `
- complex_feature_feature = feature(
- name = "complex-feature",
- enabled = True,
- flag_sets = [
- flag_set(
- actions = [ACTION_NAMES.cpp_compile, "something-else"],
- flag_groups = [
- flag_group(
- flags = ["a", "%b"],
- iterate_over = "c",
- expand_if_available = "d",
- expand_if_not_available = "e",
- expand_if_true = "f",
- expand_if_false = "g",
- expand_if_equal = variable_with_value(name = "var", value = "val"),
- ),
- flag_group(flag_groups = [flag_group(flags = ["a"])]),
- ],
- ),
- flag_set(actions = all_compile_actions),
- flag_set(actions = all_cpp_compile_actions),
- flag_set(actions = all_link_actions),
- flag_set(
- actions = all_cpp_compile_actions +
- all_link_actions,
- ),
- flag_set(
- actions = all_link_actions +
- ["some.unknown-c++.action"],
- ),
- ],
- env_sets = [
- env_set(
- actions = ["a"],
- env_entries = [env_entry(key = "k", value = "v")],
- with_features = [with_feature_set(features = ["a"])],
- ),
- env_set(actions = [ACTION_NAMES.c_compile]),
- env_set(actions = all_compile_actions),
- ],
- requires = [feature_set(features = ["a", "b"])],
- implies = ["a", "b"],
- provides = ["c", "d"],
- )`}}
-
- for _, tc := range testCases {
- crosstool := makeCrosstool(tc.toolchains)
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly declare a feature, expected to contain:\n%v\n",
- tc.expectedText)
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(tc.toolchains, "\n"), got)
- }
- }
-}
-
-func TestRule(t *testing.T) {
- simpleToolchain := getSimpleCToolchain("simple")
- expected := `load("@rules_cc//cc:cc_toolchain_config_lib.bzl",
- "action_config",
- "artifact_name_pattern",
- "env_entry",
- "env_set",
- "feature",
- "feature_set",
- "flag_group",
- "flag_set",
- "make_variable",
- "tool",
- "tool_path",
- "variable_with_value",
- "with_feature_set",
-)
-load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
-
-def _impl(ctx):
- toolchain_identifier = "id-simple"
-
- host_system_name = "host-simple"
-
- target_system_name = "target-simple"
-
- target_cpu = "cpu-simple"
-
- target_libc = "libc-simple"
-
- compiler = "compiler-simple"
-
- abi_version = "version-simple"
-
- abi_libc_version = "libc_version-simple"
-
- cc_target_os = None
-
- builtin_sysroot = None
-
- all_compile_actions = [
- ACTION_NAMES.c_compile,
- ACTION_NAMES.cpp_compile,
- ACTION_NAMES.linkstamp_compile,
- ACTION_NAMES.assemble,
- ACTION_NAMES.preprocess_assemble,
- ACTION_NAMES.cpp_header_parsing,
- ACTION_NAMES.cpp_module_compile,
- ACTION_NAMES.cpp_module_codegen,
- ACTION_NAMES.clif_match,
- ACTION_NAMES.lto_backend,
- ]
-
- all_cpp_compile_actions = [
- ACTION_NAMES.cpp_compile,
- ACTION_NAMES.linkstamp_compile,
- ACTION_NAMES.cpp_header_parsing,
- ACTION_NAMES.cpp_module_compile,
- ACTION_NAMES.cpp_module_codegen,
- ACTION_NAMES.clif_match,
- ]
-
- preprocessor_compile_actions = [
- ACTION_NAMES.c_compile,
- ACTION_NAMES.cpp_compile,
- ACTION_NAMES.linkstamp_compile,
- ACTION_NAMES.preprocess_assemble,
- ACTION_NAMES.cpp_header_parsing,
- ACTION_NAMES.cpp_module_compile,
- ACTION_NAMES.clif_match,
- ]
-
- codegen_compile_actions = [
- ACTION_NAMES.c_compile,
- ACTION_NAMES.cpp_compile,
- ACTION_NAMES.linkstamp_compile,
- ACTION_NAMES.assemble,
- ACTION_NAMES.preprocess_assemble,
- ACTION_NAMES.cpp_module_codegen,
- ACTION_NAMES.lto_backend,
- ]
-
- all_link_actions = [
- ACTION_NAMES.cpp_link_executable,
- ACTION_NAMES.cpp_link_dynamic_library,
- ACTION_NAMES.cpp_link_nodeps_dynamic_library,
- ]
-
- action_configs = []
-
- features = []
-
- cxx_builtin_include_directories = []
-
- artifact_name_patterns = []
-
- make_variables = []
-
- tool_paths = []
-
-
- out = ctx.actions.declare_file(ctx.label.name)
- ctx.actions.write(out, "Fake executable")
- return [
- cc_common.create_cc_toolchain_config_info(
- ctx = ctx,
- features = features,
- action_configs = action_configs,
- artifact_name_patterns = artifact_name_patterns,
- cxx_builtin_include_directories = cxx_builtin_include_directories,
- toolchain_identifier = toolchain_identifier,
- host_system_name = host_system_name,
- target_system_name = target_system_name,
- target_cpu = target_cpu,
- target_libc = target_libc,
- compiler = compiler,
- abi_version = abi_version,
- abi_libc_version = abi_libc_version,
- tool_paths = tool_paths,
- make_variables = make_variables,
- builtin_sysroot = builtin_sysroot,
- cc_target_os = cc_target_os
- ),
- DefaultInfo(
- executable = out,
- ),
- ]
-cc_toolchain_config = rule(
- implementation = _impl,
- attrs = {
- "cpu": attr.string(mandatory=True, values=["cpu-simple"]),
- },
- provides = [CcToolchainConfigInfo],
- executable = True,
-)
-`
- crosstool := makeCrosstool([]string{simpleToolchain})
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if got != expected {
- t.Fatalf("Expected:\n%v\nGot:\n%v\nTested CROSSTOOL:\n%v",
- expected, got, simpleToolchain)
- }
-}
-
-func TestAllowedCompilerValues(t *testing.T) {
- toolchainAA := getCToolchain("1", "cpuA", "compilerA", []string{})
- toolchainBA := getCToolchain("2", "cpuB", "compilerA", []string{})
- toolchainBB := getCToolchain("3", "cpuB", "compilerB", []string{})
- toolchainCC := getCToolchain("4", "cpuC", "compilerC", []string{})
-
- testCases := []struct {
- toolchains []string
- expectedText string
- }{
- {
- toolchains: []string{toolchainAA, toolchainBA},
- expectedText: `
-cc_toolchain_config = rule(
- implementation = _impl,
- attrs = {
- "cpu": attr.string(mandatory=True, values=["cpuA", "cpuB"]),
- },
- provides = [CcToolchainConfigInfo],
- executable = True,
-)
-`},
- {
- toolchains: []string{toolchainBA, toolchainBB},
- expectedText: `
-cc_toolchain_config = rule(
- implementation = _impl,
- attrs = {
- "cpu": attr.string(mandatory=True, values=["cpuB"]),
- "compiler": attr.string(mandatory=True, values=["compilerA", "compilerB"]),
- },
- provides = [CcToolchainConfigInfo],
- executable = True,
-)
-`},
- {
- toolchains: []string{toolchainAA, toolchainBA, toolchainBB},
- expectedText: `
-cc_toolchain_config = rule(
- implementation = _impl,
- attrs = {
- "cpu": attr.string(mandatory=True, values=["cpuA", "cpuB"]),
- "compiler": attr.string(mandatory=True, values=["compilerA", "compilerB"]),
- },
- provides = [CcToolchainConfigInfo],
- executable = True,
-)
-`},
- {
- toolchains: []string{toolchainAA, toolchainBA, toolchainBB, toolchainCC},
- expectedText: `
-cc_toolchain_config = rule(
- implementation = _impl,
- attrs = {
- "cpu": attr.string(mandatory=True, values=["cpuA", "cpuB", "cpuC"]),
- "compiler": attr.string(mandatory=True, values=["compilerA", "compilerB", "compilerC"]),
- },
- provides = [CcToolchainConfigInfo],
- executable = True,
-)
-`}}
-
- for _, tc := range testCases {
- crosstool := makeCrosstool(tc.toolchains)
- got, err := Transform(crosstool)
- if err != nil {
- t.Fatalf("CROSSTOOL conversion failed: %v", err)
- }
- if !strings.Contains(got, tc.expectedText) {
- t.Errorf("Failed to correctly declare the rule, expected to contain:\n%v\n",
- tc.expectedText)
- t.Fatalf("Tested CROSSTOOL:\n%v\n\nGenerated rule:\n%v\n",
- strings.Join(tc.toolchains, "\n"), got)
- }
- }
-}
diff --git a/tools/migration/ctoolchain_comparator.py b/tools/migration/ctoolchain_comparator.py
deleted file mode 100644
index 5143e02..0000000
--- a/tools/migration/ctoolchain_comparator.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-r"""A script that compares 2 CToolchains from proto format.
-
-This script accepts two files in either a CROSSTOOL proto text format or a
-CToolchain proto text format. It then locates the CToolchains with the given
-toolchain_identifier and checks if the resulting CToolchain objects in Java
-are the same.
-
-Example usage:
-
-bazel run \
-@rules_cc//tools/migration:ctoolchain_comparator -- \
---before=/path/to/CROSSTOOL1 \
---after=/path/to/CROSSTOOL2 \
---toolchain_identifier=id
-"""
-
-import os
-from absl import app
-from absl import flags
-from google.protobuf import text_format
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-from tools.migration.ctoolchain_comparator_lib import compare_ctoolchains
-
-flags.DEFINE_string(
- "before", None,
- ("A text proto file containing the relevant CTooclchain before the change, "
- "either a CROSSTOOL file or a single CToolchain proto text"))
-flags.DEFINE_string(
- "after", None,
- ("A text proto file containing the relevant CToolchain after the change, "
- "either a CROSSTOOL file or a single CToolchain proto text"))
-flags.DEFINE_string("toolchain_identifier", None,
- "The identifier of the CToolchain that is being compared.")
-flags.mark_flag_as_required("before")
-flags.mark_flag_as_required("after")
-
-
-def _to_absolute_path(path):
- path = os.path.expanduser(path)
- if os.path.isabs(path):
- return path
- else:
- if "BUILD_WORKING_DIRECTORY" in os.environ:
- return os.path.join(os.environ["BUILD_WORKING_DIRECTORY"], path)
- else:
- return path
-
-
-def _find_toolchain(crosstool, toolchain_identifier):
- for toolchain in crosstool.toolchain:
- if toolchain.toolchain_identifier == toolchain_identifier:
- return toolchain
- return None
-
-
-def _read_crosstool_or_ctoolchain_proto(input_file, toolchain_identifier=None):
- """Reads a proto file and finds the CToolchain with the given identifier."""
- with open(input_file, "r") as f:
- text = f.read()
- crosstool_release = crosstool_config_pb2.CrosstoolRelease()
- c_toolchain = crosstool_config_pb2.CToolchain()
- try:
- text_format.Merge(text, crosstool_release)
- if toolchain_identifier is None:
- print("CROSSTOOL proto needs a 'toolchain_identifier' specified in "
- "order to be able to select the right toolchain for comparison.")
- return None
- toolchain = _find_toolchain(crosstool_release, toolchain_identifier)
- if toolchain is None:
- print(("Cannot find a CToolchain with an identifier '%s' in CROSSTOOL "
- "file") % toolchain_identifier)
- return None
- return toolchain
- except text_format.ParseError as crosstool_error:
- try:
- text_format.Merge(text, c_toolchain)
- if (toolchain_identifier is not None and
- c_toolchain.toolchain_identifier != toolchain_identifier):
- print(("Expected CToolchain with identifier '%s', got CToolchain with "
- "identifier '%s'" % (toolchain_identifier,
- c_toolchain.toolchain_identifier)))
- return None
- return c_toolchain
- except text_format.ParseError as toolchain_error:
- print(("Error parsing file '%s':" % input_file)) # pylint: disable=superfluous-parens
- print("Attempt to parse it as a CROSSTOOL proto:") # pylint: disable=superfluous-parens
- print(crosstool_error) # pylint: disable=superfluous-parens
- print("Attempt to parse it as a CToolchain proto:") # pylint: disable=superfluous-parens
- print(toolchain_error) # pylint: disable=superfluous-parens
- return None
-
-
-def main(unused_argv):
-
- before_file = _to_absolute_path(flags.FLAGS.before)
- after_file = _to_absolute_path(flags.FLAGS.after)
- toolchain_identifier = flags.FLAGS.toolchain_identifier
-
- toolchain_before = _read_crosstool_or_ctoolchain_proto(
- before_file, toolchain_identifier)
- toolchain_after = _read_crosstool_or_ctoolchain_proto(after_file,
- toolchain_identifier)
-
- if not toolchain_before or not toolchain_after:
- print("There was an error getting the required toolchains.")
- exit(1)
-
- found_difference = compare_ctoolchains(toolchain_before, toolchain_after)
- if found_difference:
- exit(1)
-
-
-if __name__ == "__main__":
- app.run(main)
diff --git a/tools/migration/ctoolchain_comparator_lib.py b/tools/migration/ctoolchain_comparator_lib.py
deleted file mode 100644
index eb47305..0000000
--- a/tools/migration/ctoolchain_comparator_lib.py
+++ /dev/null
@@ -1,523 +0,0 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-"""Module providing compare_ctoolchains function.
-
-compare_ctoolchains takes in two parsed CToolchains and compares them
-"""
-
-
-def _print_difference(field_name, before_value, after_value):
- if not before_value and after_value:
- print(("Difference in '%s' field:\nValue before change is not set\n"
- "Value after change is set to '%s'") % (field_name, after_value))
- elif before_value and not after_value:
- print(("Difference in '%s' field:\nValue before change is set to '%s'\n"
- "Value after change is not set") % (field_name, before_value))
- else:
- print(("Difference in '%s' field:\nValue before change:\t'%s'\n"
- "Value after change:\t'%s'\n") % (field_name, before_value,
- after_value))
-
-
-def _array_to_string(arr, ordered=False):
- if not arr:
- return "[]"
- elif len(arr) == 1:
- return "[" + list(arr)[0] + "]"
- if not ordered:
- return "[\n\t%s\n]" % "\n\t".join(arr)
- else:
- return "[\n\t%s\n]" % "\n\t".join(sorted(list(arr)))
-
-
-def _check_with_feature_set_equivalence(before, after):
- before_set = set()
- after_set = set()
- for el in before:
- before_set.add((str(set(el.feature)), str(set(el.not_feature))))
- for el in after:
- after_set.add((str(set(el.feature)), str(set(el.not_feature))))
- return before_set == after_set
-
-
-def _check_tool_equivalence(before, after):
- """Compares two "CToolchain.Tool"s."""
- if before.tool_path == "NOT_USED":
- before.tool_path = ""
- if after.tool_path == "NOT_USED":
- after.tool_path = ""
- if before.tool_path != after.tool_path:
- return False
- if set(before.execution_requirement) != set(after.execution_requirement):
- return False
- if not _check_with_feature_set_equivalence(before.with_feature,
- after.with_feature):
- return False
- return True
-
-
-def _check_flag_group_equivalence(before, after):
- """Compares two "CToolchain.FlagGroup"s."""
- if before.flag != after.flag:
- return False
- if before.expand_if_true != after.expand_if_true:
- return False
- if before.expand_if_false != after.expand_if_false:
- return False
- if set(before.expand_if_all_available) != set(after.expand_if_all_available):
- return False
- if set(before.expand_if_none_available) != set(
- after.expand_if_none_available):
- return False
- if before.iterate_over != after.iterate_over:
- return False
- if before.expand_if_equal != after.expand_if_equal:
- return False
- if len(before.flag_group) != len(after.flag_group):
- return False
- for (flag_group_before, flag_group_after) in zip(before.flag_group,
- after.flag_group):
- if not _check_flag_group_equivalence(flag_group_before, flag_group_after):
- return False
- return True
-
-
-def _check_flag_set_equivalence(before, after, in_action_config=False):
- """Compares two "CToolchain.FlagSet"s."""
- # ActionConfigs in proto format do not have a 'FlagSet.action' field set.
- # Instead, when construction the Java ActionConfig object, we set the
- # flag_set.action field to the action name. This currently causes the
- # CcToolchainConfigInfo.proto to generate a CToolchain.ActionConfig that still
- # has the action name in the FlagSet.action field, therefore we don't compare
- # the FlagSet.action field when comparing flag_sets that belong to an
- # ActionConfig.
- if not in_action_config and set(before.action) != set(after.action):
- return False
- if not _check_with_feature_set_equivalence(before.with_feature,
- after.with_feature):
- return False
- if len(before.flag_group) != len(after.flag_group):
- return False
- for (flag_group_before, flag_group_after) in zip(before.flag_group,
- after.flag_group):
- if not _check_flag_group_equivalence(flag_group_before, flag_group_after):
- return False
- return True
-
-
-def _check_action_config_equivalence(before, after):
- """Compares two "CToolchain.ActionConfig"s."""
- if before.config_name != after.config_name:
- return False
- if before.action_name != after.action_name:
- return False
- if before.enabled != after.enabled:
- return False
- if len(before.tool) != len(after.tool):
- return False
- for (tool_before, tool_after) in zip(before.tool, after.tool):
- if not _check_tool_equivalence(tool_before, tool_after):
- return False
- if before.implies != after.implies:
- return False
- if len(before.flag_set) != len(after.flag_set):
- return False
- for (flag_set_before, flag_set_after) in zip(before.flag_set, after.flag_set):
- if not _check_flag_set_equivalence(flag_set_before, flag_set_after, True):
- return False
- return True
-
-
-def _check_env_set_equivalence(before, after):
- """Compares two "CToolchain.EnvSet"s."""
- if set(before.action) != set(after.action):
- return False
- if not _check_with_feature_set_equivalence(before.with_feature,
- after.with_feature):
- return False
- if before.env_entry != after.env_entry:
- return False
- return True
-
-
-def _check_feature_equivalence(before, after):
- """Compares two "CToolchain.Feature"s."""
- if before.name != after.name:
- return False
- if before.enabled != after.enabled:
- return False
- if len(before.flag_set) != len(after.flag_set):
- return False
- for (flag_set_before, flag_set_after) in zip(before.flag_set, after.flag_set):
- if not _check_flag_set_equivalence(flag_set_before, flag_set_after):
- return False
- if len(before.env_set) != len(after.env_set):
- return False
- for (env_set_before, env_set_after) in zip(before.env_set, after.env_set):
- if not _check_env_set_equivalence(env_set_before, env_set_after):
- return False
- if len(before.requires) != len(after.requires):
- return False
- for (requires_before, requires_after) in zip(before.requires, after.requires):
- if set(requires_before.feature) != set(requires_after.feature):
- return False
- if before.implies != after.implies:
- return False
- if before.provides != after.provides:
- return False
- return True
-
-
-def _compare_features(features_before, features_after):
- """Compares two "CToolchain.FlagFeature" lists."""
- feature_name_to_feature_before = {}
- feature_name_to_feature_after = {}
- for feature in features_before:
- feature_name_to_feature_before[feature.name] = feature
- for feature in features_after:
- feature_name_to_feature_after[feature.name] = feature
-
- feature_names_before = set(feature_name_to_feature_before.keys())
- feature_names_after = set(feature_name_to_feature_after.keys())
-
- before_after_diff = feature_names_before - feature_names_after
- after_before_diff = feature_names_after - feature_names_before
-
- diff_string = "Difference in 'feature' field:"
- found_difference = False
- if before_after_diff:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* List before change contains entries for the following features "
- "that the list after the change doesn't:\n%s") % _array_to_string(
- before_after_diff, ordered=True))
- if after_before_diff:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* List after change contains entries for the following features "
- "that the list before the change doesn't:\n%s") % _array_to_string(
- after_before_diff, ordered=True))
-
- names_before = [feature.name for feature in features_before]
- names_after = [feature.name for feature in features_after]
- if names_before != names_after:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("Features not in right order:\n"
- "* List of features before change:\t%s"
- "* List of features before change:\t%s") %
- (_array_to_string(names_before), _array_to_string(names_after)))
- for name in feature_name_to_feature_before:
- feature_before = feature_name_to_feature_before[name]
- feature_after = feature_name_to_feature_after.get(name, None)
- if feature_after and not _check_feature_equivalence(feature_before,
- feature_after):
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* Feature '%s' differs before and after the change:\n"
- "Value before change:\n%s\n"
- "Value after change:\n%s") % (name, str(feature_before),
- str(feature_after)))
- if found_difference:
- print("") # pylint: disable=superfluous-parens
- return found_difference
-
-
-def _compare_action_configs(action_configs_before, action_configs_after):
- """Compares two "CToolchain.ActionConfig" lists."""
- action_name_to_action_before = {}
- action_name_to_action_after = {}
- for action_config in action_configs_before:
- action_name_to_action_before[action_config.config_name] = action_config
- for action_config in action_configs_after:
- action_name_to_action_after[action_config.config_name] = action_config
-
- config_names_before = set(action_name_to_action_before.keys())
- config_names_after = set(action_name_to_action_after.keys())
-
- before_after_diff = config_names_before - config_names_after
- after_before_diff = config_names_after - config_names_before
-
- diff_string = "Difference in 'action_config' field:"
- found_difference = False
- if before_after_diff:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* List before change contains entries for the following "
- "action_configs that the list after the change doesn't:\n%s") %
- _array_to_string(before_after_diff, ordered=True))
- if after_before_diff:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* List after change contains entries for the following "
- "action_configs that the list before the change doesn't:\n%s") %
- _array_to_string(after_before_diff, ordered=True))
-
- names_before = [config.config_name for config in action_configs_before]
- names_after = [config.config_name for config in action_configs_after]
- if names_before != names_after:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("Action configs not in right order:\n"
- "* List of action configs before change:\t%s"
- "* List of action_configs before change:\t%s") %
- (_array_to_string(names_before), _array_to_string(names_after)))
- for name in config_names_before:
- action_config_before = action_name_to_action_before[name]
- action_config_after = action_name_to_action_after.get(name, None)
- if action_config_after and not _check_action_config_equivalence(
- action_config_before, action_config_after):
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* Action config '%s' differs before and after the change:\n"
- "Value before change:\n%s\n"
- "Value after change:\n%s") % (name, str(action_config_before),
- str(action_config_after)))
- if found_difference:
- print("") # pylint: disable=superfluous-parens
- return found_difference
-
-
-def _compare_tool_paths(tool_paths_before, tool_paths_after):
- """Compares two "CToolchain.ToolPath" lists."""
- tool_to_path_before = {}
- tool_to_path_after = {}
- for tool_path in tool_paths_before:
- tool_to_path_before[tool_path.name] = (
- tool_path.path if tool_path.path != "NOT_USED" else "")
- for tool_path in tool_paths_after:
- tool_to_path_after[tool_path.name] = (
- tool_path.path if tool_path.path != "NOT_USED" else "")
-
- tool_names_before = set(tool_to_path_before.keys())
- tool_names_after = set(tool_to_path_after.keys())
-
- before_after_diff = tool_names_before - tool_names_after
- after_before_diff = tool_names_after - tool_names_before
-
- diff_string = "Difference in 'tool_path' field:"
- found_difference = False
- if before_after_diff:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* List before change contains entries for the following tools "
- "that the list after the change doesn't:\n%s") % _array_to_string(
- before_after_diff, ordered=True))
- if after_before_diff:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* List after change contains entries for the following tools that "
- "the list before the change doesn't:\n%s") % _array_to_string(
- after_before_diff, ordered=True))
-
- for tool in tool_to_path_before:
- path_before = tool_to_path_before[tool]
- path_after = tool_to_path_after.get(tool, None)
- if path_after and path_after != path_before:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* Path for tool '%s' differs before and after the change:\n"
- "Value before change:\t'%s'\n"
- "Value after change:\t'%s'") % (tool, path_before, path_after))
- if found_difference:
- print("") # pylint: disable=superfluous-parens
- return found_difference
-
-
-def _compare_make_variables(make_variables_before, make_variables_after):
- """Compares two "CToolchain.MakeVariable" lists."""
- name_to_variable_before = {}
- name_to_variable_after = {}
- for variable in make_variables_before:
- name_to_variable_before[variable.name] = variable.value
- for variable in make_variables_after:
- name_to_variable_after[variable.name] = variable.value
-
- variable_names_before = set(name_to_variable_before.keys())
- variable_names_after = set(name_to_variable_after.keys())
-
- before_after_diff = variable_names_before - variable_names_after
- after_before_diff = variable_names_after - variable_names_before
-
- diff_string = "Difference in 'make_variable' field:"
- found_difference = False
- if before_after_diff:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* List before change contains entries for the following variables "
- "that the list after the change doesn't:\n%s") % _array_to_string(
- before_after_diff, ordered=True))
- if after_before_diff:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* List after change contains entries for the following variables "
- "that the list before the change doesn't:\n%s") % _array_to_string(
- after_before_diff, ordered=True))
-
- for variable in name_to_variable_before:
- value_before = name_to_variable_before[variable]
- value_after = name_to_variable_after.get(variable, None)
- if value_after and value_after != value_before:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(
- ("* Value for variable '%s' differs before and after the change:\n"
- "Value before change:\t'%s'\n"
- "Value after change:\t'%s'") % (variable, value_before, value_after))
- if found_difference:
- print("") # pylint: disable=superfluous-parens
- return found_difference
-
-
-def _compare_cxx_builtin_include_directories(directories_before,
- directories_after):
- if directories_before != directories_after:
- print(("Difference in 'cxx_builtin_include_directory' field:\n"
- "List of elements before change:\n%s\n"
- "List of elements after change:\n%s\n") %
- (_array_to_string(directories_before),
- _array_to_string(directories_after)))
- return True
- return False
-
-
-def _compare_artifact_name_patterns(artifact_name_patterns_before,
- artifact_name_patterns_after):
- """Compares two "CToolchain.ArtifactNamePattern" lists."""
- category_to_values_before = {}
- category_to_values_after = {}
- for name_pattern in artifact_name_patterns_before:
- category_to_values_before[name_pattern.category_name] = (
- name_pattern.prefix, name_pattern.extension)
- for name_pattern in artifact_name_patterns_after:
- category_to_values_after[name_pattern.category_name] = (
- name_pattern.prefix, name_pattern.extension)
-
- category_names_before = set(category_to_values_before.keys())
- category_names_after = set(category_to_values_after.keys())
-
- before_after_diff = category_names_before - category_names_after
- after_before_diff = category_names_after - category_names_before
-
- diff_string = "Difference in 'artifact_name_pattern' field:"
- found_difference = False
- if before_after_diff:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* List before change contains entries for the following categories "
- "that the list after the change doesn't:\n%s") % _array_to_string(
- before_after_diff, ordered=True))
- if after_before_diff:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* List after change contains entries for the following categories "
- "that the list before the change doesn't:\n%s") % _array_to_string(
- after_before_diff, ordered=True))
-
- for category in category_to_values_before:
- value_before = category_to_values_before[category]
- value_after = category_to_values_after.get(category, None)
- if value_after and value_after != value_before:
- if not found_difference:
- print(diff_string) # pylint: disable=superfluous-parens
- found_difference = True
- print(("* Value for category '%s' differs before and after the change:\n"
- "Value before change:\tprefix:'%s'\textension:'%s'\n"
- "Value after change:\tprefix:'%s'\textension:'%s'") %
- (category, value_before[0], value_before[1], value_after[0],
- value_after[1]))
- if found_difference:
- print("") # pylint: disable=superfluous-parens
- return found_difference
-
-
-def compare_ctoolchains(toolchain_before, toolchain_after):
- """Compares two CToolchains."""
- found_difference = False
- if (toolchain_before.toolchain_identifier !=
- toolchain_after.toolchain_identifier):
- _print_difference("toolchain_identifier",
- toolchain_before.toolchain_identifier,
- toolchain_after.toolchain_identifier)
- if toolchain_before.host_system_name != toolchain_after.host_system_name:
- _print_difference("host_system_name", toolchain_before.host_system_name,
- toolchain_after.host_system_name)
- found_difference = True
- if toolchain_before.target_system_name != toolchain_after.target_system_name:
- _print_difference("target_system_name", toolchain_before.target_system_name,
- toolchain_after.target_system_name)
- found_difference = True
- if toolchain_before.target_cpu != toolchain_after.target_cpu:
- _print_difference("target_cpu", toolchain_before.target_cpu,
- toolchain_after.target_cpu)
- found_difference = True
- if toolchain_before.target_libc != toolchain_after.target_libc:
- _print_difference("target_libc", toolchain_before.target_libc,
- toolchain_after.target_libc)
- found_difference = True
- if toolchain_before.compiler != toolchain_after.compiler:
- _print_difference("compiler", toolchain_before.compiler,
- toolchain_after.compiler)
- found_difference = True
- if toolchain_before.abi_version != toolchain_after.abi_version:
- _print_difference("abi_version", toolchain_before.abi_version,
- toolchain_after.abi_version)
- found_difference = True
- if toolchain_before.abi_libc_version != toolchain_after.abi_libc_version:
- _print_difference("abi_libc_version", toolchain_before.abi_libc_version,
- toolchain_after.abi_libc_version)
- found_difference = True
- if toolchain_before.cc_target_os != toolchain_after.cc_target_os:
- _print_difference("cc_target_os", toolchain_before.cc_target_os,
- toolchain_after.cc_target_os)
- found_difference = True
- if toolchain_before.builtin_sysroot != toolchain_after.builtin_sysroot:
- _print_difference("builtin_sysroot", toolchain_before.builtin_sysroot,
- toolchain_after.builtin_sysroot)
- found_difference = True
- found_difference = _compare_features(
- toolchain_before.feature, toolchain_after.feature) or found_difference
- found_difference = _compare_action_configs(
- toolchain_before.action_config,
- toolchain_after.action_config) or found_difference
- found_difference = _compare_tool_paths(
- toolchain_before.tool_path, toolchain_after.tool_path) or found_difference
- found_difference = _compare_cxx_builtin_include_directories(
- toolchain_before.cxx_builtin_include_directory,
- toolchain_after.cxx_builtin_include_directory) or found_difference
- found_difference = _compare_make_variables(
- toolchain_before.make_variable,
- toolchain_after.make_variable) or found_difference
- found_difference = _compare_artifact_name_patterns(
- toolchain_before.artifact_name_pattern,
- toolchain_after.artifact_name_pattern) or found_difference
- if not found_difference:
- print("No difference") # pylint: disable=superfluous-parens
- return found_difference
diff --git a/tools/migration/ctoolchain_comparator_lib_test.py b/tools/migration/ctoolchain_comparator_lib_test.py
deleted file mode 100644
index 1a3a270..0000000
--- a/tools/migration/ctoolchain_comparator_lib_test.py
+++ /dev/null
@@ -1,1821 +0,0 @@
-# Copyright 2018 The Bazel Authors. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import unittest
-
-from py import mock
-
-from google.protobuf import text_format
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-from tools.migration.ctoolchain_comparator_lib import compare_ctoolchains
-
-try:
- # Python 2
- from cStringIO import StringIO
-except ImportError:
- # Python 3
- from io import StringIO
-
-
-def make_toolchain(toolchain_proto):
- toolchain = crosstool_config_pb2.CToolchain()
- text_format.Merge(toolchain_proto, toolchain)
- return toolchain
-
-
-class CtoolchainComparatorLibTest(unittest.TestCase):
-
- def test_string_fields(self):
- first = make_toolchain("""
- toolchain_identifier: "first-id"
- host_system_name: "first-host"
- target_system_name: "first-target"
- target_cpu: "first-cpu"
- target_libc: "first-libc"
- compiler: "first-compiler"
- abi_version: "first-abi"
- abi_libc_version: "first-abi-libc"
- builtin_sysroot: "sysroot"
- """)
- second = make_toolchain("""
- toolchain_identifier: "second-id"
- host_system_name: "second-host"
- target_system_name: "second-target"
- target_cpu: "second-cpu"
- target_libc: "second-libc"
- compiler: "second-compiler"
- abi_version: "second-abi"
- abi_libc_version: "second-abi-libc"
- cc_target_os: "os"
- """)
- error_toolchain_identifier = (
- "Difference in 'toolchain_identifier' field:\n"
- "Value before change:\t'first-id'\n"
- "Value after change:\t'second-id'\n"
- )
- error_host_system_name = (
- "Difference in 'host_system_name' field:\n"
- "Value before change:\t'first-host'\n"
- "Value after change:\t'second-host'\n"
- )
- error_target_system_name = (
- "Difference in 'target_system_name' field:\n"
- "Value before change:\t'first-target'\n"
- "Value after change:\t'second-target'\n"
- )
- error_target_cpu = (
- "Difference in 'target_cpu' field:\n"
- "Value before change:\t'first-cpu'\n"
- "Value after change:\t'second-cpu'\n"
- )
- error_target_libc = (
- "Difference in 'target_libc' field:\n"
- "Value before change:\t'first-libc'\n"
- "Value after change:\t'second-libc'\n"
- )
- error_compiler = (
- "Difference in 'compiler' field:\n"
- "Value before change:\t'first-compiler'\n"
- "Value after change:\t'second-compiler'\n"
- )
- error_abi_version = (
- "Difference in 'abi_version' field:\n"
- "Value before change:\t'first-abi'\n"
- "Value after change:\t'second-abi'\n"
- )
- error_abi_libc_version = (
- "Difference in 'abi_libc_version' field:\n"
- "Value before change:\t'first-abi-libc'\n"
- "Value after change:\t'second-abi-libc'\n"
- )
- error_builtin_sysroot = (
- "Difference in 'builtin_sysroot' field:\n"
- "Value before change is set to 'sysroot'\n"
- "Value after change is not set\n"
- )
- error_cc_target_os = (
- "Difference in 'cc_target_os' field:\n"
- "Value before change is not set\n"
- "Value after change is set to 'os'\n"
- )
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(error_toolchain_identifier, mock_stdout.getvalue())
- self.assertIn(error_host_system_name, mock_stdout.getvalue())
- self.assertIn(error_target_system_name, mock_stdout.getvalue())
- self.assertIn(error_target_cpu, mock_stdout.getvalue())
- self.assertIn(error_target_libc, mock_stdout.getvalue())
- self.assertIn(error_compiler, mock_stdout.getvalue())
- self.assertIn(error_abi_version, mock_stdout.getvalue())
- self.assertIn(error_abi_libc_version, mock_stdout.getvalue())
- self.assertIn(error_builtin_sysroot, mock_stdout.getvalue())
- self.assertIn(error_cc_target_os, mock_stdout.getvalue())
-
- def test_tool_path(self):
- first = make_toolchain("""
- tool_path {
- name: "only_first"
- path: "/a/b/c"
- }
- tool_path {
- name: "paths_differ"
- path: "/path/first"
- }
- """)
- second = make_toolchain("""
- tool_path {
- name: "paths_differ"
- path: "/path/second"
- }
- tool_path {
- name: "only_second_1"
- path: "/a/b/c"
- }
- tool_path {
- name: "only_second_2"
- path: "/a/b/c"
- }
- """)
- error_only_first = (
- "* List before change contains entries for the "
- "following tools that the list after the change "
- "doesn't:\n[only_first]\n"
- )
- error_only_second = (
- "* List after change contains entries for the "
- "following tools that the list before the change "
- "doesn't:\n"
- "[\n"
- "\tonly_second_1\n"
- "\tonly_second_2\n"
- "]\n"
- )
- error_paths_differ = (
- "* Path for tool 'paths_differ' differs before and "
- "after the change:\n"
- "Value before change:\t'/path/first'\n"
- "Value after change:\t'/path/second'\n"
- )
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(error_only_first, mock_stdout.getvalue())
- self.assertIn(error_only_second, mock_stdout.getvalue())
- self.assertIn(error_paths_differ, mock_stdout.getvalue())
-
- def test_make_variable(self):
- first = make_toolchain("""
- make_variable {
- name: "only_first"
- value: "val"
- }
- make_variable {
- name: "value_differs"
- value: "first_value"
- }
- """)
- second = make_toolchain("""
- make_variable {
- name: "value_differs"
- value: "second_value"
- }
- make_variable {
- name: "only_second_1"
- value: "val"
- }
- make_variable {
- name: "only_second_2"
- value: "val"
- }
- """)
- error_only_first = (
- "* List before change contains entries for the "
- "following variables that the list after the "
- "change doesn't:\n[only_first]\n"
- )
- error_only_second = (
- "* List after change contains entries for the "
- "following variables that the list before the "
- "change doesn't:\n"
- "[\n"
- "\tonly_second_1\n"
- "\tonly_second_2\n"
- "]\n"
- )
- error_value_differs = (
- "* Value for variable 'value_differs' differs before"
- " and after the change:\n"
- "Value before change:\t'first_value'\n"
- "Value after change:\t'second_value'\n"
- )
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(error_only_first, mock_stdout.getvalue())
- self.assertIn(error_only_second, mock_stdout.getvalue())
- self.assertIn(error_value_differs, mock_stdout.getvalue())
-
- def test_cxx_builtin_include_directories(self):
- first = make_toolchain("""
- cxx_builtin_include_directory: "a/b/c"
- cxx_builtin_include_directory: "d/e/f"
- """)
- second = make_toolchain("""
- cxx_builtin_include_directory: "d/e/f"
- cxx_builtin_include_directory: "a/b/c"
- """)
- expect_error = (
- "Difference in 'cxx_builtin_include_directory' field:\n"
- "List of elements before change:\n"
- "[\n"
- "\ta/b/c\n"
- "\td/e/f\n"
- "]\n"
- "List of elements after change:\n"
- "[\n"
- "\td/e/f\n"
- "\ta/b/c\n"
- "]\n"
- )
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(expect_error, mock_stdout.getvalue())
-
- def test_artifact_name_pattern(self):
- first = make_toolchain("""
- artifact_name_pattern {
- category_name: 'object_file'
- prefix: ''
- extension: '.obj1'
- }
- artifact_name_pattern {
- category_name: 'executable'
- prefix: 'first'
- extension: '.exe'
- }
- artifact_name_pattern {
- category_name: 'dynamic_library'
- prefix: ''
- extension: '.dll'
- }
- """)
- second = make_toolchain("""
- artifact_name_pattern {
- category_name: 'object_file'
- prefix: ''
- extension: '.obj2'
- }
- artifact_name_pattern {
- category_name: 'static_library'
- prefix: ''
- extension: '.lib'
- }
- artifact_name_pattern {
- category_name: 'executable'
- prefix: 'second'
- extension: '.exe'
- }
- artifact_name_pattern {
- category_name: 'interface_library'
- prefix: ''
- extension: '.if.lib'
- }
- """)
- error_only_first = (
- "* List before change contains entries for the "
- "following categories that the list after the "
- "change doesn't:\n[dynamic_library]\n"
- )
- error_only_second = (
- "* List after change contains entries for the "
- "following categories that the list before the "
- "change doesn't:\n"
- "[\n"
- "\tinterface_library\n"
- "\tstatic_library\n"
- "]\n"
- )
- error_extension_differs = (
- "* Value for category 'object_file' differs "
- "before and after the change:\n"
- "Value before change:"
- "\tprefix:''"
- "\textension:'.obj1'\n"
- "Value after change:"
- "\tprefix:''"
- "\textension:'.obj2'\n"
- )
- error_prefix_differs = (
- "* Value for category 'executable' differs "
- "before and after the change:\n"
- "Value before change:"
- "\tprefix:'first'"
- "\textension:'.exe'\n"
- "Value after change:"
- "\tprefix:'second'"
- "\textension:'.exe'\n"
- )
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(error_only_first, mock_stdout.getvalue())
- self.assertIn(error_only_second, mock_stdout.getvalue())
- self.assertIn(error_extension_differs, mock_stdout.getvalue())
- self.assertIn(error_prefix_differs, mock_stdout.getvalue())
-
- def test_features_not_ordered(self):
- first = make_toolchain("""
- feature {
- name: 'feature1'
- }
- feature {
- name: 'feature2'
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature2'
- }
- feature {
- name: 'feature1'
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("Features not in right order", mock_stdout.getvalue())
-
- def test_features_missing(self):
- first = make_toolchain("""
- feature {
- name: 'feature1'
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature2'
- }
- """)
- error_only_first = (
- "* List before change contains entries for the "
- "following features that the list after the "
- "change doesn't:\n[feature1]\n"
- )
- error_only_second = (
- "* List after change contains entries for the "
- "following features that the list before the "
- "change doesn't:\n[feature2]\n"
- )
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(error_only_first, mock_stdout.getvalue())
- self.assertIn(error_only_second, mock_stdout.getvalue())
-
- def test_feature_enabled(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- enabled: true
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- enabled: false
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after", mock_stdout.getvalue()
- )
-
- def test_feature_provides(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- provides: 'a'
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- provides: 'b'
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after the change:",
- mock_stdout.getvalue(),
- )
-
- def test_feature_provides_preserves_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- provides: 'a'
- provides: 'b'
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- provides: 'b'
- provides: 'a'
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after the change:",
- mock_stdout.getvalue(),
- )
-
- def test_feature_implies(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- implies: 'a'
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after the change:",
- mock_stdout.getvalue(),
- )
-
- def test_feature_implies_preserves_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- implies: 'a'
- implies: 'b'
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- implies: 'b'
- implies: 'a'
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after the change:",
- mock_stdout.getvalue(),
- )
-
- def test_feature_requires_preserves_list_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- requires: {
- feature: 'feature1'
- }
- requires: {
- feature: 'feature2'
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- requires: {
- feature: 'feature2'
- }
- requires: {
- feature: 'feature1'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after the change:",
- mock_stdout.getvalue(),
- )
-
- def test_feature_requires_ignores_required_features_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- requires: {
- feature: 'feature1'
- feature: 'feature2'
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- requires: {
- feature: 'feature2'
- feature: 'feature1'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_feature_requires_differs(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- requires: {
- feature: 'feature1'
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- requires: {
- feature: 'feature2'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after the change:",
- mock_stdout.getvalue(),
- )
-
- def test_action_config_ignores_requires(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- requires: {
- feature: 'feature1'
- }
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- requires: {
- feature: 'feature2'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_env_set_actions_differ(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- env_set {
- action: 'a1'
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- env_set: {
- action: 'a1'
- action: 'a2'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after the change:",
- mock_stdout.getvalue(),
- )
-
- def test_env_set_ignores_actions_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- env_set {
- action: 'a2'
- action: 'a1'
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- env_set: {
- action: 'a1'
- action: 'a2'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_env_set_env_entries_not_ordered(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- env_set {
- env_entry {
- key: 'k1'
- value: 'v1'
- }
- env_entry {
- key: 'k2'
- value: 'v2'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- env_set {
- env_entry {
- key: 'k2'
- value: 'v2'
- }
- env_entry {
- key: 'k1'
- value: 'v1'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after the change:",
- mock_stdout.getvalue(),
- )
-
- def test_env_set_env_entries_differ(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- env_set {
- env_entry {
- key: 'k1'
- value: 'value_first'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- env_set {
- env_entry {
- key: 'k1'
- value: 'value_second'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after the change:",
- mock_stdout.getvalue(),
- )
-
- def test_feature_preserves_env_set_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- env_set {
- env_entry {
- key: 'first'
- value: 'first'
- }
- }
- env_set {
- env_entry {
- key: 'second'
- value: 'second'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- env_set {
- env_entry {
- key: 'second'
- value: 'second'
- }
- }
- env_set {
- env_entry {
- key: 'first'
- value: 'first'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after the change:",
- mock_stdout.getvalue(),
- )
-
- def test_action_config_ignores_env_set(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- env_set {
- env_entry {
- key: 'k1'
- value: 'value_first'
- }
- }
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- env_set {
- env_entry {
- key: 'k1'
- value: 'value_second'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_env_set_ignores_with_feature_set_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- env_set{
- with_feature {
- feature: 'feature1'
- }
- with_feature {
- not_feature: 'feature2'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- env_set {
- with_feature {
- not_feature: 'feature2'
- }
- with_feature {
- feature: 'feature1'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_env_set_ignores_with_feature_set_lists_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- env_set{
- with_feature {
- feature: 'feature1'
- feature: 'feature2'
- not_feature: 'not_feature1'
- not_feature: 'not_feature2'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- env_set{
- with_feature {
- feature: 'feature2'
- feature: 'feature1'
- not_feature: 'not_feature2'
- not_feature: 'not_feature1'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_flag_set_ignores_actions_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set {
- action: 'a1'
- action: 'a2'
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set {
- action: 'a2'
- action: 'a1'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_action_config_flag_set_actions_ignored(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- flag_set {
- action: 'a1'
- }
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- flag_set {
- action: 'a2'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_flag_set_ignores_with_feature_set_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set {
- with_feature {
- feature: 'feature1'
- }
- with_feature {
- not_feature: 'feature2'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set {
- with_feature {
- feature: 'feature1'
- }
- with_feature {
- not_feature: 'feature2'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set {
- with_feature {
- not_feature: 'feature2'
- }
- with_feature {
- feature: 'feature1'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set {
- with_feature {
- not_feature: 'feature2'
- }
- with_feature {
- feature: 'feature1'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_flag_set_ignores_with_feature_set_lists_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- with_feature {
- feature: 'feature1'
- feature: 'feature2'
- not_feature: 'not_feature1'
- not_feature: 'not_feature2'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- with_feature {
- feature: 'feature1'
- feature: 'feature2'
- not_feature: 'not_feature1'
- not_feature: 'not_feature2'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- with_feature {
- feature: 'feature2'
- feature: 'feature1'
- not_feature: 'not_feature2'
- not_feature: 'not_feature1'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- with_feature {
- feature: 'feature2'
- feature: 'feature1'
- not_feature: 'not_feature2'
- not_feature: 'not_feature1'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_flag_set_preserves_flag_group_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set {
- flag_group {
- flag: 'a'
- }
- flag_group {
- flag: 'b'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set {
- flag_group {
- flag: 'a'
- }
- flag_group {
- flag: 'b'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set {
- flag_group {
- flag: 'b'
- }
- flag_group {
- flag: 'a'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set {
- flag_group {
- flag: 'b'
- }
- flag_group {
- flag: 'a'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after", mock_stdout.getvalue()
- )
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_flag_group_preserves_flags_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- flag: 'flag1'
- flag: 'flag2'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- flag: 'flag1'
- flag: 'flag2'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- flag: 'flag2'
- flag: 'flag1'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- flag: 'flag2'
- flag: 'flag1'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after", mock_stdout.getvalue()
- )
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_flag_group_iterate_over_differs(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- iterate_over: 'a'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- iterate_over: 'a'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- iterate_over: 'b'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- iterate_over: 'b'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after", mock_stdout.getvalue()
- )
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_flag_group_expand_if_true_differs(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_true: 'a'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_true: 'a'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_true: 'b'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_true: 'b'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after", mock_stdout.getvalue()
- )
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_flag_group_expand_if_false_differs(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_false: 'a'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_false: 'a'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_false: 'b'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_false: 'b'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after", mock_stdout.getvalue()
- )
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_flag_group_expand_if_all_available_differs(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_all_available: 'a'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_all_available: 'a'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_all_available: 'b'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_all_available: 'b'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after", mock_stdout.getvalue()
- )
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_flag_group_expand_if_none_available_differs(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_none_available: 'a'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_none_available: 'a'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_none_available: 'b'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_none_available: 'b'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after", mock_stdout.getvalue()
- )
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_flag_group_expand_if_all_available_ignores_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_all_available: 'a'
- expand_if_all_available: 'b'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_all_available: 'a'
- expand_if_all_available: 'b'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_all_available: 'b'
- expand_if_all_available: 'a'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_all_available: 'b'
- expand_if_all_available: 'a'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_flag_group_expand_if_none_available_ignores_order(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_none_available: 'a'
- expand_if_none_available: 'b'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_none_available: 'a'
- expand_if_none_available: 'b'
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_none_available: 'b'
- expand_if_none_available: 'a'
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_none_available: 'b'
- expand_if_none_available: 'a'
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_flag_group_expand_if_equal_differs(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_equal {
- variable: 'first'
- value: 'val'
- }
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_equal {
- variable: 'first'
- value: 'val'
- }
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- expand_if_equal {
- variable: 'second'
- value: 'val'
- }
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- expand_if_equal {
- variable: 'second'
- value: 'val'
- }
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after", mock_stdout.getvalue()
- )
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_flag_group_flag_groups_differ(self):
- first = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- flag_group {
- flag: 'a'
- flag: 'b'
- }
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- flag_group {
- flag: 'a'
- flag: 'b'
- }
- }
- }
- }
- """)
- second = make_toolchain("""
- feature {
- name: 'feature'
- flag_set{
- flag_group {
- flag_group {
- flag: 'b'
- flag: 'a'
- }
- }
- }
- }
- action_config {
- config_name: 'config'
- flag_set{
- flag_group {
- flag_group {
- flag: 'b'
- flag: 'a'
- }
- }
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Feature 'feature' differs before and after", mock_stdout.getvalue()
- )
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_action_configs_not_ordered(self):
- first = make_toolchain("""
- action_config {
- config_name: 'action1'
- }
- action_config {
- config_name: 'action2'
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'action2'
- }
- action_config {
- config_name: 'action1'
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("Action configs not in right order", mock_stdout.getvalue())
-
- def test_action_configs_missing(self):
- first = make_toolchain("""
- action_config {
- config_name: 'action1'
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'action2'
- }
- """)
- error_only_first = (
- "* List before change contains entries for the "
- "following action_configs that the list after the "
- "change doesn't:\n[action1]\n"
- )
- error_only_second = (
- "* List after change contains entries for the "
- "following action_configs that the list before the "
- "change doesn't:\n[action2]\n"
- )
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(error_only_first, mock_stdout.getvalue())
- self.assertIn(error_only_second, mock_stdout.getvalue())
-
- def test_action_config_enabled(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- enabled: true
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- enabled: false
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_action_config_action_name(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- action_name: 'config1'
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- action_name: 'config2'
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_action_config_tool_tool_path_differs(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- tool {
- tool_path: 'path1'
- }
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- tool {
- tool_path: 'path2'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_action_config_tool_execution_requirements_differ(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- tool {
- execution_requirement: 'a'
- }
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- tool {
- execution_requirement: 'b'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_action_config_tool_execution_requirements_ignores_order(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- tool {
- execution_requirement: 'a'
- execution_requirement: 'b'
- }
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- tool {
- execution_requirement: 'b'
- execution_requirement: 'a'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_action_config_implies_differs(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- implies: 'a'
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- implies: 'b'
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_action_config_implies_preserves_order(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- implies: 'a'
- implies: 'b'
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- implies: 'b'
- implies: 'a'
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn(
- "* Action config 'config' differs before and after",
- mock_stdout.getvalue(),
- )
-
- def test_unused_tool_path(self):
- first = make_toolchain("""
- tool_path {
- name: "empty"
- path: ""
- }
- """)
- second = make_toolchain("""
- tool_path {
- name: "empty"
- path: "NOT_USED"
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
- def test_unused_tool_path_in_tool(self):
- first = make_toolchain("""
- action_config {
- config_name: 'config'
- tool {
- tool_path: ''
- }
- }
- """)
- second = make_toolchain("""
- action_config {
- config_name: 'config'
- tool {
- tool_path: 'NOT_USED'
- }
- }
- """)
- mock_stdout = StringIO()
- with mock.patch("sys.stdout", mock_stdout):
- compare_ctoolchains(first, second)
- self.assertIn("No difference", mock_stdout.getvalue())
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tools/migration/ctoolchain_compare.bzl b/tools/migration/ctoolchain_compare.bzl
deleted file mode 100644
index a9632af..0000000
--- a/tools/migration/ctoolchain_compare.bzl
+++ /dev/null
@@ -1,49 +0,0 @@
-"""A test rule that compares two CToolchains in proto format."""
-
-def _impl(ctx):
- toolchain_config_proto = ctx.actions.declare_file(ctx.label.name + "_toolchain_config.proto")
- ctx.actions.write(
- toolchain_config_proto,
- ctx.attr.toolchain_config[CcToolchainConfigInfo].proto,
- )
-
- script = ("%s --before='%s' --after='%s' --toolchain_identifier='%s'" % (
- ctx.executable._comparator.short_path,
- ctx.file.crosstool.short_path,
- toolchain_config_proto.short_path,
- ctx.attr.toolchain_identifier,
- ))
- test_executable = ctx.actions.declare_file(ctx.label.name)
- ctx.actions.write(test_executable, script, is_executable = True)
-
- runfiles = ctx.runfiles(files = [toolchain_config_proto, ctx.file.crosstool])
- runfiles = runfiles.merge(ctx.attr._comparator[DefaultInfo].default_runfiles)
-
- return DefaultInfo(runfiles = runfiles, executable = test_executable)
-
-cc_toolchains_compare_test = rule(
- implementation = _impl,
- attrs = {
- "crosstool": attr.label(
- mandatory = True,
- allow_single_file = True,
- doc = "Location of the CROSSTOOL file",
- ),
- "toolchain_config": attr.label(
- mandatory = True,
- providers = [CcToolchainConfigInfo],
- doc = ("Starlark rule that replaces the CROSSTOOL file functionality " +
- "for the CToolchain with the given identifier"),
- ),
- "toolchain_identifier": attr.string(
- mandatory = True,
- doc = "identifier of the CToolchain that is being compared",
- ),
- "_comparator": attr.label(
- default = ":ctoolchain_comparator",
- executable = True,
- cfg = "exec",
- ),
- },
- test = True,
-)
diff --git a/tools/migration/legacy_fields_migration_lib.py b/tools/migration/legacy_fields_migration_lib.py
deleted file mode 100644
index 6107f92..0000000
--- a/tools/migration/legacy_fields_migration_lib.py
+++ /dev/null
@@ -1,564 +0,0 @@
-"""Module providing migrate_legacy_fields function.
-
-migrate_legacy_fields takes parsed CROSSTOOL proto and migrates it (inplace) to
-use only the features.
-
-Tracking issue: https://github.com/bazelbuild/bazel/issues/5187
-
-Since C++ rules team is working on migrating CROSSTOOL from text proto into
-Starlark, we advise CROSSTOOL owners to wait for the CROSSTOOL -> Starlark
-migrator before they invest too much time into fixing their pipeline. Tracking
-issue for the Starlark effort is
-https://github.com/bazelbuild/bazel/issues/5380.
-"""
-
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-
-ALL_CC_COMPILE_ACTIONS = [
- "assemble", "preprocess-assemble", "linkstamp-compile", "c-compile",
- "c++-compile", "c++-header-parsing", "c++-module-compile",
- "c++-module-codegen", "lto-backend", "clif-match"
-]
-
-ALL_OBJC_COMPILE_ACTIONS = [
- "objc-compile", "objc++-compile"
-]
-
-ALL_CXX_COMPILE_ACTIONS = [
- action for action in ALL_CC_COMPILE_ACTIONS
- if action not in ["c-compile", "preprocess-assemble", "assemble"]
-]
-
-ALL_CC_LINK_ACTIONS = [
- "c++-link-executable", "c++-link-dynamic-library",
- "c++-link-nodeps-dynamic-library"
-]
-
-ALL_OBJC_LINK_ACTIONS = [
- "objc-executable", "objc++-executable",
-]
-
-DYNAMIC_LIBRARY_LINK_ACTIONS = [
- "c++-link-dynamic-library", "c++-link-nodeps-dynamic-library"
-]
-
-NODEPS_DYNAMIC_LIBRARY_LINK_ACTIONS = ["c++-link-nodeps-dynamic-library"]
-
-TRANSITIVE_DYNAMIC_LIBRARY_LINK_ACTIONS = ["c++-link-dynamic-library"]
-
-TRANSITIVE_LINK_ACTIONS = ["c++-link-executable", "c++-link-dynamic-library"]
-
-CC_LINK_EXECUTABLE = ["c++-link-executable"]
-
-
-def compile_actions(toolchain):
- """Returns compile actions for cc or objc rules."""
- if _is_objc_toolchain(toolchain):
- return ALL_CC_COMPILE_ACTIONS + ALL_OBJC_COMPILE_ACTIONS
- else:
- return ALL_CC_COMPILE_ACTIONS
-
-def link_actions(toolchain):
- """Returns link actions for cc or objc rules."""
- if _is_objc_toolchain(toolchain):
- return ALL_CC_LINK_ACTIONS + ALL_OBJC_LINK_ACTIONS
- else:
- return ALL_CC_LINK_ACTIONS
-
-
-def executable_link_actions(toolchain):
- """Returns transitive link actions for cc or objc rules."""
- if _is_objc_toolchain(toolchain):
- return CC_LINK_EXECUTABLE + ALL_OBJC_LINK_ACTIONS
- else:
- return CC_LINK_EXECUTABLE
-
-
-def _is_objc_toolchain(toolchain):
- return any(ac.action_name == "objc-compile" for ac in toolchain.action_config)
-
-# Map converting from LinkingMode to corresponding feature name
-LINKING_MODE_TO_FEATURE_NAME = {
- "FULLY_STATIC": "fully_static_link",
- "MOSTLY_STATIC": "static_linking_mode",
- "DYNAMIC": "dynamic_linking_mode",
- "MOSTLY_STATIC_LIBRARIES": "static_linking_mode_nodeps_library",
-}
-
-def migrate_legacy_fields(crosstool):
- """Migrates parsed crosstool (inplace) to not use legacy fields."""
- crosstool.ClearField("default_toolchain")
- for toolchain in crosstool.toolchain:
- _ = [_migrate_expand_if_all_available(f) for f in toolchain.feature]
- _ = [_migrate_expand_if_all_available(ac) for ac in toolchain.action_config]
- _ = [_migrate_repeated_expands(f) for f in toolchain.feature]
- _ = [_migrate_repeated_expands(ac) for ac in toolchain.action_config]
-
- if (toolchain.dynamic_library_linker_flag or
- _contains_dynamic_flags(toolchain)) and not _get_feature(
- toolchain, "supports_dynamic_linker"):
- feature = toolchain.feature.add()
- feature.name = "supports_dynamic_linker"
- feature.enabled = True
-
- if toolchain.supports_start_end_lib and not _get_feature(
- toolchain, "supports_start_end_lib"):
- feature = toolchain.feature.add()
- feature.name = "supports_start_end_lib"
- feature.enabled = True
-
- if toolchain.supports_interface_shared_objects and not _get_feature(
- toolchain, "supports_interface_shared_libraries"):
- feature = toolchain.feature.add()
- feature.name = "supports_interface_shared_libraries"
- feature.enabled = True
-
- if toolchain.supports_embedded_runtimes and not _get_feature(
- toolchain, "static_link_cpp_runtimes"):
- feature = toolchain.feature.add()
- feature.name = "static_link_cpp_runtimes"
- feature.enabled = True
-
- if toolchain.needsPic and not _get_feature(toolchain, "supports_pic"):
- feature = toolchain.feature.add()
- feature.name = "supports_pic"
- feature.enabled = True
-
- if toolchain.supports_fission and not _get_feature(
- toolchain, "per_object_debug_info"):
- # feature {
- # name: "per_object_debug_info"
- # enabled: true
- # flag_set {
- # action: "assemble"
- # action: "preprocess-assemble"
- # action: "c-compile"
- # action: "c++-compile"
- # action: "c++-module-codegen"
- # action: "lto-backend"
- # flag_group {
- # expand_if_all_available: 'is_using_fission'",
- # flag: "-gsplit-dwarf"
- # }
- # }
- # }
- feature = toolchain.feature.add()
- feature.name = "per_object_debug_info"
- feature.enabled = True
- flag_set = feature.flag_set.add()
- flag_set.action[:] = [
- "c-compile", "c++-compile", "c++-module-codegen", "assemble",
- "preprocess-assemble", "lto-backend"
- ]
- flag_group = flag_set.flag_group.add()
- flag_group.expand_if_all_available[:] = ["is_using_fission"]
- flag_group.flag[:] = ["-gsplit-dwarf"]
-
- if toolchain.objcopy_embed_flag and not _get_feature(
- toolchain, "objcopy_embed_flags"):
- feature = toolchain.feature.add()
- feature.name = "objcopy_embed_flags"
- feature.enabled = True
- flag_set = feature.flag_set.add()
- flag_set.action[:] = ["objcopy_embed_data"]
- flag_group = flag_set.flag_group.add()
- flag_group.flag[:] = toolchain.objcopy_embed_flag
-
- action_config = toolchain.action_config.add()
- action_config.action_name = "objcopy_embed_data"
- action_config.config_name = "objcopy_embed_data"
- action_config.enabled = True
- tool = action_config.tool.add()
- tool.tool_path = _find_tool_path(toolchain, "objcopy")
-
- if toolchain.ld_embed_flag and not _get_feature(
- toolchain, "ld_embed_flags"):
- feature = toolchain.feature.add()
- feature.name = "ld_embed_flags"
- feature.enabled = True
- flag_set = feature.flag_set.add()
- flag_set.action[:] = ["ld_embed_data"]
- flag_group = flag_set.flag_group.add()
- flag_group.flag[:] = toolchain.ld_embed_flag
-
- action_config = toolchain.action_config.add()
- action_config.action_name = "ld_embed_data"
- action_config.config_name = "ld_embed_data"
- action_config.enabled = True
- tool = action_config.tool.add()
- tool.tool_path = _find_tool_path(toolchain, "ld")
-
-
- # Create default_link_flags feature for linker_flag
- flag_sets = _extract_legacy_link_flag_sets_for(toolchain)
- if flag_sets:
- if _get_feature(toolchain, "default_link_flags"):
- continue
- if _get_feature(toolchain, "legacy_link_flags"):
- for f in toolchain.feature:
- if f.name == "legacy_link_flags":
- f.ClearField("flag_set")
- feature = f
- _rename_feature_in_toolchain(toolchain, "legacy_link_flags",
- "default_link_flags")
- break
- else:
- feature = _prepend_feature(toolchain)
- feature.name = "default_link_flags"
- feature.enabled = True
- _add_flag_sets(feature, flag_sets)
-
- # Create default_compile_flags feature for compiler_flag, cxx_flag
- flag_sets = _extract_legacy_compile_flag_sets_for(toolchain)
- if flag_sets and not _get_feature(toolchain, "default_compile_flags"):
- if _get_feature(toolchain, "legacy_compile_flags"):
- for f in toolchain.feature:
- if f.name == "legacy_compile_flags":
- f.ClearField("flag_set")
- feature = f
- _rename_feature_in_toolchain(toolchain, "legacy_compile_flags",
- "default_compile_flags")
- break
- else:
- feature = _prepend_feature(toolchain)
- feature.enabled = True
- feature.name = "default_compile_flags"
- _add_flag_sets(feature, flag_sets)
-
- # Unfiltered cxx flags have to have their own special feature.
- # "unfiltered_compile_flags" is a well-known (by Bazel) feature name that is
- # excluded from nocopts filtering.
- if toolchain.unfiltered_cxx_flag:
- # If there already is a feature named unfiltered_compile_flags, the
- # crosstool is already migrated for unfiltered_compile_flags
- if _get_feature(toolchain, "unfiltered_compile_flags"):
- for f in toolchain.feature:
- if f.name == "unfiltered_compile_flags":
- for flag_set in f.flag_set:
- for flag_group in flag_set.flag_group:
- if flag_group.iterate_over == "unfiltered_compile_flags":
- flag_group.ClearField("iterate_over")
- flag_group.ClearField("expand_if_all_available")
- flag_group.ClearField("flag")
- flag_group.flag[:] = toolchain.unfiltered_cxx_flag
- else:
- if not _get_feature(toolchain, "user_compile_flags"):
- feature = toolchain.feature.add()
- feature.name = "user_compile_flags"
- feature.enabled = True
- flag_set = feature.flag_set.add()
- flag_set.action[:] = compile_actions(toolchain)
- flag_group = flag_set.flag_group.add()
- flag_group.expand_if_all_available[:] = ["user_compile_flags"]
- flag_group.iterate_over = "user_compile_flags"
- flag_group.flag[:] = ["%{user_compile_flags}"]
-
- if not _get_feature(toolchain, "sysroot"):
- sysroot_actions = compile_actions(toolchain) + link_actions(toolchain)
- sysroot_actions.remove("assemble")
- feature = toolchain.feature.add()
- feature.name = "sysroot"
- feature.enabled = True
- flag_set = feature.flag_set.add()
- flag_set.action[:] = sysroot_actions
- flag_group = flag_set.flag_group.add()
- flag_group.expand_if_all_available[:] = ["sysroot"]
- flag_group.flag[:] = ["--sysroot=%{sysroot}"]
-
- feature = toolchain.feature.add()
- feature.name = "unfiltered_compile_flags"
- feature.enabled = True
- flag_set = feature.flag_set.add()
- flag_set.action[:] = compile_actions(toolchain)
- flag_group = flag_set.flag_group.add()
- flag_group.flag[:] = toolchain.unfiltered_cxx_flag
-
- # clear fields
- toolchain.ClearField("debian_extra_requires")
- toolchain.ClearField("gcc_plugin_compiler_flag")
- toolchain.ClearField("ar_flag")
- toolchain.ClearField("ar_thin_archives_flag")
- toolchain.ClearField("gcc_plugin_header_directory")
- toolchain.ClearField("mao_plugin_header_directory")
- toolchain.ClearField("supports_normalizing_ar")
- toolchain.ClearField("supports_thin_archives")
- toolchain.ClearField("supports_incremental_linker")
- toolchain.ClearField("supports_dsym")
- toolchain.ClearField("supports_gold_linker")
- toolchain.ClearField("default_python_top")
- toolchain.ClearField("default_python_version")
- toolchain.ClearField("python_preload_swigdeps")
- toolchain.ClearField("needsPic")
- toolchain.ClearField("compilation_mode_flags")
- toolchain.ClearField("linking_mode_flags")
- toolchain.ClearField("unfiltered_cxx_flag")
- toolchain.ClearField("ld_embed_flag")
- toolchain.ClearField("objcopy_embed_flag")
- toolchain.ClearField("supports_start_end_lib")
- toolchain.ClearField("supports_interface_shared_objects")
- toolchain.ClearField("supports_fission")
- toolchain.ClearField("supports_embedded_runtimes")
- toolchain.ClearField("compiler_flag")
- toolchain.ClearField("cxx_flag")
- toolchain.ClearField("linker_flag")
- toolchain.ClearField("dynamic_library_linker_flag")
- toolchain.ClearField("static_runtimes_filegroup")
- toolchain.ClearField("dynamic_runtimes_filegroup")
-
- # Enable features that were previously enabled by Bazel
- default_features = [
- "dependency_file", "random_seed", "module_maps", "module_map_home_cwd",
- "header_module_compile", "include_paths", "pic", "preprocessor_define"
- ]
- for feature_name in default_features:
- feature = _get_feature(toolchain, feature_name)
- if feature:
- feature.enabled = True
-
-
-def _find_tool_path(toolchain, tool_name):
- """Returns the tool path of the tool with the given name."""
- for tool in toolchain.tool_path:
- if tool.name == tool_name:
- return tool.path
- return None
-
-
-def _add_flag_sets(feature, flag_sets):
- """Add flag sets into a feature."""
- for flag_set in flag_sets:
- with_feature = flag_set[0]
- actions = flag_set[1]
- flags = flag_set[2]
- expand_if_all_available = flag_set[3]
- not_feature = None
- if len(flag_set) >= 5:
- not_feature = flag_set[4]
- flag_set = feature.flag_set.add()
- if with_feature is not None:
- flag_set.with_feature.add().feature[:] = [with_feature]
- if not_feature is not None:
- flag_set.with_feature.add().not_feature[:] = [not_feature]
- flag_set.action[:] = actions
- flag_group = flag_set.flag_group.add()
- flag_group.expand_if_all_available[:] = expand_if_all_available
- flag_group.flag[:] = flags
- return feature
-
-
-def _extract_legacy_compile_flag_sets_for(toolchain):
- """Get flag sets for default_compile_flags feature."""
- result = []
- if toolchain.compiler_flag:
- result.append(
- [None, compile_actions(toolchain), toolchain.compiler_flag, []])
-
- # Migrate compiler_flag from compilation_mode_flags
- for cmf in toolchain.compilation_mode_flags:
- mode = crosstool_config_pb2.CompilationMode.Name(cmf.mode).lower()
- # coverage mode has been a noop since a while
- if mode == "coverage":
- continue
-
- if (cmf.compiler_flag or
- cmf.cxx_flag) and not _get_feature(toolchain, mode):
- feature = toolchain.feature.add()
- feature.name = mode
-
- if cmf.compiler_flag:
- result.append([mode, compile_actions(toolchain), cmf.compiler_flag, []])
-
- if toolchain.cxx_flag:
- result.append([None, ALL_CXX_COMPILE_ACTIONS, toolchain.cxx_flag, []])
-
- # Migrate compiler_flag/cxx_flag from compilation_mode_flags
- for cmf in toolchain.compilation_mode_flags:
- mode = crosstool_config_pb2.CompilationMode.Name(cmf.mode).lower()
- # coverage mode has been a noop since a while
- if mode == "coverage":
- continue
-
- if cmf.cxx_flag:
- result.append([mode, ALL_CXX_COMPILE_ACTIONS, cmf.cxx_flag, []])
-
- return result
-
-
-def _extract_legacy_link_flag_sets_for(toolchain):
- """Get flag sets for default_link_flags feature."""
- result = []
-
- # Migrate linker_flag
- if toolchain.linker_flag:
- result.append([None, link_actions(toolchain), toolchain.linker_flag, []])
-
- # Migrate linker_flags from compilation_mode_flags
- for cmf in toolchain.compilation_mode_flags:
- mode = crosstool_config_pb2.CompilationMode.Name(cmf.mode).lower()
- # coverage mode has beed a noop since a while
- if mode == "coverage":
- continue
-
- if cmf.linker_flag and not _get_feature(toolchain, mode):
- feature = toolchain.feature.add()
- feature.name = mode
-
- if cmf.linker_flag:
- result.append([mode, link_actions(toolchain), cmf.linker_flag, []])
-
- # Migrate linker_flags from linking_mode_flags
- for lmf in toolchain.linking_mode_flags:
- mode = crosstool_config_pb2.LinkingMode.Name(lmf.mode)
- feature_name = LINKING_MODE_TO_FEATURE_NAME.get(mode)
- # if the feature is already there, we don't migrate, lmf is not used
- if _get_feature(toolchain, feature_name):
- continue
-
- if lmf.linker_flag:
- feature = toolchain.feature.add()
- feature.name = feature_name
- if mode == "DYNAMIC":
- result.append(
- [None, NODEPS_DYNAMIC_LIBRARY_LINK_ACTIONS, lmf.linker_flag, []])
- result.append([
- None,
- TRANSITIVE_DYNAMIC_LIBRARY_LINK_ACTIONS,
- lmf.linker_flag,
- [],
- "static_link_cpp_runtimes",
- ])
- result.append([
- feature_name,
- executable_link_actions(toolchain), lmf.linker_flag, []
- ])
- elif mode == "MOSTLY_STATIC":
- result.append(
- [feature_name,
- CC_LINK_EXECUTABLE, lmf.linker_flag, []])
- else:
- result.append(
- [feature_name,
- link_actions(toolchain), lmf.linker_flag, []])
-
- if toolchain.dynamic_library_linker_flag:
- result.append([
- None, DYNAMIC_LIBRARY_LINK_ACTIONS,
- toolchain.dynamic_library_linker_flag, []
- ])
-
- if toolchain.test_only_linker_flag:
- result.append([
- None,
- link_actions(toolchain), toolchain.test_only_linker_flag,
- ["is_cc_test"]
- ])
-
- return result
-
-
-def _prepend_feature(toolchain):
- """Create a new feature and make it be the first in the toolchain."""
- features = toolchain.feature
- toolchain.ClearField("feature")
- new_feature = toolchain.feature.add()
- toolchain.feature.extend(features)
- return new_feature
-
-
-def _get_feature(toolchain, name):
- """Returns feature with a given name or None."""
- for feature in toolchain.feature:
- if feature.name == name:
- return feature
- return None
-
-
-def _migrate_expand_if_all_available(message):
- """Move expand_if_all_available field to flag_groups."""
- for flag_set in message.flag_set:
- if flag_set.expand_if_all_available:
- for flag_group in flag_set.flag_group:
- new_vars = (
- flag_group.expand_if_all_available[:] +
- flag_set.expand_if_all_available[:])
- flag_group.expand_if_all_available[:] = new_vars
- flag_set.ClearField("expand_if_all_available")
-
-
-def _migrate_repeated_expands(message):
- """Replace repeated legacy fields with nesting."""
- todo_queue = []
- for flag_set in message.flag_set:
- todo_queue.extend(flag_set.flag_group)
- while todo_queue:
- flag_group = todo_queue.pop()
- todo_queue.extend(flag_group.flag_group)
- if len(flag_group.expand_if_all_available) <= 1 and len(
- flag_group.expand_if_none_available) <= 1:
- continue
-
- current_children = flag_group.flag_group
- current_flags = flag_group.flag
- flag_group.ClearField("flag_group")
- flag_group.ClearField("flag")
-
- new_flag_group = flag_group.flag_group.add()
- new_flag_group.flag_group.extend(current_children)
- new_flag_group.flag.extend(current_flags)
-
- if len(flag_group.expand_if_all_available) > 1:
- expands_to_move = flag_group.expand_if_all_available[1:]
- flag_group.expand_if_all_available[:] = [
- flag_group.expand_if_all_available[0]
- ]
- new_flag_group.expand_if_all_available.extend(expands_to_move)
-
- if len(flag_group.expand_if_none_available) > 1:
- expands_to_move = flag_group.expand_if_none_available[1:]
- flag_group.expand_if_none_available[:] = [
- flag_group.expand_if_none_available[0]
- ]
- new_flag_group.expand_if_none_available.extend(expands_to_move)
-
- todo_queue.append(new_flag_group)
- todo_queue.append(flag_group)
-
-
-def _contains_dynamic_flags(toolchain):
- for lmf in toolchain.linking_mode_flags:
- mode = crosstool_config_pb2.LinkingMode.Name(lmf.mode)
- if mode == "DYNAMIC":
- return True
- return False
-
-
-def _rename_feature_in_toolchain(toolchain, from_name, to_name):
- for f in toolchain.feature:
- _rename_feature_in(f, from_name, to_name)
- for a in toolchain.action_config:
- _rename_feature_in(a, from_name, to_name)
-
-
-def _rename_feature_in(msg, from_name, to_name):
- if from_name in msg.implies:
- msg.implies.remove(from_name)
- for requires in msg.requires:
- if from_name in requires.feature:
- requires.feature.remove(from_name)
- requires.feature.extend([to_name])
- for flag_set in msg.flag_set:
- for with_feature in flag_set.with_feature:
- if from_name in with_feature.feature:
- with_feature.feature.remove(from_name)
- with_feature.feature.extend([to_name])
- if from_name in with_feature.not_feature:
- with_feature.not_feature.remove(from_name)
- with_feature.not_feature.extend([to_name])
- for env_set in msg.env_set:
- for with_feature in env_set.with_feature:
- if from_name in with_feature.feature:
- with_feature.feature.remove(from_name)
- with_feature.feature.extend([to_name])
- if from_name in with_feature.not_feature:
- with_feature.not_feature.remove(from_name)
- with_feature.not_feature.extend([to_name])
diff --git a/tools/migration/legacy_fields_migration_lib_test.py b/tools/migration/legacy_fields_migration_lib_test.py
deleted file mode 100644
index 93972cc..0000000
--- a/tools/migration/legacy_fields_migration_lib_test.py
+++ /dev/null
@@ -1,1240 +0,0 @@
-import unittest
-from google.protobuf import text_format
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-from tools.migration.legacy_fields_migration_lib import ALL_CC_COMPILE_ACTIONS
-from tools.migration.legacy_fields_migration_lib import ALL_OBJC_COMPILE_ACTIONS
-from tools.migration.legacy_fields_migration_lib import ALL_CXX_COMPILE_ACTIONS
-from tools.migration.legacy_fields_migration_lib import ALL_CC_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import ALL_OBJC_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import DYNAMIC_LIBRARY_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import NODEPS_DYNAMIC_LIBRARY_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import TRANSITIVE_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import TRANSITIVE_DYNAMIC_LIBRARY_LINK_ACTIONS
-from tools.migration.legacy_fields_migration_lib import CC_LINK_EXECUTABLE
-from tools.migration.legacy_fields_migration_lib import migrate_legacy_fields
-
-
-def assert_has_feature(self, toolchain, name):
- self.assertTrue(any(feature.name == name for feature in toolchain.feature))
-
-
-def make_crosstool(string):
- crosstool = crosstool_config_pb2.CrosstoolRelease()
- text_format.Merge("major_version: '123' minor_version: '456'", crosstool)
- toolchain = crosstool.toolchain.add()
- text_format.Merge(string, toolchain)
- return crosstool
-
-
-def migrate_to_string(crosstool):
- migrate_legacy_fields(crosstool)
- return to_string(crosstool)
-
-
-def to_string(crosstool):
- return text_format.MessageToString(crosstool)
-
-
-class LegacyFieldsMigrationLibTest(unittest.TestCase):
-
- def test_deletes_fields(self):
- crosstool = make_crosstool("""
- debian_extra_requires: 'debian-1'
- gcc_plugin_compiler_flag: 'gcc_plugin_compiler_flag-1'
- ar_flag: 'ar_flag-1'
- ar_thin_archives_flag: 'ar_thin_archives_flag-1'
- gcc_plugin_header_directory: 'gcc_plugin_header_directory-1'
- mao_plugin_header_directory: 'mao_plugin_header_directory-1'
- default_python_top: 'default_python_top-1'
- default_python_version: 'default_python_version-1'
- python_preload_swigdeps: false
- supports_normalizing_ar: false
- supports_thin_archives: false
- supports_incremental_linker: false
- supports_dsym: false
- supports_gold_linker: false
- needsPic: false
- supports_start_end_lib: false
- supports_interface_shared_objects: false
- supports_fission: false
- supports_embedded_runtimes: false
- static_runtimes_filegroup: 'yolo'
- dynamic_runtimes_filegroup: 'yolo'
- """)
- output = migrate_to_string(crosstool)
- self.assertNotIn("debian_extra_requires", output)
- self.assertNotIn("gcc_plugin_compiler_flag", output)
- self.assertNotIn("ar_flag", output)
- self.assertNotIn("ar_thin_archives_flag", output)
- self.assertNotIn("gcc_plugin_header_directory", output)
- self.assertNotIn("mao_plugin_header_directory", output)
- self.assertNotIn("supports_normalizing_ar", output)
- self.assertNotIn("supports_thin_archives", output)
- self.assertNotIn("supports_incremental_linker", output)
- self.assertNotIn("supports_dsym", output)
- self.assertNotIn("default_python_top", output)
- self.assertNotIn("default_python_version", output)
- self.assertNotIn("python_preload_swigdeps", output)
- self.assertNotIn("supports_gold_linker", output)
- self.assertNotIn("needsPic", output)
- self.assertNotIn("supports_start_end_lib", output)
- self.assertNotIn("supports_interface_shared_objects", output)
- self.assertNotIn("supports_fission", output)
- self.assertNotIn("supports_embedded_runtimes", output)
- self.assertNotIn("static_runtimes_filegroup", output)
- self.assertNotIn("dynamic_runtimes_filegroup", output)
-
- def test_deletes_default_toolchains(self):
- crosstool = make_crosstool("")
- crosstool.default_toolchain.add()
- self.assertEqual(len(crosstool.default_toolchain), 1)
- migrate_legacy_fields(crosstool)
- self.assertEqual(len(crosstool.default_toolchain), 0)
-
- def test_replace_legacy_compile_flags(self):
- crosstool = make_crosstool("""
- feature { name: 'foo' }
- feature { name: 'legacy_compile_flags' }
- compiler_flag: 'clang-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.compiler_flag), 0)
- self.assertEqual(output.feature[0].name, "foo")
- self.assertEqual(output.feature[1].name, "default_compile_flags")
- self.assertEqual(output.feature[1].flag_set[0].action,
- ALL_CC_COMPILE_ACTIONS)
- self.assertEqual(output.feature[1].flag_set[0].flag_group[0].flag,
- ["clang-flag-1"])
-
- def test_replace_legacy_compile_flags_in_action_configs(self):
- crosstool = make_crosstool("""
- feature {
- name: 'foo'
- implies: 'legacy_compile_flags'
- requires: { feature: 'legacy_compile_flags' }
- flag_set {
- with_feature { feature: 'legacy_compile_flags' }
- with_feature { not_feature: 'legacy_compile_flags' }
- }
- env_set {
- with_feature { feature: 'legacy_compile_flags' }
- with_feature { not_feature: 'legacy_compile_flags' }
- }
- }
- feature { name: 'legacy_compile_flags' }
- action_config {
- action_name: 'foo'
- config_name: 'foo'
- implies: 'legacy_compile_flags'
- requires: { feature: 'legacy_compile_flags' }
- flag_set {
- with_feature { feature: 'legacy_compile_flags' }
- with_feature { not_feature: 'legacy_compile_flags' }
- }
- env_set {
- with_feature { feature: 'legacy_compile_flags' }
- with_feature { not_feature: 'legacy_compile_flags' }
- }
- }
- compiler_flag: 'clang-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.action_config[0].action_name, "foo")
- self.assertEqual(output.action_config[0].implies, [])
- self.assertEqual(output.action_config[0].requires[0].feature,
- ["default_compile_flags"])
- self.assertEqual(
- output.action_config[0].flag_set[0].with_feature[0].feature,
- ["default_compile_flags"])
- self.assertEqual(
- output.action_config[0].flag_set[0].with_feature[1].not_feature,
- ["default_compile_flags"])
- self.assertEqual(output.action_config[0].env_set[0].with_feature[0].feature,
- ["default_compile_flags"])
- self.assertEqual(
- output.action_config[0].env_set[0].with_feature[1].not_feature,
- ["default_compile_flags"])
- self.assertEqual(output.feature[0].name, "foo")
- self.assertEqual(output.feature[0].implies, [])
- self.assertEqual(output.feature[0].requires[0].feature,
- ["default_compile_flags"])
- self.assertEqual(output.feature[0].flag_set[0].with_feature[0].feature,
- ["default_compile_flags"])
- self.assertEqual(output.feature[0].flag_set[0].with_feature[1].not_feature,
- ["default_compile_flags"])
- self.assertEqual(output.feature[0].env_set[0].with_feature[0].feature,
- ["default_compile_flags"])
- self.assertEqual(output.feature[0].env_set[0].with_feature[1].not_feature,
- ["default_compile_flags"])
-
- def test_replace_legacy_link_flags(self):
- crosstool = make_crosstool("""
- feature { name: 'foo' }
- feature { name: 'legacy_link_flags' }
- linker_flag: 'ld-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.compiler_flag), 0)
- self.assertEqual(output.feature[0].name, "foo")
- self.assertEqual(output.feature[1].name, "default_link_flags")
- self.assertEqual(output.feature[1].flag_set[0].action, ALL_CC_LINK_ACTIONS)
- self.assertEqual(output.feature[1].flag_set[0].flag_group[0].flag,
- ["ld-flag-1"])
-
- def test_replace_legacy_link_flags_in_action_configs(self):
- crosstool = make_crosstool("""
- feature {
- name: 'foo'
- implies: 'legacy_link_flags'
- requires: { feature: 'legacy_link_flags' }
- flag_set {
- with_feature { feature: 'legacy_link_flags' }
- with_feature { not_feature: 'legacy_link_flags' }
- }
- env_set {
- with_feature { feature: 'legacy_link_flags' }
- with_feature { not_feature: 'legacy_link_flags' }
- }
- }
- feature { name: 'legacy_link_flags' }
- action_config {
- action_name: 'foo'
- config_name: 'foo'
- implies: 'legacy_link_flags'
- requires: { feature: 'legacy_link_flags' }
- flag_set {
- with_feature { feature: 'legacy_link_flags' }
- with_feature { not_feature: 'legacy_link_flags' }
- }
- env_set {
- with_feature { feature: 'legacy_link_flags' }
- with_feature { not_feature: 'legacy_link_flags' }
- }
- }
- linker_flag: 'clang-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.action_config[0].action_name, "foo")
- self.assertEqual(output.action_config[0].implies, [])
- self.assertEqual(output.action_config[0].requires[0].feature,
- ["default_link_flags"])
- self.assertEqual(
- output.action_config[0].flag_set[0].with_feature[0].feature,
- ["default_link_flags"])
- self.assertEqual(
- output.action_config[0].flag_set[0].with_feature[1].not_feature,
- ["default_link_flags"])
- self.assertEqual(output.action_config[0].env_set[0].with_feature[0].feature,
- ["default_link_flags"])
- self.assertEqual(
- output.action_config[0].env_set[0].with_feature[1].not_feature,
- ["default_link_flags"])
- self.assertEqual(output.feature[0].name, "foo")
- self.assertEqual(output.feature[0].implies, [])
- self.assertEqual(output.feature[0].requires[0].feature,
- ["default_link_flags"])
- self.assertEqual(output.feature[0].flag_set[0].with_feature[0].feature,
- ["default_link_flags"])
- self.assertEqual(output.feature[0].flag_set[0].with_feature[1].not_feature,
- ["default_link_flags"])
- self.assertEqual(output.feature[0].env_set[0].with_feature[0].feature,
- ["default_link_flags"])
- self.assertEqual(output.feature[0].env_set[0].with_feature[1].not_feature,
- ["default_link_flags"])
-
-
- def test_migrate_compiler_flags(self):
- crosstool = make_crosstool("""
- compiler_flag: 'clang-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.compiler_flag), 0)
- self.assertEqual(output.feature[0].name, "default_compile_flags")
- self.assertEqual(output.feature[0].flag_set[0].action, ALL_CC_COMPILE_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["clang-flag-1"])
-
- def test_migrate_compiler_flags_for_objc(self):
- crosstool = make_crosstool("""
- action_config { action_name: "objc-compile" }
- compiler_flag: 'clang-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.compiler_flag), 0)
- self.assertEqual(output.feature[0].name, "default_compile_flags")
- self.assertEqual(output.feature[0].flag_set[0].action, ALL_CC_COMPILE_ACTIONS + ALL_OBJC_COMPILE_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["clang-flag-1"])
-
- def test_migrate_cxx_flags(self):
- crosstool = make_crosstool("""
- cxx_flag: 'clang-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.cxx_flag), 0)
- self.assertEqual(output.feature[0].name, "default_compile_flags")
- self.assertEqual(output.feature[0].flag_set[0].action,
- ALL_CXX_COMPILE_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["clang-flag-1"])
-
- def test_compiler_flag_come_before_cxx_flags(self):
- crosstool = make_crosstool("""
- compiler_flag: 'clang-flag-1'
- cxx_flag: 'clang-flag-2'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "default_compile_flags")
- self.assertEqual(output.feature[0].flag_set[0].action, ALL_CC_COMPILE_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[1].action,
- ALL_CXX_COMPILE_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["clang-flag-1"])
- self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
- ["clang-flag-2"])
-
- def test_migrate_linker_flags(self):
- crosstool = make_crosstool("""
- linker_flag: 'linker-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.linker_flag), 0)
- self.assertEqual(output.feature[0].name, "default_link_flags")
- self.assertEqual(output.feature[0].flag_set[0].action, ALL_CC_LINK_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["linker-flag-1"])
-
- def test_migrate_dynamic_library_linker_flags(self):
- crosstool = make_crosstool("""
- dynamic_library_linker_flag: 'linker-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.dynamic_library_linker_flag), 0)
- self.assertEqual(output.feature[0].name, "default_link_flags")
- self.assertEqual(output.feature[0].flag_set[0].action,
- DYNAMIC_LIBRARY_LINK_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["linker-flag-1"])
-
- def test_compilation_mode_flags(self):
- crosstool = make_crosstool("""
- compiler_flag: "compile-flag-1"
- cxx_flag: "cxx-flag-1"
- linker_flag: "linker-flag-1"
- compilation_mode_flags {
- mode: OPT
- compiler_flag: "opt-flag-1"
- cxx_flag: "opt-flag-2"
- linker_flag: "opt-flag-3"
- }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.compilation_mode_flags), 0)
- assert_has_feature(self, output, "opt")
-
- self.assertEqual(output.feature[0].name, "default_compile_flags")
- self.assertEqual(output.feature[1].name, "default_link_flags")
-
- # flag set for compiler_flag fields
- self.assertEqual(len(output.feature[0].flag_set[0].with_feature), 0)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["compile-flag-1"])
-
- # flag set for compiler_flag from compilation_mode_flags
- self.assertEqual(len(output.feature[0].flag_set[1].with_feature), 1)
- self.assertEqual(output.feature[0].flag_set[1].with_feature[0].feature[0],
- "opt")
- self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
- ["opt-flag-1"])
-
- # flag set for cxx_flag fields
- self.assertEqual(len(output.feature[0].flag_set[2].with_feature), 0)
- self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag,
- ["cxx-flag-1"])
-
- # flag set for cxx_flag from compilation_mode_flags
- self.assertEqual(len(output.feature[0].flag_set[3].with_feature), 1)
- self.assertEqual(output.feature[0].flag_set[3].with_feature[0].feature[0],
- "opt")
- self.assertEqual(output.feature[0].flag_set[3].flag_group[0].flag,
- ["opt-flag-2"])
-
- # default_link_flags, flag set for linker_flag
- self.assertEqual(len(output.feature[1].flag_set[0].with_feature), 0)
- self.assertEqual(output.feature[1].flag_set[0].flag_group[0].flag,
- ["linker-flag-1"])
-
- # default_link_flags, flag set for linker_flag from
- # compilation_mode_flags
- self.assertEqual(len(output.feature[1].flag_set[1].with_feature), 1)
- self.assertEqual(output.feature[1].flag_set[1].with_feature[0].feature[0],
- "opt")
- self.assertEqual(output.feature[1].flag_set[1].flag_group[0].flag,
- ["opt-flag-3"])
-
- def test_linking_mode_flags(self):
- crosstool = make_crosstool("""
- linker_flag: "linker-flag-1"
- compilation_mode_flags {
- mode: DBG
- linker_flag: "dbg-flag-1"
- }
- linking_mode_flags {
- mode: MOSTLY_STATIC
- linker_flag: "mostly-static-flag-1"
- }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.compilation_mode_flags), 0)
- self.assertEqual(len(output.linking_mode_flags), 0)
-
- # flag set for linker_flag
- self.assertEqual(len(output.feature[0].flag_set[0].with_feature), 0)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["linker-flag-1"])
-
- # flag set for compilation_mode_flags
- self.assertEqual(len(output.feature[0].flag_set[1].with_feature), 1)
- self.assertEqual(output.feature[0].flag_set[1].with_feature[0].feature[0],
- "dbg")
- self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
- ["dbg-flag-1"])
-
- # flag set for linking_mode_flags
- self.assertEqual(len(output.feature[0].flag_set[2].with_feature), 1)
- self.assertEqual(output.feature[0].flag_set[2].action, CC_LINK_EXECUTABLE)
- self.assertEqual(output.feature[0].flag_set[2].with_feature[0].feature[0],
- "static_linking_mode")
- self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag,
- ["mostly-static-flag-1"])
-
- def test_coverage_compilation_mode_ignored(self):
- crosstool = make_crosstool("""
- compilation_mode_flags {
- mode: COVERAGE
- compiler_flag: "coverage-flag-1"
- cxx_flag: "coverage-flag-2"
- linker_flag: "coverage-flag-3"
- }
- """)
- output = migrate_to_string(crosstool)
- self.assertNotIn("compilation_mode_flags", output)
- self.assertNotIn("coverage-flag-1", output)
- self.assertNotIn("coverage-flag-2", output)
- self.assertNotIn("coverage-flag-3", output)
- self.assertNotIn("COVERAGE", output)
-
- def test_supports_dynamic_linker_when_dynamic_library_linker_flag_is_used(
- self):
- crosstool = make_crosstool("""
- dynamic_library_linker_flag: "foo"
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "default_link_flags")
- self.assertEqual(output.feature[1].name, "supports_dynamic_linker")
- self.assertEqual(output.feature[1].enabled, True)
-
- def test_supports_dynamic_linker_is_added_when_DYNAMIC_present(self):
- crosstool = make_crosstool("""
- linking_mode_flags {
- mode: DYNAMIC
- }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "supports_dynamic_linker")
- self.assertEqual(output.feature[0].enabled, True)
-
- def test_supports_dynamic_linker_is_not_added_when_present(self):
- crosstool = make_crosstool("""
- feature { name: "supports_dynamic_linker" enabled: false }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "supports_dynamic_linker")
- self.assertEqual(output.feature[0].enabled, False)
-
- def test_all_linker_flag_ordering(self):
- crosstool = make_crosstool("""
- linker_flag: 'linker-flag-1'
- compilation_mode_flags {
- mode: OPT
- linker_flag: 'cmf-flag-2'
- }
- linking_mode_flags {
- mode: MOSTLY_STATIC
- linker_flag: 'lmf-flag-3'
- }
- linking_mode_flags {
- mode: DYNAMIC
- linker_flag: 'lmf-dynamic-flag-4'
- }
- dynamic_library_linker_flag: 'dl-flag-5'
- test_only_linker_flag: 'to-flag-6'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "default_link_flags")
- self.assertEqual(output.feature[0].enabled, True)
- self.assertEqual(output.feature[0].flag_set[0].action[:], ALL_CC_LINK_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag[:],
- ["linker-flag-1"])
-
- self.assertEqual(output.feature[0].flag_set[1].action[:], ALL_CC_LINK_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[1].with_feature[0].feature[0],
- "opt")
- self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
- ["cmf-flag-2"])
-
- self.assertEqual(output.feature[0].flag_set[2].action, CC_LINK_EXECUTABLE)
- self.assertEqual(output.feature[0].flag_set[2].with_feature[0].feature[0],
- "static_linking_mode")
- self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag,
- ["lmf-flag-3"])
-
- self.assertEqual(len(output.feature[0].flag_set[3].with_feature), 0)
- self.assertEqual(output.feature[0].flag_set[3].flag_group[0].flag,
- ["lmf-dynamic-flag-4"])
- self.assertEqual(output.feature[0].flag_set[3].action,
- NODEPS_DYNAMIC_LIBRARY_LINK_ACTIONS)
-
- self.assertEqual(
- output.feature[0].flag_set[4].with_feature[0].not_feature[0],
- "static_link_cpp_runtimes")
- self.assertEqual(output.feature[0].flag_set[4].flag_group[0].flag,
- ["lmf-dynamic-flag-4"])
- self.assertEqual(output.feature[0].flag_set[4].action,
- TRANSITIVE_DYNAMIC_LIBRARY_LINK_ACTIONS)
-
- self.assertEqual(output.feature[0].flag_set[5].with_feature[0].feature[0],
- "dynamic_linking_mode")
- self.assertEqual(output.feature[0].flag_set[5].flag_group[0].flag,
- ["lmf-dynamic-flag-4"])
- self.assertEqual(output.feature[0].flag_set[5].action,
- CC_LINK_EXECUTABLE)
-
- self.assertEqual(output.feature[0].flag_set[6].flag_group[0].flag,
- ["dl-flag-5"])
- self.assertEqual(output.feature[0].flag_set[6].action,
- DYNAMIC_LIBRARY_LINK_ACTIONS)
-
- self.assertEqual(output.feature[0].flag_set[7].flag_group[0].flag,
- ["to-flag-6"])
- self.assertEqual(output.feature[0].flag_set[7].action, ALL_CC_LINK_ACTIONS)
- self.assertEqual(
- output.feature[0].flag_set[7].flag_group[0].expand_if_all_available,
- ["is_cc_test"])
-
- def test_all_linker_flag_objc_actions(self):
- crosstool = make_crosstool("""
- action_config { action_name: "objc-compile" }
- linker_flag: 'linker-flag-1'
- compilation_mode_flags {
- mode: OPT
- linker_flag: 'cmf-flag-2'
- }
- linking_mode_flags {
- mode: MOSTLY_STATIC
- linker_flag: 'lmf-flag-3'
- }
- dynamic_library_linker_flag: 'dl-flag-5'
- test_only_linker_flag: 'to-flag-6'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "default_link_flags")
- self.assertEqual(output.feature[0].flag_set[0].action[:],
- ALL_CC_LINK_ACTIONS + ALL_OBJC_LINK_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[1].action[:],
- ALL_CC_LINK_ACTIONS + ALL_OBJC_LINK_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[2].action[:],
- CC_LINK_EXECUTABLE)
- self.assertEqual(output.feature[0].flag_set[3].action[:],
- DYNAMIC_LIBRARY_LINK_ACTIONS)
- self.assertEqual(output.feature[0].flag_set[4].action[:],
- ALL_CC_LINK_ACTIONS + ALL_OBJC_LINK_ACTIONS)
-
- def test_linking_mode_features_are_not_added_when_present(self):
- crosstool = make_crosstool("""
- linking_mode_flags {
- mode: DYNAMIC
- linker_flag: 'dynamic-flag'
- }
- linking_mode_flags {
- mode: FULLY_STATIC
- linker_flag: 'fully-static-flag'
- }
- linking_mode_flags {
- mode: MOSTLY_STATIC
- linker_flag: 'mostly-static-flag'
- }
- linking_mode_flags {
- mode: MOSTLY_STATIC_LIBRARIES
- linker_flag: 'mostly-static-libraries-flag'
- }
- feature { name: "static_linking_mode" }
- feature { name: "dynamic_linking_mode" }
- feature { name: "static_linking_mode_nodeps_library" }
- feature { name: "fully_static_link" }
- """)
- output = migrate_to_string(crosstool)
- self.assertNotIn("linking_mode_flags", output)
- self.assertNotIn("DYNAMIC", output)
- self.assertNotIn("MOSTLY_STATIC", output)
- self.assertNotIn("MOSTLY_STATIC_LIBRARIES", output)
- self.assertNotIn("MOSTLY_STATIC_LIBRARIES", output)
- self.assertNotIn("dynamic-flag", output)
- self.assertNotIn("fully-static-flag", output)
- self.assertNotIn("mostly-static-flag", output)
- self.assertNotIn("mostly-static-libraries-flag", output)
-
- def test_unfiltered_require_user_compile_flags_and_sysroot(self):
- crosstool = make_crosstool("""
- feature { name: 'preexisting_feature' }
- unfiltered_cxx_flag: 'unfiltered-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- # all these features are added after features that are already present in
- # the crosstool
- self.assertEqual(output.feature[0].name, "preexisting_feature")
- self.assertEqual(output.feature[1].name, "user_compile_flags")
- self.assertEqual(output.feature[2].name, "sysroot")
- self.assertEqual(output.feature[3].name, "unfiltered_compile_flags")
-
- def test_user_compile_flags_not_migrated_when_present(self):
- crosstool = make_crosstool("""
- unfiltered_cxx_flag: 'unfiltered-flag-1'
- feature { name: 'user_compile_flags' }
- feature { name: 'preexisting_feature' }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "user_compile_flags")
- self.assertEqual(output.feature[1].name, "preexisting_feature")
- self.assertEqual(output.feature[2].name, "sysroot")
- self.assertEqual(output.feature[3].name, "unfiltered_compile_flags")
-
- def test_sysroot_not_migrated_when_present(self):
- crosstool = make_crosstool("""
- unfiltered_cxx_flag: 'unfiltered-flag-1'
- feature { name: 'sysroot' }
- feature { name: 'preexisting_feature' }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "sysroot")
- self.assertEqual(output.feature[1].name, "preexisting_feature")
- self.assertEqual(output.feature[2].name, "user_compile_flags")
- self.assertEqual(output.feature[3].name, "unfiltered_compile_flags")
-
- def test_user_compile_flags(self):
- crosstool = make_crosstool("""
- unfiltered_cxx_flag: 'unfiltered-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "user_compile_flags")
- self.assertEqual(output.feature[0].enabled, True)
- self.assertEqual(output.feature[0].flag_set[0].action,
- ALL_CC_COMPILE_ACTIONS)
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[0].expand_if_all_available,
- ["user_compile_flags"])
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].iterate_over,
- "user_compile_flags")
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["%{user_compile_flags}"])
-
- def test_sysroot(self):
- sysroot_actions = ALL_CC_COMPILE_ACTIONS + ALL_CC_LINK_ACTIONS
- sysroot_actions.remove("assemble")
- self.assertTrue("assemble" not in sysroot_actions)
- crosstool = make_crosstool("""
- unfiltered_cxx_flag: 'unfiltered-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[1].name, "sysroot")
- self.assertEqual(output.feature[1].enabled, True)
- self.assertEqual(output.feature[1].flag_set[0].action, sysroot_actions)
- self.assertEqual(
- output.feature[1].flag_set[0].flag_group[0].expand_if_all_available,
- ["sysroot"])
- self.assertEqual(output.feature[1].flag_set[0].flag_group[0].flag,
- ["--sysroot=%{sysroot}"])
-
- def test_unfiltered_compile_flags_is_not_added_when_already_present(self):
- crosstool = make_crosstool("""
- unfiltered_cxx_flag: 'unfiltered-flag-1'
- feature { name: 'something_else' }
- feature { name: 'unfiltered_compile_flags' }
- feature { name: 'something_else_2' }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "something_else")
- self.assertEqual(output.feature[1].name, "unfiltered_compile_flags")
- self.assertEqual(len(output.feature[1].flag_set), 0)
- self.assertEqual(output.feature[2].name, "something_else_2")
-
- def test_unfiltered_compile_flags_is_not_edited_if_old_variant_present(self):
- crosstool = make_crosstool("""
- unfiltered_cxx_flag: 'unfiltered-flag-1'
- feature {
- name: 'unfiltered_compile_flags'
- flag_set {
- action: 'c-compile'
- flag_group {
- flag: 'foo-flag-1'
- }
- }
- }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "unfiltered_compile_flags")
- self.assertEqual(len(output.feature[0].flag_set), 1)
- self.assertEqual(output.feature[0].flag_set[0].action, ["c-compile"])
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["foo-flag-1"])
-
- def test_use_of_unfiltered_compile_flags_var_is_removed_and_replaced(self):
- crosstool = make_crosstool("""
- unfiltered_cxx_flag: 'unfiltered-flag-1'
- feature {
- name: 'unfiltered_compile_flags'
- flag_set {
- action: 'c-compile'
- flag_group {
- flag: 'foo-flag-1'
- }
- }
- flag_set {
- action: 'c++-compile'
- flag_group {
- flag: 'bar-flag-1'
- }
- flag_group {
- expand_if_all_available: 'unfiltered_compile_flags'
- iterate_over: 'unfiltered_compile_flags'
- flag: '%{unfiltered_compile_flags}'
- }
- flag_group {
- flag: 'bar-flag-2'
- }
- }
- flag_set {
- action: 'c-compile'
- flag_group {
- flag: 'foo-flag-2'
- }
- }
- }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "unfiltered_compile_flags")
- self.assertEqual(output.feature[0].flag_set[0].action, ["c-compile"])
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["foo-flag-1"])
- self.assertEqual(output.feature[0].flag_set[1].action, ["c++-compile"])
- self.assertEqual(output.feature[0].flag_set[1].flag_group[0].flag,
- ["bar-flag-1"])
- self.assertEqual(output.feature[0].flag_set[1].flag_group[1].flag,
- ["unfiltered-flag-1"])
- self.assertEqual(output.feature[0].flag_set[1].flag_group[2].flag,
- ["bar-flag-2"])
- self.assertEqual(output.feature[0].flag_set[2].action, ["c-compile"])
- self.assertEqual(output.feature[0].flag_set[2].flag_group[0].flag,
- ["foo-flag-2"])
-
- def test_unfiltered_compile_flags_is_added_at_the_end(self):
- crosstool = make_crosstool("""
- feature { name: 'something_else' }
- unfiltered_cxx_flag: 'unfiltered-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "something_else")
- self.assertEqual(output.feature[1].name, "user_compile_flags")
- self.assertEqual(output.feature[2].name, "sysroot")
- self.assertEqual(output.feature[3].name, "unfiltered_compile_flags")
- self.assertEqual(output.feature[3].flag_set[0].action,
- ALL_CC_COMPILE_ACTIONS)
- self.assertEqual(output.feature[3].flag_set[0].flag_group[0].flag,
- ["unfiltered-flag-1"])
-
- def test_unfiltered_compile_flags_are_not_added_for_objc(self):
- crosstool = make_crosstool("""
- action_config { action_name: "obc-compile" }
- feature { name: 'something_else' }
- unfiltered_cxx_flag: 'unfiltered-flag-1'
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[3].name, "unfiltered_compile_flags")
- self.assertEqual(output.feature[3].flag_set[0].action,
- ALL_CC_COMPILE_ACTIONS)
- self.assertEqual(output.feature[3].flag_set[0].flag_group[0].flag,
- ["unfiltered-flag-1"])
-
- def test_default_link_flags_is_added_first(self):
- crosstool = make_crosstool("""
- linker_flag: 'linker-flag-1'
- feature { name: 'something_else' }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "default_link_flags")
- self.assertEqual(output.feature[0].enabled, True)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["linker-flag-1"])
-
- def test_default_link_flags_is_not_added_when_already_present(self):
- crosstool = make_crosstool("""
- linker_flag: 'linker-flag-1'
- feature { name: 'something_else' }
- feature { name: 'default_link_flags' }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "something_else")
- self.assertEqual(output.feature[1].name, "default_link_flags")
-
- def test_default_compile_flags_is_not_added_when_no_reason_to(self):
- crosstool = make_crosstool("""
- feature { name: 'something_else' }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "something_else")
- self.assertEqual(len(output.feature), 1)
-
- def test_default_compile_flags_is_first(self):
- crosstool = make_crosstool("""
- compiler_flag: 'compiler-flag-1'
- feature { name: 'something_else' }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "default_compile_flags")
- self.assertEqual(output.feature[0].enabled, True)
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag,
- ["compiler-flag-1"])
-
- def test_default_compile_flags_not_added_when_present(self):
- crosstool = make_crosstool("""
- compiler_flag: 'compiler-flag-1'
- feature { name: 'something_else' }
- feature { name: 'default_compile_flags' }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "something_else")
- self.assertEqual(output.feature[1].name, "default_compile_flags")
- self.assertEqual(len(output.feature[1].flag_set), 0)
-
- def test_supports_start_end_lib_migrated(self):
- crosstool = make_crosstool("supports_start_end_lib: true")
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "supports_start_end_lib")
- self.assertEqual(output.feature[0].enabled, True)
-
- def test_supports_start_end_lib_not_migrated_on_false(self):
- crosstool = make_crosstool("supports_start_end_lib: false")
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.feature), 0)
-
- def test_supports_start_end_lib_not_migrated_when_already_present(self):
- crosstool = make_crosstool("""
- supports_start_end_lib: true
- feature { name: "supports_start_end_lib" enabled: false }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "supports_start_end_lib")
- self.assertEqual(output.feature[0].enabled, False)
-
- def test_supports_interface_shared_libraries_migrated(self):
- crosstool = make_crosstool("supports_interface_shared_objects: true")
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name,
- "supports_interface_shared_libraries")
- self.assertEqual(output.feature[0].enabled, True)
-
- def test_supports_interface_shared_libraries_not_migrated_on_false(self):
- crosstool = make_crosstool("supports_interface_shared_objects: false")
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.feature), 0)
-
- def test_supports_interface_shared_libraries_not_migrated_when_present(self):
- crosstool = make_crosstool("""
- supports_interface_shared_objects: true
- feature {
- name: "supports_interface_shared_libraries"
- enabled: false }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name,
- "supports_interface_shared_libraries")
- self.assertEqual(output.feature[0].enabled, False)
-
- def test_supports_embedded_runtimes_migrated(self):
- crosstool = make_crosstool("supports_embedded_runtimes: true")
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "static_link_cpp_runtimes")
- self.assertEqual(output.feature[0].enabled, True)
-
- def test_supports_embedded_runtimes_not_migrated_on_false(self):
- crosstool = make_crosstool("supports_embedded_runtimes: false")
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.feature), 0)
-
- def test_supports_embedded_runtimes_not_migrated_when_already_present(self):
- crosstool = make_crosstool("""
- supports_embedded_runtimes: true
- feature { name: "static_link_cpp_runtimes" enabled: false }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "static_link_cpp_runtimes")
- self.assertEqual(output.feature[0].enabled, False)
-
- def test_needs_pic_migrated(self):
- crosstool = make_crosstool("needsPic: true")
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "supports_pic")
- self.assertEqual(output.feature[0].enabled, True)
-
- def test_needs_pic_not_migrated_on_false(self):
- crosstool = make_crosstool("needsPic: false")
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.feature), 0)
-
- def test_needs_pic_not_migrated_when_already_present(self):
- crosstool = make_crosstool("""
- needsPic: true
- feature { name: "supports_pic" enabled: false }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "supports_pic")
- self.assertEqual(output.feature[0].enabled, False)
-
- def test_supports_fission_migrated(self):
- crosstool = make_crosstool("supports_fission: true")
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "per_object_debug_info")
- self.assertEqual(output.feature[0].enabled, True)
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[0].expand_if_all_available,
- ["is_using_fission"])
-
- def test_supports_fission_not_migrated_on_false(self):
- crosstool = make_crosstool("supports_fission: false")
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(len(output.feature), 0)
-
- def test_supports_fission_not_migrated_when_already_present(self):
- crosstool = make_crosstool("""
- supports_fission: true
- feature { name: "per_object_debug_info" enabled: false }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "per_object_debug_info")
- self.assertEqual(output.feature[0].enabled, False)
-
- def test_migrating_objcopy_embed_flag(self):
- crosstool = make_crosstool("""
- tool_path { name: "objcopy" path: "foo/objcopy" }
- objcopy_embed_flag: "a"
- objcopy_embed_flag: "b"
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "objcopy_embed_flags")
- self.assertEqual(output.feature[0].enabled, True)
- self.assertEqual(output.feature[0].flag_set[0].action[:],
- ["objcopy_embed_data"])
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag[:],
- ["a", "b"])
- self.assertEqual(len(output.objcopy_embed_flag), 0)
- self.assertEqual(output.action_config[0].action_name, "objcopy_embed_data")
- self.assertEqual(output.action_config[0].tool[0].tool_path, "foo/objcopy")
-
- def test_not_migrating_objcopy_embed_flag_when_feature_present(self):
- crosstool = make_crosstool("""
- objcopy_embed_flag: "a"
- objcopy_embed_flag: "b"
- feature { name: "objcopy_embed_flags" }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "objcopy_embed_flags")
- self.assertEqual(output.feature[0].enabled, False)
-
- def test_migrating_ld_embed_flag(self):
- crosstool = make_crosstool("""
- tool_path { name: "ld" path: "foo/ld" }
- ld_embed_flag: "a"
- ld_embed_flag: "b"
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "ld_embed_flags")
- self.assertEqual(output.feature[0].enabled, True)
- self.assertEqual(output.feature[0].flag_set[0].action[:], ["ld_embed_data"])
- self.assertEqual(output.feature[0].flag_set[0].flag_group[0].flag[:],
- ["a", "b"])
- self.assertEqual(len(output.ld_embed_flag), 0)
- self.assertEqual(output.action_config[0].action_name, "ld_embed_data")
- self.assertEqual(output.action_config[0].tool[0].tool_path, "foo/ld")
-
- def test_not_migrating_objcopy_embed_flag_when_feature_present(self):
- crosstool = make_crosstool("""
- objcopy_embed_flag: "a"
- objcopy_embed_flag: "b"
- feature { name: "objcopy_embed_flags" }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.feature[0].name, "objcopy_embed_flags")
- self.assertEqual(output.feature[0].enabled, False)
-
- def test_migrate_expand_if_all_available_from_flag_sets(self):
- crosstool = make_crosstool("""
- action_config {
- action_name: 'something'
- config_name: 'something'
- flag_set {
- expand_if_all_available: 'foo'
- flag_group {
- flag: '%{foo}'
- }
- flag_group {
- flag: 'bar'
- }
- }
- }
- feature {
- name: 'something_else'
- flag_set {
- action: 'c-compile'
- expand_if_all_available: 'foo'
- flag_group {
- flag: '%{foo}'
- }
- flag_group {
- flag: 'bar'
- }
- }
- }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.action_config[0].action_name, "something")
- self.assertEqual(len(output.action_config[0].flag_set), 1)
- self.assertEqual(
- len(output.action_config[0].flag_set[0].expand_if_all_available), 0)
- self.assertEqual(len(output.action_config[0].flag_set[0].flag_group), 2)
- self.assertEqual(
- output.action_config[0].flag_set[0].flag_group[0]
- .expand_if_all_available, ["foo"])
- self.assertEqual(
- output.action_config[0].flag_set[0].flag_group[1]
- .expand_if_all_available, ["foo"])
-
- self.assertEqual(output.feature[0].name, "something_else")
- self.assertEqual(len(output.feature[0].flag_set), 1)
- self.assertEqual(
- len(output.feature[0].flag_set[0].expand_if_all_available), 0)
- self.assertEqual(len(output.feature[0].flag_set[0].flag_group), 2)
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[0].expand_if_all_available,
- ["foo"])
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[1].expand_if_all_available,
- ["foo"])
-
- def test_enable_previously_default_features(self):
- default_features = [
- "dependency_file", "random_seed", "module_maps", "module_map_home_cwd",
- "header_module_compile", "include_paths", "pic", "preprocessor_define"
- ]
- crosstool = make_crosstool("""
- feature { name: "dependency_file" }
- feature { name: "random_seed" }
- feature { name: "module_maps" }
- feature { name: "module_map_home_cwd" }
- feature { name: "header_module_compile" }
- feature { name: "include_paths" }
- feature { name: "pic" }
- feature { name: "preprocessor_define" }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- for i in range(0, 8):
- self.assertEqual(output.feature[i].name, default_features[i])
- self.assertTrue(output.feature[i].enabled)
-
- def test_migrate_repeated_expand_if_all_available_from_flag_groups(self):
- crosstool = make_crosstool("""
- action_config {
- action_name: 'something'
- config_name: 'something'
- flag_set {
- flag_group {
- expand_if_all_available: 'foo'
- expand_if_all_available: 'bar'
- flag: '%{foo}'
- }
- flag_group {
- expand_if_none_available: 'foo'
- expand_if_none_available: 'bar'
- flag: 'bar'
- }
- }
- }
- feature {
- name: 'something_else'
- flag_set {
- action: 'c-compile'
- flag_group {
- expand_if_all_available: 'foo'
- expand_if_all_available: 'bar'
- flag: '%{foo}'
- }
- flag_group {
- expand_if_none_available: 'foo'
- expand_if_none_available: 'bar'
- flag: 'bar'
- }
- }
- }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
- self.assertEqual(output.action_config[0].action_name, "something")
- self.assertEqual(len(output.action_config[0].flag_set), 1)
- self.assertEqual(
- len(output.action_config[0].flag_set[0].expand_if_all_available), 0)
- self.assertEqual(len(output.action_config[0].flag_set[0].flag_group), 2)
- self.assertEqual(
- output.action_config[0].flag_set[0].flag_group[0]
- .expand_if_all_available, ["foo"])
- self.assertEqual(
- output.action_config[0].flag_set[0].flag_group[0].flag_group[0]
- .expand_if_all_available, ["bar"])
- self.assertEqual(
- output.action_config[0].flag_set[0].flag_group[1]
- .expand_if_none_available, ["foo"])
- self.assertEqual(
- output.action_config[0].flag_set[0].flag_group[1].flag_group[0]
- .expand_if_none_available, ["bar"])
-
- self.assertEqual(output.feature[0].name, "something_else")
- self.assertEqual(len(output.feature[0].flag_set), 1)
- self.assertEqual(
- len(output.feature[0].flag_set[0].expand_if_all_available), 0)
- self.assertEqual(len(output.feature[0].flag_set[0].flag_group), 2)
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[0].expand_if_all_available,
- ["foo"])
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[0].flag_group[0]
- .expand_if_all_available, ["bar"])
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[1].expand_if_none_available,
- ["foo"])
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[1].flag_group[0]
- .expand_if_none_available, ["bar"])
-
- def test_migrate_repeated_expands_from_nested_flag_groups(self):
- crosstool = make_crosstool("""
- feature {
- name: 'something'
- flag_set {
- action: 'c-compile'
- flag_group {
- flag_group {
- expand_if_all_available: 'foo'
- expand_if_all_available: 'bar'
- flag: '%{foo}'
- }
- }
- flag_group {
- flag_group {
- expand_if_all_available: 'foo'
- expand_if_all_available: 'bar'
- expand_if_none_available: 'foo'
- expand_if_none_available: 'bar'
- flag: '%{foo}'
- }
- }
- }
- }
- """)
- migrate_legacy_fields(crosstool)
- output = crosstool.toolchain[0]
-
- self.assertEqual(output.feature[0].name, "something")
- self.assertEqual(len(output.feature[0].flag_set[0].flag_group), 2)
- self.assertEqual(
- len(output.feature[0].flag_set[0].flag_group[0].expand_if_all_available
- ), 0)
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[0].flag_group[0]
- .expand_if_all_available, ["foo"])
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[0].flag_group[0].flag_group[0]
- .expand_if_all_available, ["bar"])
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[0].flag_group[0].flag_group[0]
- .flag, ["%{foo}"])
-
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[1].flag_group[0]
- .expand_if_all_available, ["foo"])
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[1].flag_group[0]
- .expand_if_none_available, ["foo"])
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[1].flag_group[0].flag_group[0]
- .expand_if_none_available, ["bar"])
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[1].flag_group[0].flag_group[0]
- .expand_if_all_available, ["bar"])
- self.assertEqual(
- output.feature[0].flag_set[0].flag_group[1].flag_group[0].flag_group[0]
- .flag, ["%{foo}"])
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tools/migration/legacy_fields_migrator.py b/tools/migration/legacy_fields_migrator.py
deleted file mode 100644
index cc1bb41..0000000
--- a/tools/migration/legacy_fields_migrator.py
+++ /dev/null
@@ -1,69 +0,0 @@
-"""Script migrating legacy CROSSTOOL fields into features.
-
-This script migrates the CROSSTOOL to use only the features to describe C++
-command lines. It is intended to be added as a last step of CROSSTOOL generation
-pipeline. Since it doesn't retain comments, we assume CROSSTOOL owners will want
-to migrate their pipeline manually.
-"""
-
-# Tracking issue: https://github.com/bazelbuild/bazel/issues/5187
-#
-# Since C++ rules team is working on migrating CROSSTOOL from text proto into
-# Starlark, we advise CROSSTOOL owners to wait for the CROSSTOOL -> Starlark
-# migrator before they invest too much time into fixing their pipeline. Tracking
-# issue for the Starlark effort is
-# https://github.com/bazelbuild/bazel/issues/5380.
-
-from absl import app
-from absl import flags
-from google.protobuf import text_format
-from third_party.com.github.bazelbuild.bazel.src.main.protobuf import crosstool_config_pb2
-from tools.migration.legacy_fields_migration_lib import migrate_legacy_fields
-import os
-
-flags.DEFINE_string("input", None, "Input CROSSTOOL file to be migrated")
-flags.DEFINE_string("output", None,
- "Output path where to write migrated CROSSTOOL.")
-flags.DEFINE_boolean("inline", None, "Overwrite --input file")
-
-
-def main(unused_argv):
- crosstool = crosstool_config_pb2.CrosstoolRelease()
-
- input_filename = flags.FLAGS.input
- output_filename = flags.FLAGS.output
- inline = flags.FLAGS.inline
-
- if not input_filename:
- raise app.UsageError("ERROR --input unspecified")
- if not output_filename and not inline:
- raise app.UsageError("ERROR --output unspecified and --inline not passed")
- if output_filename and inline:
- raise app.UsageError("ERROR both --output and --inline passed")
-
- with open(to_absolute_path(input_filename), "r") as f:
- input_text = f.read()
-
- text_format.Merge(input_text, crosstool)
-
- migrate_legacy_fields(crosstool)
- output_text = text_format.MessageToString(crosstool)
-
- resolved_output_filename = to_absolute_path(
- input_filename if inline else output_filename)
- with open(resolved_output_filename, "w") as f:
- f.write(output_text)
-
-def to_absolute_path(path):
- path = os.path.expanduser(path)
- if os.path.isabs(path):
- return path
- else:
- if "BUILD_WORKING_DIRECTORY" in os.environ:
- return os.path.join(os.environ["BUILD_WORKING_DIRECTORY"], path)
- else:
- return path
-
-
-if __name__ == "__main__":
- app.run(main)