From bddb2decc98cf01769a30f0913d9cfda9f15bccc Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Fri, 13 Jun 2025 16:39:18 +0000 Subject: [PATCH 1/4] Add cc_static_library for non-bazel projects Bazel 7.4.x+ have a new `cc_static_library` rule that creates a redistributable static library from a set of deps. This allows us to create a standalone version of tcmalloc that users can easily pull into non-bazel projects. This should lower the friction for cmake users to use tcmalloc. --- docs/quickstart.md | 20 ++++++++++++++++++++ tcmalloc/BUILD | 6 ++++++ 2 files changed, 26 insertions(+) diff --git a/docs/quickstart.md b/docs/quickstart.md index cdfc71842..554a37837 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -254,6 +254,26 @@ build --cxxopt='-std=c++17' Congratulations! You've created your first binary using TCMalloc. +### Using TCMalloc in non-Bazel Projects + +If you are not using Bazel, you can instead build a standalone version +of TCMalloc that you can vendor in your project. Before doing so you +should still run the tests, as described above, to make sure the +vendored library will work in your environment. Then build the +standalone bazel target: + +``` +tcmalloc$ bazel build tcmalloc:tcmalloc_standalone --experimental_cc_static_library +``` + +Once this builds you can copy the resulting static library from +`bazel-bin/tcmalloc/libtcmalloc_standalone.a` into your project! + +Note that if you have dependencies in your project that are also +included in TCMalloc, it is up to you to ensure the versions are +compatible in order to avoid symbol conflicts (which may or may not be +hard errors at link time). + ## What's Next * Read our [overview](overview.md), if you haven't already. The overview diff --git a/tcmalloc/BUILD b/tcmalloc/BUILD index 9594b8038..4322353a0 100644 --- a/tcmalloc/BUILD +++ b/tcmalloc/BUILD @@ -117,6 +117,12 @@ cc_library( alwayslink = 1, ) +cc_static_library( + name = "tcmalloc_standalone", + deps = [":tcmalloc"], + tags = ["manual"], +) + cc_library( name = "tcmalloc_internal_methods_only", testonly = True, From d61809d17875a2260d870fd2c122dcbf2a8fd068 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Tue, 17 Jun 2025 00:34:39 +0000 Subject: [PATCH 2/4] Add basic test example --- tcmalloc/BUILD | 3 ++- tcmalloc/testing/BUILD | 21 +++++++++++++++++++++ tcmalloc/testing/standalone_test.cc | 17 +++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 tcmalloc/testing/standalone_test.cc diff --git a/tcmalloc/BUILD b/tcmalloc/BUILD index 4322353a0..87ce499cf 100644 --- a/tcmalloc/BUILD +++ b/tcmalloc/BUILD @@ -119,8 +119,9 @@ cc_library( cc_static_library( name = "tcmalloc_standalone", - deps = [":tcmalloc"], tags = ["manual"], + visibility = [":__subpackages__"], + deps = [":tcmalloc"], ) cc_library( diff --git a/tcmalloc/testing/BUILD b/tcmalloc/testing/BUILD index 425453bb5..f5cf5b4df 100644 --- a/tcmalloc/testing/BUILD +++ b/tcmalloc/testing/BUILD @@ -1053,3 +1053,24 @@ cc_test( "//tcmalloc:alloc_at_least", ], ) + +cc_import( + name = "standalone_import", + static_library = "//tcmalloc:tcmalloc_standalone", + tags = ["manual"], # TODO: Remove once cc_static_library is always enabled + alwayslink = True, +) + +cc_test( + name = "standalone_test", + srcs = ["standalone_test.cc"], + tags = [ + "manual", # TODO: Remove once cc_static_library is always enabled + "noasan", + "nomsan", + "notsan", + ], + deps = [ + ":standalone_import", + ], +) diff --git a/tcmalloc/testing/standalone_test.cc b/tcmalloc/testing/standalone_test.cc new file mode 100644 index 000000000..e3a358292 --- /dev/null +++ b/tcmalloc/testing/standalone_test.cc @@ -0,0 +1,17 @@ +#include +#include + +int main() { + std::cout << "Standard Alignment: " << alignof(std::max_align_t) << '\n'; + + double *ptr = (double*) malloc(sizeof(double)); + std::cout << "Double Alignment: " << alignof(*ptr) << '\n'; + + char *ptr2 = (char*) malloc(1); + std::cout << "Char Alignment: " << alignof(*ptr2) << '\n'; + + void *ptr3; + std::cout << "Sizeof void*: " << sizeof(ptr3) << '\n'; + + return 0; +} From f8d3a570e3edb60da3696da73008a4a966d39a20 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Tue, 17 Jun 2025 21:12:47 -0700 Subject: [PATCH 3/4] Move option to .bazelrc --- .bazelrc | 3 +++ docs/quickstart.md | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.bazelrc b/.bazelrc index ffcd8bbce..495be37d3 100644 --- a/.bazelrc +++ b/.bazelrc @@ -26,6 +26,9 @@ common --incompatible_config_setting_private_default_visibility # Link Google Test against Abseil and RE2. build --define='absl=1' +# https://github.com/bazelbuild/bazel/pull/26294 +build --experimental_cc_static_library + # AllocationGuard.CooperativeDeathTest checks for "SIGABRT received" # message printed by this signal handler. test --test_env="GTEST_INSTALL_FAILURE_SIGNAL_HANDLER=1" diff --git a/docs/quickstart.md b/docs/quickstart.md index 554a37837..b8afe5578 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -263,7 +263,7 @@ vendored library will work in your environment. Then build the standalone bazel target: ``` -tcmalloc$ bazel build tcmalloc:tcmalloc_standalone --experimental_cc_static_library +tcmalloc$ bazel build tcmalloc:tcmalloc_standalone ``` Once this builds you can copy the resulting static library from From 2c4f69ba0014913f5e2a34c1f35251b03fb327c6 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Tue, 17 Jun 2025 21:13:12 -0700 Subject: [PATCH 4/4] Always run standalone tests --- tcmalloc/testing/BUILD | 2 -- 1 file changed, 2 deletions(-) diff --git a/tcmalloc/testing/BUILD b/tcmalloc/testing/BUILD index f5cf5b4df..9963f1265 100644 --- a/tcmalloc/testing/BUILD +++ b/tcmalloc/testing/BUILD @@ -1057,7 +1057,6 @@ cc_test( cc_import( name = "standalone_import", static_library = "//tcmalloc:tcmalloc_standalone", - tags = ["manual"], # TODO: Remove once cc_static_library is always enabled alwayslink = True, ) @@ -1065,7 +1064,6 @@ cc_test( name = "standalone_test", srcs = ["standalone_test.cc"], tags = [ - "manual", # TODO: Remove once cc_static_library is always enabled "noasan", "nomsan", "notsan",