1#!/usr/bin/env python3 2 3# Copyright 2022 The Pigweed Authors 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); you may not 6# use this file except in compliance with the License. You may obtain a copy of 7# the License at 8# 9# https://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 14# License for the specific language governing permissions and limitations under 15# the License. 16""" An internal set of tools for creating embedded CC targets. """ 17 18load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain", "use_cpp_toolchain") 19load("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME") 20 21DEBUGGING = [ 22 "-g", 23] 24 25# Standard compiler flags to reduce output binary size. 26REDUCED_SIZE_COPTS = [ 27 "-fno-common", 28 "-fno-exceptions", 29 "-ffunction-sections", 30 "-fdata-sections", 31] 32 33STRICT_WARNINGS_COPTS = [ 34 "-Wall", 35 "-Wextra", 36 # Make all warnings errors, except for the exemptions below. 37 "-Werror", 38 "-Wno-error=cpp", # preprocessor #warning statement 39 "-Wno-error=deprecated-declarations", # [[deprecated]] attribute 40] 41 42DISABLE_PENDING_WORKAROUND_COPTS = [ 43 "-Wno-private-header", 44] 45 46PW_DEFAULT_COPTS = ( 47 DEBUGGING + 48 REDUCED_SIZE_COPTS + 49 STRICT_WARNINGS_COPTS + 50 DISABLE_PENDING_WORKAROUND_COPTS 51) 52 53KYTHE_COPTS = [ 54 "-Wno-unknown-warning-option", 55] 56 57def add_defaults(kwargs): 58 """Adds default arguments suitable for both C and C++ code to kwargs. 59 60 Args: 61 kwargs: cc_* arguments to be modified. 62 """ 63 64 copts = PW_DEFAULT_COPTS + kwargs.get("copts", []) 65 kwargs["copts"] = select({ 66 "@pigweed//pw_build:kythe": copts + KYTHE_COPTS, 67 "//conditions:default": copts, 68 }) 69 70 # Set linkstatic to avoid building .so files. 71 kwargs["linkstatic"] = True 72 73 kwargs.setdefault("features", []) 74 75 # Crosstool--adding this line to features disables header modules, which 76 # don't work with -fno-rtti. Note: this is not a command-line argument, 77 # it's "minus use_header_modules". 78 kwargs["features"].append("-use_header_modules") 79 80def _preprocess_linker_script_impl(ctx): 81 cc_toolchain = find_cpp_toolchain(ctx) 82 output_script = ctx.actions.declare_file(ctx.label.name + ".ld") 83 feature_configuration = cc_common.configure_features( 84 ctx = ctx, 85 cc_toolchain = cc_toolchain, 86 requested_features = ctx.features, 87 unsupported_features = ctx.disabled_features, 88 ) 89 cxx_compiler_path = cc_common.get_tool_for_action( 90 feature_configuration = feature_configuration, 91 action_name = C_COMPILE_ACTION_NAME, 92 ) 93 c_compile_variables = cc_common.create_compile_variables( 94 feature_configuration = feature_configuration, 95 cc_toolchain = cc_toolchain, 96 user_compile_flags = ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts, 97 ) 98 action_flags = cc_common.get_memory_inefficient_command_line( 99 feature_configuration = feature_configuration, 100 action_name = C_COMPILE_ACTION_NAME, 101 variables = c_compile_variables, 102 ) 103 env = cc_common.get_environment_variables( 104 feature_configuration = feature_configuration, 105 action_name = C_COMPILE_ACTION_NAME, 106 variables = c_compile_variables, 107 ) 108 ctx.actions.run( 109 outputs = [output_script], 110 inputs = depset( 111 [ctx.file.linker_script], 112 transitive = [cc_toolchain.all_files], 113 ), 114 executable = cxx_compiler_path, 115 arguments = [ 116 "-E", 117 "-P", 118 "-xc", 119 ctx.file.linker_script.short_path, 120 "-o", 121 output_script.path, 122 ] + [ 123 "-D" + d 124 for d in ctx.attr.defines 125 ] + action_flags + ctx.attr.copts, 126 env = env, 127 ) 128 return [DefaultInfo(files = depset([output_script]))] 129 130pw_linker_script = rule( 131 _preprocess_linker_script_impl, 132 attrs = { 133 "copts": attr.string_list(doc = "C compile options."), 134 "defines": attr.string_list(doc = "C preprocessor defines."), 135 "linker_script": attr.label( 136 mandatory = True, 137 allow_single_file = True, 138 doc = "Linker script to preprocess.", 139 ), 140 "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), 141 }, 142 toolchains = use_cpp_toolchain(), 143 fragments = ["cpp"], 144) 145