mpc4j 在 macOS M3(Apple Silicon)上的部署实录:JDK 21(Preview)与 FourQ 缺失排错
- 项目地址:alibaba-edu/mpc4j
- 参考教程:mpc4j macOS 部署笔记(Notion)
本文记录我在 macOS M3(arm64)上从零部署 mpc4j 的过程,并重点说明两个关键问题:
- 源码默认 JDK 为 17,而我本地安装了 JDK 21 且开启了 preview,仅 JDK 21 支持,于是将工程统一切换到 JDK 21(并启用 preview)。
- CMake 构建原生依赖时报错:找不到
fourq
库(FOURQ_LIBRARY
)。
为了便于回溯,我在合适的位置插入了问题与成功的截图。
1. 环境与准备
- 硬件/系统:macOS 14.x(Sonoma)/ Apple M3(arm64)
- 包管理器:Homebrew
- 基础工具:Xcode Command Line Tools、CMake、OpenSSL、GMP、NTL、libsodium、Maven/Gradle
- Java:JDK 21(需要启用 preview)
建议先一次性安装基础依赖:
bash
# 开发工具与库
xcode-select --install || true
brew update
brew install cmake gmp ntl libsodium openssl pkg-config
# 视团队/个人使用选择构建工具(mpc4j 本身带有构建脚本时可直接用其 wrapper)
brew install maven gradle
# Java 21(示例使用 Azul Zulu)
brew install --cask zulu21
# 或使用 SDKMAN / 直接下载 PKG 安装均可
确保 Java 21 就绪:
bash
/usr/libexec/java_home -V | grep 21
export JAVA_HOME=$(/usr/libexec/java_home -v 21)
java -version
2. 快速流程(先看后做)
- 安装依赖:
brew install cmake gmp ntl libsodium openssl
(可选:maven gradle
) - 切换并固定
JAVA_HOME
到 JDK 21,确认java -version
输出为 21。 - 在工程构建脚本启用
--enable-preview
,并将sourceCompatibility/target
调整为 21。 - 准备原生依赖,若 CMake 报错找不到
fourq
,按文中"问题 2"处理。 - 执行构建(如
./gradlew build
或mvn -T1C -DskipTests install
)。 - 运行示例/单测验证。
3. 详细步骤
3.1 切换到 JDK 21 并启用 preview
我本地装有 JDK 21,并且开启了 preview。由于工程内使用了仅 21 支持的 preview 特性,默认的 JDK 17 会导致编译/运行失败。因此:
- 全局设置 JDK 为 21:
bash
export JAVA_HOME=$(/usr/libexec/java_home -v 21)
export PATH="$JAVA_HOME/bin:$PATH"
- Gradle(示例)在
build.gradle
中设置:
groovy
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
tasks.withType(JavaCompile).configureEach {
options.release = 21
options.compilerArgs += ['--enable-preview']
}
tasks.withType(Test).configureEach {
jvmArgs += '--enable-preview'
}
# 若是应用模块
// application {
// applicationDefaultJvmArgs = ['--enable-preview']
// }
或者在根目录 gradle.properties
增加:
ini
org.gradle.jvmargs=--enable-preview
- Maven(示例)在
pom.xml
:
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<release>21</release>
<compilerArgs>
<arg>--enable-preview</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
<configuration>
<argLine>--enable-preview</argLine>
</configuration>
</plugin>
提示:CMake 侧的 JNI 头文件路径会从
JAVA_HOME
解析。如果你曾经用过 JDK 17 构建,建议清理build/
目录让 CMake 重新探测。
下面这张图展示了默认指向 JDK 17 带来的问题场景(我已在后续改为 JDK 21 并开启 preview):

3.2 原生依赖与 CMake 配置
mpc4j 涉及若干原生库(GMP、NTL、libsodium、OpenSSL 等)。在 Apple Silicon 上使用 Homebrew 的典型路径是 /opt/homebrew
。如果 CMake 找库不顺利,可显式提供头文件与库路径:
bash
export CPPFLAGS="-I/opt/homebrew/include"
export LDFLAGS="-L/opt/homebrew/lib"
export PKG_CONFIG_PATH="/opt/homebrew/lib/pkgconfig:/opt/homebrew/share/pkgconfig"
进入工程的原生构建目录(以 build
为例):
bash
mkdir -p build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(sysctl -n hw.ncpu)
4. 问题与解决
问题 1:工程默认使用 JDK 17,但本机是 JDK 21(且需启用 preview)
- 现象:编译/运行时报与 preview 特性相关的错误,或 JNI 头路径指向老版本 JDK(如 Zulu-17)。
- 原因:源码默认编译目标为 17;仅 JDK 21 支持需要的 preview 特性。
- 解决:将
JAVA_HOME
切换为 JDK 21,并在构建脚本中设置release=21
与--enable-preview
(见 3.1)。必要时清理 CMake 缓存重新配置。
问题 2:CMake 报错找不到 fourq
(FOURQ_LIBRARY)
报错节选:
text
cmake -DCMAKE_BUILD_TYPE=Release ..
Platform: arm64
-- Build type (CMAKE_BUILD_TYPE): Release
-- C Flags (CMAKE_C_FLAGS): -Wfatal-errors -fPIC -Wno-ignored-attributes -pthread -Wall -funroll-loops -march=armv8-a+simd+crypto+crc -D _ARM64_ -O3 -D __LINUX__
-- CXX Flags (CMAKE_CXX_FLAGS): -Wfatal-errors -fPIC -Wno-ignored-attributes -pthread -Wall -funroll-loops -march=armv8-a+simd+crypto+crc -D _ARM64_ -O3 -D __LINUX__
-- NTL_INCLUDE_DIRS: /opt/homebrew/include
-- NTL_LIBRARY_PATH: /opt/homebrew/lib/libntl.dylib
-- GMP_INCLUDE_DIRS: /opt/homebrew/include
-- GMP_LIBRARY_PATH: /opt/homebrew/lib/libgmp.dylib
-- LIBSODIUM_INCLUDE_DIRS: /opt/homebrew/include
-- LIBSODIUM_LIBRARY_PATH: /opt/homebrew/lib/libsodium.dylib
-- JNI_INCLUDE_DIRS: /Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home/include
-- OPENSSL_INCLUDE_DIRS: /opt/homebrew/opt/openssl/include
-- OPENSSL_LIBRARY_PATH: /opt/homebrew/opt/openssl/lib/libssl.dylib;/opt/homebrew/opt/openssl/lib/libcrypto.dylib
CMake Error at CMakeLists.txt:179 (find_library):
Could not find FOURQ_LIBRARY using the following names: fourq
- 原因:系统中未安装 FourQ,或安装位置未被 CMake 的
find_library
搜索到。 - 解决路径(任选其一):
- 从源码安装 FourQ,并让 CMake 找到它
bash
# 以 Microsoft FourQlib 为例(如工程文档要求的具体版本不同,请以其为准)
cd /tmp
git clone https://github.com/microsoft/FourQlib.git
cd FourQlib
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j$(sysctl -n hw.ncpu)
# 安装到 /usr/local,或手动复制到 Homebrew 前缀下
sudo make install
# 或者:
sudo cp libfourq.* /opt/homebrew/lib/
sudo cp -r ../include/FourQ* /opt/homebrew/include/
然后在你的工程 CMake 配置时显式指定(若仍无法自动探测):
bash
cmake -DCMAKE_BUILD_TYPE=Release \
-DFOURQ_LIBRARY=/opt/homebrew/lib/libfourq.dylib \
-DFOURQ_INCLUDE_DIRS=/opt/homebrew/include \
..
注意:不同 FourQ 仓库生成的库名可能为
libFourQ.*
或libfourq.*
,请按实际产物填写;若仅生成.a
静态库,同样可用完整路径传给-DFOURQ_LIBRARY
。
- 检查是否存在可用的 Homebrew 第三方 Formula(如无则回到方案 1)
bash
brew search fourq || true
# 若存在可用 formula(名称可能不同),安装后在 /opt/homebrew/include 与 /opt/homebrew/lib 下即可被 CMake 搜到
- 临时规避(不推荐):如果工程允许禁用 FourQ 相关功能(需查阅 mpc4j 的 CMake 选项),可以加
-D<OPTION>=OFF
,但功能会受限。
5. 构建与验证
以 Gradle 为例:
bash
./gradlew clean build -x test
以 Maven 为例:
bash
mvn -T1C -DskipTests install
看到所有模块编译通过后,运行部分示例或单测进行验证。下图为成功构建/运行后的截图:
6. 常见检查清单(Apple Silicon 友好)
- 确认
JAVA_HOME
指向 JDK 21;echo $JAVA_HOME
与java -version
一致。 - 清理 CMake 缓存目录(如
build/
)以避免 JNI/依赖路径残留。 CPPFLAGS/LDFLAGS/PKG_CONFIG_PATH
指向/opt/homebrew
,确保 CMake 能找到 Homebrew 安装的头文件与库。openssl
在 Homebrew 里通常位于/opt/homebrew/opt/openssl
,必要时传入-DOPENSSL_ROOT_DIR=/opt/homebrew/opt/openssl
。- 若自编译 FourQ,确认库文件位于 CMake 可搜到的位置;用
otool -L /opt/homebrew/lib/libfourq.dylib
检查其依赖可解析。
7. 总结
- 将工程统一到 JDK 21 并启用 preview 是本次在 macOS M3 上成功部署的关键;
- FourQ 库缺失会导致 CMake 阶段失败,最稳妥的方式是从源码构建并显式告知 CMake 库与头文件位置;
- 其他依赖(GMP/NTL/libsodium/OpenSSL)使用 Homebrew 安装后,一般通过
CPPFLAGS/LDFLAGS
即可被找到。
如需我把上述 Gradle/Maven 的 JDK21 + preview 配置直接合并到你的工程脚本里,或根据 mpc4j 的具体 CMake 选项进行更精细化配置,欢迎继续提出!