diff options
author | Austin Foxley <afoxley@google.com> | 2024-01-13 03:18:51 +0000 |
---|---|---|
committer | CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2024-01-13 03:18:51 +0000 |
commit | 4c95093e6f39f4a2e3a4c56e91ef47d57a6e57ca (patch) | |
tree | 2fa376b8dce487e5d9efe1baa007728ef1c95390 /pw_build | |
parent | d06ec146fbe683dbfd9594a0259b3ef2f0136e83 (diff) | |
download | pigweed-4c95093e6f39f4a2e3a4c56e91ef47d57a6e57ca.tar.gz |
pw_build: Add pw_cc_binary variant to generate .map files
Bug: b/319746242
Change-Id: I750da45d7cb188d9848f8bd0804367664343da35
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/187710
Presubmit-Verified: CQ Bot Account <pigweed-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ted Pudlik <tpudlik@google.com>
Commit-Queue: Austin Foxley <afoxley@google.com>
Diffstat (limited to 'pw_build')
-rw-r--r-- | pw_build/BUILD.bazel | 12 | ||||
-rw-r--r-- | pw_build/BUILD.gn | 5 | ||||
-rw-r--r-- | pw_build/bazel.rst | 17 | ||||
-rw-r--r-- | pw_build/bazel_internal/pigweed_internal.bzl | 60 | ||||
-rw-r--r-- | pw_build/empty_main.cc | 15 | ||||
-rw-r--r-- | pw_build/pigweed.bzl | 79 |
6 files changed, 188 insertions, 0 deletions
diff --git a/pw_build/BUILD.bazel b/pw_build/BUILD.bazel index ed701d706..60adeb7d7 100644 --- a/pw_build/BUILD.bazel +++ b/pw_build/BUILD.bazel @@ -14,6 +14,7 @@ load( "//pw_build:pigweed.bzl", + "pw_cc_binary_with_map", "pw_cc_blob_info", "pw_cc_blob_library", "pw_cc_test", @@ -59,6 +60,17 @@ pw_cc_test( deps = [":test_blob"], ) +pw_cc_binary_with_map( + name = "cc_binary_with_map", + srcs = ["empty_main.cc"], + # Only enable on platforms that support -Map linker flag + target_compatible_with = select({ + "@platforms//os:macos": ["@platforms//:incompatible"], + "@platforms//os:windows": ["@platforms//:incompatible"], + "//conditions:default": [], + }), +) + # Bazel produces root-relative file paths without the -ffile-prefix-map option. pw_cc_test( name = "file_prefix_map_test", diff --git a/pw_build/BUILD.gn b/pw_build/BUILD.gn index 4e56015f6..3537c5a26 100644 --- a/pw_build/BUILD.gn +++ b/pw_build/BUILD.gn @@ -434,6 +434,11 @@ if (current_toolchain != default_toolchain) { visibility = [ ":*" ] } + pw_source_set("empty_main") { + sources = [ "empty_main.cc" ] + visibility = [ ":*" ] + } + pw_test_group("tests") { tests = [ ":cc_blob_library_test", diff --git a/pw_build/bazel.rst b/pw_build/bazel.rst index 99c3754dd..a56be9702 100644 --- a/pw_build/bazel.rst +++ b/pw_build/bazel.rst @@ -329,6 +329,23 @@ Example } // namespace my::stuff +pw_cc_binary_with_map +--------------------- +The ``pw_cc_binary_with_map`` rule can be used to build a binary like +``cc_binary`` does but also generate a .map file from the linking step. + +.. code-block:: + + pw_cc_binary_with_map( + name = "test", + srcs = ["empty_main.cc"], + ) + +This should result in a ``test.map`` file generated next to the ``test`` binary. + +Note that it's only partially compatible with the ``cc_binary`` interface and +certain things are not implemented like make variable substitution. + Miscellaneous utilities ----------------------- diff --git a/pw_build/bazel_internal/pigweed_internal.bzl b/pw_build/bazel_internal/pigweed_internal.bzl index b8b4afb67..be3756c77 100644 --- a/pw_build/bazel_internal/pigweed_internal.bzl +++ b/pw_build/bazel_internal/pigweed_internal.bzl @@ -47,6 +47,7 @@ def compile_cc( deps, includes = [], defines = [], + local_defines = [], user_compile_flags = []): """Compiles a list C++ source files. @@ -57,6 +58,7 @@ def compile_cc( deps: Dependencies to link with includes: List of include paths defines: List of preprocessor defines to use + local_defines: List of preprocessor defines to use only on this unit. user_compile_flags: Extra compiler flags to pass when compiling. Returns: @@ -79,6 +81,7 @@ def compile_cc( srcs = srcs, includes = includes, defines = defines, + local_defines = local_defines, public_hdrs = hdrs, user_compile_flags = user_compile_flags, compilation_contexts = compilation_contexts, @@ -104,3 +107,60 @@ def compile_cc( compilation_context = compilation_context, linking_context = linking_context, )] + +# From cc_helper.bzl. Feature names for static/dynamic linking. +linker_mode = struct( + LINKING_DYNAMIC = "dynamic_linking_mode", + LINKING_STATIC = "static_linking_mode", +) + +def link_cc( + ctx, + linking_contexts, + linkstatic, + stamp, + user_link_flags = [], + additional_outputs = []): + """Links a binary and allows custom linker output. + + Args: + ctx: Rule context + linking_contexts: Dependencies to link with + linkstatic: True if binary should be linked statically. + stamp: Stamp behavior for linking. + user_link_flags: Extra linker flags to pass when linking + additional_outputs: Extra files generated by link + + Returns: + DefaultInfo of output files + """ + cc_toolchain = find_cpp_toolchain(ctx) + features = ctx.features + linking_mode = linker_mode.LINKING_STATIC + if not linkstatic: + linking_mode = linker_mode.LINKING_DYNAMIC + features.append(linking_mode) + feature_configuration = cc_common.configure_features( + ctx = ctx, + cc_toolchain = cc_toolchain, + requested_features = features, + unsupported_features = ctx.disabled_features, + ) + + linking_outputs = cc_common.link( + name = ctx.label.name, + actions = ctx.actions, + stamp = stamp, + feature_configuration = feature_configuration, + cc_toolchain = cc_toolchain, + linking_contexts = linking_contexts, + user_link_flags = user_link_flags, + output_type = "executable", + additional_outputs = additional_outputs, + ) + + output_files = depset( + [linking_outputs.executable] + additional_outputs, + transitive = [], + ) + return [DefaultInfo(files = output_files)] diff --git a/pw_build/empty_main.cc b/pw_build/empty_main.cc new file mode 100644 index 000000000..6ef9d5c99 --- /dev/null +++ b/pw_build/empty_main.cc @@ -0,0 +1,15 @@ +// Copyright 2024 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. + +int main() { return 0; } diff --git a/pw_build/pigweed.bzl b/pw_build/pigweed.bzl index 13472308b..49b23727a 100644 --- a/pw_build/pigweed.bzl +++ b/pw_build/pigweed.bzl @@ -19,6 +19,7 @@ load("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME") load( "//pw_build/bazel_internal:pigweed_internal.bzl", _compile_cc = "compile_cc", + _link_cc = "link_cc", ) # Used by `pw_cc_test`. @@ -282,6 +283,84 @@ pw_cc_blob_library = rule( toolchains = use_cpp_toolchain(), ) +def _pw_cc_binary_with_map_impl(ctx): + [_, cc_info] = _compile_cc( + ctx, + ctx.files.srcs, + [], + deps = ctx.attr.deps + [ctx.attr.link_extra_lib, ctx.attr.malloc], + includes = ctx.attr.includes, + defines = ctx.attr.defines, + local_defines = ctx.attr.local_defines, + ) + + map_file = ctx.actions.declare_file(ctx.label.name + ".map") + map_flags = ["-Wl,-Map=" + map_file.path] + + return _link_cc( + ctx, + [cc_info.linking_context], + ctx.attr.linkstatic, + ctx.attr.stamp, + user_link_flags = ctx.attr.linkopts + map_flags, + additional_outputs = [map_file], + ) + +pw_cc_binary_with_map = rule( + implementation = _pw_cc_binary_with_map_impl, + doc = """Links a binary like cc_binary does but generates a linker map file + and provides it as an output after the executable in the DefaultInfo list + returned by this rule. + + This rule makes an effort to somewhat mimic cc_binary args and behavior but + doesn't fully support all options currently. Make variable substitution and + tokenization handling isn't implemented by this rule on any of it's attrs. + + Args: + ctx: Rule context. + """, + attrs = { + "srcs": attr.label_list( + allow_files = True, + doc = "The list of C and C++ files that are processed to create the target.", + ), + "deps": attr.label_list( + providers = [CcInfo], + doc = "The list of other libraries to be linked in to the binary target.", + ), + "malloc": attr.label( + default = "@bazel_tools//tools/cpp:malloc", + doc = "Override the default dependency on malloc.", + ), + "link_extra_lib": attr.label( + default = "@bazel_tools//tools/cpp:link_extra_lib", + doc = "Control linking of extra libraries.", + ), + "linkstatic": attr.bool( + doc = "True if binary should be link statically", + ), + "includes": attr.string_list( + doc = "List of include dirs to add to the compile line.", + ), + "defines": attr.string_list( + doc = "List of defines to add to the compile line.", + ), + "local_defines": attr.string_list( + doc = "List of defines to add to the compile line.", + ), + "linkopts": attr.string_list( + doc = "Add these flags to the C++ linker command.", + ), + "stamp": attr.int( + default = -1, + doc = "Whether to encode build information into the binary.", + ), + }, + provides = [DefaultInfo], + fragments = ["cpp"], + toolchains = use_cpp_toolchain(), +) + def _preprocess_linker_script_impl(ctx): cc_toolchain = find_cpp_toolchain(ctx) output_script = ctx.actions.declare_file(ctx.label.name + ".ld") |