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

这里的选项表示只编译 GoPHP 版本的 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.

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

总结

你只需要 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