#!/usr/bin/env python3 # Copyright 2022 The Pigweed Authors # # 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 # # https://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. """ An internal set of tools for creating embedded CC targets. """ load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain") load("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME") DEBUGGING = [ "-g", ] # Standard compiler flags to reduce output binary size. REDUCED_SIZE_COPTS = [ "-fno-common", "-fno-exceptions", "-ffunction-sections", "-fdata-sections", ] STRICT_WARNINGS_COPTS = [ "-Wall", "-Wextra", # Make all warnings errors, except for the exemptions below. "-Werror", "-Wno-error=cpp", # preprocessor #warning statement "-Wno-error=deprecated-declarations", # [[deprecated]] attribute ] DISABLE_PENDING_WORKAROUND_COPTS = [ "-Wno-private-header", ] PW_DEFAULT_COPTS = ( DEBUGGING + REDUCED_SIZE_COPTS + STRICT_WARNINGS_COPTS + DISABLE_PENDING_WORKAROUND_COPTS ) KYTHE_COPTS = [ "-Wno-unknown-warning-option", ] def add_defaults(kwargs): """Adds default arguments suitable for both C and C++ code to kwargs. Args: kwargs: cc_* arguments to be modified. """ copts = PW_DEFAULT_COPTS + kwargs.get("copts", []) kwargs["copts"] = select({ "@pigweed//pw_build:kythe": copts + KYTHE_COPTS, "//conditions:default": copts, }) # Set linkstatic to avoid building .so files. kwargs["linkstatic"] = True kwargs.setdefault("features", []) # Crosstool--adding this line to features disables header modules, which # don't work with -fno-rtti. Note: this is not a command-line argument, # it's "minus use_header_modules". kwargs["features"].append("-use_header_modules") def _preprocess_linker_script_impl(ctx): cc_toolchain = find_cpp_toolchain(ctx) output_script = ctx.actions.declare_file(ctx.label.name + ".ld") feature_configuration = cc_common.configure_features( ctx = ctx, cc_toolchain = cc_toolchain, requested_features = ctx.features, unsupported_features = ctx.disabled_features, ) cxx_compiler_path = cc_common.get_tool_for_action( feature_configuration = feature_configuration, action_name = C_COMPILE_ACTION_NAME, ) 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, ) action_flags = cc_common.get_memory_inefficient_command_line( feature_configuration = feature_configuration, action_name = C_COMPILE_ACTION_NAME, variables = c_compile_variables, ) env = cc_common.get_environment_variables( feature_configuration = feature_configuration, action_name = C_COMPILE_ACTION_NAME, variables = c_compile_variables, ) ctx.actions.run( outputs = [output_script], inputs = depset( [ctx.file.linker_script], transitive = [cc_toolchain.all_files], ), executable = cxx_compiler_path, arguments = [ "-E", "-P", "-xc", ctx.file.linker_script.short_path, "-o", output_script.path, ] + [ "-D" + d for d in ctx.attr.defines ] + action_flags + ctx.attr.copts, env = env, ) return [DefaultInfo(files = depset([output_script]))] pw_linker_script = rule( _preprocess_linker_script_impl, attrs = { "copts": attr.string_list(doc = "C compile options."), "defines": attr.string_list(doc = "C preprocessor defines."), "linker_script": attr.label( mandatory = True, allow_single_file = True, doc = "Linker script to preprocess.", ), "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), }, toolchains = use_cpp_toolchain(), fragments = ["cpp"], )