RISC-V 架构适配知识库
  • 睿迁工具集
  • RVSmartPorting
  • 简体中文
  • English (US)
在 Gitee 上查看
  • 睿迁工具集
  • RVSmartPorting
  • 简体中文
  • English (US)
在 Gitee 上查看
  • 简介
    • 贡献规范
  • 入门
    • 内存一致性模型
    • 硬件开发板差异
    • 指令集模块
  • 通用调整
    • 检查项目对多架构的支持性
    • 文件结构调整
    • 目录结构调整
    • 测试用例调整
  • C/C++ 程序
    • 内联汇编
    • 宏定义与判断
    • 移位运算中的整形常数
    • Intrinsic 函数
    • 多版本函数
    • 系统调用
  • 汇编程序
  • 编译配置文件
    • rpmbuild
    • Makefile
    • CMake
    • Autoconf
    • QMake
    • 其它
  • 其它编程语言
    • Rust
    • Go
    • Python
    • 其它语言
  • 辅助工具集
    • 目标代码定位工具
    • 汇编指令翻译工具

Autoconf 配置文件

Autoconf 是一个用于生成 shell 脚本的工具,可自动配置源码包以适应多种类 Posix 的系统, 产生的配置脚本通常叫做 configure。 对于与 Autoconf 一起使用的每个软件包,它会从模板文件创建一个配置脚本, 其中列出了该软件包需要或可以使用的系统功能。

使用 automake 工具,程序开发人员只需要写一些简单的含有预定义宏的文件, 便可由 autoconf 根据该文件生成 configure 文件, 由 automake 工具根据另一个宏文件生成 Makefile.in 文件, 再使用 configure 文件依据 Makefile.in 来生成一个符合惯例的 Makefile 文件。

使用 autoconf 工具的最终目的是生成能够根据不同系统生成 Makefile 所需的 configure 文件。 一般情况下我们需要准备如下内容:

  • 软件源代码
  • configure.ac
  • Makefile.am

然后通过如下一系列命令可以生成 configure 文件:

aclocal; autoconf; autoheadr; automake --add-missing

在调用上述命令前,应先使用 autoscan 扫描源码目录寻找一般的可移植性问题, 生成 configure.scan 文件。 经过人工确认并修改后缀后,形成 configure.ac 文件。 其中包含对 Autoconf 内置宏的调用,这些宏用于测试软件包需要或可以使用的系统功能。 对于大多数功能,Autoconf 模板宏会生成自定义检查规则; 对于一些无法自动检查的特殊功能,configure.ac 需要包含一些手工检查配置。

configure.ac 脚本还需要一些关于如何进行初始化的指导性信息, 诸如如何寻找包的源文件信息、如何获得 configure 的输入、输出信息。

configure.ac 在做任何其他事情之前需要调用 AC_INIT 宏,来处理所有命令参数并且寻找源代码目录。

对于需要手工配置的项目来说,需要通过调用 AC_CONFIG_AUX_DIR 来告诉 configure.ac 到哪里去寻找一些其他的 shell 脚本。

Autoconf 生成的配置脚本 configure 可以根据系统类型或目标三元组的规范名称确定软件包的目标硬件架构平台, 其格式为:cpu-vendor-os。 configure 通常可以通过运行一个名为 config.guess 的脚本文件来推测目标架构类型的规范名称。

用户也可以使用自定义的命令行参数指定系统类型:

  • --build=build-type:目标架构类型。默认值为 config.guess 脚本的运行结果。 指定不同于宿主机的架构类型将启用交叉编译模式。如果指定了该参数,则会覆盖 config.guess 的推测结果, 取而代之的是用户给出的信息,并会调用 config.sub 对用户给出的信息进行规范化,规范化结果为 cpu-vendor-os 的形式。
  • --host=host-type:宿主机的架构类型。默认情况下,它与正在编译构建软件包的设备架构相同。
  • --target=target-type:目标架构类型(通常不使用)。默认情况下,它与宿主机的架构类型相同。

宏 AC_CONFIG_AUX_DIR(dir) 的目录 dir 中使用 config.guess、config.sub、 install.sh、pkg.m4 配置脚本,他们是配置中使用的辅助文件。

  • config.guess:configure 通过该脚本推测出它正在运行的系统类型的规范名, 该脚本使用 uname 或者预定义的 C 预处理器符号来推断系统类型的规范名。
  • config.sub:configure 通过该脚本对用户给出的关于主机、目标等任何别名进行规范化。

因此,autoconf 配置文件中与架构相关的原因可以归为以下两类:

  • Autoconf 配置文件
    • 推断系统类型的规范名列表是否已包含目标架构
      • 示例 openjdk-1.8.0 推断系统类型的规范名
    • 是否支持规范化目标架构的任何别名
      • 示例 openjdk-1.8.0 规范化用户给出的主机、目标等信息的任何别名

推断系统类型的规范名列表是否已包含目标架构

推断系统类型的规范名主要有两个步骤:

  • 通过 uname 获取 UNAME_MACHINE(主机硬件架构名称)、UNAME_RELEASE(操作系统发行版本)、 UNAME_SYSTEM(操作系统名称)、UNAME_VERSION(操作系统版本号)。
  • 根据以上四个信息用 switch-case 语句推断系统类型规范名

示例 openjdk-1.8.0 推断系统类型的规范名

  • 项目名称:openjdk-1.8.0
  • 项目版本:git#2805c1c367878ef4fea8e909367d64cd166258f6
  • 相关文件:
    • /openjdk/common/autoconf/build-aux/autoconf-config.guess
    • /openjdk/common/autoconf/build-aux/config.guess
  • 简介:openjdk-1.8.0 通过 autoconf-config.guess 和 config.guess 两个文件共同推断系统类型的规范名, 其中 config.guess 对 autoconf-config.guess 推断的规范名结果进行进一步的筛选。

通过 uname 系统命令获取系统架构相关信息:

UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown

推断系统类型规范名示例:

case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
    *:NetBSD:*:*)
    ...
    # other systems with GNU libc and userland
    s390:Linux:*:* | s390x:Linux:*:*)
  echo ${UNAME_MACHINE}-ibm-linux
  exit ;;
    sh64*:Linux:*:*)
  echo ${UNAME_MACHINE}-unknown-linux-gnu
  exit ;;
    sh*:Linux:*:*)
  echo ${UNAME_MACHINE}-unknown-linux-gnu
  exit ;;
    ...

为了适配 RISC-V 架构,需要增加以下获取规范名的代码:

    riscv64:Linux:*:*)
    echo riscv64-unknown-linux-gnu
    exit ;;

是否支持规范化目标架构的任何别名

规范化用户给出的主机、目标等信息的任何别名主要有以下两个步骤:

  • 分析命令行参数,从参数中提取出用户给出的包含主机信息的参数
  • 从指定的参数值中,筛选出操作系统、架构信息,并对信息进行规范化处理

示例 openjdk-1.8.0 规范化用户给出的主机、目标等信息的任何别名

  • 项目名称:openjdk-1.8.0
  • 项目版本:git#2805c1c367878ef4fea8e909367d64cd166258f6
  • 相关文件:
    • /openjdk/common/autoconf/build-aux/config.sub
    • /openjdk/common/autoconf/build-aux/autoconf-config.sub
  • 简介:openjdk-1.8.0 通过 autoconf-config.sub 和 config.sub 两个文件共同规范化信息, 其中 config.sub 对 autoconf-config.sub 规范化的结果进行进一步的筛选。

分析命令行指令:

# Parse command line
while test $# -gt 0 ; do
  case $1 in
    --time-stamp | --time* | -t )
       echo "$timestamp" ; exit ;;
    --version | -v )
       echo "$version" ; exit ;;
    --help | --h* | -h )
       echo "$usage"; exit ;;
    -- )     # Stop option processing
       shift; break ;;
    - )  # Use stdin as input.
       break ;;
    -* )
       echo "$me: invalid option $1$help"
       exit 1 ;;

    *local*)
       # First pass through any local machine types.
       echo $1
       exit ;;

    * )
       break ;;
  esac
done

提取出用户给出的包含 KERNEL-OS 格式的信息:

maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
  storm-chaos* | os2-emx* | rtmk-nova*)
    os=-$maybe_os
    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
    ;;
  *)
    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
    if [ $basic_machine != $1 ]
    then os=`echo $1 | sed 's/.*-/-/'`
    else os=; fi
    ;;
esac

识别架构类型并规范化处理:

case $basic_machine in
  # Recognize the basic CPU types without company name.
  # Some are omitted here because they have special meanings below.
  1750a | 580 \
  | a29k \
  | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
  | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
  | am33_2.0 \
  | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
  | bfin \
    ...
    | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
  | z8k)
    basic_machine=$basic_machine-unknown
    ;;
  m6811 | m68hc11 | m6812 | m68hc12)
    # Motorola 68HC11/12.
    basic_machine=$basic_machine-unknown
    os=-none
    ;;
  m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
    ;;
  ms1)
    basic_machine=mt-unknown
    ;;

在此部分添加对 RISC-V 架构判断的代码:

  | riscv32 | riscv64 \
  | riscv32-* | riscv64-* \
编辑本页面
最后更新时间:
贡献者: LightningRS, cdy
Prev
CMake
Next
QMake

本知识库采用 木兰开放作品许可协议 署名-相同方式共享 第1版 进行许可

版权所有 © 2025 RVSmartPorting. | 京ICP备20005262号 | beian京公网安备11010802043677号