mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
[bazel] Generate a filtered .def file for windows for wpimath (#8113)
wpimath otherwise quickly gets too many symbols. Instead, gradle exports only some of the symbols from protobuf files automatically, and then manually exports the math operations. Do that here too. Signed-off-by: Austin Schuh <austin.linux@gmail.com>
This commit is contained in:
@@ -7,6 +7,31 @@ load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_files")
|
||||
load("@rules_pkg//:pkg.bzl", "pkg_zip")
|
||||
|
||||
# Copied from bazel since it isn't exposed publicly that I can find.
|
||||
# https://github.com/bazelbuild/bazel/blob/cc4e3b25a89cd8294406d9489ece706cfcc019bd/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl#L272
|
||||
def generate_def_file(ctx, def_parser, object_files, dll_name):
|
||||
def_file = ctx.actions.declare_file(ctx.label.name + ".gen.def")
|
||||
|
||||
args = ctx.actions.args()
|
||||
args.add(def_file)
|
||||
args.add(dll_name)
|
||||
argv = ctx.actions.args()
|
||||
argv.use_param_file("@%s", use_always = True)
|
||||
argv.set_param_file_format("shell")
|
||||
for object_file in object_files:
|
||||
argv.add(object_file.path)
|
||||
|
||||
ctx.actions.run(
|
||||
mnemonic = "DefParser",
|
||||
executable = def_parser,
|
||||
toolchain = None,
|
||||
arguments = [args, argv],
|
||||
inputs = object_files,
|
||||
outputs = [def_file],
|
||||
use_default_shell_env = True,
|
||||
)
|
||||
return def_file
|
||||
|
||||
def _folder_prefix(name):
|
||||
if "/" in name:
|
||||
last_slash = name.rfind("/")
|
||||
@@ -154,15 +179,23 @@ def wpilib_cc_library(
|
||||
def wpilib_cc_shared_library(
|
||||
name,
|
||||
auto_export_windows_symbols = True,
|
||||
win_def_file = None,
|
||||
**kwargs):
|
||||
folder, lib = _folder_prefix(name)
|
||||
|
||||
features = []
|
||||
if auto_export_windows_symbols:
|
||||
features.append("windows_export_all_symbols")
|
||||
|
||||
cc_shared_library(
|
||||
name = name,
|
||||
features = features,
|
||||
# Only include a .def file on windows. This makes it so we can mark
|
||||
# the .def file as only compatible with windows.
|
||||
win_def_file = select({
|
||||
"@platforms//os:windows": win_def_file,
|
||||
"//conditions:default": None,
|
||||
}),
|
||||
**kwargs
|
||||
)
|
||||
|
||||
@@ -388,3 +421,91 @@ def wpilib_cc_static_library(
|
||||
static_lib_name = static_lib_name,
|
||||
**kwargs
|
||||
)
|
||||
|
||||
def _generate_def_windows_impl(ctx):
|
||||
deps = ctx.attr.deps
|
||||
|
||||
cc_toolchain = find_cpp_toolchain(ctx)
|
||||
|
||||
feature_configuration = cc_common.configure_features(
|
||||
ctx = ctx,
|
||||
cc_toolchain = cc_toolchain,
|
||||
requested_features = ctx.features + ["force_no_whole_archive"],
|
||||
unsupported_features = ctx.disabled_features,
|
||||
)
|
||||
|
||||
def_parser = ctx.file._def_parser
|
||||
win_def_file = []
|
||||
|
||||
if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "targets_windows"):
|
||||
object_files = []
|
||||
|
||||
# Now, hunt down all the linker inputs directly specified.
|
||||
for dep in deps:
|
||||
linker_input = dep[CcInfo].linking_context.linker_inputs
|
||||
|
||||
for l in linker_input.to_list():
|
||||
# Find the linker stanza owned directly by the dependency, not transitively
|
||||
if l.owner != dep.label:
|
||||
continue
|
||||
|
||||
# Grab all the .o's out of it.
|
||||
for library in l.libraries:
|
||||
if library.pic_static_library != None:
|
||||
if library.pic_objects != None:
|
||||
object_files.extend(library.pic_objects)
|
||||
elif library.static_library != None:
|
||||
if library.objects != None:
|
||||
object_files.extend(library.objects)
|
||||
|
||||
# Filter the list so we only generate def files for the provided dependencies.
|
||||
filtered_object_files = []
|
||||
for o in object_files:
|
||||
for f in ctx.attr.filters:
|
||||
if f in o.path:
|
||||
filtered_object_files.append(o)
|
||||
break
|
||||
|
||||
if def_parser != None:
|
||||
generated_def_file = generate_def_file(ctx, def_parser, filtered_object_files, ctx.label.name)
|
||||
|
||||
win_def_file = [generated_def_file]
|
||||
|
||||
files = depset(direct = win_def_file)
|
||||
return [
|
||||
DefaultInfo(files = files),
|
||||
OutputGroupInfo(default = files),
|
||||
]
|
||||
|
||||
_generate_def_windows = rule(
|
||||
implementation = _generate_def_windows_impl,
|
||||
attrs = {
|
||||
"deps": attr.label_list(
|
||||
providers = [CcInfo],
|
||||
doc = """
|
||||
List of all static libraries to not duplicate .o files from.
|
||||
""",
|
||||
),
|
||||
"filters": attr.string_list(),
|
||||
"_def_parser": attr.label(default = "@bazel_tools//tools/def_parser:def_parser", allow_single_file = True, cfg = "exec"),
|
||||
} | CC_TOOLCHAIN_ATTRS,
|
||||
toolchains = use_cc_toolchain(),
|
||||
fragments = ["cpp"],
|
||||
)
|
||||
|
||||
def generate_def_windows(name, deps = None, **kwargs):
|
||||
"""Generates a .def file for linking a windows .dll for the provided cc_library and filters
|
||||
|
||||
Args:
|
||||
deps: A list of cc_libraries to export symbols from.
|
||||
filters: All object files in the provided cc_libraries (but not their
|
||||
dependencies) are checked against this list. If a string in
|
||||
this list appears inside the name of the object file, it is
|
||||
added to the export list.
|
||||
"""
|
||||
_generate_def_windows(
|
||||
name = name,
|
||||
deps = deps,
|
||||
target_compatible_with = ["@platforms//os:windows"],
|
||||
**kwargs
|
||||
)
|
||||
|
||||
@@ -4,7 +4,7 @@ load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
|
||||
load("@rules_java//java:defs.bzl", "java_binary")
|
||||
load("@rules_pkg//:mappings.bzl", "pkg_files")
|
||||
load("@rules_python//python:defs.bzl", "py_binary")
|
||||
load("//shared/bazel/rules:cc_rules.bzl", "third_party_cc_lib_helper", "wpilib_cc_library", "wpilib_cc_shared_library", "wpilib_cc_static_library")
|
||||
load("//shared/bazel/rules:cc_rules.bzl", "generate_def_windows", "third_party_cc_lib_helper", "wpilib_cc_library", "wpilib_cc_shared_library", "wpilib_cc_static_library")
|
||||
load("//shared/bazel/rules:java_rules.bzl", "wpilib_java_junit5_test")
|
||||
load("//shared/bazel/rules:jni_rules.bzl", "wpilib_jni_cc_library", "wpilib_jni_java_library")
|
||||
load("//shared/bazel/rules:packaging.bzl", "package_minimal_jni_project")
|
||||
@@ -154,6 +154,17 @@ wpilib_cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
generate_def_windows(
|
||||
name = "wpimath_def",
|
||||
filters = [
|
||||
".pb.obj",
|
||||
".npb.obj",
|
||||
],
|
||||
deps = [
|
||||
":wpimath",
|
||||
],
|
||||
)
|
||||
|
||||
wpilib_cc_shared_library(
|
||||
name = "shared/wpimath",
|
||||
auto_export_windows_symbols = False,
|
||||
@@ -161,6 +172,7 @@ wpilib_cc_shared_library(
|
||||
"//wpiutil:shared/wpiutil",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
win_def_file = ":wpimath_def",
|
||||
deps = [
|
||||
":wpimath",
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user