| # Copyright 2021 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import("//build/config/profile/config.gni") |
| import("//build/zircon/migrated_targets.gni") |
| |
| if (toolchain_variant.tags + [ "llvm-profdata" ] - [ "llvm-profdata" ] != |
| toolchain_variant.tags) { |
| have_profdata = 1 |
| } else { |
| have_profdata = 0 |
| } |
| |
| zx_library("llvm-profdata") { |
| sdk = "source" |
| sdk_headers = [ "lib/llvm-profdata/llvm-profdata.h" ] |
| |
| sources = [ "llvm-profdata.cc" ] |
| deps = [] |
| public_deps = [ "//sdk/lib/stdcompat" ] |
| |
| defines = [ "HAVE_PROFDATA=$have_profdata" ] |
| |
| if (is_kernel) { |
| deps += [ |
| "//zircon/kernel/lib/ktl", |
| "//zircon/kernel/lib/libc", |
| ] |
| } |
| |
| if (is_efi_toolchain) { |
| # Under PE-COFF, it doesn't work for the runtime itself to be instrumented. |
| # There's no way to reconcile direct use of the __llvm_profile_raw_version |
| # symbol in the source with the compiler-generated COMDAT definition in the |
| # same translation unit. |
| _profile_configs = [ "//build/config/profile" ] |
| configs += _profile_configs |
| configs -= _profile_configs |
| } |
| } |
| |
| if (!is_kernel) { |
| import("//build/components.gni") |
| import("//build/test.gni") |
| |
| group("tests") { |
| testonly = true |
| deps = [ |
| ":llvm-profdata-tests", |
| ":llvm-profdata-unittests($host_toolchain)", |
| ] |
| } |
| |
| example_public = [ "coverage-example.h" ] |
| example_sources = [ "coverage-example.cc" ] |
| |
| # This one file is always compiled with relocatable coverage support, |
| # regardless of the prevailing variant. |
| source_set("coverage-example") { |
| testonly = true |
| public = example_public |
| sources = example_sources |
| deps = [ ":coverage-example.deps" ] |
| |
| # Make sure the LinkTimeDeadFunction is really dead at link time. |
| configs -= [ "//build/config:default_linker_gc" ] |
| configs += [ "//build/config:linker_gc" ] |
| |
| # This test requires coverage instrumentation, so we disable the profile |
| # instrumentation if enabled by removing the profile config since |
| # -fprofile-instr-generate and -fprofile-generate are mutually |
| # incompatible. These flags both use the backend instrumentation pass, but |
| # the LLVM IR intrinsics are emitted at different stages and their |
| # combination is not supported. |
| configs += [ "//build/config/profile" ] |
| configs -= [ "//build/config/profile" ] |
| } |
| |
| # When an instrumented variant might be using selective instrumentation, this |
| # could prevent the example code from being instrumented. So in that case, |
| # extra compilation switches ensure that it will be. |
| |
| group("coverage-example.deps") { |
| visibility = [ ":*" ] |
| testonly = true |
| public_configs = [ ":coverage-example.config" ] |
| if (selective_profiling) { |
| public_deps = [ ":coverage-example.list" ] |
| } |
| } |
| |
| if (selective_profiling) { |
| # The compiler switch requires an input file, so generate one. |
| generated_file("coverage-example.list") { |
| visibility = [ ":*" ] |
| testonly = true |
| outputs = [ "$target_gen_dir/$target_name" ] |
| output_conversion = "list lines" |
| contents = [] |
| foreach(file, |
| rebase_path(example_sources + example_public, root_build_dir)) { |
| contents += [ "src:$file" ] |
| } |
| } |
| } |
| |
| config("coverage-example.config") { |
| visibility = [ ":*" ] |
| |
| cflags = [ |
| "-fprofile-instr-generate", |
| "-fcoverage-mapping", |
| ] |
| if (current_os != "mac") { |
| cflags += [ |
| "-mllvm", |
| "-runtime-counter-relocation=true", |
| ] |
| } |
| |
| # Explicitly select these source files to be instrumented. When no |
| # -fprofile-list switches are passed, everything is instrumented. But if |
| # the ambient configs used -fprofile-list, then only things selected in |
| # -fprofile-list files will be instrumented. Additional -fprofile-list |
| # files always add together, so adding another file with an explicit source |
| # file list adds those to the inclusion list. But note that including this |
| # file if no other -fprofile-list files prevents functions in other source |
| # files (i.e. headers used by the example sources) form being instrumented. |
| if (selective_profiling) { |
| inputs = get_target_outputs(":coverage-example.list") |
| cflags += [ "-fprofile-list=" + rebase_path(inputs[0], root_build_dir) ] |
| } |
| } |
| |
| # When built in a variant without the instrumentation, the library code is |
| # stubbed out. For tests, use a separate compilation of its code that still |
| # lacks instrumentation itself but has the full runtime support enabled. |
| # The coverage-example code's data will be the only instrumentation data it |
| # finds. |
| if (have_profdata == 0) { |
| source_set("llvm-profdata-for-test") { |
| sources = [ "llvm-profdata.cc" ] |
| defines = [ "HAVE_PROFDATA=1" ] |
| public_deps = [ ":llvm-profdata" ] |
| } |
| } else { |
| group("llvm-profdata-for-test") { |
| public_deps = [ ":llvm-profdata" ] |
| } |
| } |
| |
| test("llvm-profdata-unittests") { |
| sources = [ "llvm-profdata-tests.cc" ] |
| deps = [ |
| ":coverage-example", |
| ":llvm-profdata-for-test", |
| "//src/lib/elfldltl", |
| "//src/lib/fxl/test:gtest_main", |
| ] |
| |
| # Make sure the LinkTimeDeadFunction is really dead at link time. |
| configs -= [ "//build/config:default_linker_gc" ] |
| configs += [ "//build/config:linker_gc" ] |
| } |
| |
| fuchsia_unittest_package("llvm-profdata-tests") { |
| deps = [ ":llvm-profdata-unittests" ] |
| } |
| } |