Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

$WCREV$

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

SubWCRev .\ yourfile.txt.template yourfile.txt

Это скопирует из yourfile.txt.template, выполнит подстановки и напишет в yourfile.txt.

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

Ответ 2

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

1/Создал папку /Build внутри каждого проекта

2/Скопированный AssemblyInfo.cs в папку Build как AssemblyInfo.cs.txt, установите для параметра "Действие сборки" значение "Нет"

3/Отредактировано AssemblyInfo.cs.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 Server с Visual Studio 2008.

UPDATE:

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

Ответ 3

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

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

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

Ответ 4

Возможно, вы захотите изучить Свойства 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) "\0"

#define MY_COMPANY_NAME         "IniTech\0"
#define MY_COPYRIGHT            "Copyright ©2009 " MY_COMPANY_NAME
#define MY_PRODUCT_NAME         "\0"
#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). Эта структура дала нам большую гибкость и прослеживаемость во всем типе штампа. Он вырос из простого куска в пакетном файле в это многоуровневое чудовище, но он работал очень хорошо для нас в течение последних нескольких лет.

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