MacOS编译安装Thrift0.10.0

Apache Thrift 是一个跨语言的 RPC 框架和数据序列化工具,它允许你定义数据类型和服务接口,并自动生成多种语言的客户端和服务器代码。本文记录了在 macOS 系统上从源码编译并使用 Thrift 0.10.0的过程,并提供一个无需安装到系统目录即可使用的方法。

写在前面

建议通读全文,包括「常见问题与解决方案」部分,再进行操作。

作者机器环境:

  1. MacOS 15.5 (24F74)
  2. Homebrew 4.6.9
  3. GNU Make 3.81

安装编译依赖

安装 brew

1
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

验证安装:

1
brew -v

看到类似输出:

1
Homebrew 4.6.9

说明安装成功。更多使用方式,详见官网:https://brew.sh/

安装基础依赖

在 macOS 上编译 Thrift C++ 版本,需要安装以下工具:

1
brew install automake libtool bison wget

说明:如果你已经安装了 Xcode 或 Command Line Tools,一些依赖可能已经存在。

下载 Thrift 源码

  1. 访问 Apache Thrift 官方下载页面。
  2. 下载 thrift-0.10.0.tar.gz 并解压:
1
2
3
wget https://downloads.apache.org/thrift/0.10.0/thrift-0.10.0.tar.gz
tar -xzf thrift-0.10.0.tar.gz
cd thrift-0.10.0

配置并编译

执行以下命令

1
./configure --without-cpp --without-boost --without-java --without-python --without-ruby --without-nodejs --without-perl --without-haskell --with-go --with-php

这里的选项表示只编译 Go 和 PHP 版本的 Thrift,可根据需求选择语言支持。
具体可执行 ./configure --help 查看详细帮助。

1
make -j$(sysctl -n hw.ncpu)

用 CPU 核心数做并行编译,加快构建速度.

参数解释:
-j N :-j 参数告诉 make 并行编译,同时启动 N 个任务。
$(sysctl -n hw.ncpu) :sysctl -n hw.ncpu 是 macOS 的命令,用来获取当前 CPU 核心数;$(…) 是 shell 的命令替换,会把输出替换进来

验证可执行文件

编译完成后,thrift 可执行文件位于:

1
./compiler/cpp/thrift

执行验证:

1
./compiler/cpp/thrift --version

输出类似:

1
Thrift version 0.10.0

说明编译成功

安装到系统目录(可选)

如果希望全局使用 Thrift,可使用 make install(需要 sudo 权限):

1
sudo make install

默认会安装到 /usr/local/bin ,并且会把库文件、头文件、模板文件一起安装。

安装到自定义目录(可选)

如果你不想安装 /usr/local/bin 目录,可以将可执行文件放到任意目录。例如:

1
2
3
mkdir -p ~/sdk/thrift0.10.0/bin
cp ./compiler/cpp/thrift ~/sdk/thrift0.10.0/bin/
chmod +x ~/sdk/thrift0.10.0/bin/thrift

然后将其加入 PATH:

1
export PATH=~/sdk/thrift0.10.0/bin:$PATH

为了每次终端都能生效,可以把上面命令添加到 ~/.zshrc 或 ~/.bash_profile。

常见问题与解决方案

Bison 版本低

在执行 ./configure ... 这步时,可能会遇到如下错误信息:

1
2
checking for bison version >= 2.5... no
configure: error: Bison version 2.5 or higher must be installed on the system!

说明 你的系统里 bison 版本太低,Thrift 0.10.0 需要 ≥ 2.5。

检查系统自带 bison

macOS 自带的 bison 非常老,一般是 2.3,所以 configure 会直接报错:

1
bison --version

很可能显示

1
bison (GNU Bison) 2.3

安装新版本 bison

用 Homebrew 安装最新版:

1
brew install bison

Homebrew 会把新版本装到:

1
2
/opt/homebrew/opt/bison/bin/bison   (Apple Silicon)
/usr/local/opt/bison/bin/bison (Intel Mac)

覆盖系统默认 bison

brew 安装 bison 若成功后,你会看到类似如下提示信息:

1
2
3
4
5
6
7
8
9
10
==> Caveats
bison is keg-only, which means it was not symlinked into /opt/homebrew,
because macOS already provides this software and installing another version in
parallel can cause all kinds of trouble.

If you need to have bison first in your PATH, run:
echo 'export PATH="/opt/homebrew/opt/bison/bin:$PATH"' >> ~/.zshrc

For compilers to find bison you may need to set:
export LDFLAGS="-L/opt/homebrew/opt/bison/lib"

keg-only 的意思
macOS 自带旧版本 Bison(通常 2.3)。
Homebrew 安装的新版 Bison 是 keg-only,不会自动覆盖系统自带的 Bison。
因此默认 bison 命令还是旧版本,如果你直接运行 bison –version,可能还是显示 2.3。

brew安装bison 默认不会将 PATH 中旧版本 覆盖,默认 PATH 里还是 /usr/bin/bison(旧版本)。
此时你需要告诉系统优先用 Homebrew 的 bison:

1
export PATH="$(brew --prefix bison)/bin:$PATH"

测试:

1
2
which bison
bison --version

应该输出的是 Homebrew 安装的版本,比如:

1
2
/opt/homebrew/opt/bison/bin/bison
bison (GNU Bison) 3.8.2

重新跑 configure

1
./configure ....

可能看到如下输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
thrift 0.10.0

Building Plugin Support ...... : no
Building C++ Library ......... : no
Building C (GLib) Library .... : no
Building Java Library ........ : no
Building C# Library .......... : no
Building Python Library ...... : no
Building Ruby Library ........ : no
Building Haxe Library ........ : no
Building Haskell Library ..... : no
Building Perl Library ........ : no
Building PHP Library ......... : yes
Building Dart Library ........ : no
Building Erlang Library ...... : no
Building Go Library .......... : yes
Building D Library ........... : no
Building NodeJS Library ...... : no
Building Lua Library ......... : no

PHP Library:
Using php-config .......... :

Go Library:
Using Go................... : /Users/xxxx/sdk/go1.14.15/bin/go
Using Go version........... : go version go1.14.15 darwin/amd64

If something is missing that you think should be present,
please skim the output of configure to find the missing
component. Details are present in config.log.

看到上述信息,表示配置成功。
因为我只编译 Go 和 PHP 版本的 Thrift,没有 C++、Boost、Java 等多余依赖,所以只显示 Go 和 PHP 的信息。

总结

你只需要 brew install bison,然后把 新 bison 放到 PATH 里,问题就解决了。

缺少 go.mod 文件

问题现象

执行 make 时,有如下报错信息:

1
2
3
4
5
6
7
8
9
Making all in go
Making all in .
/Users/xxx/sdk/go1.19.13/bin/go build ./thrift
go: go.mod file not found in current directory or any parent directory; see 'go help modules'
make[4]: *** [all-local] Error 1
make[3]: *** [all-recursive] Error 1
make[2]: *** [all-recursive] Error 1
make[1]: *** [all-recursive] Error 1
make: *** [all] Error 2

问题原因

Thrift 0.10.0 的 Go 支持在当时还没完全迁移到 Go Modules。
我本机的 Go 是 1.19(默认启用 Go Modules),而 Thrift 源码里 没有 go.mod 文件。
go build ./thrift 就报错了,因为 Go 1.16+ 会默认要求模块化环境。

换句话说:Thrift 0.10.0 的 makefile 对新版 Go 不兼容。

解决方案

用一个 较老的 Go 版本,默认不开启 Modules,源码就能编译通过。

我这里安装的是 go 1.14.15

1
go version go1.14.15 darwin/arm64

清理之前 configure 生成的文件:

1
2
make clean
rm -rf config.cache

重新 configure & make ,错误即可解决。

注: Thrift 编译后,Go版本即可替换成其他日常使用版本,我这里重新替换成 1.19