Implement libraries_to_link as cc_args

BEGIN_PUBLIC

Implement libraries_to_link as cc_args

Implements the libraries_to_link feature as libraries_to_link rules.

END_PUBLIC

PiperOrigin-RevId: 671775909
Change-Id: Ie3758e37f3db5c24ed9d757aa7cbeb78aecb153d
This commit is contained in:
Googler 2024-09-06 08:55:58 -07:00 committed by Copybara-Service
parent 7c2883f3b1
commit 0cd5c640a7
8 changed files with 521 additions and 1 deletions

View File

@ -16,6 +16,7 @@ cc_feature(
args = [
"//cc/toolchains/args/archiver_flags",
"//cc/toolchains/args/force_pic_flags",
"//cc/toolchains/args/libraries_to_link",
"//cc/toolchains/args/linker_param_file",
"//cc/toolchains/args/runtime_library_search_directories",
"//cc/toolchains/args/shared_flag",
@ -37,6 +38,5 @@ cc_feature(
"//cc/toolchains/features/legacy:unfiltered_compile_flags",
"//cc/toolchains/features/legacy:user_compile_flags",
"//cc/toolchains/features/legacy:user_link_flags",
"//cc/toolchains/features/legacy:libraries_to_link",
],
)

View File

@ -0,0 +1,175 @@
load("//cc/toolchains:args.bzl", "cc_args")
load("//cc/toolchains:nested_args.bzl", "cc_nested_args")
load("//cc/toolchains/args/libraries_to_link/private:library_link_args.bzl", "library_link_args")
package(default_visibility = ["//visibility:private"])
cc_args(
name = "libraries_to_link",
actions = [
"//cc/toolchains/actions:cpp_link_executable",
"//cc/toolchains/actions:cpp_link_dynamic_library",
"//cc/toolchains/actions:cpp_link_nodeps_dynamic_library",
"//cc/toolchains/actions:lto_index_for_executable",
"//cc/toolchains/actions:lto_index_for_dynamic_library",
"//cc/toolchains/actions:lto_index_for_nodeps_dynamic_library",
],
nested = [
":thinlto_param_file",
":libraries_to_link_args",
],
visibility = ["//visibility:public"],
)
cc_nested_args(
name = "thinlto_param_file",
args = ["-Wl,@{param_file}"],
format = {
"param_file": "//cc/toolchains/variables:thinlto_param_file",
},
requires_not_none = "//cc/toolchains/variables:thinlto_param_file",
)
cc_nested_args(
name = "libraries_to_link_args",
nested = [":iterate_over_libraries_to_link"],
requires_not_none = "//cc/toolchains/variables:libraries_to_link",
)
cc_nested_args(
name = "iterate_over_libraries_to_link",
iterate_over = "//cc/toolchains/variables:libraries_to_link",
nested = [
":optional_object_file_group_start",
":single_library_args",
":optional_object_file_group_end",
],
)
cc_nested_args(
name = "optional_object_file_group_start",
nested = [":start_lib_arg"],
requires_equal = "//cc/toolchains/variables:libraries_to_link.type",
requires_equal_value = "object_file_group",
)
cc_nested_args(
name = "start_lib_arg",
args = ["-Wl,--start-lib"],
requires_false = "//cc/toolchains/variables:libraries_to_link.is_whole_archive",
)
cc_nested_args(
name = "optional_object_file_group_end",
nested = [":end_lib_arg"],
requires_equal = "//cc/toolchains/variables:libraries_to_link.type",
requires_equal_value = "object_file_group",
)
cc_nested_args(
name = "end_lib_arg",
args = ["-Wl,--end-lib"],
requires_false = "//cc/toolchains/variables:libraries_to_link.is_whole_archive",
)
cc_nested_args(
name = "single_library_args",
nested = select({
"@platforms//os:macos": [],
"//conditions:default": [":optional_whole_archive_start"],
}) + [
":optional_object_file_group",
":optional_object_file",
":optional_interface_library",
":optional_static_library",
":optional_dynamic_library",
] + select({
# maOS has a minor nuance where it uses the path to the library instead of `-l:{library_name}`.
"@platforms//os:macos": [":macos_optional_versioned_dynamic_library"],
"//conditions:default": [":generic_optional_versioned_dynamic_library"],
}) + select({
"@platforms//os:macos": [],
"//conditions:default": [":optional_whole_archive_end"],
}),
)
cc_nested_args(
name = "optional_whole_archive_start",
nested = [":whole_archive_start_arg"],
requires_true = "//cc/toolchains/variables:libraries_to_link.is_whole_archive",
)
cc_nested_args(
name = "whole_archive_start_arg",
args = ["-Wl,-whole-archive"],
requires_equal = "//cc/toolchains/variables:libraries_to_link.type",
requires_equal_value = "static_library",
)
cc_nested_args(
name = "optional_whole_archive_end",
nested = [":whole_archive_end_arg"],
requires_true = "//cc/toolchains/variables:libraries_to_link.is_whole_archive",
)
cc_nested_args(
name = "whole_archive_end_arg",
args = ["-Wl,-no-whole-archive"],
requires_equal = "//cc/toolchains/variables:libraries_to_link.type",
requires_equal_value = "static_library",
)
library_link_args(
name = "optional_object_file_group",
from_variable = "//cc/toolchains/variables:libraries_to_link.object_files",
iterate_over_variable = True,
library_type = "object_file_group",
)
library_link_args(
name = "optional_object_file",
from_variable = "//cc/toolchains/variables:libraries_to_link.name",
library_type = "object_file",
)
library_link_args(
name = "optional_interface_library",
from_variable = "//cc/toolchains/variables:libraries_to_link.name",
library_type = "interface_library",
)
library_link_args(
name = "optional_static_library",
from_variable = "//cc/toolchains/variables:libraries_to_link.name",
library_type = "static_library",
)
cc_nested_args(
name = "optional_dynamic_library",
args = ["-l{library}"],
format = {
"library": "//cc/toolchains/variables:libraries_to_link.name",
},
requires_equal = "//cc/toolchains/variables:libraries_to_link.type",
requires_equal_value = "dynamic_library",
)
cc_nested_args(
name = "generic_optional_versioned_dynamic_library",
args = ["-l:{library_name}"],
format = {
"library_name": "//cc/toolchains/variables:libraries_to_link.name",
},
requires_equal = "//cc/toolchains/variables:libraries_to_link.type",
requires_equal_value = "versioned_dynamic_library",
)
cc_nested_args(
name = "macos_optional_versioned_dynamic_library",
args = ["{library_path}"],
format = {
"library_path": "//cc/toolchains/variables:libraries_to_link.path",
},
requires_equal = "//cc/toolchains/variables:libraries_to_link.type",
requires_equal_value = "versioned_dynamic_library",
)

View File

@ -0,0 +1 @@
package(default_visibility = ["//visibility:private"])

View File

@ -0,0 +1,104 @@
# Copyright 2024 The Bazel Authors. All rights reserved.
#
# 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
#
# http://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.
"""Helper macros for declaring library link arguments."""
load("//cc/toolchains:nested_args.bzl", "cc_nested_args")
def macos_force_load_library_args(name, variable):
"""A helper for declaring -force_load argument expansion for a library.
This creates an argument expansion that will expand to -Wl,-force_load,<library>
if the library should be linked as a whole archive.
Args:
name: The name of the rule.
variable: The variable to expand.
"""
cc_nested_args(
name = name,
nested = [
":{}_force_load_library".format(name),
":{}_no_force_load_library".format(name),
],
)
cc_nested_args(
name = name + "_no_force_load_library",
requires_false = "//cc/toolchains/variables:libraries_to_link.is_whole_archive",
args = ["{library}"],
format = {
"library": variable,
},
)
cc_nested_args(
name = name + "_force_load_library",
requires_true = "//cc/toolchains/variables:libraries_to_link.is_whole_archive",
args = ["-Wl,-force_load,{library}"],
format = {
"library": variable,
},
)
def library_link_args(name, library_type, from_variable, iterate_over_variable = False):
"""A helper for declaring a library to link.
For most platforms, this expands something akin to the following:
cc_nested_args(
name = "foo",
requires_equal = "//cc/toolchains/variables:libraries_to_link.type",
requires_equal_value = "interface_library",
iterate_over = None,
args = ["{library}"],
format = {
"library": //cc/toolchains/variables:libraries_to_link.name,
},
)
For macos, this expands to a more complex cc_nested_args structure that
handles the -force_load flag.
Args:
name: The name of the rule.
library_type: The type of the library.
from_variable: The variable to expand.
iterate_over_variable: Whether to iterate over the variable.
"""
native.alias(
name = name,
actual = select({
"@platforms//os:macos": ":macos_{}".format(name),
"//conditions:default": ":generic_{}".format(name),
}),
)
cc_nested_args(
name = "generic_{}".format(name),
requires_equal = "//cc/toolchains/variables:libraries_to_link.type",
requires_equal_value = library_type,
iterate_over = from_variable if iterate_over_variable else None,
args = ["{library}"],
format = {
"library": from_variable,
},
)
cc_nested_args(
name = "macos_{}".format(name),
requires_equal = "//cc/toolchains/variables:libraries_to_link.type",
requires_equal_value = library_type,
iterate_over = from_variable if iterate_over_variable else None,
nested = [":{}_maybe_force_load".format(name)],
)
macos_force_load_library_args(
name = "{}_maybe_force_load".format(name),
variable = from_variable,
)

View File

@ -136,6 +136,7 @@ cc_external_feature(
cc_external_feature(
name = "libraries_to_link",
deprecation = "Use //cc/toolchains/args/libraries_to_link instead",
feature_name = "libraries_to_link",
overridable = True,
)

View File

@ -27,6 +27,15 @@ compare_feature_implementation(
}),
)
compare_feature_implementation(
name = "libraries_to_link_test",
actual_implementation = "//cc/toolchains/args/libraries_to_link",
expected = select({
"@platforms//os:macos": "//tests/rule_based_toolchain/legacy_features_as_args:goldens/macos/libraries_to_link.textproto",
"//conditions:default": "//tests/rule_based_toolchain/legacy_features_as_args:goldens/unix/libraries_to_link.textproto",
}),
)
compare_feature_implementation(
name = "linker_param_file_test",
actual_implementation = "//cc/toolchains/args/linker_param_file",

View File

@ -0,0 +1,123 @@
enabled: false
flag_sets {
actions: "c++-link-dynamic-library"
actions: "c++-link-executable"
actions: "c++-link-nodeps-dynamic-library"
actions: "lto-index-for-dynamic-library"
actions: "lto-index-for-executable"
actions: "lto-index-for-nodeps-dynamic-library"
flag_groups {
flag_groups {
expand_if_available: "thinlto_param_file"
flags: "-Wl,@%{thinlto_param_file}"
}
flag_groups {
expand_if_available: "libraries_to_link"
flag_groups {
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "object_file_group"
}
flag_groups {
expand_if_false: "libraries_to_link.is_whole_archive"
flags: "-Wl,--start-lib"
}
}
flag_groups {
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "object_file_group"
}
flag_groups {
flag_groups {
expand_if_true: "libraries_to_link.is_whole_archive"
flags: "-Wl,-force_load,%{libraries_to_link.object_files}"
}
flag_groups {
expand_if_false: "libraries_to_link.is_whole_archive"
flags: "%{libraries_to_link.object_files}"
}
}
iterate_over: "libraries_to_link.object_files"
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "object_file"
}
flag_groups {
flag_groups {
expand_if_true: "libraries_to_link.is_whole_archive"
flags: "-Wl,-force_load,%{libraries_to_link.name}"
}
flag_groups {
expand_if_false: "libraries_to_link.is_whole_archive"
flags: "%{libraries_to_link.name}"
}
}
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "interface_library"
}
flag_groups {
flag_groups {
expand_if_true: "libraries_to_link.is_whole_archive"
flags: "-Wl,-force_load,%{libraries_to_link.name}"
}
flag_groups {
expand_if_false: "libraries_to_link.is_whole_archive"
flags: "%{libraries_to_link.name}"
}
}
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "static_library"
}
flag_groups {
flag_groups {
expand_if_true: "libraries_to_link.is_whole_archive"
flags: "-Wl,-force_load,%{libraries_to_link.name}"
}
flag_groups {
expand_if_false: "libraries_to_link.is_whole_archive"
flags: "%{libraries_to_link.name}"
}
}
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "dynamic_library"
}
flags: "-l%{libraries_to_link.name}"
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "versioned_dynamic_library"
}
flags: "%{libraries_to_link.path}"
}
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "object_file_group"
}
flag_groups {
expand_if_false: "libraries_to_link.is_whole_archive"
flags: "-Wl,--end-lib"
}
}
iterate_over: "libraries_to_link"
}
}
}
}
name: "libraries_to_link_test"

View File

@ -0,0 +1,107 @@
enabled: false
flag_sets {
actions: "c++-link-dynamic-library"
actions: "c++-link-executable"
actions: "c++-link-nodeps-dynamic-library"
actions: "lto-index-for-dynamic-library"
actions: "lto-index-for-executable"
actions: "lto-index-for-nodeps-dynamic-library"
flag_groups {
flag_groups {
expand_if_available: "thinlto_param_file"
flags: "-Wl,@%{thinlto_param_file}"
}
flag_groups {
expand_if_available: "libraries_to_link"
flag_groups {
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "object_file_group"
}
flag_groups {
expand_if_false: "libraries_to_link.is_whole_archive"
flags: "-Wl,--start-lib"
}
}
flag_groups {
flag_groups {
expand_if_true: "libraries_to_link.is_whole_archive"
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "static_library"
}
flags: "-Wl,-whole-archive"
}
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "object_file_group"
}
flags: "%{libraries_to_link.object_files}"
iterate_over: "libraries_to_link.object_files"
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "object_file"
}
flags: "%{libraries_to_link.name}"
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "interface_library"
}
flags: "%{libraries_to_link.name}"
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "static_library"
}
flags: "%{libraries_to_link.name}"
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "dynamic_library"
}
flags: "-l%{libraries_to_link.name}"
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "versioned_dynamic_library"
}
flags: "-l:%{libraries_to_link.name}"
}
flag_groups {
expand_if_true: "libraries_to_link.is_whole_archive"
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "static_library"
}
flags: "-Wl,-no-whole-archive"
}
}
}
flag_groups {
expand_if_equal {
name: "libraries_to_link.type"
value: "object_file_group"
}
flag_groups {
expand_if_false: "libraries_to_link.is_whole_archive"
flags: "-Wl,--end-lib"
}
}
iterate_over: "libraries_to_link"
}
}
}
}
name: "libraries_to_link_test"