facebook/folly
GitHub: facebook/folly
Facebook 开源的高性能 C++20 核心组件库,旨在补充标准库和 Boost,为超大规模系统提供极致的运行效率。
Stars: 30310 | Forks: 5859
# Folly: Facebook 开源库
# 什么是 `folly`?
Folly( loosely 源自 Facebook Open Source Library 的缩写)是一个
考虑到实用性和效率而设计的
C++20 组件库。**Folly 包含了在 Facebook 广泛使用的各种核心库组件**。
特别是,它通常是 Facebook 其他
开源 C++ 项目的依赖项,也是这些项目可以共享代码的地方。
它补充(而不是竞争)诸如
Boost 之类的产品,当然也包括 `std`。事实上,只有当我们需要的东西
要么不可用,要么
不符合所需的性能标准时,我们才开始定义自己的
组件。如果或在 `std` 或 Boost 淘汰它们时,我们会努力从 folly 中移除
这些东西。
性能问题渗透到 Folly 的很多方面,有时会导致
比其他情况更独特的设计(参见
例如 `PackedSyncPtr.h`、`SmallLocks.h`)。在大
规模下保持良好性能是所有 Folly 的统一主题。
## 在介绍视频中查看
[](https://www.youtube.com/watch?v=Wr_IfOICYSs)
# 逻辑设计
Folly 是一组相对独立的组件集合,有些
简单到只有几个符号。对内部
依赖没有限制,这意味着给定的 folly 模块可以使用任何其他
folly 组件。
所有符号都定义在顶级命名空间 `folly` 中,当然
宏除外。宏名称全部大写 (ALL_UPPERCASE),并且应以
`FOLLY_` 为前缀。命名空间 `folly` 定义了其他内部命名空间,
例如 `internal` 或 `detail`。用户代码不应依赖于
这些命名空间中的符号。
# 物理设计
在顶层,Folly 使用了 Boost 等人使用的经典“重复”方案
`folly/folly`。第一个目录用作
库的安装根目录(可能带有类似
`folly-1.0/` 的版本控制),第二个是为了在
包含文件时区分该库,例如 `#include `。
目录结构是扁平的(模仿命名空间结构),
即我们没有精心设计的目录层次结构(这
在未来的版本中可能会发生改变)。子目录 `experimental`
包含在 folly 内部以及可能在 Facebook 使用但
被认为不够稳定而不适合客户端使用的文件。您的代码不应使用
`folly/experimental` 中的文件,否则在您更新 Folly 时它可能会损坏。
`folly/folly/test` 子目录包含所有
组件的单元测试,通常每个
`ComponentXyz.*` 对应命名为 `ComponentXyzTest.cpp`。`folly/folly/docs` 目录包含
文档。
# 它里面有什么?
由于 folly 具有相当扁平的结构,查看其中内容的最佳方法
是查看[顶级 `folly/` 目录](https://github.com/facebook/folly/tree/main/folly)中的头文件。您也可以
查看 [`docs` 文件夹](folly/docs)获取文档,从
[概述](folly/docs/Overview.md)开始。
Folly 在 GitHub 上发布,地址为 https://github.com/facebook/folly。
# 构建说明
由于 folly 不提供任何 commit 间的 ABI 兼容性保证,
我们通常建议将 folly 构建为静态库。
folly 支持 gcc (5.1+)、clang 或 MSVC。它应该可以在 Linux (x86-32、
x86-64 和 ARM)、iOS、macOS 和 Windows (x86-64) 上运行。CMake 构建仅在
其中一些平台上进行了测试;至少,我们的目标是支持 macOS 和
Linux(在最新的 Ubuntu LTS 版本或更新版本上)。
## `getdeps.py`
此脚本被许多 Meta 的 OSS 工具使用。它将首先下载并构建所有必需的依赖项,然后调用 cmake 等工具来构建 folly。这将有助于确保您使用所有依赖库的相关版本进行构建,同时考虑到您系统本地安装的版本。
它是用 python 编写的,因此您需要在 PATH 中包含 python3.6 或更高版本。它可在 Linux、macOS 和 Windows 上运行。
folly 的 cmake 构建设置保存在其 getdeps 清单 `build/fbcode_builder/manifests/folly` 中,如果需要,您可以在本地进行编辑。
### 依赖项
如果在 Linux 或 MacOS(已安装 homebrew)上,您可以安装系统依赖项以节省构建它们的时间:
```
# Clone 仓库
git clone https://github.com/facebook/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` 将在构建步骤中为您下载并构建它们的大部分。
`getdeps.py` 使用和安装的一些依赖项是:
* 使用 C++14 支持编译的 boost 版本。
* googletest 是构建和运行 folly 的测试所必需的。
### 构建
此脚本将首先下载并构建所有必需的依赖项,
然后调用 cmake 等工具来构建 folly。这将有助于确保您使用所有依赖库的相关版本进行构建,同时考虑到系统本地安装的版本。
`getdeps.py` 目前要求您的路径中有 python 3.6+。
`getdeps.py` 将调用 cmake 等。
```
# Clone 仓库
git clone https://github.com/facebook/folly
cd folly
# 构建,若可用则使用系统依赖
python3 ./build/fbcode_builder/getdeps.py --allow-system-packages build
```
它将输出放在其暂存区中:
* `installed/folly/lib/libfolly.a`:库
您还可以指定 `--scratch-path` 参数来控制
用于构建的暂存目录的位置。您可以从日志中或使用 `python3 ./build/fbcode_builder/getdeps.py show-inst-dir` 找到默认的暂存安装位置。
还有
`--install-dir` 和 `--install-prefix` 参数可提供对安装目录更
精细的控制。但是,鉴于
folly 在各次 commit 之间不提供兼容性保证,我们通常
建议将库构建并安装到临时位置,然后
将您项目的构建指向此临时位置,而不是
将 folly 安装在传统的系统安装目录中。例如,如果您使用 CMake 进行构建,可以使用 `CMAKE_PREFIX_PATH` 变量来允许 CMake 在构建您的项目时在此临时安装目录中找到 folly。
如果您想再次调用 `cmake` 进行迭代,在暂存构建目录中有一个有用的 `run_cmake.py` 脚本输出。您可以从日志中或使用 `python3 ./build/fbcode_builder/getdeps.py show-build-dir` 找到暂存构建目录。
### 运行测试
默认情况下,`getdeps.py` 将构建 folly 的测试。要运行它们:
```
cd folly
python3 ./build/fbcode_builder/getdeps.py --allow-system-packages test
```
### `build.sh`/`build.bat` 包装器
`build.sh` 可在 Linux 和 MacOS 上使用,在 Windows 上请使用
`build.bat` 脚本。它是 `getdeps.py` 的包装器。
## 直接使用 cmake 构建
如果您不想让 getdeps 为您调用 cmake,默认情况下,作为 CMake `all` 目标的一部分,构建测试是被禁用的。
要构建测试,请在配置时向 CMake 指定 `-DBUILD_TESTS=ON`。
注意:如果您想再次调用 `cmake` 以迭代 `getdeps.py` 构建,在暂存路径构建目录中有一个有用的 `run_cmake.py` 脚本输出。您可以从日志中或使用 `python3 ./build/fbcode_builder/getdeps.py show-build-dir` 找到暂存构建目录。
如果您 cd 到构建目录,使用 ctests 运行测试也是可行的,例如
`(cd $(python3 ./build/fbcode_builder/getdeps.py show-build-dir) && ctest)`
### 在非默认位置查找依赖项
如果您将 boost、gtest 或其他依赖项安装在非默认
位置,您可以使用 `CMAKE_INCLUDE_PATH` 和 `CMAKE_LIBRARY_PATH`
变量让 CMAKE 也在非标准位置查找头文件和库。例如,还要搜索目录
`/alt/include/path1` 和 `/alt/include/path2` 以查找头文件,并搜索目录
`/alt/lib/path1` 和 `/alt/lib/path2` 以查找库,您可以按如下方式调用
`cmake`:
```
cmake \
-DCMAKE_INCLUDE_PATH=/alt/include/path1:/alt/include/path2 \
-DCMAKE_LIBRARY_PATH=/alt/lib/path1:/alt/lib/path2 ...
```
## Ubuntu LTS, CentOS Stream, Fedora
请使用上述 `getdeps.py` 方法。我们在 CI 中基于 Ubuntu LTS 进行测试,偶尔也会在其他发行版上测试。
如果您发现系统软件包集不太适合您选择的发行版,您可以在依赖清单中指定特定发行版版本的覆盖(例如 https://github.com/facebook/folly/blob/main/build/fbcode_builder/manifests/boost )。您很可能可以让它在大多数最新的 Ubuntu/Debian 或 Fedora/Redhat 派生发行版上运行。
在撰写本文时(2021 年 12 月),在基于 GCC 11.x 的系统上的 lang_badge_test 中存在一个构建中断。如果您不需要 badge 功能,可以通过在 CMakeLists.txt 中将其注释掉来绕过这个问题(不幸的是 fbthrift 确实需要它)
## Windows (Vcpkg)
请注意,许多测试在 folly 的 Windows 构建中被禁用,您可以在 cmake 配置步骤的日志中看到它们,或者通过在 `CMakeLists.txt` 中查找 WINDOWS_DISABLED 来查看。
话虽如此,`getdeps.py` 构建在 Windows 上有效,并在 CI 中进行了测试。
如果您愿意,可以尝试 Vcpkg。folly 可在 [Vcpkg](https://github.com/Microsoft/vcpkg#vcpkg) 中获取,并且可以通过 `vcpkg install folly:x64-windows` 构建发布版本。
您也可以使用 `vcpkg install folly:x64-windows --head` 来针对 `main` 分支进行构建。
## macOS
`getdeps.py` 构建在 macOS 上有效,并在 CI 中进行了测试,但是如果您愿意,可以尝试其中一种 macOS 包管理器
### Homebrew
folly 以 Formula 形式提供,可以通过 `brew install folly` 构建发布版本。
您也可以使用 `folly/build/bootstrap-osx-homebrew.sh` 针对 `main` 进行构建:
```
./folly/build/bootstrap-osx-homebrew.sh
```
这将在顶级目录中创建一个 `_build` 构建目录。
### MacPorts
从 MacPorts 安装所需的软件包:
```
sudo port install \
boost \
cmake \
gflags \
git \
google-glog \
libevent \
libtool \
lz4 \
lzma \
openssl \
snappy \
xz \
zlib
```
下载并安装 double-conversion:
```
git clone https://github.com/google/double-conversion.git
cd double-conversion
cmake -DBUILD_SHARED_LIBS=ON .
make
sudo make install
```
使用下面列出的参数下载并安装 folly:
```
git clone https://github.com/facebook/folly.git
cd folly
mkdir _build
cd _build
cmake ..
make
sudo make install
```
标签:Bash脚本, Boost补充, C++, C++20, Facebook, std补充, 内存管理, 后端开发, 基础架构, 大规模并发, 威胁情报, 并发, 底层库, 开发者工具, 开源库, 异步编程, 搜索引擎爬虫, 数据擦除, 核心组件, 逆向工具