summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Abseil Team <absl-team@google.com>2021-03-17 20:08:11 -0700
committerGravatar Dino Radaković <dinor@google.com>2021-03-18 08:44:23 -0700
commitdcf4899377ca63246efb17f5468c40913855777c (patch)
tree65a6ae9798857f7197b650448a31824175c74ad0
parent2e9532cc6c701a8323d0cffb468999ab804095ab (diff)
Export of internal Abseil changes
-- 8e75347c10d85112296811be6ef35761744ad9bc by Derek Mauro <dmauro@google.com>: Big update to LTS release process * Add create_lts.py script to to the LTS modification This is simpler than copybara since very few changes are needed * Use the default installation paths instead of a versioned path. If a versioned path is needed, this is easy to change on the commandline. * Make the integration test use the LTS transformed version * Test both static and dynamic linking (fixes pkg-config dynamic linking) PiperOrigin-RevId: 363566934 -- e00e971a2de3138861f5e1900201c9cc7788f714 by Laramie Leavitt <lar@google.com>: Add a non-compile test to absl::BitGenRef for temporaries. PiperOrigin-RevId: 363437284 -- 3685644ec115d99789de32aceb76c32a00756fea by Derek Mauro <dmauro@google.com>: Make OSS code consistent with internal code by using the forward declaration of absl::Status that contains ABSL_MUST_USE_RESULT. PiperOrigin-RevId: 363426906 -- b85fec142c3aa3f632fa985f9f8f73a253819723 by Evan Brown <ezb@google.com>: Move raw_hash_set::infoz_ into raw_hash_set::settings_. This reduces the size of raw_hash_sets by alignof(size_t) bytes when hashtablez is disabled. PiperOrigin-RevId: 363034264 -- c6fde3b17e5845191eb8b2bfc1760c8bfb9573ff by Mark Barolak <mbar@google.com>: Internal change PiperOrigin-RevId: 362990378 -- 81713cf964905b43d1cbe32ce5fed97539029625 by Abseil Team <absl-team@google.com>: Fix typo in comment (execeptions -> exceptions). PiperOrigin-RevId: 362946191 -- 3ee92ca470feca44da417b03ee45a915c6eb5155 by Abseil Team <absl-team@google.com>: Add absl::FindAndReportLeaks and routes it to the corresponding __lsan_do_recoverable_leak_check. PiperOrigin-RevId: 362622199 -- b95b7194b20e02c20d72289fbc79a0d35b82e256 by Abseil Team <absl-team@google.com>: Add `kWithEverything` to StatusToStringMode PiperOrigin-RevId: 362595218 -- 0a960d96a0014eab7e1c55b479269450ed8e98d7 by Abseil Team <absl-team@google.com>: Accept e.g. ".__uniq" as a valid clone name. Further, bring the implementation on par with libiberty's demangler grammar. Clang introduced option -funique-internal-linkage-names that adds the suffix ".__uniq.[0-9]+" to internal linkage functions to give them a globally unique identifier. The suffix was designed to work with existing demanglers which do recognize a "_" along with the alphanumeric string. This change enhances the demangler to allow "_" with the alphanumeric string. Please refer to libiberty's cp-demangle.c where function d_clone_suffix implements the demangling of clone suffixes : 1. '_' is accepted as a valid character with the alphanumeric sequence. 2. The alphanumberic sequence is optional. 3. The digit sequence is optional. PiperOrigin-RevId: 362557420 -- 2ac5ea212c150afd2f58025a5cab8c45d16949c6 by Abseil Team <absl-team@google.com>: Change variable name 'slots' to 'slot_count' to avoid name-clash with Qt builds. PiperOrigin-RevId: 362556289 -- 934f0f409c9c548716a46363d6e243406fad4028 by Mark Barolak <mbar@google.com>: Clarify the comment on ABSL_CACHELINE_SIZE to indicate that the macro definition itself shouldn't change, but rather that call sites should change when possible. This addresses the request for improved documentation in https://github.com/abseil/abseil-cpp/pull/842. PiperOrigin-RevId: 362354288 GitOrigin-RevId: 8e75347c10d85112296811be6ef35761744ad9bc Change-Id: I33ec8561d8d645c3353e9d2dd447501d0e1825a7
-rw-r--r--CMake/AbseilDll.cmake9
-rw-r--r--CMake/AbseilHelpers.cmake22
-rw-r--r--CMake/AbseilInstallDirs.cmake20
-rwxr-xr-xCMake/install_test_project/test.sh138
-rw-r--r--CMakeLists.txt14
-rw-r--r--absl/base/optimization.h5
-rw-r--r--absl/container/internal/btree.h8
-rw-r--r--absl/container/internal/raw_hash_set.h57
-rw-r--r--absl/container/internal/raw_hash_set_test.cc39
-rw-r--r--absl/debugging/internal/demangle.cc28
-rw-r--r--absl/debugging/internal/demangle_test.cc30
-rw-r--r--absl/debugging/leak_check.cc1
-rw-r--r--absl/debugging/leak_check.h13
-rw-r--r--absl/status/internal/status_internal.h11
-rw-r--r--absl/status/status.h9
-rw-r--r--absl/status/status_test.cc4
-rw-r--r--absl/status/statusor.h2
-rw-r--r--absl/strings/numbers.h1
-rwxr-xr-xci/cmake_install_test.sh18
-rwxr-xr-xcreate_lts.py121
20 files changed, 339 insertions, 211 deletions
diff --git a/CMake/AbseilDll.cmake b/CMake/AbseilDll.cmake
index 39f85f2f..253c73ff 100644
--- a/CMake/AbseilDll.cmake
+++ b/CMake/AbseilDll.cmake
@@ -1,4 +1,5 @@
include(CMakeParseArguments)
+include(GNUInstallDirs)
set(ABSL_INTERNAL_DLL_FILES
"algorithm/algorithm.h"
@@ -500,7 +501,7 @@ function(absl_make_dll)
abseil_dll
PUBLIC
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
- $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_compile_options(
@@ -518,8 +519,8 @@ function(absl_make_dll)
${ABSL_CC_LIB_DEFINES}
)
install(TARGETS abseil_dll EXPORT ${PROJECT_NAME}Targets
- RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR}
- LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endfunction()
diff --git a/CMake/AbseilHelpers.cmake b/CMake/AbseilHelpers.cmake
index 1541435d..4f6394ab 100644
--- a/CMake/AbseilHelpers.cmake
+++ b/CMake/AbseilHelpers.cmake
@@ -17,7 +17,6 @@
include(CMakeParseArguments)
include(AbseilConfigureCopts)
include(AbseilDll)
-include(AbseilInstallDirs)
# The IDE folder for Abseil that will be used if Abseil is included in a CMake
# project that sets
@@ -151,6 +150,10 @@ function(absl_cc_library)
endif()
foreach(dep ${ABSL_CC_LIB_DEPS})
if(${dep} MATCHES "^absl::(.*)")
+ # Join deps with commas.
+ if(PC_DEPS)
+ set(PC_DEPS "${PC_DEPS},")
+ endif()
set(PC_DEPS "${PC_DEPS} absl_${CMAKE_MATCH_1} = ${PC_VERSION}")
endif()
endforeach()
@@ -167,14 +170,14 @@ function(absl_cc_library)
FILE(GENERATE OUTPUT "${CMAKE_BINARY_DIR}/lib/pkgconfig/absl_${_NAME}.pc" CONTENT "\
prefix=${CMAKE_INSTALL_PREFIX}\n\
exec_prefix=\${prefix}\n\
-libdir=\${prefix}/lib\n\
-includedir=\${prefix}/include\n\
+libdir=\${prefix}/${CMAKE_INSTALL_LIBDIR}\n\
+includedir=\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}\n\
\n\
Name: absl_${_NAME}\n\
Description: Abseil ${_NAME} library\n\
URL: https://abseil.io/\n\
Version: ${PC_VERSION}\n\
-Requires.private:${PC_DEPS}\n\
+Requires:${PC_DEPS}\n\
Libs: -L\${libdir} $<JOIN:${ABSL_CC_LIB_LINKOPTS}, > $<$<NOT:$<BOOL:${ABSL_CC_LIB_IS_INTERFACE}>>:-labsl_${_NAME}>\n\
Cflags: -I\${includedir}${PC_CFLAGS}\n")
INSTALL(FILES "${CMAKE_BINARY_DIR}/lib/pkgconfig/absl_${_NAME}.pc"
@@ -235,7 +238,7 @@ Cflags: -I\${includedir}${PC_CFLAGS}\n")
target_include_directories(${_NAME}
PUBLIC
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
- $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_compile_options(${_NAME}
PRIVATE ${ABSL_CC_LIB_COPTS})
@@ -260,7 +263,6 @@ Cflags: -I\${includedir}${PC_CFLAGS}\n")
if(ABSL_ENABLE_INSTALL)
set_target_properties(${_NAME} PROPERTIES
OUTPUT_NAME "absl_${_NAME}"
- # TODO(b/173696973): Figure out how to set SOVERSION for LTS releases.
SOVERSION 0
)
endif()
@@ -270,7 +272,7 @@ Cflags: -I\${includedir}${PC_CFLAGS}\n")
target_include_directories(${_NAME}
INTERFACE
"$<BUILD_INTERFACE:${ABSL_COMMON_INCLUDE_DIRS}>"
- $<INSTALL_INTERFACE:${ABSL_INSTALL_INCLUDEDIR}>
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
if (_build_type STREQUAL "dll")
@@ -290,9 +292,9 @@ Cflags: -I\${includedir}${PC_CFLAGS}\n")
# installed abseil can't be tested.
if(NOT ABSL_CC_LIB_TESTONLY AND ABSL_ENABLE_INSTALL)
install(TARGETS ${_NAME} EXPORT ${PROJECT_NAME}Targets
- RUNTIME DESTINATION ${ABSL_INSTALL_BINDIR}
- LIBRARY DESTINATION ${ABSL_INSTALL_LIBDIR}
- ARCHIVE DESTINATION ${ABSL_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endif()
diff --git a/CMake/AbseilInstallDirs.cmake b/CMake/AbseilInstallDirs.cmake
deleted file mode 100644
index 6fc914b6..00000000
--- a/CMake/AbseilInstallDirs.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-include(GNUInstallDirs)
-
-# absl_VERSION is only set if we are an LTS release being installed, in which
-# case it may be into a system directory and so we need to make subdirectories
-# for each installed version of Abseil. This mechanism is implemented in
-# Abseil's internal Copybara (https://github.com/google/copybara) workflows and
-# isn't visible in the CMake buildsystem itself.
-
-if(absl_VERSION)
- set(ABSL_SUBDIR "${PROJECT_NAME}_${PROJECT_VERSION}")
- set(ABSL_INSTALL_BINDIR "${CMAKE_INSTALL_BINDIR}/${ABSL_SUBDIR}")
- set(ABSL_INSTALL_CONFIGDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${ABSL_SUBDIR}")
- set(ABSL_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/${ABSL_SUBDIR}")
- set(ABSL_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/${ABSL_SUBDIR}")
-else()
- set(ABSL_INSTALL_BINDIR "${CMAKE_INSTALL_BINDIR}")
- set(ABSL_INSTALL_CONFIGDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}")
- set(ABSL_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}")
- set(ABSL_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
-endif()
diff --git a/CMake/install_test_project/test.sh b/CMake/install_test_project/test.sh
index ddc7726b..a3d39773 100755
--- a/CMake/install_test_project/test.sh
+++ b/CMake/install_test_project/test.sh
@@ -13,70 +13,44 @@
# 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.
-
-# "Unit" and integration tests for Absl CMake installation
-
-# TODO(absl-team): This script isn't fully hermetic because
-# -DABSL_USE_GOOGLETEST_HEAD=ON means that this script isn't pinned to a fixed
-# version of GoogleTest. This means that an upstream change to GoogleTest could
-# break this test. Fix this by allowing this script to pin to a known-good
-# version of GoogleTest.
+#
+# Unit and integration tests for Abseil LTS CMake installation
# Fail on any error. Treat unset variables an error. Print commands as executed.
set -euox pipefail
-install_absl() {
- pushd "${absl_build_dir}"
- if [[ "${#}" -eq 1 ]]; then
- cmake -DCMAKE_INSTALL_PREFIX="${1}" "${absl_dir}"
- else
- cmake "${absl_dir}"
- fi
- cmake --build . --target install -- -j
- popd
-}
-
-uninstall_absl() {
- xargs rm < "${absl_build_dir}"/install_manifest.txt
- rm -rf "${absl_build_dir}"
- mkdir -p "${absl_build_dir}"
-}
-
-lts_install=""
-
-while getopts ":l" lts; do
- case "${lts}" in
- l )
- lts_install="true"
- ;;
- esac
-done
+source ci/cmake_common.sh
absl_dir=/abseil-cpp
-absl_build_dir=/buildfs/absl-build
+absl_build_dir=/buildfs
project_dir="${absl_dir}"/CMake/install_test_project
project_build_dir=/buildfs/project-build
-mkdir -p "${absl_build_dir}"
-mkdir -p "${project_build_dir}"
-
-if [[ "${lts_install}" ]]; then
- install_dir="/usr/local"
-else
- install_dir="${project_build_dir}"/install
+build_shared_libs="OFF"
+if [ "${LINK_TYPE:-}" = "DYNAMIC" ]; then
+ build_shared_libs="ON"
fi
-mkdir -p "${install_dir}"
-# Test build, install, and link against installed abseil
-pushd "${project_build_dir}"
-if [[ "${lts_install}" ]]; then
- install_absl
- cmake "${project_dir}"
-else
- install_absl "${install_dir}"
- cmake "${project_dir}" -DCMAKE_PREFIX_PATH="${install_dir}"
-fi
+# Run the LTS transformations
+./create_lts.py 99998877
+
+# Install Abseil
+pushd "${absl_build_dir}"
+cmake "${absl_dir}" \
+ -DABSL_GOOGLETEST_DOWNLOAD_URL="${ABSL_GOOGLETEST_DOWNLOAD_URL}" \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DBUILD_TESTING=ON \
+ -DBUILD_SHARED_LIBS="${build_shared_libs}"
+make -j $(nproc)
+ctest -j $(nproc)
+make install
+ldconfig
+popd
+# Test the project against the installed Abseil
+mkdir -p "${project_build_dir}"
+pushd "${project_build_dir}"
+cmake "${project_dir}"
cmake --build . --target simple
output="$(${project_build_dir}/simple "printme" 2>&1)"
@@ -88,32 +62,8 @@ fi
popd
-# Test that we haven't accidentally made absl::abslblah
-pushd "${install_dir}"
-
-# Starting in CMake 3.12 the default install dir is lib$bit_width
-if [[ -d lib64 ]]; then
- libdir="lib64"
-elif [[ -d lib ]]; then
- libdir="lib"
-else
- echo "ls *, */*, */*/*:"
- ls *
- ls */*
- ls */*/*
- echo "unknown lib dir"
-fi
-
-if [[ "${lts_install}" ]]; then
- # LTS versions append the date of the release to the subdir.
- # 9999/99/99 is the dummy date used in the local_lts workflow.
- absl_subdir="absl_99999999"
-else
- absl_subdir="absl"
-fi
-
-if ! grep absl::strings "${libdir}/cmake/${absl_subdir}/abslTargets.cmake"; then
- cat "${libdir}"/cmake/absl/abslTargets.cmake
+if ! grep absl::strings "/usr/local/lib/cmake/absl/abslTargets.cmake"; then
+ cat "/usr/local/lib/cmake/absl/abslTargets.cmake"
echo "CMake targets named incorrectly"
exit 1
fi
@@ -129,34 +79,18 @@ int main(int argc, char **argv) {
return EXIT_SUCCESS;
}
EOF
-export PKG_CONFIG_PATH="${install_dir}/${libdir}/pkgconfig"
-pc_args=($(pkg-config --cflags --libs --static absl_str_format))
-g++ -static -o hello-abseil hello-abseil.cc "${pc_args[@]}"
+
+if [ "${LINK_TYPE:-}" != "DYNAMIC" ]; then
+ pc_args=($(pkg-config --cflags --libs --static absl_str_format))
+ g++ -static -o hello-abseil hello-abseil.cc "${pc_args[@]}"
+else
+ pc_args=($(pkg-config --cflags --libs absl_str_format))
+ g++ -o hello-abseil hello-abseil.cc "${pc_args[@]}"
+fi
hello="$(./hello-abseil)"
[[ "${hello}" == "Hello Abseil!" ]]
-popd
-uninstall_absl
popd
-if [[ ! "${lts_install}" ]]; then
- # Test that we warn if installed without a prefix or a system prefix
- output="$(install_absl 2>&1)"
- if [[ "${output}" != *"Please set CMAKE_INSTALL_PREFIX"* ]]; then
- echo "Install without prefix didn't warn as expected. Output:"
- echo "${output}"
- exit 1
- fi
- uninstall_absl
-
- output="$(install_absl /usr 2>&1)"
- if [[ "${output}" != *"Please set CMAKE_INSTALL_PREFIX"* ]]; then
- echo "Install with /usr didn't warn as expected. Output:"
- echo "${output}"
- exit 1
- fi
- uninstall_absl
-fi
-
echo "Install test complete!"
exit 0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8843ee79..e09e335c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -45,7 +45,7 @@ endif (POLICY CMP0077)
# This must come before the project() and include(CTest) lines.
OPTION(BUILD_TESTING "Build tests" OFF)
-project(absl CXX)
+project(absl LANGUAGES CXX)
include(CTest)
# Output directory is correct by default for most build setups. However, when
@@ -67,8 +67,8 @@ list(APPEND CMAKE_MODULE_PATH
${CMAKE_CURRENT_LIST_DIR}/absl/copts
)
-include(AbseilInstallDirs)
include(CMakePackageConfigHelpers)
+include(GNUInstallDirs)
include(AbseilDll)
include(AbseilHelpers)
@@ -159,16 +159,16 @@ if(ABSL_ENABLE_INSTALL)
# install as a subdirectory only
install(EXPORT ${PROJECT_NAME}Targets
NAMESPACE absl::
- DESTINATION "${ABSL_INSTALL_CONFIGDIR}"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
configure_package_config_file(
CMake/abslConfig.cmake.in
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
- INSTALL_DESTINATION "${ABSL_INSTALL_CONFIGDIR}"
+ INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
- DESTINATION "${ABSL_INSTALL_CONFIGDIR}"
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
# Abseil only has a version in LTS releases. This mechanism is accomplished
@@ -181,12 +181,12 @@ if(ABSL_ENABLE_INSTALL)
)
install(FILES "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
- DESTINATION ${ABSL_INSTALL_CONFIGDIR}
+ DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
endif() # absl_VERSION
install(DIRECTORY absl
- DESTINATION ${ABSL_INSTALL_INCLUDEDIR}
+ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING
PATTERN "*.inc"
PATTERN "*.h"
diff --git a/absl/base/optimization.h b/absl/base/optimization.h
index 6332b625..d090be12 100644
--- a/absl/base/optimization.h
+++ b/absl/base/optimization.h
@@ -106,9 +106,10 @@
// Cacheline aligning objects properly allows constructive memory sharing and
// prevents destructive (or "false") memory sharing.
//
-// NOTE: this macro should be replaced with usage of `alignas()` using
+// NOTE: callers should replace uses of this macro with `alignas()` using
// `std::hardware_constructive_interference_size` and/or
-// `std::hardware_destructive_interference_size` when available within C++17.
+// `std::hardware_destructive_interference_size` when C++17 becomes available to
+// them.
//
// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html
// for more information.
diff --git a/absl/container/internal/btree.h b/absl/container/internal/btree.h
index 00444a53..0bb38366 100644
--- a/absl/container/internal/btree.h
+++ b/absl/container/internal/btree.h
@@ -579,10 +579,10 @@ class btree_node {
};
// Leaves can have less than kNodeSlots values.
- constexpr static layout_type LeafLayout(const int slots = kNodeSlots) {
+ constexpr static layout_type LeafLayout(const int slot_count = kNodeSlots) {
return layout_type(/*parent*/ 1,
/*position, start, finish, max_count*/ 4,
- /*slots*/ slots,
+ /*slots*/ slot_count,
/*children*/ 0);
}
constexpr static layout_type InternalLayout() {
@@ -591,8 +591,8 @@ class btree_node {
/*slots*/ kNodeSlots,
/*children*/ kNodeSlots + 1);
}
- constexpr static size_type LeafSize(const int slots = kNodeSlots) {
- return LeafLayout(slots).AllocSize();
+ constexpr static size_type LeafSize(const int slot_count = kNodeSlots) {
+ return LeafLayout(slot_count).AllocSize();
}
constexpr static size_type InternalSize() {
return InternalLayout().AllocSize();
diff --git a/absl/container/internal/raw_hash_set.h b/absl/container/internal/raw_hash_set.h
index 80fc2cba..8615de8b 100644
--- a/absl/container/internal/raw_hash_set.h
+++ b/absl/container/internal/raw_hash_set.h
@@ -792,7 +792,8 @@ class raw_hash_set {
explicit raw_hash_set(size_t bucket_count, const hasher& hash = hasher(),
const key_equal& eq = key_equal(),
const allocator_type& alloc = allocator_type())
- : ctrl_(EmptyGroup()), settings_(0, hash, eq, alloc) {
+ : ctrl_(EmptyGroup()),
+ settings_(0, HashtablezInfoHandle(), hash, eq, alloc) {
if (bucket_count) {
capacity_ = NormalizeCapacity(bucket_count);
initialize_slots();
@@ -903,7 +904,7 @@ class raw_hash_set {
auto target = find_first_non_full(ctrl_, hash, capacity_);
set_ctrl(target.offset, H2(hash));
emplace_at(target.offset, v);
- infoz_.RecordInsert(hash, target.probe_length);
+ infoz().RecordInsert(hash, target.probe_length);
}
size_ = that.size();
growth_left() -= that.size();
@@ -917,28 +918,27 @@ class raw_hash_set {
slots_(absl::exchange(that.slots_, nullptr)),
size_(absl::exchange(that.size_, 0)),
capacity_(absl::exchange(that.capacity_, 0)),
- infoz_(absl::exchange(that.infoz_, HashtablezInfoHandle())),
// Hash, equality and allocator are copied instead of moved because
// `that` must be left valid. If Hash is std::function<Key>, moving it
// would create a nullptr functor that cannot be called.
- settings_(that.settings_) {
- // growth_left was copied above, reset the one from `that`.
- that.growth_left() = 0;
- }
+ settings_(absl::exchange(that.growth_left(), 0),
+ absl::exchange(that.infoz(), HashtablezInfoHandle()),
+ that.hash_ref(), that.eq_ref(), that.alloc_ref()) {}
raw_hash_set(raw_hash_set&& that, const allocator_type& a)
: ctrl_(EmptyGroup()),
slots_(nullptr),
size_(0),
capacity_(0),
- settings_(0, that.hash_ref(), that.eq_ref(), a) {
+ settings_(0, HashtablezInfoHandle(), that.hash_ref(), that.eq_ref(),
+ a) {
if (a == that.alloc_ref()) {
std::swap(ctrl_, that.ctrl_);
std::swap(slots_, that.slots_);
std::swap(size_, that.size_);
std::swap(capacity_, that.capacity_);
std::swap(growth_left(), that.growth_left());
- std::swap(infoz_, that.infoz_);
+ std::swap(infoz(), that.infoz());
} else {
reserve(that.size());
// Note: this will copy elements of dense_set and unordered_set instead of
@@ -1009,7 +1009,7 @@ class raw_hash_set {
reset_growth_left();
}
assert(empty());
- infoz_.RecordStorageChanged(0, capacity_);
+ infoz().RecordStorageChanged(0, capacity_);
}
// This overload kicks in when the argument is an rvalue of insertable and
@@ -1301,7 +1301,7 @@ class raw_hash_set {
swap(growth_left(), that.growth_left());
swap(hash_ref(), that.hash_ref());
swap(eq_ref(), that.eq_ref());
- swap(infoz_, that.infoz_);
+ swap(infoz(), that.infoz());
SwapAlloc(alloc_ref(), that.alloc_ref(),
typename AllocTraits::propagate_on_container_swap{});
}
@@ -1310,7 +1310,7 @@ class raw_hash_set {
if (n == 0 && capacity_ == 0) return;
if (n == 0 && size_ == 0) {
destroy_slots();
- infoz_.RecordStorageChanged(0, 0);
+ infoz().RecordStorageChanged(0, 0);
return;
}
// bitor is a faster way of doing `max` here. We will round up to the next
@@ -1528,7 +1528,7 @@ class raw_hash_set {
set_ctrl(index, was_never_full ? kEmpty : kDeleted);
growth_left() += was_never_full;
- infoz_.RecordErase();
+ infoz().RecordErase();
}
void initialize_slots() {
@@ -1545,7 +1545,7 @@ class raw_hash_set {
// bound more carefully.
if (std::is_same<SlotAlloc, std::allocator<slot_type>>::value &&
slots_ == nullptr) {
- infoz_ = Sample();
+ infoz() = Sample();
}
auto layout = MakeLayout(capacity_);
@@ -1555,7 +1555,7 @@ class raw_hash_set {
slots_ = layout.template Pointer<1>(mem);
reset_ctrl();
reset_growth_left();
- infoz_.RecordStorageChanged(size_, capacity_);
+ infoz().RecordStorageChanged(size_, capacity_);
}
void destroy_slots() {
@@ -1603,7 +1603,7 @@ class raw_hash_set {
Deallocate<Layout::Alignment()>(&alloc_ref(), old_ctrl,
layout.AllocSize());
}
- infoz_.RecordRehash(total_probe_length);
+ infoz().RecordRehash(total_probe_length);
}
void drop_deletes_without_resize() ABSL_ATTRIBUTE_NOINLINE {
@@ -1669,7 +1669,7 @@ class raw_hash_set {
}
}
reset_growth_left();
- infoz_.RecordRehash(total_probe_length);
+ infoz().RecordRehash(total_probe_length);
}
void rehash_and_grow_if_necessary() {
@@ -1743,7 +1743,7 @@ class raw_hash_set {
++size_;
growth_left() -= IsEmpty(ctrl_[target.offset]);
set_ctrl(target.offset, H2(hash));
- infoz_.RecordInsert(hash, target.probe_length);
+ infoz().RecordInsert(hash, target.probe_length);
return target.offset;
}
@@ -1800,13 +1800,15 @@ class raw_hash_set {
size_t& growth_left() { return settings_.template get<0>(); }
- hasher& hash_ref() { return settings_.template get<1>(); }
- const hasher& hash_ref() const { return settings_.template get<1>(); }
- key_equal& eq_ref() { return settings_.template get<2>(); }
- const key_equal& eq_ref() const { return settings_.template get<2>(); }
- allocator_type& alloc_ref() { return settings_.template get<3>(); }
+ HashtablezInfoHandle& infoz() { return settings_.template get<1>(); }
+
+ hasher& hash_ref() { return settings_.template get<2>(); }
+ const hasher& hash_ref() const { return settings_.template get<2>(); }
+ key_equal& eq_ref() { return settings_.template get<3>(); }
+ const key_equal& eq_ref() const { return settings_.template get<3>(); }
+ allocator_type& alloc_ref() { return settings_.template get<4>(); }
const allocator_type& alloc_ref() const {
- return settings_.template get<3>();
+ return settings_.template get<4>();
}
// TODO(alkis): Investigate removing some of these fields:
@@ -1816,10 +1818,11 @@ class raw_hash_set {
slot_type* slots_ = nullptr; // [capacity * slot_type]
size_t size_ = 0; // number of full slots
size_t capacity_ = 0; // total number of slots
- HashtablezInfoHandle infoz_;
- absl::container_internal::CompressedTuple<size_t /* growth_left */, hasher,
+ absl::container_internal::CompressedTuple<size_t /* growth_left */,
+ HashtablezInfoHandle, hasher,
key_equal, allocator_type>
- settings_{0, hasher{}, key_equal{}, allocator_type{}};
+ settings_{0, HashtablezInfoHandle{}, hasher{}, key_equal{},
+ allocator_type{}};
};
// Erases all elements that satisfy the predicate `pred` from the container `c`.
diff --git a/absl/container/internal/raw_hash_set_test.cc b/absl/container/internal/raw_hash_set_test.cc
index 81c4b47c..7dac65a0 100644
--- a/absl/container/internal/raw_hash_set_test.cc
+++ b/absl/container/internal/raw_hash_set_test.cc
@@ -419,6 +419,13 @@ TEST(Table, EmptyFunctorOptimization) {
size_t growth_left;
void* infoz;
};
+ struct MockTableInfozDisabled {
+ void* ctrl;
+ void* slots;
+ size_t size;
+ size_t capacity;
+ size_t growth_left;
+ };
struct StatelessHash {
size_t operator()(absl::string_view) const { return 0; }
};
@@ -426,17 +433,27 @@ TEST(Table, EmptyFunctorOptimization) {
size_t dummy;
};
- EXPECT_EQ(
- sizeof(MockTable),
- sizeof(
- raw_hash_set<StringPolicy, StatelessHash,
- std::equal_to<absl::string_view>, std::allocator<int>>));
-
- EXPECT_EQ(
- sizeof(MockTable) + sizeof(StatefulHash),
- sizeof(
- raw_hash_set<StringPolicy, StatefulHash,
- std::equal_to<absl::string_view>, std::allocator<int>>));
+ if (std::is_empty<HashtablezInfoHandle>::value) {
+ EXPECT_EQ(sizeof(MockTableInfozDisabled),
+ sizeof(raw_hash_set<StringPolicy, StatelessHash,
+ std::equal_to<absl::string_view>,
+ std::allocator<int>>));
+
+ EXPECT_EQ(sizeof(MockTableInfozDisabled) + sizeof(StatefulHash),
+ sizeof(raw_hash_set<StringPolicy, StatefulHash,
+ std::equal_to<absl::string_view>,
+ std::allocator<int>>));
+ } else {
+ EXPECT_EQ(sizeof(MockTable),
+ sizeof(raw_hash_set<StringPolicy, StatelessHash,
+ std::equal_to<absl::string_view>,
+ std::allocator<int>>));
+
+ EXPECT_EQ(sizeof(MockTable) + sizeof(StatefulHash),
+ sizeof(raw_hash_set<StringPolicy, StatefulHash,
+ std::equal_to<absl::string_view>,
+ std::allocator<int>>));
+ }
}
TEST(Table, Empty) {
diff --git a/absl/debugging/internal/demangle.cc b/absl/debugging/internal/demangle.cc
index 46cdb67b..5cd56320 100644
--- a/absl/debugging/internal/demangle.cc
+++ b/absl/debugging/internal/demangle.cc
@@ -386,24 +386,28 @@ static bool IsDigit(char c) { return c >= '0' && c <= '9'; }
// by GCC 4.5.x and later versions (and our locally-modified version of GCC
// 4.4.x) to indicate functions which have been cloned during optimization.
// We treat any sequence (.<alpha>+.<digit>+)+ as a function clone suffix.
+// Additionally, '_' is allowed along with the alphanumeric sequence.
static bool IsFunctionCloneSuffix(const char *str) {
size_t i = 0;
while (str[i] != '\0') {
- // Consume a single .<alpha>+.<digit>+ sequence.
- if (str[i] != '.' || !IsAlpha(str[i + 1])) {
- return false;
+ bool parsed = false;
+ // Consume a single [.<alpha> | _]*[.<digit>]* sequence.
+ if (str[i] == '.' && (IsAlpha(str[i + 1]) || str[i + 1] == '_')) {
+ parsed = true;
+ i += 2;
+ while (IsAlpha(str[i]) || str[i] == '_') {
+ ++i;
+ }
}
- i += 2;
- while (IsAlpha(str[i])) {
- ++i;
+ if (str[i] == '.' && IsDigit(str[i + 1])) {
+ parsed = true;
+ i += 2;
+ while (IsDigit(str[i])) {
+ ++i;
+ }
}
- if (str[i] != '.' || !IsDigit(str[i + 1])) {
+ if (!parsed)
return false;
- }
- i += 2;
- while (IsDigit(str[i])) {
- ++i;
- }
}
return true; // Consumed everything in "str".
}
diff --git a/absl/debugging/internal/demangle_test.cc b/absl/debugging/internal/demangle_test.cc
index 0bed7359..6b142902 100644
--- a/absl/debugging/internal/demangle_test.cc
+++ b/absl/debugging/internal/demangle_test.cc
@@ -70,12 +70,34 @@ TEST(Demangle, Clones) {
EXPECT_STREQ("Foo()", tmp);
EXPECT_TRUE(Demangle("_ZL3Foov.isra.2.constprop.18", tmp, sizeof(tmp)));
EXPECT_STREQ("Foo()", tmp);
- // Invalid (truncated), should not demangle.
- EXPECT_FALSE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp)));
+ // Demangle suffixes produced by -funique-internal-linkage-names.
+ EXPECT_TRUE(Demangle("_ZL3Foov.__uniq.12345", tmp, sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ EXPECT_TRUE(Demangle("_ZL3Foov.__uniq.12345.isra.2.constprop.18", tmp,
+ sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ // Suffixes without the number should also demangle.
+ EXPECT_TRUE(Demangle("_ZL3Foov.clo", tmp, sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ // Suffixes with just the number should also demangle.
+ EXPECT_TRUE(Demangle("_ZL3Foov.123", tmp, sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ // (.clone. followed by non-number), should also demangle.
+ EXPECT_TRUE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ // (.clone. followed by multiple numbers), should also demangle.
+ EXPECT_TRUE(Demangle("_ZL3Foov.clone.123.456", tmp, sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ // (a long valid suffix), should demangle.
+ EXPECT_TRUE(Demangle("_ZL3Foov.part.9.165493.constprop.775.31805", tmp,
+ sizeof(tmp)));
+ EXPECT_STREQ("Foo()", tmp);
+ // Invalid (. without anything else), should not demangle.
+ EXPECT_FALSE(Demangle("_ZL3Foov.", tmp, sizeof(tmp)));
+ // Invalid (. with mix of alpha and digits), should not demangle.
+ EXPECT_FALSE(Demangle("_ZL3Foov.abc123", tmp, sizeof(tmp)));
// Invalid (.clone. not followed by number), should not demangle.
EXPECT_FALSE(Demangle("_ZL3Foov.clone.", tmp, sizeof(tmp)));
- // Invalid (.clone. followed by non-number), should not demangle.
- EXPECT_FALSE(Demangle("_ZL3Foov.clone.foo", tmp, sizeof(tmp)));
// Invalid (.constprop. not followed by number), should not demangle.
EXPECT_FALSE(Demangle("_ZL3Foov.isra.2.constprop.", tmp, sizeof(tmp)));
}
diff --git a/absl/debugging/leak_check.cc b/absl/debugging/leak_check.cc
index ff904955..db9d5d09 100644
--- a/absl/debugging/leak_check.cc
+++ b/absl/debugging/leak_check.cc
@@ -38,6 +38,7 @@ ABSL_NAMESPACE_END
namespace absl {
ABSL_NAMESPACE_BEGIN
bool HaveLeakSanitizer() { return true; }
+bool FindAndReportLeaks() { return __lsan_do_recoverable_leak_check(); }
void DoIgnoreLeak(const void* ptr) { __lsan_ignore_object(ptr); }
void RegisterLivePointers(const void* ptr, size_t size) {
__lsan_register_root_region(ptr, size);
diff --git a/absl/debugging/leak_check.h b/absl/debugging/leak_check.h
index b66a81c3..61c3216f 100644
--- a/absl/debugging/leak_check.h
+++ b/absl/debugging/leak_check.h
@@ -71,6 +71,19 @@ T* IgnoreLeak(T* ptr) {
return ptr;
}
+// FindAndReportLeaks()
+//
+// If any leaks are detected, prints a leak report and returns true. This
+// function may be called repeatedly, and does not affect end-of-process leak
+// checking.
+//
+// Example:
+// if (FindAndReportLeaks()) {
+// ... diagnostic already printed. Exit with failure code.
+// exit(1)
+// }
+bool FindAndReportLeaks();
+
// LeakCheckDisabler
//
// This helper class indicates that any heap allocations done in the code block
diff --git a/absl/status/internal/status_internal.h b/absl/status/internal/status_internal.h
index 279f8f55..99a2d964 100644
--- a/absl/status/internal/status_internal.h
+++ b/absl/status/internal/status_internal.h
@@ -19,6 +19,17 @@
#include "absl/container/inlined_vector.h"
#include "absl/strings/cord.h"
+#ifndef SWIG
+// Disabled for SWIG as it doesn't parse attributes correctly.
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+// Returned Status objects may not be ignored. Codesearch doesn't handle ifdefs
+// as part of a class definitions (b/6995610), so we use a forward declaration.
+class ABSL_MUST_USE_RESULT Status;
+ABSL_NAMESPACE_END
+} // namespace absl
+#endif // !SWIG
+
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/absl/status/status.h b/absl/status/status.h
index df9e330c..61486fee 100644
--- a/absl/status/status.h
+++ b/absl/status/status.h
@@ -291,6 +291,8 @@ enum class StatusToStringMode : int {
kWithNoExtraData = 0,
// ToString will contain the payloads.
kWithPayload = 1 << 0,
+ // ToString will include all the extra data this Status has.
+ kWithEverything = ~kWithNoExtraData,
};
// absl::StatusToStringMode is specified as a bitmask type, which means the
@@ -410,7 +412,12 @@ inline StatusToStringMode& operator^=(StatusToStringMode& lhs,
// return result;
// }
//
-class ABSL_MUST_USE_RESULT Status final {
+// For documentation see https://abseil.io/docs/cpp/guides/status.
+//
+// Returned Status objects may not be ignored. status_internal.h has a forward
+// declaration of the form
+// class ABSL_MUST_USE_RESULT Status;
+class Status final {
public:
// Constructors
diff --git a/absl/status/status_test.cc b/absl/status/status_test.cc
index 7116ba67..0e1a43ce 100644
--- a/absl/status/status_test.cc
+++ b/absl/status/status_test.cc
@@ -292,6 +292,10 @@ TEST(Status, ToStringMode) {
AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
HasSubstr("[bar='\\xff']")));
+ EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithEverything),
+ AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
+ HasSubstr("[bar='\\xff']")));
+
EXPECT_THAT(s.ToString(~absl::StatusToStringMode::kWithPayload),
AllOf(HasSubstr("INTERNAL: fail"), Not(HasSubstr("[foo='bar']")),
Not(HasSubstr("[bar='\\xff']"))));
diff --git a/absl/status/statusor.h b/absl/status/statusor.h
index 469d486f..b7c55cc8 100644
--- a/absl/status/statusor.h
+++ b/absl/status/statusor.h
@@ -135,7 +135,7 @@ class ABSL_MUST_USE_RESULT StatusOr;
//
// NOTE: using `absl::StatusOr<T>::value()` when no valid value is present will
// throw an exception if exceptions are enabled or terminate the process when
-// execeptions are not enabled.
+// exceptions are not enabled.
//
// Example:
//
diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h
index ffc738fa..1780bb44 100644
--- a/absl/strings/numbers.h
+++ b/absl/strings/numbers.h
@@ -124,6 +124,7 @@ inline void PutTwoDigits(size_t i, char* buf) {
}
// safe_strto?() functions for implementing SimpleAtoi()
+
bool safe_strto32_base(absl::string_view text, int32_t* value, int base);
bool safe_strto64_base(absl::string_view text, int64_t* value, int base);
bool safe_strto128_base(absl::string_view text, absl::int128* value,
diff --git a/ci/cmake_install_test.sh b/ci/cmake_install_test.sh
index 5bf540c5..ffc6b516 100755
--- a/ci/cmake_install_test.sh
+++ b/ci/cmake_install_test.sh
@@ -20,18 +20,24 @@ if [[ -z ${ABSEIL_ROOT:-} ]]; then
ABSEIL_ROOT="$(realpath $(dirname ${0})/..)"
fi
+if [[ -z ${LINK_TYPE:-} ]]; then
+ LINK_TYPE="STATIC DYNAMIC"
+fi
+
source "${ABSEIL_ROOT}/ci/cmake_common.sh"
source "${ABSEIL_ROOT}/ci/linux_docker_containers.sh"
readonly DOCKER_CONTAINER=${LINUX_GCC_LATEST_CONTAINER}
-time docker run \
- --mount type=bind,source="${ABSEIL_ROOT}",target=/abseil-cpp,readonly \
- --workdir=/abseil-cpp \
+for link_type in ${LINK_TYPE}; do
+ time docker run \
+ --mount type=bind,source="${ABSEIL_ROOT}",target=/abseil-cpp-ro,readonly \
--tmpfs=/buildfs:exec \
+ --tmpfs=/abseil-cpp:exec \
+ --workdir=/abseil-cpp \
--cap-add=SYS_PTRACE \
+ -e "LINK_TYPE=${link_type}" \
--rm \
- -e CFLAGS="-Werror" \
- -e CXXFLAGS="-Werror" \
${DOCKER_CONTAINER} \
- /bin/bash CMake/install_test_project/test.sh $@
+ /bin/bash -c "cp -r /abseil-cpp-ro/* . && CMake/install_test_project/test.sh"
+done
diff --git a/create_lts.py b/create_lts.py
new file mode 100755
index 00000000..a98c76b4
--- /dev/null
+++ b/create_lts.py
@@ -0,0 +1,121 @@
+#!/usr/bin/env python
+#
+# Copyright 2021 The Abseil Authors.
+#
+# 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
+#
+# https://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.
+"""A script to do source transformations to create a new LTS release.
+
+ Usage: ./create_lts.py YYYYMMDD
+"""
+
+import sys
+
+
+def ReplaceStringsInFile(filename, replacement_dict):
+ """Performs textual replacements in a file.
+
+ Rewrites filename with the keys in replacement_dict replaced with
+ their values. This function assumes the file can fit in memory.
+
+ Args:
+ filename: the filename to perform the replacement on
+ replacement_dict: a dictionary of key strings to be replaced with their
+ values
+
+ Raises:
+ Exception: A failure occured
+ """
+ f = open(filename, 'r')
+ content = f.read()
+ f.close()
+
+ for key, value in replacement_dict.items():
+ original = content
+ content = content.replace(key, value)
+ if content == original:
+ raise Exception('Failed to find {} in {}'.format(key, filename))
+
+ f = open(filename, 'w')
+ f.write(content)
+ f.close()
+
+
+def StripContentBetweenTags(filename, strip_begin_tag, strip_end_tag):
+ """Strip contents from a file.
+
+ Rewrites filename with by removing all content between
+ strip_begin_tag and strip_end_tag, including the tags themselves.
+
+ Args:
+ filename: the filename to perform the replacement on
+ strip_begin_tag: the start of the content to be removed
+ strip_end_tag: the end of the content to be removed
+
+ Raises:
+ Exception: A failure occured
+ """
+ f = open(filename, 'r')
+ content = f.read()
+ f.close()
+
+ while True:
+ begin = content.find(strip_begin_tag)
+ if begin == -1:
+ break
+ end = content.find(strip_end_tag, begin + len(strip_begin_tag))
+ if end == -1:
+ raise Exception('{}: imbalanced strip begin ({}) and '
+ 'end ({}) tags'.format(filename, strip_begin_tag,
+ strip_end_tag))
+ content = content.replace(content[begin:end + len(strip_end_tag)], '')
+
+ f = open(filename, 'w')
+ f.write(content)
+ f.close()
+
+
+def main(argv):
+ if len(argv) != 2:
+ print('Usage: {} YYYYMMDD'.format(sys.argv[0], file=sys.stderr))
+ sys.exit(1)
+
+ datestamp = sys.argv[1]
+ if len(datestamp) != 8 or not datestamp.isdigit():
+ raise Exception(
+ 'datestamp={} is not in the YYYYMMDD format'.format(datestamp))
+
+ # Replacement directives go here.
+ ReplaceStringsInFile(
+ 'absl/base/options.h', {
+ '#define ABSL_OPTION_USE_INLINE_NAMESPACE 0':
+ '#define ABSL_OPTION_USE_INLINE_NAMESPACE 1',
+ '#define ABSL_OPTION_INLINE_NAMESPACE_NAME head':
+ '#define ABSL_OPTION_INLINE_NAMESPACE_NAME lts_{}'.format(
+ datestamp)
+ })
+ ReplaceStringsInFile(
+ 'CMakeLists.txt', {
+ 'project(absl LANGUAGES CXX)':
+ 'project(absl LANGUAGES CXX VERSION {})'.format(datestamp)
+ })
+ # Set the SOVERSION to YYYYMMDD.0.0 - The first 0 means we only have
+ # ABI compatible changes, and the second 0 means we can increment it
+ # to mark changes as ABI-compatible, for patch releases.
+ ReplaceStringsInFile('CMake/AbseilHelpers.cmake',
+ {'SOVERSION 0': 'SOVERSION "{}.0.0"'.format(datestamp)})
+ StripContentBetweenTags('CMakeLists.txt', '# absl:lts-remove-begin',
+ '# absl:lts-remove-end')
+
+
+if __name__ == '__main__':
+ main(sys.argv)