Skip to content

Commit

Permalink
Add toolchain_rule to enable rule authors to define toolchains.
Browse files Browse the repository at this point in the history
Change-Id: I407240708f4aacc89ec5c00bf3e8ff46a1d6d6d6
PiperOrigin-RevId: 152692981
  • Loading branch information
katre authored and buchgr committed Apr 11, 2017
1 parent ba51190 commit 5dc81a2
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/create_embedded_tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ for i in $*; do
case "$i" in
*tools/jdk/BUILD*) OUTPUT_PATH=tools/jdk/BUILD ;;
*tools/platforms/platforms.BUILD) OUTPUT_PATH=platforms/BUILD ;;
*tools/platforms/*) OUTPUT_PATH=platforms/${i##*/} ;;
*JavaBuilder*_deploy.jar) OUTPUT_PATH=tools/jdk/${i##*/} ;;
*JacocoCoverage*_deploy.jar) OUTPUT_PATH=tools/jdk/JacocoCoverage_deploy.jar ;;
*turbine_deploy.jar) OUTPUT_PATH=tools/jdk/turbine_deploy.jar ;;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public ClassObjectConstructor getConstraintSettingInfoConstructor() {
public ClassObjectConstructor getConstraintValueInfoConstructor() {
return ConstraintValueInfo.SKYLARK_CONSTRUCTOR;
}

@SkylarkCallable(
name = ToolchainInfo.SKYLARK_NAME,
doc = "The key used to retrieve the provider containing toolchain data.",
Expand Down
7 changes: 7 additions & 0 deletions src/test/shell/bazel/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,13 @@ sh_test(
data = [":test-deps"],
)

sh_test(
name = "toolchain_test",
size = "small",
srcs = ["toolchain_test.sh"],
data = [":test-deps"],
)

test_suite(
name = "all_tests",
visibility = ["//visibility:public"],
Expand Down
150 changes: 150 additions & 0 deletions src/test/shell/bazel/toolchain_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#!/bin/bash
#
# Copyright 2017 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.
#
# Test the providers and rules related to toolchains.
#

# Load the test setup defined in the parent directory
CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "${CURRENT_DIR}/../integration_test_setup.sh" \
|| { echo "integration_test_setup.sh not found!" >&2; exit 1; }

function set_up() {
create_new_workspace

# Create shared constraints.
mkdir -p constraints
cat >>constraints/BUILD <<EOF
package(default_visibility = ['//visibility:public'])
constraint_setting(name = 'os')
constraint_value(name = 'linux',
constraint_setting = ':os')
constraint_value(name = 'mac',
constraint_setting = ':os')
EOF

# Create shared report rule for printing info.
mkdir report
touch report/BUILD
cat >>report/report.bzl <<EOF
def _report_impl(ctx):
toolchain = ctx.attr.toolchain[platform_common.ToolchainInfo]
for field in ctx.attr.fields:
value = getattr(toolchain, field)
if type(value) == 'Target':
value = value.label
print('%s = "%s"' % (field, value))
report_toolchain = rule(
_report_impl,
attrs = {
'fields': attr.string_list(),
'toolchain': attr.label(providers = [platform_common.ToolchainInfo]),
}
)
EOF
}

function test_toolchain_rule() {

mkdir -p toolchain
cat >> toolchain/toolchain.bzl <<EOF
load('@bazel_tools//platforms:toolchains.bzl', 'toolchain_rule')
test_toolchain = toolchain_rule(
extra_attrs = {
'extra_label': attr.label(),
'extra_str': attr.string(),
}
)
EOF

cat >> toolchain/BUILD <<EOF
load('//report:report.bzl', 'report_toolchain')
load(':toolchain.bzl', 'test_toolchain')
filegroup(name = 'dep_rule')
test_toolchain(
name = 'linux_toolchain',
exec_compatible_with = [
'//constraints:linux',
],
target_compatible_with = [
'//constraints:mac',
],
extra_label = ':dep_rule',
extra_str = 'bar',
)
report_toolchain(
name = 'report',
fields = ['extra_label', 'extra_str'],
toolchain = ':linux_toolchain',
)
EOF

bazel build //toolchain:report &> $TEST_log || fail "Build failed"
expect_log 'extra_label = "//toolchain:dep_rule"'
expect_log 'extra_str = "bar"'
}

function test_toolchain_rule_override_impl() {

mkdir -p toolchain
cat >> toolchain/toolchain.bzl <<EOF
load('@bazel_tools//platforms:toolchains.bzl', 'toolchain_rule', 'default_toolchain_rule_impl')
def _impl(ctx):
overridde_attrs = {
'extra_label': 'override:' + ctx.attr.extra_str,
'extra_str': 'foo',
}
return default_toolchain_rule_impl(ctx, overridde_attrs)
test_toolchain = toolchain_rule(
implementation = _impl,
extra_attrs = {
'extra_label': attr.label(),
'extra_str': attr.string(),
}
)
EOF

cat >> toolchain/BUILD <<EOF
load('//report:report.bzl', 'report_toolchain')
load(':toolchain.bzl', 'test_toolchain')
filegroup(name = 'dep_rule')
test_toolchain(
name = 'linux_toolchain',
exec_compatible_with = [
'//constraints:linux',
],
target_compatible_with = [
'//constraints:mac',
],
extra_label = ':dep_rule',
extra_str = 'bar',
)
report_toolchain(
name = 'report',
fields = ['extra_label', 'extra_str'],
toolchain = ':linux_toolchain',
)
EOF

bazel build //toolchain:report &> $TEST_log || fail "Build failed"
expect_log 'extra_label = "override:bar"'
expect_log 'extra_str = "foo"'
}

run_suite "toolchain tests"
1 change: 1 addition & 0 deletions tools/platforms/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ filegroup(
name = "package-srcs",
srcs = [
"platforms.BUILD",
"toolchains.bzl",
],
)

Expand Down
2 changes: 2 additions & 0 deletions tools/platforms/platforms.BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ package(
default_visibility = ["//visibility:public"],
)

export_files = ["toolchains.bzl"]

# These match values in //src/main/java/com/google/build/lib/util:CPU.java
constraint_setting(name = "cpu")

Expand Down
63 changes: 63 additions & 0 deletions tools/platforms/toolchains.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright 2017 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.
"""Useful functions and rules for defining toolchains."""

_default_toolchain_rule_attrs = {
"exec_compatible_with": attr.label_list(
providers = [platform_common.ConstraintValueInfo]),
"target_compatible_with": attr.label_list(
providers = [platform_common.ConstraintValueInfo]),
}

def default_toolchain_rule_impl(ctx, override_attrs = {}):
"""A default implementation for toolchain_rule.
This implementation creates a toolchain provider and adds all extra
attributes.
Args:
ctx: The rule context.
override_attrs: Any data in this dict will override the corresponding
attribute from the context. toolchain_rule implementations can use this
to customize the values set in the provider.
Returns:
The created toolchain provider.
"""
toolchain_data = {}

# Collect the extra_args from ctx.attrs.
attr_names = ctx.attr._extra_attr_names
for name in attr_names:
if name in override_attrs:
attr = override_attrs[name]
else:
attr = getattr(ctx.attr, name)
toolchain_data[name] = attr

toolchain = platform_common.toolchain(
exec_compatible_with = ctx.attr.exec_compatible_with,
target_compatible_with = ctx.attr.target_compatible_with,
**toolchain_data)

return [toolchain]

def toolchain_rule(implementation = default_toolchain_rule_impl, fragments = [], extra_attrs = {}):
return rule(
implementation = implementation,
attrs = _default_toolchain_rule_attrs + extra_attrs + {
# default_toolchain_rule_impl needs this to know what attributes are extra args.
"_extra_attr_names": attr.string_list(default = extra_attrs.keys()),
},
fragments = fragments,
)

0 comments on commit 5dc81a2

Please sign in to comment.