Краткий ответ (версия с вопросом): (формат 3.33.20150710.182906)
Пожалуйста, просто используйте makefile
с:
MAJOR = 3
MINOR = 33
BUILD = $(shell date +"%Y%m%d.%H%M%S")
VERSION = "\"$(MAJOR).$(MINOR).$(BUILD)\""
CPPFLAGS = -DVERSION=$(VERSION)
program.x : source.c
gcc $(CPPFLAGS) source.c -o program.x
и если вы не хотите makefile
, еще короче, просто скомпилируйте с помощью:
gcc source.c -o program.x -DVERSION=\"2.22.$(date +"%Y%m%d.%H%M%S")\"
Краткий ответ (предлагаемый вариант): (формат 150710.182906)
Используйте double
для номера версии:
MakeFile:
VERSION = $(shell date +"%g%m%d.%H%M%S")
CPPFLAGS = -DVERSION=$(VERSION)
program.x : source.c
gcc $(CPPFLAGS) source.c -o program.x
Или простая команда bash:
$ gcc source.c -o program.x -DVERSION=$(date +"%g%m%d.%H%M%S")
Совет. Все еще не нравится makefile
или это просто не очень маленькая тестовая программа? Добавьте эту строку:
export CPPFLAGS='-DVERSION='$(date +"%g%m%d.%H%M%S")
к вашему ~/.profile
, и не забудьте скомпилировать с gcc $CPPFLAGS ...
Длинный ответ:
Я знаю, что этот вопрос старше, но у меня есть небольшой вклад. Лучшей практикой всегда является автоматизация того, что в противном случае может стать источником ошибок (или забвения).
Я привык к функции, которая создавала для меня номер версии. Но я предпочитаю, чтобы эта функция возвращала float
. Мой номер версии может быть напечатан с помощью: printf("%13.6f\n", version());
, который выдает что-то вроде: 150710.150411
(год (2 цифры) месяц день DOT час минута секунд).
Но, хорошо, вопрос к вам. Если вы предпочитаете "major.minor.date.time", это должна быть строка. (Поверьте мне, двойное число лучше. Если вы настаиваете на мажоре, вы все равно можете использовать двойное значение, если установите мажор и разрешите десятичным дробям быть датой + временем, например: major.datetime = 1.150710150411
Приступим к делу. Пример ниже будет работать, если вы компилируете как обычно, забыв его установить, или используете -DVERSION
для установки версии непосредственно из оболочки, но лучше всего я рекомендую третий вариант: используйте makefile
.
Три формы компиляции и результаты:
Использование make:
beco> make program.x
gcc -Wall -Wextra -g -O0 -ansi -pedantic-errors -c -DVERSION="\"3.33.20150710.045829\"" program.c -o program.o
gcc program.o -o program.x
Бег:
__DATE__: 'Jul 10 2015'
__TIME__: '04:58:29'
VERSION: '3.33.20150710.045829'
Использование -DVERSION:
beco> gcc program.c -o program.x -Wall -Wextra -g -O0 -ansi -pedantic-errors -DVERSION=\"2.22.$(date +"%Y%m%d.%H%M%S")\"
Бег:
__DATE__: 'Jul 10 2015'
__TIME__: '04:58:37'
VERSION: '2.22.20150710.045837'
Использование встроенной функции:
beco> gcc program.c -o program.x -Wall -Wextra -g -O0 -ansi -pedantic-errors
Бег:
__DATE__: 'Jul 10 2015'
__TIME__: '04:58:43'
VERSION(): '1.11.20150710.045843'
Исходный код
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4
5 #define FUNC_VERSION (0)
6 #ifndef VERSION
7 #define MAJOR 1
8 #define MINOR 11
9 #define VERSION version()
10 #undef FUNC_VERSION
11 #define FUNC_VERSION (1)
12 char sversion[]="9999.9999.20150710.045535";
13 #endif
14
15 #if(FUNC_VERSION)
16 char *version(void);
17 #endif
18
19 int main(void)
20 {
21
22 printf("__DATE__: '%s'\n", __DATE__);
23 printf("__TIME__: '%s'\n", __TIME__);
24
25 printf("VERSION%s: '%s'\n", (FUNC_VERSION?"()":""), VERSION);
26 return 0;
27 }
28
29 /* String format: */
30 /* __DATE__="Oct 8 2013" */
31 /* __TIME__="00:13:39" */
32
33 /* Version Function: returns the version string */
34 #if(FUNC_VERSION)
35 char *version(void)
36 {
37 const char data[]=__DATE__;
38 const char tempo[]=__TIME__;
39 const char nomes[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
40 char omes[4];
41 int ano, mes, dia, hora, min, seg;
42
43 if(strcmp(sversion,"9999.9999.20150710.045535"))
44 return sversion;
45
46 if(strlen(data)!=11||strlen(tempo)!=8)
47 return NULL;
48
49 sscanf(data, "%s %d %d", omes, &dia, &ano);
50 sscanf(tempo, "%d:%d:%d", &hora, &min, &seg);
51 mes=(strstr(nomes, omes)-nomes)/3+1;
52 sprintf(sversion,"%d.%d.%04d%02d%02d.%02d%02d%02d", MAJOR, MINOR, ano, mes, dia, hora, min, seg);
53
54 return sversion;
55 }
56 #endif
Обратите внимание, что строка ограничена MAJOR<=9999
и MINOR<=9999
. Конечно, я установил это высокое значение, которое, надеюсь, никогда не переполнится. Но использовать double
все же лучше (плюс, это полностью автоматически, не нужно вручную задавать MAJOR
и MINOR
).
Теперь программа выше - это слишком много. Лучше полностью удалить функцию и гарантировать, что макрос VERSION
определен либо -DVERSION
непосредственно в командной строке GCC (или псевдонимом, который автоматически добавляет его, чтобы вы не могли забыть), либо рекомендуемым решением, чтобы включить этот процесс в makefile
.
Вот makefile
, который я использую:
Источник MakeFile:
1 MAJOR = 3
2 MINOR = 33
3 BUILD = $(shell date +"%Y%m%d.%H%M%S")
4 VERSION = "\"$(MAJOR).$(MINOR).$(BUILD)\""
5 CC = gcc
6 CFLAGS = -Wall -Wextra -g -O0 -ansi -pedantic-errors
7 CPPFLAGS = -DVERSION=$(VERSION)
8 LDLIBS =
9
10 %.x : %.c
11 $(CC) $(CFLAGS) $(CPPFLAGS) $(LDLIBS) $^ -o $@
Улучшенная версия с DOUBLE
Теперь, когда я представил вам «ваше» предпочтительное решение, вот мое решение:
Скомпилировать напрямую с помощью (а) makefile или (б) gcc:
(а) MakeFile:
VERSION = $(shell date +"%g%m%d.%H%M%S")
CC = gcc
CFLAGS = -Wall -Wextra -g -O0 -ansi -pedantic-errors
CPPFLAGS = -DVERSION=$(VERSION)
LDLIBS =
%.x : %.c
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDLIBS) $^ -o $@
(b) Или простая команда bash:
$ gcc program.c -o program.x -Wall -Wextra -g -O0 -ansi -pedantic-errors -DVERSION=$(date +"%g%m%d.%H%M%S")
Исходный код (двойная версия):
#ifndef VERSION
#define VERSION version()
#endif
double version(void);
int main(void)
{
printf("VERSION%s: '%13.6f'\n", (FUNC_VERSION?"()":""), VERSION);
return 0;
}
double version(void)
{
const char data[]=__DATE__;
const char tempo[]=__TIME__;
const char nomes[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
char omes[4];
int ano, mes, dia, hora, min, seg;
char sversion[]="130910.001339";
double fv;
if(strlen(data)!=11||strlen(tempo)!=8)
return -1.0;
sscanf(data, "%s %d %d", omes, &dia, &ano);
sscanf(tempo, "%d:%d:%d", &hora, &min, &seg);
mes=(strstr(nomes, omes)-nomes)/3+1;
sprintf(sversion,"%04d%02d%02d.%02d%02d%02d", ano, mes, dia, hora, min, seg);
fv=atof(sversion);
return fv;
}
Примечание: эта двойная функция существует только в том случае, если вы забыли определить макрос VERSION. Если вы используете makefile
или устанавливаете alias gcc gcc -DVERSION=$(date +"%g%m%d.%H%M%S")
, вы можете полностью удалить эту функцию.
Вот и все. Очень аккуратный и простой способ настроить контроль версий и больше никогда об этом не беспокоиться!
person
DrBeco
schedule
10.07.2015
_VERSION
нарушает правило идентификатора, которое начинается с подчеркивания, за которым следует заглавная буква, зарезервировано для реализации. - person chris   schedule 28.07.20121.4.1432.2234
Не могли бы вы объяснить, почему1432
— это дата, а2234
— это время? Это время просто22:34
(то есть10:34 P.M.
)? - person steveha   schedule 10.05.2013