C 如何让程序在源代码管理中显示正确的版本号?

C 如何让程序在源代码管理中显示正确的版本号?,c,version-control,makefile,C,Version Control,Makefile,我希望我的C程序在mercurial源代码管理中显示正确的版本。我的方法存在一些问题 如果我修改other.c,则版本无法正确显示 如果我没有签入就修改main.c,我希望make会警告我 在不同的目录中有许多文件。我希望只有在依赖文件更改时才能更改版本 顺便说一下,我不在乎使用哪个版本控制系统,只是想知道这些问题是否可以解决 main.c int main() { printf("version=%s\n", VERSION); return 0; } 生成文件 VERSION=$(

我希望我的C程序在mercurial源代码管理中显示正确的版本。我的方法存在一些问题

  • 如果我修改other.c,则版本无法正确显示
  • 如果我没有签入就修改main.c,我希望make会警告我
  • 在不同的目录中有许多文件。我希望只有在依赖文件更改时才能更改版本
  • 顺便说一下,我不在乎使用哪个版本控制系统,只是想知道这些问题是否可以解决

    main.c

    int main() {
      printf("version=%s\n", VERSION);
      return 0;
    }
    
    生成文件

    VERSION=$(shell hg id -i)
    # PHONY force main.c always compile
    .PHONY: main.c
    all: main
    main: main.o other.o
        gcc main.o other.o -o main
    main.o : main.c
        gcc -c -DVERSION=\"${VERSION}\" main.c -o main.o
    other.o : other.c
        gcc -c other.c -o other.o
    
    对于我的第一个问题,Carl Norum提供了一个使用PHONY的解决方案,这种方法有副作用,它将始终构建main.c和可执行文件main,即使没有修改

  • 如果希望版本字符串保持最新,则需要每次生成包含该字符串的文件。在您的例子中,这意味着构建
    main.c
    ,即使没有过时的东西。你可以把
    main.o
    做成一个虚假的目标,这样你就可以做到。如果
    main.c
    变得复杂,并且每次构建它都会让您的速度过慢,那么您可能会考虑将版本信息放在一个单独的文件中,然后构建一个

  • make
    无法单独处理您的请求,但您的版本控制系统可能会告诉您是否尚未签入文件。你可以在你的任何食谱中添加一个检查,如果失败就退出。下面是一个示例(对于git,我不知道mercurial):

  • 我不确定我是否完全理解您的第三个问题-如果您能澄清,我将尽力帮助您。

    使用SVN或CVS之类的工具进行版本控制。然后使用
    what
    格式(参见man-what)在每个.c或.cpp文件中放置一个静态字符串,该文件包含一个版本,任何一个版本系统都可以自动放置在其中

    i、 e


    您可以使用实用程序
    what
    来准确地查找生成中所有文件的版本

    第一个问题的标准解决方案是创建一个包含系统配置和更改全局变量(如版本)的文件(比如config.h)。main然后可以包含config.h。您可以手动编辑config.h,也可以使用以下规则从Makefile标志重新生成config.h:

    config.h : force-rebuild
        sed -e 's/[@]VERSION[@]/$(VERSION)/' $<.in > $@
    
    .PHONY : force-rebuild
    

    看看区别$MYREPO可以从
    svn info
    的输出和config.h的当前_版本中刮取。

    谢谢你的提示,但是你曾经做过这样的事情吗,你能给我一个示例生成文件吗?我为你添加了一个#2的示例。这个方法有两个缺点。首先,会降低源代码版本控制系统的性能。因此,git、hg默认情况下不支持此方法。第二,这种方法会让比较旧的源代码总是显示不同。特别是当您的源代码存储在多个存储库中时。您的意思是,在我将程序传递给测试团队之前,我应该标记一个标记或创建一个分支。然后将标签或分支的名称放在测试团队的版本上?
    static const char[] = "@(#) $Id$"); /* For example SVN */
    
    config.h : force-rebuild
        sed -e 's/[@]VERSION[@]/$(VERSION)/' $<.in > $@
    
    .PHONY : force-rebuild
    
    svn diff $MYREPO/tags/$CURRENT_VERSION .