1

我们已经通过 RCS 关键字在 CVS 中使用“Ident”工具从我们的源代码中获取一些信息,例如“ID”和“DATE”。我们可以通过在文本文件中插入关键字 $Id$ 和 $Date$ 来简单地做到这一点,而且当我们编译程序时,可以通过 Ident 工具从二进制文件中获得相同的信息:

$ ident a.out

现在,我们正在使用 SVN。它仍然可以通过具有更好功能的 svn 属性来简单地完成。唯一的问题是我们只能在文本文件中获取此信息,但我们还需要以某种方式从二进制编译文件中获取它们,例如上面的 Ident。

知道如何从二进制文件中获取它们吗?

4

1 回答 1

1

Subversion 设置关键字后,将创建一个相同的 ID 类型字符串。未在二进制程序中设置关键字,因为这会损害二进制程序。相反,您可以在源代码中创建一个带有版本信息的字符串变量:

VERSION_STRING = "$Id$";

当 Subversion 进行结帐时,它会将其扩展为:

VERSION_STRING = "$Id: foo.blah 12338 2014/06/12 02:11:38 bsmith $";

由于这是一个变量,它会保存在二进制代码中,ident程序应该能够找到它。

确保在这个源文件上设置了 Subversion 属性svn:keywords 。否则,Subversion 不会扩展关键字。

而不是为什么你不应该使用关键字扩展......


关键字扩展是一个从更原始的版本控制系统开始的概念。这是一种跟踪修订的方法,因为working directory不存在的概念。最后,关键字最终不仅仅是痛苦而不是它的价值。有趣的是,第一个放弃自动关键字的版本控制系统是基于 RCS 的 CVS。CVS 是第一个创建工作目录而不是逐个版本控制的单个文件的版本控制系统。

一个程序不是一个或两个文件,它可以是几十个——也许是几百个。如果我有一个放置$Id$关键字的文件,则显示的版本信息就是该文件的版本信息。如果我不修改该文件,则该版本信息在每个版本中都是相同的。解决此问题的一种方法是将关键字放在每个文件中:

$ ident /bin/ksh | wc -l 
    58

/bin/ksh我的文件中有 57 个单独的关键字。现在,我所要做的就是查看每个单独的 ID 并推断出我实际拥有的 Kornshell 版本。

或者我可以这样做:

$ ksh --version
  version         sh (AT&T Research) 93u 2011-02-08

啊,现在我知道要签出哪个版本的代码了。它可能被标记为93u 2011-02-08(好吧,不是真的,因为 CVS 和 RCS 不允许带有空格或以数字开头的标签。但是,我应该能够轻松地将其转换为特定的 CVS/RCS 标签)。使用 CVS,我可以查看日志信息并查看发生了哪些更改。是否修复了某个错误?是否添加了特定功能?谁修改了代码?

为了创建此信息,构建系统使用某种方法在签出时使用此信息修改源文件。您甚至不必提交该更改。事实上,最好不要这样做。我的来源如下所示:

VERSION = "$Id: %VERSION% $";

并通过构建系统替换%VERSION%为我想要的任何内容%VERSION%。即使是像 PHP 或 JavaScript 版本这样的非编译代码也可以从中受益。将它与像Jenkins这样的 CI 系统相结合,它可以运行单元测试,并将软件与代码中的每个更改一起打包,您可以自动将其包含在您的实际版本中。

我们是一家 Java 商店,所以我们像这样嵌入这些信息:

<copy file="${version.file}"
    tofile="${actual.version.file}">
    <filterset>
         <filter token="VERSION" value="${env.JENKINS_JOB} Build #${env.BUILD_NUMBER}"/>
    </filterset>
</copy>

Jenkins 将用 Jenkins 作业名称和内部版本号替换该字符串。由于我们基于 Jenkins 作业和内部版本号发布我们的软件,因此我们可以通过这种方式跟踪我们的更改。

想象一下,如果这个更改产生了一个这样的编译字符串:

$Id: Project-trunk Build #343 $

ident命令可以挑选出来。此构建与一组特定的 Subversion 修订(甚至可能是一个 Subversion 标签)相关,通过使用 Subversion,我可以看到进行了哪些更改,以及是否将其集成到问题跟踪系统中。事实上,你为什么要这样做,为什么不设置它,以便 SCCS 的 `what 命令也可以获取它:

$Id: @(#) Project-trunk Build #343 < $

@ ( what command picks up the#) string and prints out the entire string until it runs into a NULL character, a _NL_ character, or the<`。

$ what program.exe
/opt/bin/program.ext
              Project-trunk Build #343
$ ident program.exe
/opt/bin/program.exe
              $Id: @(#) Project-trunk Build #343 < $
于 2014-07-03T15:42:04.523 回答