• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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