【问题标题】:What's the best way to insert version and arch info into C++ sources?将版本和架构信息插入 C++ 源代码的最佳方法是什么?
【发布时间】:2010-01-19 20:10:20
【问题描述】:

我希望我的 C++ 程序包含一个“--version”选项,它会导致它打印出来:

  • 为其编译的架构
  • 源版本(例如 v0.1.0)
  • 应用名称

我也是第一次使用 autoconf/automake,我注意到 configure.ac 既有二进制文件又有版本。它目前没有架构信息,我不想添加此类信息,因为我将在多个架构下编译。

是否有一种简单的方法可以自动在头文件或源文件中插入版本/arch/appname 信息?大多数 C++ 编码人员是如何做到这一点的?

【问题讨论】:

    标签: c++ version autoconf automake


    【解决方案1】:

    autoconf 为您提供了一个config.h,它提供了诸如PACKAGEPACKAGE_NAMEPACKAGE_STRINGPACKAGE_VERSIONVERSION 等字符串宏。

    (当我使用Argp 参数解析器时,我只是使用

    #ifdef HAVE_CONFIG_H
    # include <config.h>
    #endif
    #include <argp.h>
    const char *argp_program_version = PACKAGE_STRING;
    const char *argp_program_bug_address = PACKAGE_BUGREPORT;
    /* et cetera */
    int main(int argc, char **argv) {
        error_t argp_result = argp_parse(&argp, argc, argv, 0, 0, NULL);
        if (argp_result) return argp_result;
        /* et cetera */
    }
    

    然后--help--version 等就会自动工作。)

    你也可以添加

    AC_CANONICAL_HOST
    AC_DEFINE_UNQUOTED([CHOST], ["$host"], [Canonical host])
    AC_CANONICAL_BUILD
    AC_DEFINE_UNQUOTED([CBUILD], ["$build"], [Canonical build])
    AC_CANONICAL_TARGET
    AC_DEFINE_UNQUOTED([CTARGET], ["$target"], [Canonical target])
    

    到您的configure.ac,如果您也想在您的config.h 中包含这些字符串宏。这些通常是 $arch-$vendor-$kernel-$libc 形式的字符串,其中
    CHOST 是构建软件后将运行软件的平台,
    CBUILD 是当前正在运行的平台构建软件,并且
    CTARGET 是软件将运行的平台。
    (除非您正在交叉编译或构建交叉编译工具链,否则这些都是相同的。)

    【讨论】:

    • 第二部分正是我想要的。非常感谢。
    • 所以,有趣的是,当我以这种方式包含 config.h 时,我在下一行代码中收到此错误: main.cpp:11: error: expected unqualified-id before string constant make [2]: *** [phenomatrix-main.o] 错误1 自动生成的config.h 中除了#defines 之外什么都没有,我也没有修改过。我唯一能想到的是 config.h 在 ../ 而不是 src 中,但即使我将它移到 src 并用引号而不是克拉来#include 它,我也会得到同样的错误。
    • 适用于我,使用 autoconf 2.65 和 automake 1.10。您能否发布您的版本、configure.ac 和生成的config.h,以及您如何尝试使用 C 宏?
    • 当然。我把它们放在一个要点上:gist.github.com/282960我尝试了几种不同的方法。它编译的唯一方法是我根本不使用宏。它是 GNU autoconf 2.64,GNU automake 1.7.9。
    • 那是因为你写了const std::string VERSION = PACKAGE_STRING;VERSION 被替换为"0.1.0"PACKAGE_STRING 被替换为"phenomatrix 0.1.0",将整行变成const std::string "0.1.0" = "phenomatrix 0.1.0"; - 显然是非法的。
    【解决方案2】:

    编写一个 python 脚本来生成你的版本源文件。然后通过您使用的任何构建脚本/工具使其运行。

    选择一个规则来实际重写版本文件并在 python 脚本中强制执行:这实际上取决于您正在执行的项目类型和发布组织。


    在我的家庭项目中,我使用一个脚本,每次构建时都会生成一个版本文件,因为我需要知道计算机开发人员在什么时间构建了版本。

    但在很多工作中,我使用了一个生成版本文件的脚本,但前提是我需要它。那是因为开发团队决定了特定版本何时是“发布”。

    我建议使用 Python 脚本,因为 Python 可在所有开发平台上运行,并且在处理文本文件时非常强大且简单。然后可以由您使用的任何构建系统(Visual Studio、CMake 等)调用它。

    【讨论】:

    • 如果您在 *nix 下运行,则使用 shell/perl 脚本。(默认情况下,两者都比 python 更可能安装)
    • 我正在考虑某种方式让编译器将宏存储到您的代码中,但我真的很喜欢这个想法。
    • 既然 config.h 已经包含了信息(见 ehemient 的回答),就不用自己写脚本了
    • 我认为这个问题不是特定于 automake 的。毕竟,他问的是“大多数 C++ 编码人员是如何做到这一点的?”。对于某些长生命周期的软件,过于依赖构建系统可能会在未来的变化中产生问题。
    猜你喜欢
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    • 2010-09-08
    相关资源
    最近更新 更多