[bazel] Add cc_library_with_options

This can let us create versions of skia_public with certain settings
enabled in an easy way (i.e. not requiring clients to set the compile
flags themselves).

Change-Id: I909449c6186f4912ea80dd9d579fcd7cafb4775c
Bug: skia:12541 b/237076898
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/553377
Reviewed-by: Jorge Betancourt <jmbetancourt@google.com>
This commit is contained in:
Kevin Lubick 2022-06-27 10:41:10 -04:00
parent b007c1909b
commit 4855152354
4 changed files with 103 additions and 8 deletions

View File

@ -10,6 +10,7 @@ _bool_flags = [
"//bazel/common_config_settings:enable_sksl",
"//bazel/common_config_settings:enable_sksl_tracing",
"//bazel/common_config_settings:enable_skslc",
"//bazel/common_config_settings:enable_svg_canvas",
"//bazel/common_config_settings:is_skia_dev_build",
"//bazel/common_config_settings:use_icu",
]
@ -58,7 +59,7 @@ def _flag_transition_impl(settings, attr):
return rv
# This defines a Starlark transition and which flags it reads and writes.
_flag_transition = transition(
with_flags_transition = transition(
implementation = _flag_transition_impl,
inputs = _flags,
outputs = _flags,
@ -94,13 +95,13 @@ transition_rule = rule(
# set_flags is a dictionary with the keys being the short-form of a flag name
# (e.g. the part that comes after the colon) and the value being a list of values
# that the flag should be set to, regardless of the relevant CLI flags.
# https://docs.bazel.build/versions/main/skylark/lib/attr.html#string_list_dict
# https://bazel.build/rules/lib/attr#string_list_dict
"set_flags": attr.string_list_dict(),
# This is the cc_binary whose deps will select() on that feature.
# Note specifically how it is modified with _flag_transition, which
# ensures that the flags propagates down the graph.
# https://docs.bazel.build/versions/main/skylark/lib/attr.html#label
"actual_binary": attr.label(cfg = _flag_transition),
# https://bazel.build/rules/lib/attr#label
"actual_binary": attr.label(cfg = with_flags_transition),
# This is a stock Bazel requirement for any rule that uses Starlark
# transitions. It's okay to copy the below verbatim for all such rules.
#

View File

@ -0,0 +1,80 @@
"""
This file contains a way to set flags from BUILD.bazel instead of requiring users to set them from
the CLI.
For example, a user could create:
cc_library_with_flags(
name = "skia_with_jpeg_png_and_svg",
set_flags = {
"include_decoder": [
"jpeg_decode_codec",
"png_decode_codec",
],
"enable_svg_canvas": ["True"],
},
target = "//:skia_public",
)
Then, compiling with
bazel build :skia_with_jpeg_png_and_svg
would produce the same output as
bazel build //:skia_public --include_encoder=jpeg_decode_codec \
--include_encoder=png_decode_codec \
--enable_svg_canvas
which uses aliases defined in .bazelrc to be the same as
bazel build //:skia_public --//bazel/common_config_settings:include_encoder=jpeg_decode_codec \
--//bazel/common_config_settings:include_encoder=png_decode_codec \
--//bazel/common_config_settings:enable_svg_canvas
Having the options be defined in the BUILD.bazel target is much more convenient.
See more here about Bazel transitions:
- https://bazel.build/rules/config#user-defined-transitions
- https://bazel.build/rules/lib/transition
- https://github.com/bazelbuild/examples/tree/5a8696429e36090a75eb6fee4ef4e91a3413ef13/configurations
"""
load("//bazel:cc_binary_with_flags.bzl", "with_flags_transition")
# This transition implementation just forwards the outputs from the target as its own.
# We expect target to be a cc_library, so we return its CcInfo outputs, describing the compilation
# and linking of C++ code. That way, this rule can be used anywhere a cc_library could be used
# (e.g. in the deps of a cc_binary).
# https://bazel.build/rules/rules#default_outputs
def _transition_rule_impl(ctx):
target = ctx.attr.target[0]
return [
# https://bazel.build/rules/lib/CcInfo
target[CcInfo],
]
cc_library_with_flags = rule(
implementation = _transition_rule_impl,
attrs = {
# set_flags is a dictionary with the keys being the short-form of a flag name
# (e.g. the part that comes after the colon) and the value being a list of values
# that the flag should be set to, regardless of the relevant CLI flags.
# https://bazel.build/rules/lib/attr#string_list_dict
"set_flags": attr.string_list_dict(),
"target": attr.label(
mandatory = True,
allow_single_file = True,
# Setting cfg to be a transition allows us to modify the build settings before
# Bazel actually does the building. In this way, we can read the set_flags dictionary
# and modify/update the appropriate build settings that we defined in
# //bazel/common_config_settings. We share this transition with cc_binary_with_flags.
cfg = with_flags_transition,
),
# This is a stock Bazel requirement for any rule that uses Starlark
# transitions. It's okay to copy the below verbatim for all such rules.
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
)

View File

@ -1,6 +1,5 @@
load("//bazel:macros.bzl", "exports_files_legacy")
load("@rules_cc//cc:defs.bzl", "cc_binary")
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
load("//bazel:macros.bzl", "cc_binary", "exports_files_legacy", "go_binary", "go_library")
load("//bazel:cc_library_with_flags.bzl", "cc_library_with_flags")
licenses(["notice"])
@ -12,11 +11,19 @@ cc_binary(
"bazel_test.cpp",
],
deps = [
"//:skia_public",
":skia_with_svg",
"@libpng",
],
)
cc_library_with_flags(
name = "skia_with_svg",
set_flags = {
"enable_svg_canvas": ["True"],
},
target = "//:skia_public",
)
go_binary(
name = "hello_world",
embed = [":bazel_test_lib"],

View File

@ -1,7 +1,10 @@
// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
#include "include/core/SkCanvas.h"
#include "include/core/SkRect.h"
#include "include/core/SkTypes.h"
#include "include/svg/SkSVGCanvas.h"
#include "png.h"
@ -22,6 +25,10 @@ int main(int argc, char** argv) {
printf("PASS\n"); // This tells the human the test passed.
return 0; // This tells Bazel the test passed.
}
if (argc < -10) {
std::unique_ptr<SkCanvas> not_used = SkSVGCanvas::Make({}, nullptr, 0);
not_used->save();
}
printf("FAIL\n"); // This tells the human the test failed.
return 1; // This tells Bazel the test failed.
}