diff --git a/.bazelignore b/.bazelignore new file mode 100644 index 0000000000000..04680184abec6 --- /dev/null +++ b/.bazelignore @@ -0,0 +1,2 @@ +api +examples/grpc-bridge/script diff --git a/WORKSPACE b/WORKSPACE index ec06147ab36f5..5609189bd56df 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -1,5 +1,9 @@ workspace(name = "envoy") +load("//bazel:api_repositories.bzl", "envoy_api_dependencies") + +envoy_api_dependencies() + load("//bazel:repositories.bzl", "GO_VERSION", "envoy_dependencies") load("//bazel:cc_configure.bzl", "cc_configure") @@ -11,10 +15,6 @@ rules_foreign_cc_dependencies() cc_configure() -load("@envoy_api//bazel:repositories.bzl", "api_dependencies") - -api_dependencies() - load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") go_rules_dependencies() diff --git a/bazel/api_repositories.bzl b/bazel/api_repositories.bzl new file mode 100644 index 0000000000000..016fb16c8a2ee --- /dev/null +++ b/bazel/api_repositories.bzl @@ -0,0 +1,35 @@ +def _default_envoy_api_impl(ctx): + ctx.file("WORKSPACE", "") + ctx.file("BUILD.bazel", "") + api_dirs = [ + "bazel", + "docs", + "envoy", + "examples", + "test", + "tools", + ] + for d in api_dirs: + ctx.symlink(ctx.path(ctx.attr.api).dirname.get_child(d), d) + +_default_envoy_api = repository_rule( + implementation = _default_envoy_api_impl, + attrs = { + "api": attr.label(default = "@envoy//api:BUILD"), + }, +) + +def envoy_api_dependencies(): + # Treat the data plane API as an external repo, this simplifies exporting the API to + # https://github.com/envoyproxy/data-plane-api. + if "envoy_api" not in native.existing_rules().keys(): + _default_envoy_api(name = "envoy_api") + + native.bind( + name = "api_httpbody_protos", + actual = "@googleapis//:api_httpbody_protos", + ) + native.bind( + name = "http_api_protos", + actual = "@googleapis//:http_api_protos", + ) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index f2cfc4cfe6c1a..a6b762243efeb 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -1,6 +1,6 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load(":genrule_repository.bzl", "genrule_repository") -load("//api/bazel:envoy_http_archive.bzl", "envoy_http_archive") +load("@envoy_api//bazel:envoy_http_archive.bzl", "envoy_http_archive") load(":repository_locations.bzl", "REPOSITORY_LOCATIONS") load( "@bazel_tools//tools/cpp:windows_cc_configure.bzl", @@ -8,6 +8,7 @@ load( "setup_vc_env_vars", ) load("@bazel_tools//tools/cpp:lib_cc_configure.bzl", "get_env_var") +load("@envoy_api//bazel:repositories.bzl", "api_dependencies") # dict of {build recipe name: longform extension name,} PPC_SKIP_TARGETS = {"luajit": "envoy.filters.http.lua"} @@ -38,27 +39,6 @@ _default_envoy_build_config = repository_rule( }, ) -def _default_envoy_api_impl(ctx): - ctx.file("WORKSPACE", "") - ctx.file("BUILD.bazel", "") - api_dirs = [ - "bazel", - "docs", - "envoy", - "examples", - "test", - "tools", - ] - for d in api_dirs: - ctx.symlink(ctx.path(ctx.attr.api).dirname.get_child(d), d) - -_default_envoy_api = repository_rule( - implementation = _default_envoy_api_impl, - attrs = { - "api": attr.label(default = "@envoy//api:BUILD"), - }, -) - # Python dependencies. If these become non-trivial, we might be better off using a virtualenv to # wrap them, but for now we can treat them as first-class Bazel. def _python_deps(): @@ -94,6 +74,14 @@ def _python_deps(): name = "com_github_twitter_common_finagle_thrift", build_file = "@envoy//bazel/external:twitter_common_finagle_thrift.BUILD", ) + _repository_impl( + name = "six_archive", + build_file = "@com_google_protobuf//:six.BUILD", + ) + native.bind( + name = "six", + actual = "@six_archive//:six", + ) # Bazel native C++ dependencies. For the dependencies that doesn't provide autoconf/automake builds. def _cc_deps(): @@ -127,29 +115,6 @@ def _go_deps(skip_targets): _repository_impl("io_bazel_rules_go") _repository_impl("bazel_gazelle") -def _envoy_api_deps(): - # Treat the data plane API as an external repo, this simplifies exporting the API to - # https://github.com/envoyproxy/data-plane-api. - if "envoy_api" not in native.existing_rules().keys(): - _default_envoy_api(name = "envoy_api") - - native.bind( - name = "api_httpbody_protos", - actual = "@googleapis//:api_httpbody_protos", - ) - native.bind( - name = "http_api_protos", - actual = "@googleapis//:http_api_protos", - ) - _repository_impl( - name = "six_archive", - build_file = "@com_google_protobuf//:six.BUILD", - ) - native.bind( - name = "six", - actual = "@six_archive//:six", - ) - def envoy_dependencies(skip_targets = []): # Treat Envoy's overall build config as an external repo, so projects that # build Envoy as a subcomponent can easily override the config. @@ -207,7 +172,7 @@ def envoy_dependencies(skip_targets = []): _python_deps() _cc_deps() _go_deps(skip_targets) - _envoy_api_deps() + api_dependencies() def _boringssl(): _repository_impl("boringssl") diff --git a/ci/WORKSPACE b/ci/WORKSPACE deleted file mode 100644 index f33b9aa583168..0000000000000 --- a/ci/WORKSPACE +++ /dev/null @@ -1,29 +0,0 @@ -workspace(name = "ci") - -load("//bazel:repositories.bzl", "GO_VERSION", "envoy_dependencies") -load("//bazel:cc_configure.bzl", "cc_configure") - -# We shouldn't need this, but it's a workaround for https://github.com/bazelbuild/bazel/issues/3580. -local_repository( - name = "envoy", - path = "/source", -) - -envoy_dependencies() - -# TODO(htuch): Roll this into envoy_dependencies() -load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependencies") - -rules_foreign_cc_dependencies() - -cc_configure() - -load("@envoy_api//bazel:repositories.bzl", "api_dependencies") - -api_dependencies() - -load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") - -go_rules_dependencies() - -go_register_toolchains(go_version = GO_VERSION) diff --git a/ci/WORKSPACE.filter.example b/ci/WORKSPACE.filter.example index 6262671453103..4eb98345a13f7 100644 --- a/ci/WORKSPACE.filter.example +++ b/ci/WORKSPACE.filter.example @@ -5,6 +5,9 @@ local_repository( path = "/source", ) +load("@envoy//bazel:api_repositories.bzl", "envoy_api_dependencies") +envoy_api_dependencies() + load("@envoy//bazel:repositories.bzl", "envoy_dependencies", "GO_VERSION") load("@envoy//bazel:cc_configure.bzl", "cc_configure") @@ -16,9 +19,6 @@ rules_foreign_cc_dependencies() cc_configure() -load("@envoy_api//bazel:repositories.bzl", "api_dependencies") -api_dependencies() - load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") go_rules_dependencies() go_register_toolchains(go_version = GO_VERSION) diff --git a/ci/build_setup.sh b/ci/build_setup.sh index 6e969f272c652..fa685a7eb498b 100755 --- a/ci/build_setup.sh +++ b/ci/build_setup.sh @@ -68,7 +68,6 @@ else fi # Not sandboxing, since non-privileged Docker can't do nested namespaces. -BAZEL_OPTIONS="--package_path %workspace%:${ENVOY_SRCDIR}" export BAZEL_QUERY_OPTIONS="${BAZEL_OPTIONS}" export BAZEL_BUILD_OPTIONS="--strategy=Genrule=standalone --spawn_strategy=standalone \ --verbose_failures ${BAZEL_OPTIONS} --action_env=HOME --action_env=PYTHONUSERBASE \ @@ -92,7 +91,7 @@ if [ "$1" != "-nofetch" ]; then then git clone https://github.com/envoyproxy/envoy-filter-example.git "${ENVOY_FILTER_EXAMPLE_SRCDIR}" fi - + # This is the hash on https://github.com/envoyproxy/envoy-filter-example.git we pin to. (cd "${ENVOY_FILTER_EXAMPLE_SRCDIR}" && git fetch origin && git checkout -f 6c0625cb4cc9a21df97cef2a1d065463f2ae81ae) cp -f "${ENVOY_SRCDIR}"/ci/WORKSPACE.filter.example "${ENVOY_FILTER_EXAMPLE_SRCDIR}"/WORKSPACE @@ -101,7 +100,6 @@ fi # Also setup some space for building Envoy standalone. export ENVOY_BUILD_DIR="${BUILD_DIR}"/envoy mkdir -p "${ENVOY_BUILD_DIR}" -cp -f "${ENVOY_SRCDIR}"/ci/WORKSPACE "${ENVOY_BUILD_DIR}" # This is where we copy build deliverables to. export ENVOY_DELIVERY_DIR="${ENVOY_BUILD_DIR}"/source/exe @@ -119,29 +117,17 @@ mkdir -p "${ENVOY_FAILED_TEST_LOGS}" export ENVOY_BUILD_PROFILE="${ENVOY_BUILD_DIR}"/generated/build-profile mkdir -p "${ENVOY_BUILD_PROFILE}" -# This is where we build for bazel.release* and bazel.dev. -export ENVOY_CI_DIR="${ENVOY_SRCDIR}"/ci - function cleanup() { # Remove build artifacts. This doesn't mess with incremental builds as these # are just symlinks. rm -rf "${ENVOY_SRCDIR}"/bazel-* - rm -rf "${ENVOY_CI_DIR}"/bazel-* - rm -rf "${ENVOY_CI_DIR}"/bazel - rm -rf "${ENVOY_CI_DIR}"/tools - rm -f "${ENVOY_CI_DIR}"/.bazelrc } cleanup trap cleanup EXIT -# Hack due to https://github.com/envoyproxy/envoy/issues/838 and the need to have -# .bazelrc available for build linkstamping. mkdir -p "${ENVOY_FILTER_EXAMPLE_SRCDIR}"/bazel -mkdir -p "${ENVOY_CI_DIR}"/bazel ln -sf "${ENVOY_SRCDIR}"/bazel/get_workspace_status "${ENVOY_FILTER_EXAMPLE_SRCDIR}"/bazel/ -ln -sf "${ENVOY_SRCDIR}"/bazel/get_workspace_status "${ENVOY_CI_DIR}"/bazel/ cp -f "${ENVOY_SRCDIR}"/.bazelrc "${ENVOY_FILTER_EXAMPLE_SRCDIR}"/ -cp -f "${ENVOY_SRCDIR}"/.bazelrc "${ENVOY_CI_DIR}"/ export BUILDIFIER_BIN="/usr/local/bin/buildifier" diff --git a/ci/do_ci.sh b/ci/do_ci.sh index dff1ee8c1ceae..aa2105a0184aa 100755 --- a/ci/do_ci.sh +++ b/ci/do_ci.sh @@ -13,6 +13,7 @@ fi . "$(dirname "$0")"/setup_gcs_cache.sh . "$(dirname "$0")"/build_setup.sh $build_setup_args +cd "${ENVOY_SRCDIR}" echo "building using ${NUM_CPUS} CPUs" @@ -27,11 +28,12 @@ function bazel_with_collection() { if [ "${BAZEL_STATUS}" != "0" ] then declare -r FAILED_TEST_LOGS="$(grep " /build.*test.log" "${BAZEL_OUTPUT}" | sed -e 's/ \/build.*\/testlogs\/\(.*\)/\1/')" - cd bazel-testlogs + pushd bazel-testlogs for f in ${FAILED_TEST_LOGS} do cp --parents -f $f "${ENVOY_FAILED_TEST_LOGS}" done + popd exit "${BAZEL_STATUS}" fi collect_build_profile $1 @@ -39,13 +41,12 @@ function bazel_with_collection() { function bazel_release_binary_build() { echo "Building..." - pushd "${ENVOY_CI_DIR}" bazel build ${BAZEL_BUILD_OPTIONS} -c opt //source/exe:envoy-static collect_build_profile release_build # Copy the envoy-static binary somewhere that we can access outside of the # container. cp -f \ - "${ENVOY_CI_DIR}"/bazel-bin/source/exe/envoy-static \ + "${ENVOY_SRCDIR}"/bazel-bin/source/exe/envoy-static \ "${ENVOY_DELIVERY_DIR}"/envoy # TODO(mattklein123): Replace this with caching and a different job which creates images. @@ -54,20 +55,16 @@ function bazel_release_binary_build() { cp -f "${ENVOY_DELIVERY_DIR}"/envoy "${ENVOY_SRCDIR}"/build_release mkdir -p "${ENVOY_SRCDIR}"/build_release_stripped strip "${ENVOY_DELIVERY_DIR}"/envoy -o "${ENVOY_SRCDIR}"/build_release_stripped/envoy - # TODO(wu-bin): Remove once https://github.com/envoyproxy/envoy/pull/6229 is merged. - bazel clean - popd } function bazel_debug_binary_build() { echo "Building..." - cd "${ENVOY_CI_DIR}" bazel build ${BAZEL_BUILD_OPTIONS} -c dbg //source/exe:envoy-static collect_build_profile debug_build # Copy the envoy-static binary somewhere that we can access outside of the # container. cp -f \ - "${ENVOY_CI_DIR}"/bazel-bin/source/exe/envoy-static \ + "${ENVOY_SRCDIR}"/bazel-bin/source/exe/envoy-static \ "${ENVOY_DELIVERY_DIR}"/envoy-debug } @@ -122,12 +119,12 @@ elif [[ "$1" == "bazel.asan" ]]; then setup_clang_toolchain echo "bazel ASAN/UBSAN debug build with tests" echo "Building and testing envoy tests..." - cd "${ENVOY_SRCDIR}" bazel_with_collection test ${BAZEL_TEST_OPTIONS} -c dbg --config=clang-asan //test/... echo "Building and testing envoy-filter-example tests..." - cd "${ENVOY_FILTER_EXAMPLE_SRCDIR}" + pushd "${ENVOY_FILTER_EXAMPLE_SRCDIR}" bazel_with_collection test ${BAZEL_TEST_OPTIONS} -c dbg --config=clang-asan \ //:echo2_integration_test //:envoy_binary_test + popd # Also validate that integration test traffic tapping (useful when debugging etc.) # works. This requires that we set TAP_PATH. We do this under bazel.asan to # ensure a debug build in CI. @@ -135,7 +132,6 @@ elif [[ "$1" == "bazel.asan" ]]; then TAP_TMP=/tmp/tap/ rm -rf "${TAP_TMP}" mkdir -p "${TAP_TMP}" - cd "${ENVOY_SRCDIR}" bazel_with_collection test ${BAZEL_TEST_OPTIONS} -c dbg --config=clang-asan \ //test/extensions/transport_sockets/tls/integration:ssl_integration_test \ --test_env=TAP_PATH="${TAP_TMP}/tap" @@ -148,7 +144,6 @@ elif [[ "$1" == "bazel.tsan" ]]; then setup_clang_toolchain echo "bazel TSAN debug build with tests" echo "Building and testing envoy tests..." - cd "${ENVOY_SRCDIR}" bazel_with_collection test ${BAZEL_TEST_OPTIONS} -c dbg --config=clang-tsan //test/... echo "Building and testing envoy-filter-example tests..." cd "${ENVOY_FILTER_EXAMPLE_SRCDIR}" @@ -159,13 +154,12 @@ elif [[ "$1" == "bazel.dev" ]]; then setup_clang_toolchain # This doesn't go into CI but is available for developer convenience. echo "bazel fastbuild build with tests..." - cd "${ENVOY_CI_DIR}" echo "Building..." bazel build ${BAZEL_BUILD_OPTIONS} -c fastbuild //source/exe:envoy-static # Copy the envoy-static binary somewhere that we can access outside of the # container for developers. cp -f \ - "${ENVOY_CI_DIR}"/bazel-bin/source/exe/envoy-static \ + "${ENVOY_SRCDIR}"/bazel-bin/source/exe/envoy-static \ "${ENVOY_DELIVERY_DIR}"/envoy-fastbuild echo "Building and testing..." bazel test ${BAZEL_TEST_OPTIONS} -c fastbuild //test/... @@ -187,7 +181,6 @@ elif [[ "$1" == "bazel.compile_time_options" ]]; then # This doesn't go into CI but is available for developer convenience. echo "bazel with different compiletime options build with tests..." # Building all the dependencies from scratch to link them against libc++. - cd "${ENVOY_SRCDIR}" echo "Building..." bazel build ${BAZEL_BUILD_OPTIONS} ${COMPILE_TIME_OPTIONS} -c dbg //source/exe:envoy-static echo "Building and testing..." @@ -213,13 +206,11 @@ elif [[ "$1" == "bazel.ipv6_tests" ]]; then setup_clang_toolchain echo "Testing..." - cd "${ENVOY_CI_DIR}" bazel_with_collection test ${BAZEL_TEST_OPTIONS} --test_env=ENVOY_IP_TEST_VERSIONS=v6only -c fastbuild \ //test/integration/... //test/common/network/... exit 0 elif [[ "$1" == "bazel.api" ]]; then setup_clang_toolchain - cd "${ENVOY_CI_DIR}" echo "Building API..." bazel build ${BAZEL_BUILD_OPTIONS} -c fastbuild @envoy_api//envoy/... echo "Testing API..." @@ -232,7 +223,6 @@ elif [[ "$1" == "bazel.coverage" ]]; then # gcovr is a pain to run with `bazel run`, so package it up into a # relocatable and hermetic-ish .par file. - cd "${ENVOY_SRCDIR}" bazel build @com_github_gcovr_gcovr//:gcovr.par export GCOVR="/tmp/gcovr.par" cp -f "${ENVOY_SRCDIR}/bazel-bin/external/com_github_gcovr_gcovr/gcovr.par" ${GCOVR} @@ -250,10 +240,7 @@ elif [[ "$1" == "bazel.coverage" ]]; then exit 0 elif [[ "$1" == "bazel.clang_tidy" ]]; then setup_clang_toolchain - # TODO(wu-bin): Remove once https://github.com/envoyproxy/envoy/pull/6229 is merged. - export BAZEL_BUILD_OPTIONS="${BAZEL_BUILD_OPTIONS} --linkopt='-Wl,--allow-multiple-definition'" - cd "${ENVOY_CI_DIR}" - ./run_clang_tidy.sh + ci/run_clang_tidy.sh exit 0 elif [[ "$1" == "bazel.coverity" ]]; then # Coverity Scan version 2017.07 fails to analyze the entirely of the Envoy @@ -263,7 +250,6 @@ elif [[ "$1" == "bazel.coverity" ]]; then setup_gcc_toolchain echo "bazel Coverity Scan build" echo "Building..." - cd "${ENVOY_CI_DIR}" /build/cov-analysis/bin/cov-build --dir "${ENVOY_BUILD_DIR}"/cov-int bazel build --action_env=LD_PRELOAD ${BAZEL_BUILD_OPTIONS} \ -c opt //source/exe:envoy-static # tar up the coverity results @@ -275,11 +261,9 @@ elif [[ "$1" == "bazel.coverity" ]]; then exit 0 elif [[ "$1" == "fix_format" ]]; then echo "fix_format..." - cd "${ENVOY_SRCDIR}" ./tools/check_format.py fix exit 0 elif [[ "$1" == "check_format" ]]; then - cd "${ENVOY_SRCDIR}" echo "check_format_test..." ./tools/check_format_test_helper.py --log=WARN echo "check_format..." @@ -287,27 +271,22 @@ elif [[ "$1" == "check_format" ]]; then ./tools/format_python_tools.sh check exit 0 elif [[ "$1" == "check_repositories" ]]; then - cd "${ENVOY_SRCDIR}" echo "check_repositories..." ./tools/check_repositories.sh exit 0 elif [[ "$1" == "check_spelling" ]]; then - cd "${ENVOY_SRCDIR}" echo "check_spelling..." ./tools/check_spelling.sh check exit 0 elif [[ "$1" == "fix_spelling" ]];then - cd "${ENVOY_SRCDIR}" echo "fix_spell..." ./tools/check_spelling.sh fix exit 0 elif [[ "$1" == "check_spelling_pedantic" ]]; then - cd "${ENVOY_SRCDIR}" echo "check_spelling_pedantic..." ./tools/check_spelling_pedantic.py check exit 0 elif [[ "$1" == "fix_spelling_pedantic" ]]; then - cd "${ENVOY_SRCDIR}" echo "fix_spelling_pedantic..." ./tools/check_spelling_pedantic.py fix exit 0 diff --git a/ci/run_clang_tidy.sh b/ci/run_clang_tidy.sh index 29d4381b51828..27c8212b87ef0 100755 --- a/ci/run_clang_tidy.sh +++ b/ci/run_clang_tidy.sh @@ -3,6 +3,15 @@ set -e echo "Generating compilation database..." + +cp -f .bazelrc .bazelrc.bak + +function cleanup() { + cp -f .bazelrc.bak .bazelrc + rm -f .bazelrc.bak +} +trap cleanup EXIT + # The compilation database generate script doesn't support passing build options via CLI. # Writing them into bazelrc echo "build ${BAZEL_BUILD_OPTIONS}" >> .bazelrc @@ -11,11 +20,6 @@ echo "build ${BAZEL_BUILD_OPTIONS}" >> .bazelrc # by clang-tidy "${ENVOY_SRCDIR}/tools/gen_compilation_database.py" --run_bazel_build --include_headers -# It had to be in ENVOY_CI_DIR to run bazel to generate compile database, but clang-tidy-diff -# diff against current directory, moving them to ENVOY_SRCDIR. -mv ./compile_commands.json "${ENVOY_SRCDIR}/compile_commands.json" -cd "${ENVOY_SRCDIR}" - # Do not run incremental clang-tidy on check_format testdata files. function exclude_testdata() { grep -v tools/testdata/check_format/ diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index f241151682fe5..b5045be4171e6 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -271,7 +271,7 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { *dispatcher_, fake_upstream_->localAddress(), nullptr, std::move(async_client_transport_socket_), nullptr); ON_CALL(*mock_cluster_info_, connectTimeout()) - .WillByDefault(Return(std::chrono::milliseconds(1000))); + .WillByDefault(Return(std::chrono::milliseconds(10000))); EXPECT_CALL(*mock_cluster_info_, name()).WillRepeatedly(ReturnRef(fake_cluster_name_)); EXPECT_CALL(cm_, get(_)).WillRepeatedly(Return(&thread_local_cluster_)); EXPECT_CALL(thread_local_cluster_, info()).WillRepeatedly(Return(cluster_info_ptr_)); diff --git a/test/run_envoy_bazel_coverage.sh b/test/run_envoy_bazel_coverage.sh index 21a10464b774b..bed4baa803c48 100755 --- a/test/run_envoy_bazel_coverage.sh +++ b/test/run_envoy_bazel_coverage.sh @@ -61,7 +61,7 @@ BAZEL_TEST_OPTIONS="${BAZEL_TEST_OPTIONS} -c dbg --copt=-DNDEBUG" # stats. The #foo# pattern is because gcov produces files such as # bazel-out#local-fastbuild#bin#external#spdlog_git#_virtual_includes#spdlog#spdlog#details#pattern_formatter_impl.h.gcov. # To find these while modifying this regex, perform a gcov run with -k set. -[[ -z "${GCOVR_EXCLUDE_REGEX}" ]] && GCOVR_EXCLUDE_REGEX=".*pb.h.gcov|.*#genfiles#.*|test#.*|external#.*|.*#external#.*|.*#prebuilt#.*|.*#config_validation#.*" +[[ -z "${GCOVR_EXCLUDE_REGEX}" ]] && GCOVR_EXCLUDE_REGEX=".*pb.h.gcov|.*#genfiles#.*|test#.*|external#.*|.*#external#.*|.*#prebuilt#.*|.*#config_validation#.*|.*#chromium_url#.*" [[ -z "${GCOVR_EXCLUDE_DIR}" ]] && GCOVR_EXCLUDE_DIR=".*/external/.*" COVERAGE_DIR="${SRCDIR}"/generated/coverage