mirror of https://github.com/bazelbuild/rules_cc
Merge branch 'main' into rules-based-toolchain-example
This commit is contained in:
commit
b82c650543
|
@ -16,7 +16,6 @@ x_defaults:
|
|||
- "//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 @@ x_defaults:
|
|||
- "//examples/my_c_archive:all"
|
||||
- "//examples/my_c_compile:all"
|
||||
- "//examples/write_cc_toolchain_cpu:all"
|
||||
- "//tools/migration:all"
|
||||
- "//tests/..."
|
||||
|
||||
buildifier:
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
{
|
||||
"homepage": "https://github.com/bazelbuild/rules_cc",
|
||||
"maintainers": [],
|
||||
"maintainers": [
|
||||
{
|
||||
"email": "ilist@google.com",
|
||||
"github": "comius",
|
||||
"name": "Ivo Ristovski List"
|
||||
}
|
||||
],
|
||||
"versions": [],
|
||||
"yanked_versions": {}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
matrix:
|
||||
platform: ["centos7", "debian10", "macos", "ubuntu2004", "windows"]
|
||||
bazel:
|
||||
- 6.x
|
||||
- 7.x
|
||||
tasks:
|
||||
verify_targets:
|
||||
name: "Verify build targets"
|
||||
platform: ${{ platform }}
|
||||
bazel: ${{ bazel }}
|
||||
build_targets:
|
||||
- "@rules_cc//cc/..."
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"integrity": "",
|
||||
"strip_prefix": "{REPO}-{VERSION}",
|
||||
"url": "https://github.com/{OWNER}/{REPO}/archive/refs/tags/{TAG}.tar.gz"
|
||||
"url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/rules_cc-{TAG}.tar.gz"
|
||||
}
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
module(
|
||||
name = "rules_cc",
|
||||
version = "0.0.10",
|
||||
version = "0.0.12",
|
||||
compatibility_level = 1,
|
||||
)
|
||||
|
||||
bazel_dep(name = "bazel_skylib", version = "1.7.1")
|
||||
bazel_dep(name = "platforms", version = "0.0.10")
|
||||
bazel_dep(name = "stardoc", version = "0.7.0")
|
||||
|
||||
cc_configure = use_extension("//cc:extensions.bzl", "cc_configure_extension")
|
||||
use_repo(cc_configure, "local_config_cc", "local_config_cc_toolchains")
|
||||
|
@ -14,3 +13,4 @@ use_repo(cc_configure, "local_config_cc", "local_config_cc_toolchains")
|
|||
register_toolchains("@local_config_cc_toolchains//:all")
|
||||
|
||||
bazel_dep(name = "rules_testing", version = "0.6.0", dev_dependency = True)
|
||||
bazel_dep(name = "stardoc", version = "0.7.0", dev_dependency = True)
|
||||
|
|
67
WORKSPACE
67
WORKSPACE
|
@ -11,34 +11,6 @@ http_archive(
|
|||
],
|
||||
)
|
||||
|
||||
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",
|
||||
|
@ -48,49 +20,10 @@ http_archive(
|
|||
],
|
||||
)
|
||||
|
||||
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",
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
filegroup(
|
||||
name = "srcs",
|
||||
srcs = glob([
|
||||
"**/*.bzl",
|
||||
"**/BUILD",
|
||||
]) + [
|
||||
"//cc/private/rules_impl:srcs",
|
||||
|
|
|
@ -13,11 +13,6 @@
|
|||
# limitations under the License.
|
||||
|
||||
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
||||
load("@bazel_skylib//rules:diff_test.bzl", "diff_test")
|
||||
load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
|
||||
load("@stardoc//stardoc:stardoc.bzl", "stardoc")
|
||||
load("//cc/toolchains/impl:documented_api.bzl", "DOCUMENTED_TOOLCHAIN_RULES")
|
||||
load("//cc/toolchains/impl:markdown_helpers.bzl", "xref_substitutions")
|
||||
|
||||
bzl_library(
|
||||
name = "toolchain_rules",
|
||||
|
@ -42,35 +37,3 @@ filegroup(
|
|||
]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
stardoc(
|
||||
name = "toolchain_api",
|
||||
out = "raw_generated_toolchain_api.md",
|
||||
input = "//cc/toolchains/impl:documented_api.bzl",
|
||||
deps = [":toolchain_rules"],
|
||||
)
|
||||
|
||||
expand_template(
|
||||
name = "toolchain_api_md",
|
||||
out = "generated_toolchain_api.md",
|
||||
# Dictionary order 100% matters here!
|
||||
# buildifier: disable=unsorted-dict-items
|
||||
substitutions = {
|
||||
# Strip @rules_cc to prevent instances of @rules_cc@rules_cc//cc.
|
||||
"@rules_cc//cc": "//cc",
|
||||
# In GitHub, we prefer to clarify all the labels that come from
|
||||
# rules_cc.
|
||||
"//cc": "@rules_cc//cc",
|
||||
} | xref_substitutions({
|
||||
"`{}`".format(rule_name): "#{}".format(rule_name)
|
||||
for rule_name in DOCUMENTED_TOOLCHAIN_RULES
|
||||
}),
|
||||
# buildifier: enable=unsorted-dict-items
|
||||
template = ":raw_generated_toolchain_api.md",
|
||||
)
|
||||
|
||||
diff_test(
|
||||
name = "toolchain_api_diff_test",
|
||||
file1 = ":generated_toolchain_api.md",
|
||||
file2 = ":toolchain_api.md",
|
||||
)
|
||||
|
|
|
@ -40,7 +40,7 @@ cc_action_type = rule(
|
|||
`cc_action_type` rules are used to associate arguments and tools together to
|
||||
perform a specific action. Bazel prescribes a set of known action types that are used to drive
|
||||
typical C/C++/ObjC actions like compiling, linking, and archiving. The set of well-known action
|
||||
types can be found in [//cc/toolchains/actions:BUILD](https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/actions/BUILD).
|
||||
types can be found in [//third_party/bazel_rules/rules_cc/cc/toolchains/actions:BUILD](https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/actions/BUILD).
|
||||
|
||||
It's possible to create project-specific action types for use in toolchains. Be careful when
|
||||
doing this, because every toolchain that encounters the action will need to be configured to
|
||||
|
|
|
@ -235,6 +235,8 @@ cc_action_type_set(
|
|||
":cpp_compile_actions",
|
||||
":c_compile_actions",
|
||||
":assembly_actions",
|
||||
":objc_compile",
|
||||
":objcpp_compile",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
@ -17,13 +17,14 @@ load("//cc/toolchains:args.bzl", "cc_args")
|
|||
|
||||
visibility("public")
|
||||
|
||||
def cc_sysroot(name, sysroot, **kwargs):
|
||||
def cc_sysroot(name, sysroot, args = [], **kwargs):
|
||||
"""Creates args for a sysroot.
|
||||
|
||||
Args:
|
||||
name: (str) The name of the target
|
||||
sysroot: (bazel_skylib's directory rule) The directory that should be the
|
||||
sysroot.
|
||||
args: (List[str]) Extra command-line args to add.
|
||||
**kwargs: kwargs to pass to cc_args.
|
||||
"""
|
||||
cc_args(
|
||||
|
@ -33,7 +34,7 @@ def cc_sysroot(name, sysroot, **kwargs):
|
|||
Label("//cc/toolchains/actions:c_compile"),
|
||||
Label("//cc/toolchains/actions:link_actions"),
|
||||
],
|
||||
args = ["--sysroot={sysroot}"],
|
||||
args = ["--sysroot={sysroot}"] + args,
|
||||
format = {"sysroot": sysroot},
|
||||
**kwargs
|
||||
)
|
||||
|
|
|
@ -9,7 +9,7 @@ load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
|
|||
|
||||
exports_files(
|
||||
["documented_api.bzl"],
|
||||
visibility = ["//cc/toolchains:__subpackages__"],
|
||||
visibility = ["//docs:__pkg__"],
|
||||
)
|
||||
|
||||
bzl_library(
|
||||
|
|
|
@ -75,7 +75,7 @@ def cc_variable(name, type, **kwargs):
|
|||
it's not possible to declare custom variables.
|
||||
|
||||
For a full list of available variables, see
|
||||
[//cc/toolchains/varaibles:BUILD](https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/variables/BUILD).
|
||||
[//third_party/bazel_rules/rules_cc/cc/toolchains/varaibles:BUILD](https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/variables/BUILD).
|
||||
|
||||
Example:
|
||||
```
|
||||
|
@ -91,7 +91,7 @@ def cc_variable(name, type, **kwargs):
|
|||
Args:
|
||||
name: (str) The name of the outer variable, and the rule.
|
||||
type: The type of the variable, constructed using `types` factory in
|
||||
[//cc/toolchains/impl:variables.bzl](https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/impl/variables.bzl).
|
||||
[//third_party/bazel_rules/rules_cc/cc/toolchains/impl:variables.bzl](https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/impl/variables.bzl).
|
||||
**kwargs: [common attributes](https://bazel.build/reference/be/common-definitions#common-attributes) that should be applied to this rule.
|
||||
"""
|
||||
_cc_variable(name = name, type = json.encode(type), **kwargs)
|
||||
|
|
|
@ -102,7 +102,7 @@ This can help work around errors like:
|
|||
providers = [ToolCapabilityInfo],
|
||||
doc = """Declares that a tool is capable of doing something.
|
||||
|
||||
For example, `//cc/toolchains/capabilities:supports_pic`.
|
||||
For example, `//third_party/bazel_rules/rules_cc/cc/toolchains/capabilities:supports_pic`.
|
||||
""",
|
||||
),
|
||||
},
|
||||
|
|
|
@ -75,7 +75,7 @@ def cc_tool_map(name, tools, **kwargs):
|
|||
`CXX=/path/to/clang++` environment variables that most build systems use to determine which
|
||||
tools to use for a given action. To simplify usage, some actions have been grouped together (for
|
||||
example,
|
||||
[//cc/toolchains/actions:cpp_compile_actions](https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/actions/BUILD)) to
|
||||
[//third_party/bazel_rules/rules_cc/cc/toolchains/actions:cpp_compile_actions](https://github.com/bazelbuild/rules_cc/tree/main/cc/toolchains/actions/BUILD)) to
|
||||
logically express "all the C++ compile actions".
|
||||
|
||||
In Bazel, there is a little more granularity to the mapping, so the mapping doesn't follow the
|
||||
|
|
|
@ -19,11 +19,6 @@ load("//cc/private/toolchain:windows_cc_configure.bzl", _find_vc_path = "find_vc
|
|||
|
||||
MSVC_ENVVARS = _MSVC_ENVVARS
|
||||
|
||||
def find_vc_path(repository_ctx):
|
||||
return _find_vc_path(repository_ctx)
|
||||
|
||||
def setup_vc_env_vars(repository_ctx):
|
||||
return _setup_vc_env_vars(repository_ctx)
|
||||
|
||||
def escape_string(string):
|
||||
return _escape_string(string)
|
||||
find_vc_path = _find_vc_path
|
||||
setup_vc_env_vars = _setup_vc_env_vars
|
||||
escape_string = _escape_string
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
# Copyright 2024 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//rules:diff_test.bzl", "diff_test")
|
||||
load("@bazel_skylib//rules:expand_template.bzl", "expand_template")
|
||||
load("@stardoc//stardoc:stardoc.bzl", "stardoc")
|
||||
load("//cc/toolchains/impl:documented_api.bzl", "DOCUMENTED_TOOLCHAIN_RULES")
|
||||
load("//cc/toolchains/impl:markdown_helpers.bzl", "xref_substitutions")
|
||||
|
||||
filegroup(
|
||||
name = "srcs",
|
||||
srcs = glob([
|
||||
"**/*.bzl",
|
||||
"**/BUILD",
|
||||
]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
stardoc(
|
||||
name = "toolchain_api",
|
||||
out = "raw_generated_toolchain_api.md",
|
||||
input = "//cc/toolchains/impl:documented_api.bzl",
|
||||
deps = ["//cc/toolchains:toolchain_rules"],
|
||||
)
|
||||
|
||||
expand_template(
|
||||
name = "toolchain_api_md",
|
||||
out = "generated_toolchain_api.md",
|
||||
# Dictionary order 100% matters here!
|
||||
# buildifier: disable=unsorted-dict-items
|
||||
substitutions = {
|
||||
# Strip @rules_cc to prevent instances of @rules_cc@rules_cc//cc.
|
||||
"@rules_cc//cc": "//cc",
|
||||
# In GitHub, we prefer to clarify all the labels that come from
|
||||
# rules_cc.
|
||||
"//cc": "@rules_cc//cc",
|
||||
} | xref_substitutions({
|
||||
"`{}`".format(rule_name): "#{}".format(rule_name)
|
||||
for rule_name in DOCUMENTED_TOOLCHAIN_RULES
|
||||
}),
|
||||
# buildifier: enable=unsorted-dict-items
|
||||
template = ":raw_generated_toolchain_api.md",
|
||||
)
|
||||
|
||||
diff_test(
|
||||
name = "toolchain_api_diff_test",
|
||||
file1 = ":generated_toolchain_api.md",
|
||||
file2 = ":toolchain_api.md",
|
||||
)
|
|
@ -1 +0,0 @@
|
|||
# Intentionally empty, only there to make //third_party a package.
|
|
@ -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__",
|
||||
],
|
||||
)
|
|
@ -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;
|
||||
}
|
|
@ -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"],
|
||||
)
|
|
@ -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"],
|
||||
)
|
|
@ -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,
|
||||
)
|
|
@ -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!")
|
||||
}
|
|
@ -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)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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)
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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,
|
||||
)
|
|
@ -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])
|
File diff suppressed because it is too large
Load Diff
|
@ -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)
|
Loading…
Reference in New Issue