Folly:Facebook 开源 C++20 组件库的架构设计、核心组件与跨平台构建实战指南
【免费下载链接】follyAn open-source C++ library developed and used at Facebook.项目地址: https://gitcode.com/GitHub_Trending/fol/folly
导读:本文以 folly 仓库根目录的 README.md 为骨架,系统讲解 Facebook 开源 C++ 组件库 Folly 的定位与设计哲学、逻辑与物理架构、核心组件清单,并完整继承其构建文档,给出基于getdeps.py与 CMake 的跨平台(Linux / macOS / Windows)编译、测试与集成实战方案。读者读完后将掌握 Folly 的目录结构与命名规范,能够在自己的项目中正确获取、编译、链接并运行 Folly 测试。
一、Folly 是什么:定位与设计哲学
Folly(全称 Facebook Open Source Library,即“Facebook 开源库”的松散缩写)是一套以实用性和效率为设计核心的 C++20 组件库。它不是单一功能的框架,而是 Facebook 内部大量核心库组件沉淀后的开源集合,常作为 Facebook 其他开源 C++ 项目的公共依赖,让这些项目得以共享底层代码。
从设计哲学上看,Folly 与 Boost、标准库(std)是互补关系而非竞争关系:
- 只有在标准库或 Boost 没有提供、或者性能表现达不到要求时,Folly 才会定义自己的组件;
- 一旦
std或 Boost 的对应功能成熟,Folly 会主动移除自己的实现。
性能考量贯穿 Folly 的方方面面,有时甚至会因此催生一些看起来“特立独行”的设计。README 中明确点名的两个典型例子是 folly/PackedSyncPtr.h(把指针、1 位自旋锁与 15 位整数压缩进一个 64 位字)和 folly/synchronization/SmallLocks.h(1 字节、1 位的极小型自旋锁)。这种“为大规模高性能服务而生”的统一主题,是理解 Folly 每一个组件取舍的钥匙。仓库 folly/VERSION 记录当前版本为57:0,顶层 CMakeLists.txt 中声明包版本为0.58.0-dev。
二、逻辑设计(Logical Design):命名空间与组件边界
Folly 的逻辑结构非常清晰:
- 相对独立的组件集合:Folly 是一系列彼此相对独立的组件组成的集合,有些组件简单到只有几个符号;
- 组件间允许内部依赖:没有任何关于内部依赖的限制,即某个 folly 模块可以使用其他任何 folly 组件;
- 统一顶层命名空间
folly:除宏以外,所有符号都定义在顶层命名空间folly中; - 宏命名规范:宏名全部大写,且必须以
FOLLY_前缀开头; - 内部命名空间不可依赖:
folly命名空间内还定义了internal、detail等内部命名空间,用户代码不应依赖这些命名空间中的符号——它们不构成稳定接口。
这一约定在仓库中随处可见,例如在顶层头文件 folly/Bits.h、folly/Conv.h 中,所有公开 API 都位于namespace folly内,而FOLLY_前缀宏则广泛分布于 folly/CPortability.h、folly/Portability.h 等可移植性头文件中,用于屏蔽不同编译器/平台的差异。
三、物理设计(Physical Design):folly/folly目录结构
Folly 的顶层目录沿用了 Boost 等库经典的“stuttering”(叠词)方案folly/folly:
- 第一层目录是库的安装根目录(可带版本号,如
folly-1.0/); - 第二层目录用于区分库名,使包含文件时写作
#include <folly/FBString.h>而非#include <FBString.h>,避免头文件冲突。
具体布局要点如下:
- 扁平化目录结构:目录结构是扁平的,与命名空间结构一一对应,不建立繁复的目录层级(README 也提示未来版本可能调整)。
experimental子目录:包含仅在 folly 内部(以及 Facebook 内部)使用、但对客户端而言还不够稳定的文件。用户代码不应使用folly/experimental下的文件,否则升级 Folly 时可能编译失败。- 测试目录:各组件的单元测试统一放在
folly/test下,命名遵循ComponentXyzTest.cpp对应每个ComponentXyz.*的规律,例如 folly/test/FBStringTest.cpp、folly/test/ConvTest.cpp。这些测试通过顶层 CMakeLists.txt 中的folly_define_tests宏统一注册到 CTest,并支持WINDOWS_DISABLED、SLOW、BROKEN、HANGING等标记来管理平台与运行时长。 - 文档目录:
folly/docs存放各组件的专项文档,建议从 folly/docs/Overview.md 开始阅读。
四、组件全景:folly 里有什么
由于 Folly 结构扁平,最好的“目录”就是顶层folly/目录下的头文件本身。下表按功能域整理了 folly/docs/Overview.md 中列出的主要组件(均可在仓库中直接查看对应源码):
| 功能域 | 组件 | 一句话说明 |
|---|---|---|
| 基础容器 | folly/container/F14Map.h、folly/container/F14Set.h | 高性能开放寻址哈希表(Facebook 内部大规模使用) |
| 字符串 | folly/FBString.h、folly/small_vector.h、folly/sorted_vector_types.h | std::string/std::vector的高性能替代实现 |
| 并发与同步 | folly/MPMCQueue.h、folly/ProducerConsumerQueue.h、folly/Synchronized.h、folly/ThreadLocal.h、folly/ThreadCachedInt.h | 多生产者多消费者队列、无锁单写单读队列、高层同步与线程局部存储 |
| 极小型锁 | folly/synchronization/SmallLocks.h、folly/MicroSpinLock.h、folly/PackedSyncPtr.h | 以字节/比特为单位的极紧凑自旋锁与压缩指针结构 |
| 原子数据结构 | folly/AtomicHashMap.h、folly/ConcurrentSkipList.h、folly/EvictingCacheMap.h | 面向特定权衡的高性能原子数据结构 |
| 异步编程 | folly/futures/、folly/coro/、folly/io/、folly/executors/ | Promise/Future 模式、协程、事件驱动 IO 与线程池执行器 |
| 转换与格式化 | folly/Conv.h、folly/Format.h、folly/dynamic.h、folly/json.h | 高速安全的类型转换、Python 风格格式化、动态类型与 JSON |
| 哈希与编码 | folly/Hash.h、folly/GroupVarint.h、folly/Fingerprint.h、folly/base64.h | 多种哈希实现、Group Varint 压缩编码、Rabin 指纹 |
| 内存管理 | folly/memory/、folly/Memory.h、folly/IndexedMemPool.h | Arena/ThreadCachedArena、jemalloc 辅助、索引内存池 |
| 工具与元编程 | folly/ScopeGuard.h、folly/Singleton.h、folly/Function.h、folly/Range.h、folly/Traits.h、folly/Indirect.h | RAII 守卫、可正确管理生命周期的单例、不可拷贝可调用对象包装、Boost 风格区间与类型萃取 |
| 网络与地址 | folly/IPAddress.h、folly/Uri.h、folly/SocketAddress.h、folly/io/async/EventBase.h | IPv4/IPv6 地址、URI 解析、socket 地址与异步事件循环 |
| 统计与基准 | folly/stats/、folly/Benchmark.h | 时间序列计数器/直方图/分位数统计,以及代码基准测试框架 |
| 其他 | folly/Baton.h(单次交接的信号量)、folly/Subprocess.h(Python 风格子进程库)、folly/Demangle.h、folly/gen/(LINQ 风格声明式序列处理) | 面向特定场景的精简工具 |
每个组件对应的深入文档位于 folly/docs/(如 FBString.md、Futures.md、Synchronized.md、AtomicHashMap.md),并有配套的可编译示例在 folly/docs/examples/。
五、构建 Folly:从 getdeps.py 到 CMake 的完整指南
5.1 ABI 稳定性与静态库建议
Folly不提供提交与提交之间的 ABI 兼容性保证,因此官方一般建议将 folly 构建为静态库,并把编译产物安装到临时目录,再由你的项目构建系统指向该临时位置,而不是安装到传统系统目录。这一建议在顶层 CMakeLists.txt 中也有印证:BUILD_SHARED_LIBS选项被显式标记为“一般不建议开启(folly 不承诺稳定 ABI)”。
5.2 平台与编译器支持
README 明确的支持矩阵为:
- 编译器:gcc(5.1+)、clang、MSVC;
- 操作系统:Linux(x86-32、x86-64 与 ARM)、iOS、macOS、Windows(x86-64);
- CMake 构建的测试覆盖:仅在部分平台上经过测试,最低目标是 macOS 与 Linux(最新的 Ubuntu LTS 或更新版本)。
顶层 CMakeLists.txt 还补充了 Windows 前提:Folly 要求 64 位目标架构,且 MSVC 至少为 Visual Studio 2017(MSVC_VERSION >= 1900)。
5.3getdeps.py:一键式依赖管理与构建
getdeps.py是 Meta 多个开源工具共用的构建脚本,位于 build/fbcode_builder/getdeps.py。从源码看,它本身只是一个入口 shim(第 8-12 行注释说明真正逻辑在getdeps/cli.py),用户可以直接运行。它的工作流程是:
- 先下载并构建所有必要依赖;
- 再调用 CMake 等工具构建 folly 本身;
- 构建时会考虑本地系统已安装依赖的版本,确保使用相关版本组合。
使用前提:Python 3.6+ 在PATH中;支持 Linux、macOS、Windows。folly 的 CMake 构建设置存放在其 getdeps manifest(build/fbcode_builder/manifests/folly)中,如需调整可以在本地编辑。
5.4 安装系统依赖
在 Linux 或装有 Homebrew 的 macOS 上,可先安装系统依赖以节省编译时间:
# 克隆仓库 git clone https://gitcode.com/GitHub_Trending/fol/folly # 安装依赖 cd folly sudo ./build/fbcode_builder/getdeps.py install-system-deps --recursive如果只想先查看将要安装的软件包清单而不真正安装:
./build/fbcode_builder/getdeps.py install-system-deps --dry-run --recursive在其他平台、或 Linux 上缺少系统依赖时,getdeps.py会在构建阶段自行下载并编译依赖。README 点名的关键依赖包括:
- 以C++14 支持编译的 Boost 版本;
- googletest(构建与运行 folly 测试所必需)。
5.5 构建命令与产物
# Clone the repo git clone https://gitcode.com/GitHub_Trending/fol/folly cd folly # Build, using system dependencies if available python3 ./build/fbcode_builder/getdeps.py --allow-system-packages build构建输出位于其 scratch 区域中:
installed/folly/lib/libfolly.a:静态库本体
相关控制参数:
--scratch-path:指定构建所用 scratch 目录的位置;默认安装位置可通过日志或python3 ./build/fbcode_builder/getdeps.py show-inst-dir查询;--install-dir、--install-prefix:更细粒度地控制安装目录;- 由于 folly 提交间无兼容性保证,官方建议将库安装到临时位置,并在你自己的项目中通过
CMAKE_PREFIX_PATH指向该临时安装目录,让 CMake 能find_package(folly)找到它; - 构建目录中会生成一个便于反复迭代 CMake 的
run_cmake.py脚本;scratch 构建目录可通过日志或python3 ./build/fbcode_builder/getdeps.py show-build-dir查询。
5.6 运行测试
默认情况下getdeps.py会构建 folly 的测试,运行方式:
cd folly python3 ./build/fbcode_builder/getdeps.py --allow-system-packages test5.7build.sh/build.bat包装脚本
Linux 和 macOS 上可使用build.sh,Windows 上使用build.bat,二者都是对getdeps.py的包装。
5.8 直接使用 CMake 构建
如果不想让 getdeps 代劳,可以直接用 CMake。注意:默认情况下测试并不属于 CMakeall目标,需要显式开启:
cmake .. -DBUILD_TESTS=ON make若要在 getdeps 构建基础上反复迭代 CMake,同样可借助 scratch 构建目录中的run_cmake.py脚本。测试运行也支持 ctest:
(cd $(python3 ./build/fbcode_builder/getdeps.py show-build-dir) && ctest)依赖位于非默认位置时,可通过CMAKE_INCLUDE_PATH与CMAKE_LIBRARY_PATH让 CMake 额外查找头文件与库。例如同时搜索/alt/include/path1、/alt/include/path2下的头文件以及/alt/lib/path1、/alt/lib/path2下的库:
cmake \ -DCMAKE_INCLUDE_PATH=/alt/include/path1:/alt/include/path2 \ -DCMAKE_LIBRARY_PATH=/alt/lib/path1:/alt/lib/path2 ...5.9 Ubuntu LTS、CentOS Stream、Fedora
推荐统一采用上面的getdeps.py方案;Folly 的 CI 主要在 Ubuntu LTS 上测试,偶尔覆盖其他发行版。若某发行版的系统软件包集合不匹配,可以在依赖 manifest(如build/fbcode_builder/manifests/boost)中针对发行版版本指定覆盖项,通常可在多数较新的 Ubuntu/Debian 或 Fedora/RedHat 衍生发行版上构建成功。
README 同时记录了一个已知问题:截至 2021 年 12 月,GCC 11.x 系统上lang_badge_test存在构建失败;如果不需要 badge 功能,可以通过在 CMakeLists.txt 中注释掉它来规避(注意 fbthrift 确实需要该功能)。
5.10 Windows(Vcpkg)
注意 folly 的 Windows 构建会禁用大量测试,可通过 CMake 配置步骤的日志、或搜索 CMakeLists.txt 中的WINDOWS_DISABLED标记查看。getdeps.py在 Windows 上可以构建并通过 CI 测试。若偏好 Vcpkg:
# 安装发布版本 vcpkg install folly:x64-windows # 或基于 main 分支构建 vcpkg install folly:x64-windows --head5.11 macOS
getdeps.py在 macOS 上可构建并通过 CI 测试;也可以使用 macOS 包管理器:
Homebrew:
# 安装发布版本 brew install folly # 或基于 main 分支构建(在顶层创建 _build 目录) ./folly/build/bootstrap-osx-homebrew.shMacPorts:先安装所需软件包:
sudo port install \ boost \ cmake \ gflags \ git \ google-glog \ libevent \ libtool \ lz4 \ lzma \ openssl \ snappy \ xz \ zlib再下载并安装 folly:
git clone https://gitcode.com/GitHub_Trending/fol/folly.git cd folly mkdir _build cd _build cmake .. make sudo make install六、从 CMake 源码看构建系统实现细节
除了 README 中的操作说明,顶层 CMakeLists.txt 还揭示了若干值得注意的工程细节:
- C++ 标准:默认设置
CMAKE_CXX_STANDARD 20(CMakeLists.txt),与 README 所称“C++20 组件库”一致;GCC 下还会检测并启用-fcoroutines以支持 C++ 协程(CMakeLists.txt)。 - 静态/共享库选项:
BUILD_SHARED_LIBS默认OFF且被标记为高级选项(CMakeLists.txt),呼应“无 ABI 保证、推荐静态库”的官方建议;PYTHON_EXTENSIONS=ON时会强制开启共享库(CMakeLists.txt)。 - 测试选项家族:
BUILD_TESTS、BUILD_BENCHMARKS、BUILD_BROKEN_TESTS、BUILD_HANGING_TESTS、BUILD_SLOW_TESTS五个开关(CMakeLists.txt),分别控制普通测试、基准、已知损坏、会挂起、调试模式下过慢的测试,默认全部关闭。 - 下游集成方式:安装时会生成
folly-config.cmake(CMakeLists.txt),下游项目可用find_package(folly CONFIG)并链接Folly::folly;同时生成 pkg-config 文件libfolly.pc(CMakeLists.txt),供非 CMake 构建系统使用。模板分别位于 CMake/folly-config.cmake.in 与 CMake/libfolly.pc.in。 - 库的粒度:源码先按子目录编译为 OBJECT 库,再聚合生成细粒度
.a与单一libfolly.a(CMakeLists.txt)。
七、继续深入:文档、示例与构建元数据
- 组件文档:所有专项文档集中在 folly/docs/,建议阅读顺序为 Overview.md → 按需查阅 Benchmark.md、ThreadLocal.md、Hazptr.md、Rcu.md 等;
- 可运行示例:folly/docs/examples/ 提供可直接阅读的示例源码;
- 测试范例:每个组件的单元测试即最佳用法示范,例如 folly/test/MPMCQueueTest.cpp、folly/futures/test/FutureTest.cpp;
- 构建元数据:Bazel/Buck 用户可参考 folly/BUCK 与 folly/defs.bzl,CMake 用户直接使用顶层 CMakeLists.txt 即可。
总而言之,Folly 是一套“以性能为纲、与标准库互补、服务于 Facebook 大规模生产环境”的 C++20 组件库。理解其扁平目录、folly命名空间与FOLLY_宏约定,再配合getdeps.py或 CMake 的完整构建链路,你就可以在 Linux、macOS 与 Windows 上把它编译为静态库并集成进自己的项目,按需选用其中的字符串、容器、并发、异步与 IO 组件。
【免费下载链接】follyAn open-source C++ library developed and used at Facebook.项目地址: https://gitcode.com/GitHub_Trending/fol/folly
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考