Page 34 - 《软件学报》2026年第6期
P. 34

屈晟 等: 面向  RISC-V  指令集多样性的兼容性感知多层级构建方法                                           2353


                 段引入动态模板机制, 依据目标设备自动生成匹配的指令集与微架构模板. 通过这                           3  种机制, RuyiBuild  实现了
                 LLVM IR  在终端与云端之间的稳定迁移与再构建. 此外, 作为保底, 如果存在                  LLVM IR  不兼容问题, 则不会生成
                 新的动态库, 使用传统方法编译的动态库依然可以使用.
                  3.1   透明化双路径编译与    LLVM IR  提取机制的设计与实现原理
                    LLVM IR  技术在操作系统发行版级别暂时无法广泛使用的一个主要原因是, 现有广泛使用的软件构建系统,
                 如  GNU Autotools、CMake 等均假定软件使用传统的编译方式, 使用            LLVM IR  技术可能需要对现有软件的组织
                 方式进行重大改造, 其需要极大的软件开发工程量, 也会为软件增加非常多的复杂性. 这在工程实践中是不可接受的.
                    RuyiBuild  工具链的核心技术思想是利用         LLVM  中间表示   (LLVM IR) 在不修改目标软件源码与原始构建系
                 统的情况下, 创建透明的双路径编译流程, 以解决               RISC-V  架构指令集碎片化问题所带来的软件兼容性与性能优
                 化难题.
                    如图  1  所示, 通过  RuyiBuild  工具链, 两次调用  clang  等工具, 将源代码分别编译成为真实目标代码文件             (对于
                 RISC-V  和  Linux  的组合来讲为  ELF) 和  LLVM IR  文件; 之后, 将真实目标代码文件打包进入传统        RPM, 该  RPM  可
                 被用户直接安装使用; 之后, 将       LLVM IR  文件以类似的文件夹结构打包进入           IR RPM. 对于  IR RPM  软件包, 既可以
                 被直接安装到用户设备, 并通过使用相同版本              LLVM  转换为目标文件; 也可以在云端服务器使用相同版本的                LLVM
                 与编译命令, 依据目标平台支持的指令集, 转换为传统               RPM  文件, 并通过进一步构建      RPM  软件仓库进行分发.
                    如图  1  所示, 在用户终端内部, 以动态链接库为例说明             LLVM IR  文件的使用方式. 在     IR RPM  包未安装或尚
                 未将  LLVM IR  转换为对应动态链接库之前, 用户程序默认使用传统                RPM  软件包提供的动态链接库, 一般其位于
                 系统的/usr/lib64  文件夹下. 在  IR RPM  软件包安装后, 且   LLVM IR  文件成功转换成为动态链接库之后, 可以通过
                 预设的环境与配置文件要求应用软件优先使用转换得到的动态链接库, 再次使用这些应用程序时即可实现性能提
                 升. 类似地, 也可以提供优化的可执行程序, 并通过             PATH  环境变量等方式, 使用户优先使用优化过的可执行程序.
                    为了实现这一目标, RuyiBuild     以操作系统环境变量和编译工具包装              (wrapper) 脚本为基础, 精心设计了一套
                 非侵入式的编译过程拦截机制, 如图           2  所示. 该机制通过环境变量       PATH  的动态设置, 覆盖标准构建工具         (包括但
                 不限于   clang、clang++、ar、ln、install 等), 当构建系统调用这些标准工具时, 实际上调用的是             RuyiBuild  提供的
                 同名包装脚本. 包装脚本的核心实现原理是对原始编译命令进行两次调用: 第                        1  次调用完全保持原命令不变, 以生
                 成传统的   ELF  目标文件或动态库, 确保原始构建系统的正常运行与兼容性; 第                   2  次调用则在原始编译命令基础上
                 追加生成   LLVM IR  的编译选项, 以生成对应的       LLVM IR bitcode 文件.
                    在具体实现中, 我们将原始编译命令中产生的路径信息, 特别是输出文件及其依赖的辅助文件的路径进行统
                 一的抽象与重构, 以减少文件冲突与混乱. 系统通过识别路径特征, 对路径的空间位置进行语义分类, 并将其映射
                 到用户界定的统一命名空间中. 相对路径在该命名空间中依据工作目录层级实现语义拓展, 而绝对路径则通过直
                 接进行输出路径映射保持其编译上下文不变, 实现了传统编译产物与                       IR  表征之间的严格对应, 使      IR  生成过程具
                 有可追溯性与构建语义完整性, 保障了跨层编译分析流程的稳定性与一致性.
                    此外, RuyiBuild  工具链包装脚本还需要保证对原始构建系统的透明化, 尤其是在日志处理方面. 为了避免干
                 扰原始构建系统的标准输出与错误流, 包装脚本在生成                  LLVM IR  文件的过程中, 会将详细的日志信息统一重定向
                 到单独的日志文件中. 若       LLVM IR  编译过程中发生错误, 包装脚本会自动删除之前生成的传统                   ELF  文件, 并立即
                 终止编译, 以便原始构建系统及时捕捉到错误信息并停止构建. 这种机制确保了                          RuyiBuild  对原始构建系统的完
                 全透明性与高度兼容性.
                    同时, 考虑实际软件开发中可能存在复杂的静态库构建场景, 即动态库的构建过程可能依赖于静态库中间产
                 物, RuyiBuild  进一步对传统归档工具     ar 进行了包装扩展. 当构建系统调用         ar 工具生成传统静态库文件时, 包装脚
                 本自动地在    LLVM IR  路径下进行对应的归档操作, 生成.a 格式的            LLVM IR  静态库文件. 这种扩展设计确保了
                 RuyiBuild  能够全面支持各种复杂构建场景, 而无需开发人员修改任何构建脚本或源码.
                    如图  2  所示, 为了保持软件现有的构建系统不做改动, RuyiBuild            包装了  clang、ld、install 等命令. 软件的构
                 建系统首先调用      RuyiBuild  提供的  clang, 将源码文件分别编译成目标文件和         LLVM IR bitcode 文件. 随后软件的
   29   30   31   32   33   34   35   36   37   38   39