大家好,我是 PLCT 丁丑小队的一名实习生。这是我们工程软件测试系列帖的第五篇,接续上篇。
在上期,我们处理了那些构建流程相对标准的软件。而本期,我们将进入更具挑战性的领域:这些软件不仅需要从源码编译,还可能伴随着以下一种或多种情况:
- 关键依赖缺失: 软件依赖的某个特定版本的库在 RevyOS 源中不存在,需要我们手动编译和安装这个依赖。
- 构建系统魔改: 软件的构建脚本存在问题,例如硬编码了不适用于 RISC-V 的编译器标志、或者无法正确找到已安装的依赖,需要我们手动修改构建脚本。
- 源码级 Patch: 软件的源代码中包含了一些与现代编译器或库不兼容的写法,需要我们直接修改源码。
这些操作无疑增加了在 RISC-V 平台上使用这些软件的门槛,但成功克服这些障碍的过程,也正是开源社区 porting 工作乐趣的一部分。
1. CalculiX - 需要手动编译依赖的三维结构 FEA 程序
CalculiX 是一款功能强大的三维结构有限元分析软件。它的特殊之处在于,它依赖一个特定且较旧版本的稀疏矩阵求解库 SPOOLES 2.2,这个库在现代发行版中早已不见踪影。因此,我们必须先手动编译这个“古董”依赖。
构建步骤:
-
安装基础依赖
sudo apt update sudo apt install build-essential gfortran make libarpack2-dev libopenblas-dev -
编译并安装 SPOOLES 2.2
- 获取并解压源码:
cd /usr/local sudo mkdir spooles && cd spooles sudo wget http://netlib.org/linalg/spooles/spooles.2.2.tgz sudo tar -xvzf spooles.2.2.tgz - 魔改时刻:
SPOOLES 2.2的源码过于古老,无法直接通过现代 GCC 编译。我们需要打两个 Patch:# 修复 Makefile 中的一个文件名错误 sudo sed -i 's/drawTree\.c/draw.c/' Tree/src/makeGlobalLib # 修复 C 源码中一个不再被支持的 NULL 指针用法 sudo find . -type f -name '*.c' -exec sed -i -E 's/IVinit\(([^,]+),[[:space:]]*NULL\)/IVinit(\1, 0)/g' {} + - 编译
SPOOLES:
这会在sudo make global/usr/local/spooles/spooles.a生成我们需要的静态库。
- 获取并解压源码:
-
编译 CalculiX
- 获取源码并解压。
- 魔改时刻:修改
CalculiX/ccx_2.22/src/Makefile,手动指定SPOOLES库的路径以及其他链接库:... DIR=/usr/local/spooles.2.2 LIBS = \ $(DIR)/spooles.a \ -larpack -lopenblas \ -lpthread -lm -lc ... - 编译 CalculiX 主程序:
make
运行验证:
编译成功后,我们使用官方提供的一个名为 achtel 的测试用例进行验证。
# 假设 acht.inp 文件在当前目录
./ccx_2.22 achtel
程序正常执行计算,并将结果输出到 achtel.dat 文件中,证明整个编译流程成功。
...
Factoring the system of equations using the symmetric spooles solver
Using 1 cpu for spooles.
...
Job finished
详细的测试报告请见:CalculiX 测试报告。
2. OpenCASCADE & NETGEN - 互相依赖的 CAD 内核与网格生成器
OpenCASCADE (OCCT) 是一个强大的开源 CAD 内核,而 NETGEN 则是一款优秀的网格生成器,并且可以选择使用 OCCT 作为其几何内核。在 RevyOS 上,我们需要先从源码编译 OCCT,然后再编译 NETGEN 并链接到我们自己编译的 OCCT。
构建 OpenCASCADE (OCCT):
- 安装依赖
sudo apt install cmake-curses-gui tcl-dev tk-dev libfreetype6-dev libgl1-mesa-dev libx11-dev - 配置与编译
OCCT 使用标准的 CMake 流程,过程比较顺利。# 获取源码并进入 mkdir build && cd build cmake .. make -j$(nproc) sudo make installsudo make install会将 OCCT 的头文件和库安装到系统目录,方便后续其他程序(如 NETGEN)找到它。
构建 NETGEN:
- 安装依赖
sudo apt install python3-dev python3-tk tk-dev tcl-dev libxmu-dev liblapacke-dev - 获取源码并初始化子模块
git clone https://github.com/NGSolve/netgen.git cd netgen git checkout v6.2.2505 # 锁定到一个稳定版本 git submodule update --init --recursive - 魔改时刻:NETGEN 的 CMake 脚本默认会启用
-march=native编译器优化选项,但这在我们的 RISC-V 测试平台上会导致编译错误。因此需要手动修改根目录的CMakeLists.txt文件,禁用该选项:# 将 ON 修改为 OFF option(ENABLE_NATIVE_ARCH "Enable native architecture optimizations" OFF) - 配置与编译
在配置阶段,CMake 会自动找到我们上一步安装好的 OCCT。mkdir build && cd build cmake .. make -j$(nproc) make install
运行验证:
安装后,配置好环境变量,即可启动 NETGEN 的 GUI。
export NETGENDIR="/path/to/your/netgen/install/bin"
export PATH="$NETGENDIR:$PATH"
export PYTHONPATH="/path/to/your/netgen/install/lib/python3.11/dist-packages:$PYTHONPATH"
netgen
GUI 成功启动,证明 OCCT 和 NETGEN 均已正确构建和链接。
详细的测试报告请见:
3. MayaVi - 依赖系统库的 Python 可视化工具
MayaVi 是一款基于 VTK 的科学数据可视化 Python 库。在 RISC-V 平台上,其关键依赖 VTK 和 wxPython 都没有预编译的 wheel 包,直接 pip install 会失败。我们的策略是:使用 apt 安装最复杂的原生依赖 VTK,然后利用 pip 在一个特殊的虚拟环境中安装 MayaVi 及其余 Python 依赖。
构建步骤:
-
安装系统依赖
sudo apt install git uv build-essential python3-vtk9 libgtk-3-dev这里的
python3-vtk9是关键,它为我们提供了系统级的 VTK Python 绑定。 -
创建可访问系统包的虚拟环境
这是本次操作的核心技巧。git clone https://github.com/enthought/mayavi.git cd mayavi # --system-site-packages 标志是关键 uv venv --system-site-packages source .venv/bin/activate -
分步安装
- 首先,在不处理依赖的情况下,强制在当前环境中编译安装 MayaVi:
uv pip install --no-build-isolation --no-deps . - 然后,再使用
uv安装剩下的纯 Python 依赖和需要编译的 wxPython:uv pip install "numpy>=2.0" traits traitsui pyface envisage apptools wxPython
- 首先,在不处理依赖的情况下,强制在当前环境中编译安装 MayaVi:
运行验证:
执行一段测试代码,如果能成功显示三维图像窗口,则证明安装成功。
python -c "from mayavi import mlab; mlab.test_points3d(); mlab.show()"
在我们的测试平台上,成功弹出了交互式 3D 窗口。
详细的测试报告请见:MayaVi 测试报告。
总结
本期我们通过三个案例,展示了在 RISC-V 平台上构建复杂工程软件时可能遇到的一些典型问题及其解决方案,包括手动编译古老依赖、修改构建脚本以及利用混合包管理策略等。这些操作虽然比简单的 apt install 要复杂得多,但它们是打通软件生态“最后一公里”的关键步骤。
下一期,我们将直面那些最顽固的挑战——即使我们使出浑身解数,最终仍然构建失败的软件。我们将详细分析失败的原因,为社区的未来工作提供参考。
欢迎各位复现/吐槽丁丑小队的所有测试结果。
如果有对我们的测试方法/结果有任何建议/问题,欢迎直接在 GitHub 开 issue,或者在论坛 @ 我们、回帖询问。


