Просто отвечая на заглавный вопрос, я придумала полупрофессиональное решение (которое может быть полезно некоторым людям), которое автоматически помечает мой код тегом git version, на который я указываю, поэтому я не приходится (не забывать) вручную обновлять номер версии при каждой сборке. В настоящее время я работаю в небольшой группе (<5 разработчиков), и наше управление конфигурациями все еще находится в стадии разработки. Но пока это не созреет, это решение, которое работает для меня. </p>
Вид высокого уровня, это шаги:
Я написал скрипт, который запрашивает git для моего текущего тега версии (, используя начальные части этого ответа ).
Автоматически генерировать заголовочный файл, который #define
содержит извлеченную версию и ее части.
- Сначала поместите команду оболочки в мой make-файл верхнего уровня, который запускает этот скрипт (поэтому файл заголовка генерируется каждый раз, когда я что-то строю).
- Соответствующий код
#include
s этого заголовочного файла (который является , а не частью хранилища), и вуаля, версия автоматически включается без какого-либо ручного ввода от меня.
Более подробно:
Сценарий
В настоящее время я использую схему управления версиями из трех чисел, major.minor.build , где build может быть строкой (например, v1.8.3b). Обратите внимание, что использование echo -e
для печати новых строк работает для меня, но, возможно, printf
является лучшим вариантом
# queries git for the version tag I'm currently pointed at. Throughout SO there
# are different versions of this command, but this one works for me. And in fact
# all my tags are annotated, so I could just use "git describe"
VERSION=`git describe --tags`
# replace all the '.' with ' ', then split the array based on the spaces.
# Obviously this will have its limitations if there are spaces in your
# version tag, or maybe even wildcard characters, but that should never
# be the case for me
VER_ARRAY=(${VERSION//./ })
# pull out the major, minor, and build components. These can be used to
# pre-processor check different versions of my code for certain compatibility,
# should the need arise
V_MAJOR=${VER_ARRAY[0]}
V_MINOR=$(VER_ARRAY[1]}
V_BUILD=${VER_ARRAY[2]}
# all of my build tags are preceded by a 'v', so remove that simply by taking
# the substring starting at position 1
V_MAJOR=${V_MAJOR:1}
# define the path and header file
VERSION_HEADER=./path/to/codeVer.h
# write these to file. > creates the file and >> appends to the file
echo -e "// Auto-generated version header on " `date` "\n\n" > $VERSION_HEADER
echo -e "#define MY_CODE_VERSION \""$VERSION"\"\n\n" >> $VERSION_HEADER
echo -e "#define MY_CODE_MAJOR "$V_MAJOR >> $VERSION_HEADER
echo -e "#define MY_CODE_MINOR "$V_MINOR >> $VERSION_HEADER
echo -e "#define MY_CODE_BUILD \""$V_BUILD"\"\n\n" >> $VERSION_HEADER
Makefile
В верхней части моего make-файла у меня есть $(shell ./genVer.sh)
. Это говорит make для запуска команды оболочки, ./genVer.sh
- это путь и имя скрипта. Лучшим способом сделать это было бы сделать цель для сценария .PHONY
, а затем поместить эту цель в качестве необходимого условия для соответствующих целей, но у меня есть много целей, и это было одним ударом.
код
Теперь во всех соответствующих исходных / заголовочных файлах у меня просто есть
#include "codeVer.h"
....
#ifndef MY_CODE_VERSION
// although if codeVer.h cannot be found we will get a fatal error before
// this warning
#warning "Unable to find code version, defaulting to v0.0.0"
#define MY_CODE_VERSION "v0.0.0"
#endif
Теперь, когда я make
извлекаю текущую версию, генерируется заголовок, мой код #include
с файлом, и я получаю правильный номер версии, не выполняя никакой ручной работы. Обратите внимание, что это работает не только для последней версии, если вы извлечете старый тег, это также будет работать (если, конечно, изменения, реализующие это, были в этой версии).
У этого есть свои недостатки. Наиболее заметно
- Вы должны собрать что-то , чтобы получить версию. На самом деле я добавил
codeVer.h
в список .gitignore, так как не хочу, чтобы он отслеживался в репо. Это означает, что вы можете передать свой код кому-то, у кого этот файл отсутствует, и они не будут знать, какая это версия. Но если они используют git (как они должны делать!), И они git pull/clone
ваши вещи, все теги все равно будут с ним.
make clean
также генерирует этот файл (который кажется нелогичным), но если вы сделали это правильно и использовали цель .PHONY
, как описано выше, это не будет проблемой.
- Вероятно, о других, о которых я сейчас не думаю.