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 选项进行更精细化配置,欢迎继续提出!

相关推荐
油泼辣子多加5 小时前
[特殊字符] GitHub 热门开源项目速览(2025/09/09)
github
CoderJia程序员甲6 小时前
GitHub 热榜项目 - 日榜(2025-09-09)
ai·开源·大模型·github·ai教程
BillKu6 小时前
下载 Eclipse Temurin 的 OpenJDK 提示 “无法访问此网站 github.com 的响应时间过长”
github·openjdk·eclipse temurin
绝无仅有7 小时前
HTTP面试之实战经验与总结
后端·面试·github
绝无仅有7 小时前
职场面试redis经历之与一位资深技术面试官的技术问答与总结
后端·面试·github
老马啸西风12 小时前
v0.29.2 敏感词性能优化之基本类型拆箱、装箱的进一步优化的尝试
性能优化·开源·nlp·github·敏感词
伴杯猫15 小时前
【ESP32-IDF】基础外设开发2:系统中断矩阵
c语言·单片机·嵌入式硬件·mcu·物联网·github
程序视点17 小时前
GitHub Copilot代码审查大升级!路径级指令+组织级规范,开发者效率再提升!
github·github copilot
行思理21 小时前
linux 安全与防护,全方向讲解
linux·安全·github