Как синхронизировать ресурсы и редакции SVN файлов EXE / DLL? - PullRequest
12 голосов
/ 25 апреля 2009

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

Ответы [ 4 ]

11 голосов
/ 25 апреля 2009

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

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

$WCREV$

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

SubWCRev .\ yourfile.txt.template yourfile.txt

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

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

3 голосов
/ 03 декабря 2010

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

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

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

3 голосов
/ 17 июля 2009

Это отличная помощь, спасибо. Я улучшил это для 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 для решения этой проблемы.

2 голосов
/ 25 апреля 2009

Возможно, вы захотите посмотреть Свойства 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, который определяет пользовательский инструмент, который обрабатывает это.

...