From 3d5980e5cb0fa71912fc743228fc39d5f57be2d6 Mon Sep 17 00:00:00 2001 From: hlopko Date: Wed, 27 Feb 2019 00:36:50 -0800 Subject: [PATCH] Add example writing custom rule that depends and is dependable from rules_cc RELNOTES: None. PiperOrigin-RevId: 235869541 --- examples/my_c_archive/BUILD | 42 ++++++++ examples/my_c_archive/bar.c | 1 + examples/my_c_archive/foo.c | 15 +++ examples/my_c_archive/main.c | 3 + examples/my_c_archive/my_c_archive.bzl | 98 +++++++++++++++++++ examples/my_c_compile/my_c_compile.bzl | 12 ++- .../write_cc_toolchain_cpu.bzl | 2 +- 7 files changed, 169 insertions(+), 4 deletions(-) create mode 100644 examples/my_c_archive/BUILD create mode 100644 examples/my_c_archive/bar.c create mode 100644 examples/my_c_archive/foo.c create mode 100644 examples/my_c_archive/main.c create mode 100644 examples/my_c_archive/my_c_archive.bzl diff --git a/examples/my_c_archive/BUILD b/examples/my_c_archive/BUILD new file mode 100644 index 0000000..a734c66 --- /dev/null +++ b/examples/my_c_archive/BUILD @@ -0,0 +1,42 @@ +# Copyright 2019 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 showing how to create a custom Starlark rule that rules_cc can depend on +licenses(["notice"]) + +load("//examples/my_c_compile:my_c_compile.bzl", "my_c_compile") +load("//examples/my_c_archive:my_c_archive.bzl", "my_c_archive") +load("//cc:rules.bzl", "cc_binary") + +cc_binary( + name = "main", + srcs = ["main.c"], + deps = [":archive"], +) + +my_c_archive( + name = "archive", + object = ":object", + deps = [":bar"], +) + +my_c_compile( + name = "object", + src = "foo.c", +) + +cc_library( + name = "bar", + srcs = ["bar.c"], +) diff --git a/examples/my_c_archive/bar.c b/examples/my_c_archive/bar.c new file mode 100644 index 0000000..8c9de53 --- /dev/null +++ b/examples/my_c_archive/bar.c @@ -0,0 +1 @@ +int bar() { return -42; } diff --git a/examples/my_c_archive/foo.c b/examples/my_c_archive/foo.c new file mode 100644 index 0000000..6718fbd --- /dev/null +++ b/examples/my_c_archive/foo.c @@ -0,0 +1,15 @@ +// Copyright 2019 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. + +int foo() { return 42; } diff --git a/examples/my_c_archive/main.c b/examples/my_c_archive/main.c new file mode 100644 index 0000000..33ca256 --- /dev/null +++ b/examples/my_c_archive/main.c @@ -0,0 +1,3 @@ +int foo(); +int bar(); +int main() { return foo() + bar(); } diff --git a/examples/my_c_archive/my_c_archive.bzl b/examples/my_c_archive/my_c_archive.bzl new file mode 100644 index 0000000..ee792a8 --- /dev/null +++ b/examples/my_c_archive/my_c_archive.bzl @@ -0,0 +1,98 @@ +# Copyright 2019 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 showing how to create a rule that rules_cc can depend on.""" + +load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") +load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "CPP_LINK_STATIC_LIBRARY_ACTION_NAME") +load("//examples/my_c_compile:my_c_compile.bzl", "MyCCompileInfo") + +def _my_c_archive_impl(ctx): + cc_toolchain = find_cpp_toolchain(ctx) + object_file = ctx.attr.object[MyCCompileInfo].object + output_file = ctx.actions.declare_file(ctx.label.name + ".a") + + feature_configuration = cc_common.configure_features( + cc_toolchain = cc_toolchain, + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + + library_to_link = cc_common.create_library_to_link( + actions = ctx.actions, + feature_configuration = feature_configuration, + cc_toolchain = cc_toolchain, + static_library = output_file, + ) + compilation_context = cc_common.create_compilation_context() + linking_context = cc_common.create_linking_context(libraries_to_link = [library_to_link]) + + feature_configuration = cc_common.configure_features( + cc_toolchain = cc_toolchain, + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + archiver_path = cc_common.get_tool_for_action( + feature_configuration = feature_configuration, + action_name = CPP_LINK_STATIC_LIBRARY_ACTION_NAME, + ) + archiver_variables = cc_common.create_link_variables( + feature_configuration = feature_configuration, + cc_toolchain = cc_toolchain, + output_file = output_file.path, + is_using_linker = False, + ) + command_line = cc_common.get_memory_inefficient_command_line( + feature_configuration = feature_configuration, + action_name = CPP_LINK_STATIC_LIBRARY_ACTION_NAME, + variables = archiver_variables, + ) + args = ctx.actions.args() + args.add_all(command_line) + args.add(object_file) + + env = cc_common.get_environment_variables( + feature_configuration = feature_configuration, + action_name = CPP_LINK_STATIC_LIBRARY_ACTION_NAME, + variables = archiver_variables, + ) + + ctx.actions.run( + executable = archiver_path, + arguments = [args], + env = env, + inputs = depset( + direct = [object_file], + transitive = [ + # TODO: Use CcToolchainInfo getters when available + # See https://github.com/bazelbuild/bazel/issues/7427. + ctx.attr._cc_toolchain.files, + ], + ), + outputs = [output_file], + ) + + cc_info = cc_common.merge_cc_infos(cc_infos = [ + CcInfo(compilation_context = compilation_context, linking_context = linking_context), + ] + [dep[CcInfo] for dep in ctx.attr.deps]) + return [cc_info] + +my_c_archive = rule( + implementation = _my_c_archive_impl, + attrs = { + "object": attr.label(mandatory = True, providers = [MyCCompileInfo]), + "deps": attr.label_list(providers = [CcInfo]), + "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), + }, +) diff --git a/examples/my_c_compile/my_c_compile.bzl b/examples/my_c_compile/my_c_compile.bzl index a9cec34..7987f6b 100644 --- a/examples/my_c_compile/my_c_compile.bzl +++ b/examples/my_c_compile/my_c_compile.bzl @@ -12,11 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Example about how to create a custom Starlark rule that just compiles C sources.""" +"""Example showing how to create a rule that just compiles C sources.""" load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "C_COMPILE_ACTION_NAME") +MyCCompileInfo = provider(doc = "", fields = ["object"]) + DISABLED_FEATURES = [ ] @@ -36,6 +38,7 @@ def _my_c_compile_impl(ctx): c_compile_variables = cc_common.create_compile_variables( feature_configuration = feature_configuration, cc_toolchain = cc_toolchain, + user_compile_flags = ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts, source_file = source_file.path, output_file = output_file.path, ) @@ -62,13 +65,16 @@ def _my_c_compile_impl(ctx): ), outputs = [output_file], ) - return [DefaultInfo(files = depset(items = [output_file]))] + return [ + DefaultInfo(files = depset(items = [output_file])), + MyCCompileInfo(object = output_file), + ] -# This rule does nothing, just propagates all cc_toolchain files. my_c_compile = rule( implementation = _my_c_compile_impl, attrs = { "src": attr.label(mandatory = True, allow_single_file = True), "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), }, + fragments = ["cpp"], ) diff --git a/examples/write_cc_toolchain_cpu/write_cc_toolchain_cpu.bzl b/examples/write_cc_toolchain_cpu/write_cc_toolchain_cpu.bzl index 2a62168..549c8b2 100644 --- a/examples/write_cc_toolchain_cpu/write_cc_toolchain_cpu.bzl +++ b/examples/write_cc_toolchain_cpu/write_cc_toolchain_cpu.bzl @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Example about how to get CcToolchainInfo in a custom starlark rule.""" +"""Example showing how to get CcToolchainInfo in a custom rule.""" load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")