abseil-cpp
ライブラリabseil/abseil-cpp
Abseil は Google がオープンソース化した C++ 汎用ライブラリであり、C++ 標準ライブラリを拡張します。
概要
Abseil は、Google が自社の内部コードベースから抽出してオープンソース化した C++ 汎用ライブラリ群であり、本番環境で広くテストされています。文字列処理、コンテナ、同期プリミティブなど、標準ライブラリに欠けているコンポーネントを提供し、C++ プロジェクトの基盤となる依存関係として機能することを目的としています。
README プレビュー
# Abseil - C++ Common Libraries\n\nThe repository contains the Abseil C++ library code. Abseil is an open-source\ncollection of C++ code (compliant to C++17) designed to augment the C++\nstandard library.\n\n## Table of Contents\n\n- [About Abseil](#about)\n- [Quickstart](#quickstart)\n- [Building Abseil](#build)\n- [Support](#support)\n- [Codemap](#codemap)\n- [Releases](#releases)\n- [License](#license)\n- [Links](#links)\n\n\n## About Abseil\n\nAbseil is an open-source collection of C++ library code designed to augment\nthe C++ standard library. The Abseil library code is collected from Google's\nown C++ code base, has been extensively tested and used in production, and\nis the same code we depend on in our daily coding lives.\n\nIn some cases, Abseil provides pieces missing from the C++ standard; in\nothers, Abseil provides alternatives to the standard for special needs\nwe've found through usage in the Google code base. We denote those cases\nclearly within the library code we provide you.\n\nAbseil is not meant to be a competitor to the standard library; we've\njust found that many of these utilities serve a purpose within our code\nbase, and we now want to provide those resources to the C++ community as\na whole.\n\n\n## Quickstart\n\nIf you want to just get started, make sure you at least run through the\n[Abseil Quickstart](https://abseil.io/docs/cpp/quickstart). The Quickstart\ncontains information about setting up your development environment, downloading\nthe Abseil code, running tests, and getting a simple binary working.\n\n\n## Building Abseil\n\n[Bazel](https://bazel.build) and [CMake](https://cmake.org/) are the official\nbuild systems for Abseil.\nSee the [quickstart](https://abseil.io/docs/cpp/quickstart) for more information\non building Abseil using the Bazel build system.\nIf you require CMake support, please check the [CMake build\ninstructions](CMake/README.md) and [CMake\nQuickstart](https://abseil.io/docs/cpp/quickstart-cmake).\n\n\n## Supp
FAQ (5)
トラブル対応空の Cord に対して SetExpectedChecksum() を呼び出した後に大きな std::string を末尾または先頭に追加すると absl::Cord がクラッシュする問題を修正するにはどうすればよいですか?
この問題は、期待チェックサムが設定された空の absl::Cord に対して、512 バイト以上の右辺値 std::string を append/prepend した場合に発生します。アサーションを有効にしたビルドでは IsDataEdge() 内で edge != nullptr の失敗が発生し、NDEBUG ビルドではセグメンテーションフォルトが発生する可能性があります。511 バイト以下の文字列は正常に動作します。
absl/strings/cord.cc に upstream の修正を適用し、両方の右辺値オーバーロードで、大きな文字列用のツリーを作成する前に空の CRC ノードを削除します:
// Cord::Append(T&& src) 内の、src.size() > 511 の else 分岐の中:
contents_.MaybeRemoveEmptyCrcNode();
CordRep* rep = CordRepFromString(std::forward<T>(src));
contents_.AppendTree(rep, CordzUpdateTracker::kAppendString);
// Cord::Prepend(T&& src) 内の、同等の else 分岐の中:
contents_.MaybeRemoveEmptyCrcNode();
CordRep* rep = CordRepFromString(std::forward<T>(src));
contents_.PrependTree(rep, CordzUpdateTracker::kPrependString);
その後、Abseil とプロジェクトを再ビルドしてください。パッチ適用版が利用可能になるまでは、初期データが追加された後に SetExpectedChecksum() を呼び出すか、最初の append/prepend を 511 バイト以下に抑えるか、大きな右辺値 std::string パスの代わりに absl::string_view の append/prepend パスを使用することで、このバグを回避できます。
トラブル対応等しくないPMRアロケーターでのムーブ代入後に、absl::linked_hash_setでheap-use-after-freeが発生する問題や、linked_hash_mapでコンパイルエラーが発生する問題を修正する方法は?
これは、伝播せず、比較結果が等しくならないアロケータを使用してムーブ代入を行った場合に発生します。std::list はコピー先のアロケータでノードを再作成しますが、linked_hash_set の内部イテレータインデックスは依然としてコピー元のノードを指しており、それらのノードはその後解放されます。linked_hash_map でも、std::pair<const K, V> に対する要素の代入が ill-formed であるため、コンパイルに失敗することがあります。
修正方法: コミット d5c2f53dfc56c6d0d65a93a5e303c16a046e5fe6 を含むリリースに Abseil を更新するか、そのパッチを適用して再ビルドしてください。
一時的な回避策:
- 両方のコンテナで、比較結果が等しくなるアロケータ(例えば同じ std::pmr::memory_resource)を使用していることを確認してください:
Set a{Alloc(&resource)};
Set b{Alloc(&resource)}; // 同じリソース
b = std::move(a); // 安全- 等しくない非伝播アロケータ間でのムーブ代入を避け、代わりにコピー先を再構築してください:
b.clear();
for (const auto& x : a) b.insert(x);
a.clear();linked_hash_map の場合は、各キーと値のペアをコピー先のコンテナに挿入してください。AddressSanitizer で再ビルドして、heap-use-after-free が解消されていることを確認してください。トラブル対応arm-none-eabi またはベアメタル ELF 向けにビルドする際の Abseil 'fatal error: link.h: No such file or directory' の修正方法
この問題は Abseil コミット 71330b9 で発生します。ABSL_HAVE_ELF_MEM_IMAGE がすべての __ELF__ ターゲットで有効になっていますが、arm-none-eabi-g++ と newlib を組み合わせたベアメタルツールチェーンは glibc の <link.h> を同梱せずに ELF オブジェクトを生成するためです。
暫定的な回避策: absl/debugging/internal/elf_mem_image.h を編集し、ABSL_HAVE_ELF_MEM_IMAGE を定義している既存の #if に <link.h> の利用可否チェックを追加します。
!defined(__XTENSA__) && __has_include(<link.h>)
例えば、条件は次のように終わるようにします。
#if defined(__ELF__) &&
// ...既存の拒否リストチェック...
!defined(__XTENSA__) && __has_include(<link.h>)
#define ABSL_HAVE_ELF_MEM_IMAGE 1
#endif
これにより、必要なヘッダーが存在しない場合にのみ ELF メモリイメージサポートが無効になります。__has_include は C++17 で利用可能であり、Abseil の他の箇所でもすでに使用されています。
次のコマンドで確認します。
arm-none-eabi-g++ -std=c++17 -I. -fsyntax-only absl/debugging/internal/elf_mem_image.cc
arm-none-eabi-g++ -std=c++17 -I. -fsyntax-only absl/debugging/internal/vdso_support.cc
上流での修正では、<link.h> が利用できない場合に <elf.h> を使用して ElfW をローカルに定義することで、サポートを有効のまま維持する可能性があります。そのため、修正済みの Abseil リリースが利用可能な場合は、そちらへの更新が推奨されます。
トラブル対応WindowsでCMakeを使用してAbseil DLLをビルドする際に発生する'crc_cpu_detect'ターゲットが見つからないエラーを修正する方法
このエラーは、MSVC/CMakeを使用してWindows上でAbseil v20260817.0をDLLとしてビルドする際に発生します。CMake/AbseilDll.cmakeファイルが、削除されたcrc_cpu_detectビルドターゲットを依然として参照しており、このターゲットはabsl/base/CMakeLists.txt内でbase_cpu_detectに置き換えられています。以下の手動による修正を適用してください。1. Abseilソースディレクトリ内のCMake/AbseilDll.cmakeを開き、約548行目に移動します。2. crc_cpu_detectへの参照をbase_cpu_detectに置き換えます。3. CMakeのconfigureコマンドを再実行し、プロジェクトを再ビルドします。
トラブル対応arm-none-eabi/newlib 向けに Abseil をビルドする際に発生する 'EncodeVarint' の曖昧なオーバーロードエラーは、どのように修正すればよいですか?
これは Abseil の issue #2148 です。arm-none-eabi のような newlib ターゲットでは、int32_t は通常の int ではなく long int であるため、int 引数はどの EncodeVarint オーバーロードとも完全一致しません。bool 引数も曖昧になることがあります。修正を含むリビジョンへ Abseil を更新するか、固定幅オーバーロードへ転送する明示的な int および bool のオーバーロードを absl/log/internal/proto.h に追加してください:
bool EncodeVarint(uint64_t field_number, int value,
absl::Span<char>* buf) {
return EncodeVarint(field_number, static_cast<int32_t>(value), buf);
}
bool EncodeVarint(uint64_t field_number, bool value,
absl::Span<char>* buf) {
return EncodeVarint(field_number, static_cast<uint64_t>(value), buf);
}
既存の関数がヘッダーでのみ宣言されている場合は、一致する宣言を追加し、転送定義を proto.cc に記述してください。同等の回避策としては、呼び出し箇所で source_line() を int32_t にキャストする方法や、エンコード前に bool 値を明示的に uint64_t にキャストする方法があります。例えば、次のように再ビルドします:
arm-none-eabi-g++ -std=c++17 -I. -fsyntax-only \
absl/log/internal/structured_proto.cc \
absl/log/internal/log_message.cc