248 lines
7.4 KiB
Python
248 lines
7.4 KiB
Python
|
|
# Copyright (C) 2023 The Android Open Source Project
|
||
|
|
#
|
||
|
|
# 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.
|
||
|
|
|
||
|
|
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
|
||
|
|
load("//build/bazel/rules/cc:cc_binary.bzl", "cc_binary")
|
||
|
|
load("//build/bazel/rules/cc:cc_library_shared.bzl", "cc_library_shared")
|
||
|
|
load("//build/bazel/rules/cc:cc_library_static.bzl", "cc_library_static")
|
||
|
|
load(
|
||
|
|
"//build/bazel/rules/cc/testing:transitions.bzl",
|
||
|
|
"ActionArgsInfo",
|
||
|
|
"compile_action_argv_aspect_generator",
|
||
|
|
)
|
||
|
|
|
||
|
|
lto_flag = "-flto=thin"
|
||
|
|
static_cpp_suffix = "_cpp"
|
||
|
|
shared_cpp_suffix = "__internal_root_cpp"
|
||
|
|
binary_suffix = "__internal_root"
|
||
|
|
|
||
|
|
def _lto_deps_test_impl(ctx):
|
||
|
|
env = analysistest.begin(ctx)
|
||
|
|
target_under_test = analysistest.target_under_test(env)
|
||
|
|
argv_map = target_under_test[ActionArgsInfo].argv_map
|
||
|
|
|
||
|
|
for target in ctx.attr.targets_with_lto:
|
||
|
|
asserts.true(
|
||
|
|
env,
|
||
|
|
target in argv_map,
|
||
|
|
"can't find {} in argv map".format(target),
|
||
|
|
)
|
||
|
|
if target in argv_map:
|
||
|
|
argv = argv_map[target]
|
||
|
|
asserts.true(
|
||
|
|
env,
|
||
|
|
lto_flag in argv,
|
||
|
|
"Compile action of {} didn't have LTO but it was expected".format(
|
||
|
|
target,
|
||
|
|
),
|
||
|
|
)
|
||
|
|
for target in ctx.attr.targets_without_lto:
|
||
|
|
asserts.true(
|
||
|
|
env,
|
||
|
|
target in argv_map,
|
||
|
|
"can't find {} in argv map".format(target),
|
||
|
|
)
|
||
|
|
if target in argv_map:
|
||
|
|
argv = argv_map[target]
|
||
|
|
asserts.true(
|
||
|
|
env,
|
||
|
|
lto_flag not in argv,
|
||
|
|
"Compile action of {} had LTO but it wasn't expected".format(
|
||
|
|
target,
|
||
|
|
),
|
||
|
|
)
|
||
|
|
return analysistest.end(env)
|
||
|
|
|
||
|
|
_compile_action_argv_aspect = compile_action_argv_aspect_generator({
|
||
|
|
"_cc_library_combiner": ["deps", "roots", "includes"],
|
||
|
|
"_cc_includes": ["deps"],
|
||
|
|
"_cc_library_shared_proxy": ["deps"],
|
||
|
|
"stripped_binary": ["androidmk_deps"],
|
||
|
|
})
|
||
|
|
|
||
|
|
lto_deps_test = analysistest.make(
|
||
|
|
_lto_deps_test_impl,
|
||
|
|
attrs = {
|
||
|
|
"targets_with_lto": attr.string_list(),
|
||
|
|
"targets_without_lto": attr.string_list(),
|
||
|
|
},
|
||
|
|
# We need to use aspect to examine the dependencies' actions of the apex
|
||
|
|
# target as the result of the transition, checking the dependencies directly
|
||
|
|
# using names will give you the info before the transition takes effect.
|
||
|
|
extra_target_under_test_aspects = [_compile_action_argv_aspect],
|
||
|
|
)
|
||
|
|
|
||
|
|
def _test_static_deps_have_lto():
|
||
|
|
name = "static_deps_have_lto"
|
||
|
|
requested_target_name = name + "_requested_target"
|
||
|
|
static_dep_name = name + "_static_dep"
|
||
|
|
static_dep_of_static_dep_name = "_static_dep_of_static_dep"
|
||
|
|
test_name = name + "_test"
|
||
|
|
|
||
|
|
cc_library_static(
|
||
|
|
name = requested_target_name,
|
||
|
|
srcs = ["foo.cpp"],
|
||
|
|
deps = [static_dep_name],
|
||
|
|
features = ["android_thin_lto"],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
cc_library_static(
|
||
|
|
name = static_dep_name,
|
||
|
|
srcs = ["bar.cpp"],
|
||
|
|
deps = [static_dep_of_static_dep_name],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
cc_library_static(
|
||
|
|
name = static_dep_of_static_dep_name,
|
||
|
|
srcs = ["baz.cpp"],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
lto_deps_test(
|
||
|
|
name = test_name,
|
||
|
|
target_under_test = requested_target_name,
|
||
|
|
targets_with_lto = [
|
||
|
|
requested_target_name + static_cpp_suffix,
|
||
|
|
static_dep_name + static_cpp_suffix,
|
||
|
|
static_dep_of_static_dep_name + static_cpp_suffix,
|
||
|
|
],
|
||
|
|
targets_without_lto = [],
|
||
|
|
)
|
||
|
|
|
||
|
|
return test_name
|
||
|
|
|
||
|
|
def _test_deps_of_shared_have_lto_if_enabled():
|
||
|
|
name = "deps_of_shared_have_lto_if_enabled"
|
||
|
|
requested_target_name = name + "_requested_target"
|
||
|
|
shared_dep_name = name + "_shared_dep"
|
||
|
|
static_dep_of_shared_dep_name = name + "_static_dep_of_shared_dep"
|
||
|
|
test_name = name + "_test"
|
||
|
|
|
||
|
|
cc_library_static(
|
||
|
|
name = requested_target_name,
|
||
|
|
srcs = ["foo.cpp"],
|
||
|
|
dynamic_deps = [shared_dep_name],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
cc_library_shared(
|
||
|
|
name = shared_dep_name,
|
||
|
|
srcs = ["bar.cpp"],
|
||
|
|
deps = [static_dep_of_shared_dep_name],
|
||
|
|
features = ["android_thin_lto"],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
cc_library_static(
|
||
|
|
name = static_dep_of_shared_dep_name,
|
||
|
|
srcs = ["baz.cpp"],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
lto_deps_test(
|
||
|
|
name = test_name,
|
||
|
|
target_under_test = requested_target_name,
|
||
|
|
targets_with_lto = [
|
||
|
|
shared_dep_name + "__internal_root_cpp",
|
||
|
|
static_dep_of_shared_dep_name + static_cpp_suffix,
|
||
|
|
],
|
||
|
|
targets_without_lto = [requested_target_name + static_cpp_suffix],
|
||
|
|
)
|
||
|
|
|
||
|
|
return test_name
|
||
|
|
|
||
|
|
def _test_deps_of_shared_deps_no_lto_if_disabled():
|
||
|
|
name = "deps_of_shared_deps_no_lto_if_disabled"
|
||
|
|
requested_target_name = name + "_requested_target"
|
||
|
|
shared_dep_name = name + "_shared_dep"
|
||
|
|
static_dep_of_shared_dep_name = name + "_static_dep_of_shared_dep"
|
||
|
|
test_name = name + "_test"
|
||
|
|
|
||
|
|
cc_library_static(
|
||
|
|
name = requested_target_name,
|
||
|
|
srcs = ["foo.cpp"],
|
||
|
|
dynamic_deps = [shared_dep_name],
|
||
|
|
features = ["android_thin_lto"],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
cc_library_shared(
|
||
|
|
name = shared_dep_name,
|
||
|
|
srcs = ["bar.cpp"],
|
||
|
|
deps = [static_dep_of_shared_dep_name],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
cc_library_static(
|
||
|
|
name = static_dep_of_shared_dep_name,
|
||
|
|
srcs = ["baz.cpp"],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
lto_deps_test(
|
||
|
|
name = test_name,
|
||
|
|
target_under_test = requested_target_name,
|
||
|
|
targets_with_lto = [requested_target_name + static_cpp_suffix],
|
||
|
|
targets_without_lto = [
|
||
|
|
shared_dep_name + shared_cpp_suffix,
|
||
|
|
static_dep_of_shared_dep_name + static_cpp_suffix,
|
||
|
|
],
|
||
|
|
)
|
||
|
|
|
||
|
|
return test_name
|
||
|
|
|
||
|
|
def _test_binary_propagates_to_static_deps():
|
||
|
|
name = "binary_propagates_to_static_deps"
|
||
|
|
requested_target_name = name + "_requested_target"
|
||
|
|
dep_name = name + "_dep"
|
||
|
|
test_name = name + "_test"
|
||
|
|
|
||
|
|
cc_binary(
|
||
|
|
name = requested_target_name,
|
||
|
|
srcs = ["foo.cpp"],
|
||
|
|
deps = [dep_name],
|
||
|
|
features = ["android_thin_lto"],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
cc_library_static(
|
||
|
|
name = dep_name,
|
||
|
|
srcs = ["bar.cpp"],
|
||
|
|
tags = ["manual"],
|
||
|
|
)
|
||
|
|
|
||
|
|
lto_deps_test(
|
||
|
|
name = test_name,
|
||
|
|
target_under_test = requested_target_name,
|
||
|
|
targets_with_lto = [
|
||
|
|
requested_target_name + binary_suffix + static_cpp_suffix,
|
||
|
|
dep_name + static_cpp_suffix,
|
||
|
|
],
|
||
|
|
)
|
||
|
|
|
||
|
|
return test_name
|
||
|
|
|
||
|
|
def lto_transition_test_suite(name):
|
||
|
|
native.test_suite(
|
||
|
|
name = name,
|
||
|
|
tests = [
|
||
|
|
_test_static_deps_have_lto(),
|
||
|
|
_test_deps_of_shared_have_lto_if_enabled(),
|
||
|
|
_test_deps_of_shared_deps_no_lto_if_disabled(),
|
||
|
|
_test_binary_propagates_to_static_deps(),
|
||
|
|
],
|
||
|
|
)
|