Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cc/common/cc_helper_internal.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ def wrap_with_check_private_api(symbol):

return callback

def create_solib_symlink(actions, library, symlink_path):
"""Declares a shareable symlink to a dynamic library."""
symlink = actions.declare_shareable_artifact(symlink_path)
actions.symlink(
output = symlink,
target_file = library,
)
return symlink

CPP_SOURCE_TYPE_HEADER = "HEADER"
CPP_SOURCE_TYPE_SOURCE = "SOURCE"
CPP_SOURCE_TYPE_CLIF_INPUT_PROTO = "CLIF_INPUT_PROTO"
Expand Down
11 changes: 6 additions & 5 deletions cc/private/cc_common.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ load(
"//cc/common:cc_helper_internal.bzl",
_CREATE_COMPILE_ACTION_API_ALLOWLISTED_PACKAGES = "CREATE_COMPILE_ACTION_API_ALLOWLISTED_PACKAGES",
_PRIVATE_STARLARKIFICATION_ALLOWLIST = "PRIVATE_STARLARKIFICATION_ALLOWLIST",
_create_solib_symlink = "create_solib_symlink",
)
load("//cc/private:cc_info.bzl", "CcNativeLibraryInfo", "create_compilation_context", "create_debug_context", "create_linking_context", "create_module_map", "merge_cc_infos", "merge_compilation_contexts", "merge_debug_context", "merge_linking_contexts")
load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
Expand Down Expand Up @@ -712,11 +713,11 @@ def _cc_toolchain_features(*, toolchain_config_info, tools_directory):

def _solib_symlink_action(*, ctx, artifact, solib_directory, runtime_solib_dir_base):
_cc_internal.check_private_api(allowlist = _PRIVATE_STARLARKIFICATION_ALLOWLIST)
return _cc_internal.solib_symlink_action(
ctx = ctx,
artifact = artifact,
solib_directory = solib_directory,
runtime_solib_dir_base = runtime_solib_dir_base,
symlink_directory = runtime_solib_dir_base if runtime_solib_dir_base != None else solib_directory
return _create_solib_symlink(
ctx.actions,
artifact,
symlink_directory + "/" + artifact.basename,
)

def _cc_toolchain_variables(*, vars):
Expand Down
14 changes: 11 additions & 3 deletions cc/private/link/create_library_to_link.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The cc_common.create_library_to_link function.
"""

load("@bazel_skylib//lib:paths.bzl", "paths")
load("//cc/common:cc_helper_internal.bzl", "is_versioned_shared_library", "path_contains_up_level_references")
load("//cc/common:cc_helper_internal.bzl", "create_solib_symlink", "is_versioned_shared_library", "path_contains_up_level_references")
load("//cc/private:cc_internal.bzl", _cc_internal = "cc_internal")
load("//cc/private/compile:lto_compilation_context.bzl", _EMPTY_LTO = "EMPTY_LTO_COMPILATION_CONTEXT")
load("//cc/private/link:lto_backends.bzl", "create_shared_non_lto_artifacts")
Expand Down Expand Up @@ -211,7 +211,11 @@ def create_library_to_link(
if dynamic_library_symlink_path:
if dynamic_library.short_path.startswith("_solib_"):
fail("dynamic_library must not be a symbolic link in the solib directory. Got '%s'" % dynamic_library.short_path)
dynamic_library = _cc_internal.dynamic_library_symlink2(actions, dynamic_library, cc_toolchain._solib_dir, dynamic_library_symlink_path)
dynamic_library = create_solib_symlink(
actions,
dynamic_library,
cc_toolchain._solib_dir + "/" + dynamic_library_symlink_path,
)
else:
dynamic_library = _cc_internal.dynamic_library_symlink(actions, dynamic_library, cc_toolchain._solib_dir, True, True)

Expand All @@ -226,7 +230,11 @@ def create_library_to_link(
if interface_library_symlink_path:
if interface_library.short_path.startswith("_solib_"):
fail("dynamic_library must not be a symbolic link in the solib directory. Got '%s'" % dynamic_library.short_path)
interface_library = _cc_internal.dynamic_library_symlink2(actions, interface_library, cc_toolchain._solib_dir, interface_library_symlink_path)
interface_library = create_solib_symlink(
actions,
interface_library,
cc_toolchain._solib_dir + "/" + interface_library_symlink_path,
)
else:
interface_library = _cc_internal.dynamic_library_symlink(actions, interface_library, cc_toolchain._solib_dir, True, True)

Expand Down
65 changes: 65 additions & 0 deletions tests/cc/common/cc_common_test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ load("@rules_testing//lib:analysis_test.bzl", "test_suite")
load("@rules_testing//lib:truth.bzl", "matching")
load("@rules_testing//lib:util.bzl", "TestingAspectInfo", "util")
load("//cc:cc_library.bzl", "cc_library")
load("//cc:find_cc_toolchain.bzl", "CC_TOOLCHAIN_ATTRS", "find_cpp_toolchain", "use_cc_toolchain")
load("//cc/common:cc_common.bzl", "cc_common")
load("//cc/common:cc_info.bzl", "CcInfo")
load("//tests/cc/testutil:cc_analysis_test.bzl", "cc_analysis_test")
load("//tests/cc/testutil:cc_info_subject.bzl", "cc_info_subject")
Expand Down Expand Up @@ -482,6 +484,68 @@ def _test_alwayslink_yields_lo_impl(env, target):
files = [f.basename for f in target[DefaultInfo].files.to_list()]
env.expect.that_collection(files).contains("libalways_link.lo")

def _solib_symlinks_impl(ctx):
cc_toolchain = find_cpp_toolchain(ctx)
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
library = ctx.actions.declare_file("liboriginal.so")
ctx.actions.write(library, "")
library_to_link = cc_common.create_library_to_link(
actions = ctx.actions,
cc_toolchain = cc_toolchain,
dynamic_library = library,
dynamic_library_symlink_path = "custom/libalias.so",
feature_configuration = feature_configuration,
)
runtime_symlink = cc_common.solib_symlink_action(
ctx = ctx,
artifact = library,
solib_directory = "unused_solib_directory",
runtime_solib_dir_base = "runtime_solib",
)
return [DefaultInfo(files = depset([library_to_link.dynamic_library, runtime_symlink]))]

_solib_symlinks = rule(
implementation = _solib_symlinks_impl,
attrs = CC_TOOLCHAIN_ATTRS,
fragments = ["cpp"],
toolchains = use_cc_toolchain(),
)

def _test_solib_symlinks(name):
util.helper_target(
_solib_symlinks,
name = name + "/target",
)
cc_analysis_test(
name = name,
impl = _test_solib_symlinks_impl,
target = name + "/target",
)

def _test_solib_symlinks_impl(env, target):
symlink_outputs = target[DefaultInfo].files.to_list()
explicit = [output for output in symlink_outputs if output.basename == "libalias.so"][0]
runtime = [output for output in symlink_outputs if output.basename == "liboriginal.so"][0]

explicit_path = env.expect.that_str(explicit.short_path)
explicit_path.contains("_solib_")
explicit_path.ends_with("/custom/libalias.so")
env.expect.that_str(runtime.short_path).ends_with("runtime_solib/liboriginal.so")

symlinks = [action for action in target[TestingAspectInfo].actions if action.mnemonic == "Symlink"]
env.expect.that_collection(symlinks).has_size(2)
env.expect.that_collection([output for action in symlinks for output in action.outputs.to_list()]).contains_exactly([
explicit,
runtime,
])
for action in symlinks:
env.expect.that_collection([input.basename for input in action.inputs.to_list()]).contains_exactly(["liboriginal.so"])

def cc_common_tests(name):
tests = [
_test_same_cc_file_twice,
Expand All @@ -505,6 +569,7 @@ def cc_common_tests(name):
_test_strip_include_prefix_no_virtual_includes_when_enabled,
_test_strip_include_prefix_with_include_prefix_uses_virtual_includes,
_test_strip_include_prefix_error_not_under_prefix,
_test_solib_symlinks,
])
test_suite(
name = name,
Expand Down