diff --git a/.bazelrc b/.bazelrc index a365b1d064bc..771d01e27b3f 100644 --- a/.bazelrc +++ b/.bazelrc @@ -8,8 +8,12 @@ startup --host_jvm_args=-Xmx512m build --workspace_status_command=bazel/get_workspace_status build --experimental_remap_main_repo build --host_force_python=PY2 +build --action_env=BAZEL_LINKLIBS=-l%:libstdc++.a +build --action_env=BAZEL_LINKOPTS=-lm:-static-libgcc # Basic ASAN/UBSAN that works for gcc +build:asan --action_env=BAZEL_LINKLIBS= +build:asan --action_env=BAZEL_LINKOPTS=-lstdc++:-lm build:asan --define ENVOY_CONFIG_ASAN=1 build:asan --copt -fsanitize=address,undefined build:asan --linkopt -fsanitize=address,undefined @@ -60,6 +64,8 @@ build:clang-msan --copt -fsanitize-memory-track-origins=2 build:libc++ --action_env=CC build:libc++ --action_env=CXX build:libc++ --action_env=CXXFLAGS=-stdlib=libc++ +build:libc++ --action_env=BAZEL_CXXOPTS=-stdlib=libc++ +build:libc++ --action_env=BAZEL_LINKLIBS=-l%:libc++.a:-l%:libc++abi.a:-lm build:libc++ --action_env=PATH build:libc++ --host_linkopt=-fuse-ld=lld build:libc++ --define force_libcpp=enabled diff --git a/WORKSPACE b/WORKSPACE index 5609189bd56d..bc3ce13bd3a7 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -5,7 +5,6 @@ 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") envoy_dependencies() @@ -13,8 +12,6 @@ load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependen rules_foreign_cc_dependencies() -cc_configure() - load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies") go_rules_dependencies() diff --git a/bazel/BUILD b/bazel/BUILD index c288f351054f..a574dc1eb27a 100755 --- a/bazel/BUILD +++ b/bazel/BUILD @@ -85,6 +85,20 @@ config_setting( values = {"define": "ENVOY_CONFIG_COVERAGE=1"}, ) +config_setting( + name = "clang_build", + flag_values = { + "@bazel_tools//tools/cpp:compiler": "clang", + }, +) + +config_setting( + name = "gcc_build", + flag_values = { + "@bazel_tools//tools/cpp:compiler": "gcc", + }, +) + config_setting( name = "disable_tcmalloc", values = {"define": "tcmalloc=disabled"}, diff --git a/bazel/cc_configure.bzl b/bazel/cc_configure.bzl deleted file mode 100644 index 30275140b917..000000000000 --- a/bazel/cc_configure.bzl +++ /dev/null @@ -1,79 +0,0 @@ -load("@bazel_tools//tools/cpp:cc_configure.bzl", _upstream_cc_autoconf_impl = "cc_autoconf_impl") -load("@bazel_tools//tools/cpp:lib_cc_configure.bzl", "get_cpu_value") -load("@bazel_tools//tools/cpp:unix_cc_configure.bzl", "find_cc") - -def _build_envoy_cc_wrapper(repository_ctx): - real_cc = find_cc(repository_ctx, {}) - - # Copy our CC wrapper script into @local_config_cc, with the true paths - # to the C and C++ compiler injected in. The wrapper will use these paths - # to invoke the compiler after deciding which one is correct for the current - # invocation. - # - # Since the script is Python, we can inject values using `repr(str(value))` - # and escaping will be handled correctly. - repository_ctx.template("extra_tools/envoy_cc_wrapper", repository_ctx.attr._envoy_cc_wrapper, { - "{ENVOY_REAL_CC}": repr(str(real_cc)), - "{ENVOY_CFLAGS}": repr(str(repository_ctx.os.environ.get("CFLAGS", ""))), - "{ENVOY_CXXFLAGS}": repr(str(repository_ctx.os.environ.get("CXXFLAGS", ""))), - }) - return repository_ctx.path("extra_tools/envoy_cc_wrapper") - -def _needs_envoy_cc_wrapper(repository_ctx): - # When building for Linux we set additional C++ compiler options that aren't - # handled well by Bazel, so we need a wrapper around $CC to fix its - # compiler invocations. - cpu_value = get_cpu_value(repository_ctx) - return cpu_value not in ["freebsd", "x64_windows", "darwin"] - -def cc_autoconf_impl(repository_ctx): - overriden_tools = {} - if _needs_envoy_cc_wrapper(repository_ctx): - # Bazel uses "gcc" as a generic name for all C and C++ compilers. - overriden_tools["gcc"] = _build_envoy_cc_wrapper(repository_ctx) - return _upstream_cc_autoconf_impl(repository_ctx, overriden_tools = overriden_tools) - -cc_autoconf = repository_rule( - implementation = cc_autoconf_impl, - attrs = { - "_envoy_cc_wrapper": attr.label(default = "@envoy//bazel:cc_wrapper.py"), - }, - environ = [ - "ABI_LIBC_VERSION", - "ABI_VERSION", - "BAZEL_COMPILER", - "BAZEL_HOST_SYSTEM", - "BAZEL_CXXOPTS", - "BAZEL_LINKOPTS", - "BAZEL_PYTHON", - "BAZEL_SH", - "BAZEL_TARGET_CPU", - "BAZEL_TARGET_LIBC", - "BAZEL_TARGET_SYSTEM", - "BAZEL_USE_CPP_ONLY_TOOLCHAIN", - "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN", - "BAZEL_USE_LLVM_NATIVE_COVERAGE", - "BAZEL_VC", - "BAZEL_VS", - "BAZEL_LLVM", - "USE_CLANG_CL", - "CC", - "CFLAGS", - "CXXFLAGS", - "CC_CONFIGURE_DEBUG", - "CC_TOOLCHAIN_NAME", - "CPLUS_INCLUDE_PATH", - "GCOV", - "HOMEBREW_RUBY_PATH", - "SYSTEMROOT", - "VS90COMNTOOLS", - "VS100COMNTOOLS", - "VS110COMNTOOLS", - "VS120COMNTOOLS", - "VS140COMNTOOLS", - ], -) - -def cc_configure(): - cc_autoconf(name = "local_config_cc") - native.bind(name = "cc_toolchain", actual = "@local_config_cc//:toolchain") diff --git a/bazel/cc_wrapper.py b/bazel/cc_wrapper.py deleted file mode 100755 index 41029a05eb4b..000000000000 --- a/bazel/cc_wrapper.py +++ /dev/null @@ -1,128 +0,0 @@ -#!/usr/bin/python3 -import contextlib -import os -import shlex -import sys -import tempfile - -compiler = {ENVOY_REAL_CC} -envoy_cflags = {ENVOY_CFLAGS} -envoy_cxxflags = {ENVOY_CXXFLAGS} - - -@contextlib.contextmanager -def closing_fd(fd): - try: - yield fd - finally: - os.close(fd) - - -def sanitize_flagfile(in_path, out_fd): - with open(in_path, "rb") as in_fp: - for line in in_fp: - if line != "-lstdc++\n": - os.write(out_fd, line) - elif "-stdlib=libc++" in envoy_cxxflags: - os.write(out_fd, "-l:libc++.a\n-l:libc++abi.a\n") - - -# Is the arg a flag indicating that we're building for C++ (rather than C)? -def is_cpp_flag(arg): - return arg in ["-static-libstdc++", "-stdlib=libc++", "-lstdc++", "-lc++" - ] or arg.startswith("-std=c++") or arg.startswith("-std=gnu++") - - -def modify_driver_args(input_driver_flags): - # Detect if we're building for C++ or vanilla C. - if any(map(is_cpp_flag, input_driver_flags)): - # Append CXXFLAGS to all C++ targets (this is mostly for dependencies). - argv = shlex.split(envoy_cxxflags) - else: - # Append CFLAGS to all C targets (this is mostly for dependencies). - argv = shlex.split(envoy_cflags) - - # Either: - # a) remove all occurrences of -lstdc++ (when statically linking against libstdc++), - # b) replace all occurrences of -lstdc++ with -lc++ (when linking against libc++). - if "-static-libstdc++" in input_driver_flags or "-stdlib=libc++" in envoy_cxxflags: - for arg in input_driver_flags: - if arg in ("-lstdc++", "-static-libstdc++"): - pass - elif arg.startswith("-Wl,@"): - # tempfile.mkstemp will write to the out-of-sandbox tempdir - # unless the user has explicitly set environment variables - # before starting Bazel. But here in $PWD is the Bazel sandbox, - # which will be deleted automatically after the compiler exits. - (flagfile_fd, flagfile_path) = tempfile.mkstemp(dir="./", suffix=".linker-params") - with closing_fd(flagfile_fd): - sanitize_flagfile(arg[len("-Wl,@"):], flagfile_fd) - argv.append("-Wl,@" + flagfile_path) - else: - argv.append(arg) - else: - argv += input_driver_flags - - # This flags should after all libraries - if "-static-libstdc++" in input_driver_flags: - argv.append("-l:libstdc++.a") - if "-lstdc++" in input_driver_flags and "-stdlib=libc++" in envoy_cxxflags: - argv.append("-l:libc++.a") - argv.append("-l:libc++abi.a") - - # Bazel will add -fuse-ld=gold in some cases, gcc/clang will take the last -fuse-ld argument, - # so whenever we see lld once, add it to the end. - if "-fuse-ld=lld" in argv: - argv.append("-fuse-ld=lld") - - # Add compiler-specific options - if "clang" in compiler: - # This ensures that STL symbols are included. - # See https://github.com/envoyproxy/envoy/issues/1341 - argv.append("-fno-limit-debug-info") - argv.append("-Wthread-safety") - argv.append("-Wgnu-conditional-omitted-operand") - elif "gcc" in compiler or "g++" in compiler: - # -Wmaybe-initialized is warning about many uses of absl::optional. Disable - # to prevent build breakage. This option does not exist in clang, so setting - # it in clang builds causes a build error because of unknown command line - # flag. - # See https://github.com/envoyproxy/envoy/issues/2987 - argv.append("-Wno-maybe-uninitialized") - - return argv - - -def main(): - # Append CXXFLAGS to correctly detect include paths for either libstdc++ or libc++. - if sys.argv[1:5] == ["-E", "-xc++", "-", "-v"]: - os.execv(compiler, [compiler] + sys.argv[1:] + shlex.split(envoy_cxxflags)) - - if sys.argv[1].startswith("@"): - # Read flags from file - flagfile_path = sys.argv[1][1:] - with open(flagfile_path, "r") as fd: - input_driver_flags = fd.read().splitlines() - - # Compute new args - new_driver_args = modify_driver_args(input_driver_flags) - - # Write args to temp file - (new_flagfile_fd, new_flagfile_path) = tempfile.mkstemp(dir="./", suffix=".linker-params") - - with closing_fd(new_flagfile_fd): - for arg in new_driver_args: - os.write(new_flagfile_fd, bytes(str(arg + "\n").encode("utf-8"))) - - # Provide new arguments using the temp file containing the args - new_args = ["@" + new_flagfile_path] - else: - # TODO(https://github.com/bazelbuild/bazel/issues/7687): Remove this branch - # when Bazel 0.27 is released. - new_args = modify_driver_args(sys.argv[1:]) - - os.execv(compiler, [compiler] + new_args) - - -if __name__ == "__main__": - main() diff --git a/bazel/envoy_binary.bzl b/bazel/envoy_binary.bzl index a7a369e8c16b..edcdd09ae03b 100644 --- a/bazel/envoy_binary.bzl +++ b/bazel/envoy_binary.bzl @@ -4,7 +4,6 @@ load( ":envoy_internal.bzl", "envoy_copts", "envoy_external_dep_path", - "envoy_static_link_libstdcpp_linkopts", "tcmalloc_external_dep", ) @@ -50,25 +49,24 @@ def _envoy_select_exported_symbols(xs): # Compute the final linkopts based on various options. def _envoy_linkopts(): return select({ - # The macOS system library transitively links common libraries (e.g., pthread). - "@envoy//bazel:apple": [ - # See note here: https://luajit.org/install.html - "-pagezero_size 10000", - "-image_base 100000000", - ], - "@envoy//bazel:windows_x86_64": [ - "-DEFAULTLIB:advapi32.lib", - "-DEFAULTLIB:ws2_32.lib", - "-WX", - ], - "//conditions:default": [ - "-pthread", - "-lrt", - "-ldl", - "-Wl,--hash-style=gnu", - ], - }) + envoy_static_link_libstdcpp_linkopts() + \ - _envoy_select_exported_symbols(["-Wl,-E"]) + # The macOS system library transitively links common libraries (e.g., pthread). + "@envoy//bazel:apple": [ + # See note here: https://luajit.org/install.html + "-pagezero_size 10000", + "-image_base 100000000", + ], + "@envoy//bazel:windows_x86_64": [ + "-DEFAULTLIB:advapi32.lib", + "-DEFAULTLIB:ws2_32.lib", + "-WX", + ], + "//conditions:default": [ + "-pthread", + "-lrt", + "-ldl", + "-Wl,--hash-style=gnu", + ], + }) + _envoy_select_exported_symbols(["-Wl,-E"]) def _envoy_stamped_deps(): return select({ diff --git a/bazel/envoy_internal.bzl b/bazel/envoy_internal.bzl index 4ea71659d295..325ea94f5596 100644 --- a/bazel/envoy_internal.bzl +++ b/bazel/envoy_internal.bzl @@ -40,6 +40,10 @@ def envoy_copts(repository, test = False): repository + "//bazel:windows_opt_build": [], repository + "//bazel:windows_fastbuild_build": [], repository + "//bazel:windows_dbg_build": [], + }) + select({ + repository + "//bazel:clang_build": ["-fno-limit-debug-info", "-Wgnu-conditional-omitted-operand"], + repository + "//bazel:gcc_build": ["-Wno-maybe-uninitialized"], + "//conditions:default": [], }) + select({ repository + "//bazel:disable_tcmalloc": ["-DABSL_MALLOC_HOOK_MMAP_DISABLE"], "//conditions:default": ["-DTCMALLOC"], @@ -82,12 +86,6 @@ def envoy_select_force_libcpp(if_libcpp, default = None): "//conditions:default": default or [], }) -def envoy_static_link_libstdcpp_linkopts(): - return envoy_select_force_libcpp( - ["-stdlib=libc++", "-l:libc++.a", "-l:libc++abi.a", "-static-libgcc"], - ["-static-libstdc++", "-static-libgcc"], - ) - # Dependencies on tcmalloc_and_profiler should be wrapped with this function. def tcmalloc_external_dep(repository): return select({ diff --git a/bazel/envoy_test.bzl b/bazel/envoy_test.bzl index ea564d619fa8..c836096913fa 100644 --- a/bazel/envoy_test.bzl +++ b/bazel/envoy_test.bzl @@ -8,7 +8,6 @@ load( "envoy_external_dep_path", "envoy_linkstatic", "envoy_select_force_libcpp", - "envoy_static_link_libstdcpp_linkopts", "tcmalloc_external_dep", ) @@ -205,7 +204,7 @@ def envoy_cc_test_binary( envoy_cc_binary( name, testonly = 1, - linkopts = _envoy_test_linkopts() + envoy_static_link_libstdcpp_linkopts(), + linkopts = _envoy_test_linkopts(), **kargs ) diff --git a/bazel/repositories.bzl b/bazel/repositories.bzl index ed14486d3a5e..865ad858b76a 100644 --- a/bazel/repositories.bzl +++ b/bazel/repositories.bzl @@ -2,12 +2,6 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load(":genrule_repository.bzl", "genrule_repository") 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", - "find_vc_path", - "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,} diff --git a/ci/WORKSPACE.filter.example b/ci/WORKSPACE.filter.example index 4eb98345a13f..5013077c2468 100644 --- a/ci/WORKSPACE.filter.example +++ b/ci/WORKSPACE.filter.example @@ -9,7 +9,6 @@ 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") envoy_dependencies() @@ -17,8 +16,6 @@ envoy_dependencies() load("@rules_foreign_cc//:workspace_definitions.bzl", "rules_foreign_cc_dependencies") rules_foreign_cc_dependencies() -cc_configure() - 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 a8069429be0d..f1729b64b5e6 100755 --- a/ci/build_setup.sh +++ b/ci/build_setup.sh @@ -13,6 +13,7 @@ echo "ENVOY_SRCDIR=${ENVOY_SRCDIR}" function setup_gcc_toolchain() { export CC=gcc export CXX=g++ + export BAZEL_COMPILER=gcc echo "$CC/$CXX toolchain configured" } @@ -20,6 +21,7 @@ function setup_clang_toolchain() { export PATH=/usr/lib/llvm-8/bin:$PATH export CC=clang export CXX=clang++ + export BAZEL_COMPILER=clang export ASAN_SYMBOLIZER_PATH=/usr/lib/llvm-8/bin/llvm-symbolizer echo "$CC/$CXX toolchain configured" } diff --git a/test/integration/stats_integration_test.cc b/test/integration/stats_integration_test.cc index a404e8de89d5..ad2b87484f58 100644 --- a/test/integration/stats_integration_test.cc +++ b/test/integration/stats_integration_test.cc @@ -210,6 +210,7 @@ TEST_P(ClusterMemoryTestRunner, MemoryLargeClusterSizeWithStats) { // 2019/06/29 7364 45685 46000 combine 2 levels of stat ref-counting into 1 // 2019/06/30 7428 42742 43000 remove stats multiple inheritance, inline HeapStatData // 2019/07/06 7477 42742 43000 fork gauge representation to drop pending_increment_ + // 2019/07/15 7555 42806 43000 static link libstdc++ in tests // Note: when adjusting this value: EXPECT_MEMORY_EQ is active only in CI // 'release' builds, where we control the platform and tool-chain. So you @@ -219,7 +220,7 @@ TEST_P(ClusterMemoryTestRunner, MemoryLargeClusterSizeWithStats) { // On a local clang8/libstdc++/linux flow, the memory usage was observed in // June 2019 to be 64 bytes higher than it is in CI/release. Your mileage may // vary. - EXPECT_MEMORY_EQ(m_per_cluster, 42742); // 104 bytes higher than a debug build. + EXPECT_MEMORY_EQ(m_per_cluster, 42806); // 104 bytes higher than a debug build. EXPECT_MEMORY_LE(m_per_cluster, 43000); }