mpc4j 在 macOS M3(Apple Silicon)上的部署实录:JDK 21(Preview)与 FourQ 缺失排错

mpc4j 在 macOS M3(Apple Silicon)上的部署实录:JDK 21(Preview)与 FourQ 缺失排错

本文记录我在 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. 快速流程(先看后做)

  1. 安装依赖:brew install cmake gmp ntl libsodium openssl(可选:maven gradle
  2. 切换并固定 JAVA_HOME 到 JDK 21,确认 java -version 输出为 21。
  3. 在工程构建脚本启用 --enable-preview,并将 sourceCompatibility/target 调整为 21。
  4. 准备原生依赖,若 CMake 报错找不到 fourq,按文中"问题 2"处理。
  5. 执行构建(如 ./gradlew buildmvn -T1C -DskipTests install)。
  6. 运行示例/单测验证。

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 搜索到。
  • 解决路径(任选其一):
  1. 从源码安装 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

  1. 检查是否存在可用的 Homebrew 第三方 Formula(如无则回到方案 1)
bash 复制代码
brew search fourq || true
# 若存在可用 formula(名称可能不同),安装后在 /opt/homebrew/include 与 /opt/homebrew/lib 下即可被 CMake 搜到
  1. 临时规避(不推荐):如果工程允许禁用 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_HOMEjava -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 选项进行更精细化配置,欢迎继续提出!

相关推荐
京东零售技术7 小时前
京东正式开源基于国产芯片自研的xLLM大模型推理引擎
github
寻月隐君8 小时前
Rust 泛型编程基石:AsRef 和 AsMut 的核心作用与实战应用
后端·github
ayyyy____9 小时前
把项目通过pycharm上传到github(两种方式)
ide·pycharm·github
专注VB编程开发20年9 小时前
vb.net编写DDE(Dynamic Data Exchange)服务器
运维·服务器·github·vb.net·dde
qq_377572779 小时前
github repository 一个文件忘记添加到 .gitignore
github
方圆想当图灵9 小时前
深入浅出 gRPC
java·后端·github
chaofan98010 小时前
如何用 Claude Code 搭建安全、可测、可自动化的 GitHub CI 流程?
运维·人工智能·ci/cd·ai·自动化·github·claude
ITsheng_ge11 小时前
GitHub Pages 部署静态网站流程、常见问题以及解决方案
前端·github·持续部署
小Lu的开源日常11 小时前
如何使用 GitHub Action 发布 Docker 镜像
docker·开源·github
没有鸡汤吃不下饭15 小时前
Git将某个分支合并到开发(dev)、测试(test)后突然想撤销该分支的功能,怎么处理?
前端·git·github