【问题标题】:How to check Linux version with Autoconf?如何使用 Autoconf 检查 Linux 版本?
【发布时间】:2010-06-06 13:51:47
【问题描述】:

我的程序至少需要 Linux 2.6.26(我使用 timerfd 和其他一些 Linux 特定功能)。

我对如何编写这个宏有一个大致的了解,但我没有足够的知识来编写 Autoconf 的测试宏。算法:

  1. 运行“uname --release”并存储输出
  2. 解析输出并减去 Linux 版本号 (MAJOR.MINOR.MICRO)
  3. 比较版本

我不知道如何运行命令、存储输出和解析它。

也许这样的宏已经存在并且可用(我还没有找到)?

【问题讨论】:

    标签: linux autoconf


    【解决方案1】:

    我认为您最好使用AC_CHECK_FUNC 检测您需要的特定功能,而不是使用特定的内核版本。 如果您发现自己在将来的某个时间进行交叉编译,这也将防止损坏

    【讨论】:

    • 这对我不起作用,因为 Linux 函数从 2.6.26 版开始接受 functrion timerfd_settime() 中的标志,我只能在运行时检查它。还有其他想法吗?
    • 你的意思是它接受 2.6.26 中某些以前不存在的标志吗?您可以使用AC_CHECK_DECL 检查这些标志是否存在,如果所有其他方法都失败了,您可以使用AC_RUN_IFELSE 编译并运行一个测试程序,以检查是否真的只能在运行时进行测试
    • 是的,Linux 从 2.6.26 版本开始支持此功能中的标志。当使用任何标志时,旧内核 timerfd_settime() 上的 AFAIR 会因 EINVAL 错误而失败。我会按照你的建议尝试使用 AC_RUN_IFELSE。
    • @Goofy(18 个月大的问题可能已经完全过时)任何“只能在运行时完成”的事情也可以在配置时完成。如果您需要某个函数的某些行为,您可以编写一个被调用的测试并检查其输出。 (当运行配置脚本并运行测试时,您处于“运行时”)
    【解决方案2】:

    第 2 步(解析)和第 3 步(比较)版本有一个宏,ax_compare_version。例如:

    linux_version=$(uname --release)
    AX_COMPARE_VERSION($linux_version, [eq3], [2.6.26],
        [AC_MSG_NOTICE([Ok])],
        [AC_MSG_ERROR([Bad Linux version])])
    

    这里我使用了eq3,所以如果$linux_version 包含额外的字符串,例如-amd64,则比较仍然成功。有大量的比较运算符可用。

    【讨论】:

      【解决方案3】:

      我建议您不要检查 Linux 版本号,而是检查您需要的特定类型或功能。谁知道呢,也许有人决定将timerfd_settime() 向后移植到 2.4.x?所以我认为AC_CANONICAL_TARGETAC_CHECK_LIB 或类似的都是你的朋友。如果您需要检查函数参数或测试行为,您最好编写一个简单的程序并使用AC_LANG_CONFTEST([AC_LANG_PROGRAM(...)])/AC_TRY_RUN 来完成这项工作。

      【讨论】:

        【解决方案4】:

        不要太深入并正确编写 autoconf 宏(无论如何这将是更可取的),不要忘记 configure.ac 基本上是一个由 m4 预处理的 shell 脚本。所以可以直接写shell命令。

        # 上一页configure.ac 的一部分 if test `uname -r |cut -d. -f1` -lt 2 然后;回声“主要诉错误”; 1号出口;菲 if test `uname -r |cut -d. -f2` -lt 6 然后;回声“小诉错误”; 1号出口;菲 if test `uname -r |cut -d. -f3` -lt 26 然后; echo "微错误"; 1号出口;菲 # ...

        如果您想避免为 autoconf 编写宏,这只是一个想法。这个选择不好,但应该可以……

        最好的方法是已经建议的方法:您应该检查功能;因此,假设将来内核 timerfd 不再可用...或以某种方式更改您的代码已损坏...您将无法捕获它,因为您测试了版本。

        编辑

        正如用户 foof 在 cmets 中所说(换句话说),检查major.minor.micro 是一种幼稚的方法。例如。 3.5.1 将失败,因为 5 是 lt 6,但 3.5.1 出现在 2.6.26 之后,因此(很可能)它应该被接受。为了将 x.y.z 转换为将每个版本置于其“自然”顺序的表示,可以使用许多技巧。例如。如果我们预计 x、y 或 z 不会大于 999,我们可以做类似乘以 1000000 主要、1000 次要和 1 微:因此,您可以将结果与 2006026 进行比较,如 Foof 在评论中建议的那样.

        【讨论】:

        • 请注意,示例代码会因主要/次要版本更改而中断。 :-) 例如Linux 内核版本 3.5.25 将失败两次。 (您可以简单地将主要、次要和微型版本组合成一个版本号 v=$(uname -r | awk -F'[^[0-9]]*' '{print (1000000 * $1 + 1000 * $2 + $3) }') 并将此 $v2006026 进行比较,以获得更强大的测试。)
        • 你当然是对的。这是一个廉价的直接示例,说明如何对这些数字进行一些测试。它应该被视为“工具演示”,而不是工具的“正确使用”:) 将添加一些关于的词
        • (请注意,某些内核版本的微版本大于 99 - 曾经有 1.3.100 和 2.1.132 版本(参见 kernel.org/pub/linux/kernel 的子目录)。您编辑的答案仍然适用于 检查 2.6.26,但是阅读您的代码的人需要使用额外的思考周期来记住/怀疑微版本溢出;也有人可能会将解决方案复制粘贴到一个设置,但它碰巧不起作用当然不太可能有人认真使用这么旧的内核版本。我保证这是关于这个主题的最后评论!)
        • 我当时正想存零:)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-05-12
        • 2012-07-20
        • 2015-11-14
        • 1970-01-01
        • 1970-01-01
        • 2018-05-17
        • 2011-06-05
        相关资源
        最近更新 更多