Add examples of how to name packages with build time values. (#256)

* Move examples tree and create one for naming packages.

TIL that having examples with their own WORKSPACE inside the scope of the
main WORKSPACE leads to strange behavior. Doing
```
bazel test ...
```
from the top would try to build the examples, which we don't want.

* add an example of package naming
This commit is contained in:
aiuto 2021-01-19 15:32:42 -05:00 committed by GitHub
parent db0c9ae570
commit 875dabddfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 286 additions and 0 deletions

23
.bazelci/examples.yml Normal file
View File

@ -0,0 +1,23 @@
common: &common
build_targets:
- "..."
tasks:
centos7:
platform: centos7
working_directory: /workdir/examples/naming_package_files
<<: *common
ubuntu1604:
platform: ubuntu1604
working_directory: /workdir/examples/naming_package_files
<<: *common
ubuntu1804:
platform: ubuntu1804
working_directory: /workdir/examples/naming_package_files
<<: *common
macos:
working_directory: ../examples/naming_package_files
<<: *common
windows:
working_directory: ../examples/naming_package_files
<<: *common

View File

@ -1,3 +1,4 @@
imports:
- tests.yml
- examples.yml
- integration.yml

View File

@ -0,0 +1,76 @@
# Copyright 2020 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.
# -*- coding: utf-8 -*-
licenses(["notice"])
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load(":my_package_name.bzl", "basic_naming", "names_from_toolchains")
config_setting(
name = "special_build",
values = {"define": "SPECIAL=1"},
)
# Exposes the value of the compilation mode to the package naming.
basic_naming(
name = "my_naming_vars",
# An explicit value.
# This technique can be useful if you need to create packages in many
# different formats but have not decided on the final naming yet. You
# can use a placeholder and change it on one location.
#
product_name = "RulesPkgExamples",
# Use a config_setting flag to specify part of the package name.
# In this example, we define the config_setting based on a command line
# flag. Example
# bazel build :example1
# bazel build :example1 --define=SPECIAL=1
special_build = select({
":special_build": "-IsSpecial",
"//conditions:default": "",
}),
)
# Try building with various flag combinations to explore.
# bazel build :example1
# bazel build :example1 -c dbg
# bazel build :example1 -define=SPECIAL=1
# bazel build :example1 -c dbg --define=SPECIAL=1
pkg_tar(
name = "example1",
srcs = [
":BUILD",
],
package_file_name = "example1-{product_name}-{target_cpu}-{compilation_mode}{special_build}.tar",
package_variables = ":my_naming_vars",
)
#
# names_from_toolchains() extracts variables from the CC toolchain.
#
names_from_toolchains(
name = "toolchain_vars",
)
pkg_tar(
name = "example2",
srcs = [
":BUILD",
],
package_file_name = "example2-{cc_cpu}-{compiler}-{compilation_mode}.tar",
package_variables = ":toolchain_vars",
)

View File

@ -0,0 +1,36 @@
# Copyright 2020 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.
workspace(name = "rules_pkg_examples")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
local_repository(
name = "rules_pkg",
path = "../../pkg",
)
http_archive
load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies")
rules_pkg_dependencies()
http_archive(
name = "rules_cc",
url = "https://github.com/bazelbuild/rules_cc/archive/b1c40e1de81913a3c40e5948f78719c28152486d.zip",
sha256 = "d0c573b94a6ef20ef6ff20154a23d0efcb409fb0e1ff0979cec318dfe42f0cdd",
strip_prefix = "rules_cc-b1c40e1de81913a3c40e5948f78719c28152486d",
)

View File

@ -0,0 +1,84 @@
# Copyright 2020 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.
"""Example rule to show package naming techniques."""
load("@rules_pkg//:providers.bzl", "PackageVariablesInfo")
load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain")
def _basic_naming_impl(ctx):
values = {}
# Copy attributes from the rule to the provider
values["product_name"] = ctx.attr.product_name
values["special_build"] = ctx.attr.special_build
# Add some well known variables from the rule context.
values["target_cpu"] = ctx.var.get("TARGET_CPU")
values["compilation_mode"] = ctx.var.get("COMPILATION_MODE")
return PackageVariablesInfo(values = values)
#
# A rule to inject variables from the build file into package names.
#
basic_naming = rule(
implementation = _basic_naming_impl,
attrs = {
"product_name": attr.string(
doc = "Placeholder for our final product name.",
),
"special_build": attr.string(
doc = "Indicates that we have built with a 'special' option.",
),
},
)
def _names_from_toolchains_impl(ctx):
values = {}
# TODO(https://github.com/bazelbuild/bazel/issues/7260): Switch from
# calling find_cc_toolchain to direct lookup via the name.
# cc_toolchain = ctx.toolchains["@rules_cc//cc:toolchain_type"]
cc_toolchain = find_cc_toolchain(ctx)
# compiler is uninformative. Use the name of the executable
values["compiler"] = cc_toolchain.compiler_executable.split("/")[-1]
values["cc_cpu"] = cc_toolchain.cpu
values["libc"] = cc_toolchain.libc
values["compilation_mode"] = ctx.var.get("COMPILATION_MODE")
return PackageVariablesInfo(values = values)
#
# Extracting variables from the toolchain to use in the pacakge name.
#
names_from_toolchains = rule(
implementation = _names_from_toolchains_impl,
# Going forward, the preferred way to depend on a toolchain through the
# toolchains atttribute. The current C++ toolchains, however, are still not
# using toolchain resolution, so we have to depend on the toolchain
# directly.
# TODO(https://github.com/bazelbuild/bazel/issues/7260): Delete the
# _cc_toolchain attribute.
attrs = {
"_cc_toolchain": attr.label(
default = Label(
"@rules_cc//cc:current_cc_toolchain",
),
),
},
toolchains = ["@rules_cc//cc:toolchain_type"],
)

View File

@ -0,0 +1,66 @@
# Examples of how to name packages using build time configuration.
## Examples
The examples below only show snippets of the relevant technique.
See the BUILD file for the complete source.
### Using command line flags to modify a package name
We can use a `config_setting` to capture the command line flag and then
`select()` on that to drop a label into the name.
```
config_setting(
name = "special_build",
values = {"define": "SPECIAL=1"},
)
my_package_naming(
name = "my_naming_vars",
special_build = select({
":special_build": "-IsSpecial",
"//conditions:default": "",
}),
)
```
```
bazel build :example1
ls -l bazel-bin/example1.tar bazel-bin/RulesPkgExamples-k8-fastbuild.tar
```
```
bazel build :example1 --define=SPECIAL=1
ls -l bazel-bin/example1*.tar
```
### Using values from a toolchain in a package name.
The rule providing the naming can depend on toolchains just like a `*_library`
or `*_binary` rule
```
def _names_from_toolchains_impl(ctx):
values = {}
cc_toolchain = find_cc_toolchain(ctx)
values['cc_cpu'] = cc_toolchain.cpu
return PackageVariablesInfo(values = values)
names_from_toolchains = rule(
implementation = _names_from_toolchains_impl,
attrs = {
"_cc_toolchain": attr.label(
default = Label(
"@rules_cc//cc:current_cc_toolchain",
),
),
},
toolchains = ["@rules_cc//cc:toolchain_type"],
)
```
```
bazel build :example2
ls -l bazel-bin/example2*.tar
```