Skip to content

Instantly share code, notes, and snippets.

@meteorcloudy
Created October 13, 2022 12:56
Show Gist options
  • Save meteorcloudy/392355424b6986a8c7eb3361813d3849 to your computer and use it in GitHub Desktop.
Save meteorcloudy/392355424b6986a8c7eb3361813d3849 to your computer and use it in GitHub Desktop.
$ diff -u ./experimental_cc_shared_library.bzl.5.3.1 ./experimental_cc_shared_library.bzl.head
--- ./experimental_cc_shared_library.bzl.5.3.1 2022-10-13 14:54:02.527927885 +0200
+++ ./experimental_cc_shared_library.bzl.head 2022-10-13 14:51:43.980623854 +0200
@@ -241,7 +241,7 @@
preloaded_deps_direct_labels,
link_once_static_libs_map):
linker_inputs = []
- link_once_static_libs = []
+ curr_link_once_static_libs_map = {}
graph_structure_aspect_nodes = []
dependency_linker_inputs = []
@@ -266,13 +266,15 @@
precompiled_only_dynamic_libraries = []
unaccounted_for_libs = []
exports = {}
- owners_seen = {}
+ linker_inputs_seen = {}
+ dynamic_only_roots = {}
linked_statically_but_not_exported = {}
for linker_input in dependency_linker_inputs:
- owner = str(linker_input.owner)
- if owner in owners_seen:
+ stringified_linker_input = cc_helper.stringify_linker_input(linker_input)
+ if stringified_linker_input in linker_inputs_seen:
continue
- owners_seen[owner] = True
+ linker_inputs_seen[stringified_linker_input] = True
+ owner = str(linker_input.owner)
if owner in link_dynamically_labels:
dynamic_linker_input = transitive_exports[owner]
linker_inputs.append(dynamic_linker_input)
@@ -281,7 +283,6 @@
linked_statically_but_not_exported.setdefault(link_once_static_libs_map[owner], []).append(owner)
is_direct_export = owner in direct_exports
-
dynamic_only_libraries = []
static_libraries = []
for library in linker_input.libraries:
@@ -291,15 +292,14 @@
static_libraries.append(library)
if len(dynamic_only_libraries):
- if not len(static_libraries):
- if is_direct_export:
- fail("Do not place libraries which only contain a precompiled dynamic library in roots.")
-
precompiled_only_dynamic_libraries.extend(dynamic_only_libraries)
-
if not len(static_libraries):
+ if is_direct_export:
+ dynamic_only_roots[owner] = True
linker_inputs.append(linker_input)
continue
+ if len(static_libraries) and owner in dynamic_only_roots:
+ dynamic_only_roots.pop(owner)
if is_direct_export:
wrapped_library = _wrap_static_library_with_alwayslink(
@@ -310,7 +310,7 @@
)
if not link_statically_labels[owner]:
- link_once_static_libs.append(owner)
+ curr_link_once_static_libs_map[owner] = True
linker_inputs.append(wrapped_library)
else:
can_be_linked_statically = False
@@ -332,14 +332,22 @@
if can_be_linked_statically:
if not link_statically_labels[owner]:
- link_once_static_libs.append(owner)
+ curr_link_once_static_libs_map[owner] = True
linker_inputs.append(linker_input)
else:
unaccounted_for_libs.append(linker_input.owner)
+ if dynamic_only_roots:
+ message = ("Do not place libraries which only contain a " +
+ "precompiled dynamic library in roots. The following " +
+ "libraries only have precompiled dynamic libraries:\n")
+ for dynamic_only_root in dynamic_only_roots:
+ message += dynamic_only_root + "\n"
+ fail(message)
+
_throw_linked_but_not_exported_errors(linked_statically_but_not_exported)
_throw_error_if_unaccounted_libs(unaccounted_for_libs)
- return (exports, linker_inputs, link_once_static_libs, precompiled_only_dynamic_libraries)
+ return (exports, linker_inputs, curr_link_once_static_libs_map.keys(), precompiled_only_dynamic_libraries)
def _throw_linked_but_not_exported_errors(error_libs_dict):
if not error_libs_dict:
@@ -401,7 +409,8 @@
return None
def _cc_shared_library_impl(ctx):
- cc_common.check_experimental_cc_shared_library()
+ semantics.check_experimental_cc_shared_library(ctx)
+
cc_toolchain = cc_helper.find_cpp_toolchain(ctx)
feature_configuration = cc_common.configure_features(
ctx = ctx,
@@ -413,6 +422,16 @@
merged_cc_shared_library_info = _merge_cc_shared_library_infos(ctx)
exports_map = _build_exports_map_from_only_dynamic_deps(merged_cc_shared_library_info)
for export in ctx.attr.roots:
+ # Do not check for overlap between targets matched by the current
+ # rule's exports_filter and what is in exports_map. A library in roots
+ # will have to be linked in statically into the current rule with 100%
+ # guarantee and it will also have to be exported. Therefore, we must
+ # check it's not already exported by a different shared library. On the
+ # other hand, a library in the transitive closure of the current rule
+ # may be matched by the exports_filter but if it's already exported by
+ # a dynamic_dep then it won't be linked statically (therefore not give
+ # an error either) in the current target. The rule will intentionally
+ # not throw an error in these cases.
if str(export.label) in exports_map:
fail("Trying to export a library already exported by a different shared library: " +
str(export.label))
@@ -450,16 +469,6 @@
if ctx.attr.shared_lib_name:
main_output = ctx.actions.declare_file(ctx.attr.shared_lib_name)
- debug_files = []
- exports_debug_file = ctx.actions.declare_file(ctx.label.name + "_exports.txt")
- ctx.actions.write(content = "\n".join(["Owner:" + str(ctx.label)] + exports.keys()), output = exports_debug_file)
-
- link_once_static_libs_debug_file = ctx.actions.declare_file(ctx.label.name + "_link_once_static_libs.txt")
- ctx.actions.write(content = "\n".join(["Owner:" + str(ctx.label)] + link_once_static_libs), output = link_once_static_libs_debug_file)
-
- debug_files.append(exports_debug_file)
- debug_files.append(link_once_static_libs_debug_file)
-
win_def_file = None
if cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "targets_windows"):
object_files = []
@@ -489,6 +498,7 @@
linking_contexts = [linking_context],
user_link_flags = user_link_flags,
additional_inputs = additional_inputs,
+ grep_includes = ctx.executable._grep_includes,
name = ctx.label.name,
output_type = "dynamic_library",
main_output = main_output,
@@ -524,6 +534,16 @@
for export in ctx.attr.roots:
exports[str(export.label)] = True
+ debug_files = []
+ exports_debug_file = ctx.actions.declare_file(ctx.label.name + "_exports.txt")
+ ctx.actions.write(content = "\n".join(["Owner:" + str(ctx.label)] + exports.keys()), output = exports_debug_file)
+
+ link_once_static_libs_debug_file = ctx.actions.declare_file(ctx.label.name + "_link_once_static_libs.txt")
+ ctx.actions.write(content = "\n".join(["Owner:" + str(ctx.label)] + link_once_static_libs), output = link_once_static_libs_debug_file)
+
+ debug_files.append(exports_debug_file)
+ debug_files.append(link_once_static_libs_debug_file)
+
if not ctx.fragments.cpp.experimental_link_static_libraries_once():
link_once_static_libs = []
@@ -533,16 +553,6 @@
else:
library.append(linking_outputs.library_to_link.dynamic_library)
- precompiled_only_dynamic_libraries_runfiles = []
- for precompiled_dynamic_library in precompiled_only_dynamic_libraries:
- # precompiled_dynamic_library.dynamic_library could be None if the library to link just contains
- # an interface library which is valid if the actual library is obtained from the system.
- if precompiled_dynamic_library.dynamic_library != None:
- precompiled_only_dynamic_libraries_runfiles.append(precompiled_dynamic_library.dynamic_library)
- if precompiled_dynamic_library.resolved_symlink_dynamic_library != None:
- precompiled_only_dynamic_libraries_runfiles.append(precompiled_dynamic_library.resolved_symlink_dynamic_library)
-
- runfiles = runfiles.merge(ctx.runfiles(files = precompiled_only_dynamic_libraries_runfiles))
interface_library = []
if linking_outputs.library_to_link.resolved_symlink_interface_library != None:
interface_library.append(linking_outputs.library_to_link.resolved_symlink_interface_library)
@@ -636,8 +646,14 @@
"user_link_flags": attr.string_list(),
"_def_parser": semantics.get_def_parser(),
"_cc_toolchain": attr.label(default = "@" + semantics.get_repo() + "//tools/cpp:current_cc_toolchain"),
+ "_grep_includes": attr.label(
+ allow_files = True,
+ executable = True,
+ cfg = "exec",
+ default = Label("@" + semantics.get_repo() + "//tools/cpp:grep-includes"),
+ ),
},
- toolchains = ["@" + semantics.get_repo() + "//tools/cpp:toolchain_type"], # copybara-use-repo-external-label
+ toolchains = cc_helper.use_cpp_toolchain(),
fragments = ["google_cpp", "cpp"],
incompatible_use_toolchain_transition = True,
)
@@ -646,3 +662,4 @@
merge_cc_shared_library_infos = _merge_cc_shared_library_infos
build_link_once_static_libs_map = _build_link_once_static_libs_map
build_exports_map_from_only_dynamic_deps = _build_exports_map_from_only_dynamic_deps
+throw_linked_but_not_exported_errors = _throw_linked_but_not_exported_errors
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment