Как синхронизировать SVN ревизию и версии ресурсов EXE / DLL файлов?

скажем, у меня есть проект C++, который создает exe или dll-файл. Проект регистрируется в репозитории SVN. Я хочу автоматически синхронизировать ревизию из SVN с ресурсом версии, встроенным в мой exe / dll-файл, т. е. версия должна быть чем-то вроде $ major.$незначительный.$svn_revision.
Есть идеи, как этого достичь? Есть любые из доступных решений?

4 ответов


если у Вас установлен TortoiseSVN, то с ним установлена программа,SubWCRev.

если в вашем файле есть это значение:

$WCREV$

тогда он будет заменен на самый высокий зафиксированный номер ревизии, если вы выполните что-то вроде этого:

SubWCRev .\ yourfile.txt.template yourfile.txt

это копия с yourfile.txt.template, сделайте замены и напишите yourfile.txt.

обратите внимание, что есть много других макросов, которые вы также можете использовать, если вы выполняете SubWCRev без какого-либо аргументы, он перечислит их все на консоли.


Это большая помощь, спасибо. Я уточнил это для Visual Studio 2008, если это кому-то поможет.

1 / создал папку / Build в каждом проекте

2 / Скопировано AssemblyInfo.cs в папку сборки как AssemblyInfo.цезий.txt, установите действие сборки в "None"

3 / отредактировал AssemblyInfo.цезий.txt, чтобы иметь атрибуты версии, как показано ниже:

[assembly: AssemblyVersion("2.0.0.$WCREV$")]
[assembly: AssemblyFileVersion("2.0.0.$WCREV$")]

4 / к событиям Prebuild добавлено следующее:

SubWCRev $(SolutionDir) $(ProjectDir)\Build\AssemblyInfo.cs.txt $(ProjectDir)\Properties\AssemblyInfo.cs

это работает каждый раз, когда вы компилируете.

Я использую VisualSVN / TortoiseSVN и сервер VisualSVN с Visual Studio 2008.

обновление:

мой коллега только что обновил свою рабочую копию и AssemblyInfo.CS-это противоречие. Кажется очевидным. Я исключил его из SVN, используя VisualSVN для решения этой проблемы.


ответ по программе.X работает отлично. Однако я хотел бы добавить, что если вы создадите свой исполняемый файл до внесения изменений, ревизия будет на один меньше, чем фактический номер ревизии запущенного кода. Чтобы смягчить это, вы можете установить версии в

"2.0.$WCREV$.$WCMODS?1:0$"

это поставит 1 на конец, если есть какие-либо локальные изменения, и 0, если нет. Поэтому, если вы посмотрите на свой исполняемый файл позже и увидите 2.0.54.1, вы знаете, что это, вероятно, на самом деле версия 55.


возможно, вы захотите взглянуть на Свойства Subversion и Ключевые Слова Subversion. Они не решают проблему ресурсов, так как они всегда включают это проклятое $KeywordName: ...$ часть. Пользовательские свойства предоставляют хороший способ для внесения данных в пакетных файлах, а что нет.

в любом случае, я искал решение проблемы ресурсов несколько лет назад и не нашел его. Итак, мы создали собственное доморощенное решение. Мы изменили наш файл RC на включите файл заголовка, созданный в процессе сборки. RC зависел от заголовка, и заголовок имел пользовательское правило сборки, которое вызывало пакетный файл для создания заголовка. Следующий фрагмент извлекает текущую ревизию из выходных данных svn info.

SET rootdir=%1
SET svnrev=0
PUSHD "%rootdir%"
FOR /F "tokens=1-4 delims=: " %%I IN ('svn info') DO (
    IF /I {%%I}=={rev} SET svnrev=%%L
)
(ECHO./*
 ECHO. * version-stamp.h - repository version information
 ECHO. */
 ECHO.#ifndef VERSION_STAMP_H
 ECHO.#define VERSION_STAMP_H
 ECHO.#define REPOSITORY_VERSION %svnrev%
 ECHO.#endif) > include\version-stamp.h
POPD

затем мы создали заголовок штамповки конкретной версии компонента с именем component-info.h это выглядело примерно так:

#ifndef component_info_h
#define component_info_h
#include "product-info.h"
#include "version-stamp.h"

#define VERS_MAJOR 1
#define VERS_MINOR 2
#define VERS_PATCH 3
#define VERS_BUILD REPOSITORY_VERSION

#define MY_COMPONENT_NAME "TPS Report Generator"    
#define MY_VERSION_NUMBER VERS_MAJOR,VERS_MINOR,VERS_PATCH,VERS_BUILD
#define MY_VERSION_STRING VERSION_STRING(VERS_MAJOR,VERS_MINOR,VERS_PATCH,VERS_BUILD)

#endif

наконец, у нас был файл версии линейки продуктов, который определил информация о продукте с именем product-info.h:

#ifndef product_info_h
#define product_info_h

#define PROD_VERS_MAJOR 0
#define PROD_VERS_MINOR 1
#define PROD_VERS_PATCH 0
#define PROD_VERS_BUILD 0

#define VSTR1(s) #s
#define VSTR(s) VSTR1(s)
#define VERSION_STRING(a,b,c,d) VSTR(a) "." VSTR(b) "." VSTR(c) "." VSTR(d) ""

#define MY_COMPANY_NAME         "IniTech"
#define MY_COPYRIGHT            "Copyright ©2009 " MY_COMPANY_NAME
#define MY_PRODUCT_NAME         ""
#define MY_PRODUCT_VERSION_NUM  PROD_VERS_MAJOR,PROD_VERS_MINOR,PROD_VERS_PATCH,PROD_VERS_BUILD
#define MY_PRODUCT_VERSION_STR  VERSION_STRING(PROD_VERS_MAJOR,PROD_VERS_MINOR,PROD_VERS_PATCH,PROD_VERS_BUILD)
#endif

тогда ваш файл ресурсов включает component-info.h и использует различные определения в соответствующих местах (например, FILEVERSION MY_VERSION_NUMBER). Эта структура дала нам много гибкость и traceability в всем процессе версии штемпелюя. Он вырос из простого куска в пакетном файле в это многоуровневое чудовище, но он работал очень хорошо для нас в течение последних нескольких лет.

мне трудно поверить, что никто не нашел лучшего способа сделать это еще предстоит. С другой стороны, я не занимался этим уже несколько лет. Я бы предположил, что вы можете добавить custom .rules файл, который определяет пользовательский инструмент, который обрабатывает это.